Fix error when calling non-static method (#6916)
This commit is contained in:
parent
09ca7ea8d1
commit
4563501192
|
|
@ -237,6 +237,8 @@ class WidthVisitor final : public VNVisitor {
|
|||
TableMap m_tableMap; // Created tables so can remove duplicates
|
||||
std::map<const AstNodeDType*, AstQueueDType*>
|
||||
m_queueDTypeIndexed; // Queues with given index type
|
||||
std::map<const AstNode*, const AstClass*>
|
||||
m_containingClassp; // Containing class cache for containingClass() function
|
||||
std::unordered_set<AstVar*> m_aliasedVars; // Variables referenced in alias
|
||||
|
||||
static constexpr int ENUM_LOOKUP_BITS = 16; // Maximum # bits to make enum lookup table
|
||||
|
|
@ -6582,6 +6584,22 @@ class WidthVisitor final : public VNVisitor {
|
|||
}
|
||||
return VN_CAST(pkgItemp->backp(), Package);
|
||||
}
|
||||
const AstClass* containingClass(AstNode* nodep) {
|
||||
// backp is still needed, m_containingClassp is just a cache
|
||||
if (const AstClass* const classp = VN_CAST(nodep, Class))
|
||||
return m_containingClassp[nodep] = classp;
|
||||
if (const AstClassPackage* const packagep = VN_CAST(nodep, ClassPackage)) {
|
||||
return m_containingClassp[nodep] = packagep->classp();
|
||||
}
|
||||
if (m_containingClassp.find(nodep) != m_containingClassp.end()) {
|
||||
return m_containingClassp[nodep];
|
||||
}
|
||||
if (nodep->backp()) {
|
||||
return m_containingClassp[nodep] = containingClass(nodep->backp());
|
||||
} else {
|
||||
return m_containingClassp[nodep] = nullptr;
|
||||
}
|
||||
}
|
||||
void visit(AstFuncRef* nodep) override {
|
||||
visit(static_cast<AstNodeFTaskRef*>(nodep));
|
||||
if (nodep->taskp() && VN_IS(nodep->taskp(), Task)) {
|
||||
|
|
@ -6889,10 +6907,26 @@ class WidthVisitor final : public VNVisitor {
|
|||
return;
|
||||
}
|
||||
if ((nodep->taskp()->classMethod() && !nodep->taskp()->isStatic())
|
||||
&& !VN_IS(m_procedurep, InitialAutomatic)
|
||||
&& (!m_ftaskp || !m_ftaskp->classMethod() || m_ftaskp->isStatic()) && !m_constraintp) {
|
||||
nodep->v3error("Cannot call non-static member function "
|
||||
<< nodep->prettyNameQ() << " without object (IEEE 1800-2023 8.10)");
|
||||
&& !VN_IS(m_procedurep, InitialAutomatic) && !m_constraintp) {
|
||||
bool allow = false;
|
||||
if (m_ftaskp && m_ftaskp->classMethod() && !m_ftaskp->isStatic()) {
|
||||
if (const AstFuncRef* const funcRefp = VN_CAST(nodep, FuncRef)) {
|
||||
allow = funcRefp->superReference();
|
||||
} else if (const AstTaskRef* const taskRefp = VN_CAST(nodep, TaskRef)) {
|
||||
allow = taskRefp->superReference();
|
||||
}
|
||||
if (!allow) {
|
||||
const AstClass* callerClassp = containingClass(m_ftaskp);
|
||||
if (!callerClassp) callerClassp = containingClass(m_ftaskp->classOrPackagep());
|
||||
const AstClass* calleeClassp = VN_CAST(nodep->classOrPackagep(), Class);
|
||||
if (!calleeClassp) calleeClassp = containingClass(nodep->taskp());
|
||||
allow = AstClass::isClassExtendedFrom(callerClassp, calleeClassp);
|
||||
}
|
||||
}
|
||||
if (!allow) {
|
||||
nodep->v3error("Cannot call non-static member function "
|
||||
<< nodep->prettyNameQ() << " without object (IEEE 1800-2023 8.10)");
|
||||
}
|
||||
}
|
||||
if (nodep->taskp() && !nodep->scopeNamep()
|
||||
&& (nodep->taskp()->dpiContext() || nodep->taskp()->dpiExport())) {
|
||||
|
|
|
|||
|
|
@ -1,14 +1,22 @@
|
|||
%Error: t/t_class_misstatic_bad.v:31:5: Cannot call non-static member function 'nonstatic' without object (IEEE 1800-2023 8.10)
|
||||
: ... note: In instance 't'
|
||||
31 | nonstatic();
|
||||
| ^~~~~~~~~
|
||||
... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance.
|
||||
%Error: t/t_class_misstatic_bad.v:38:10: Cannot call non-static member function 'nonstatic' without object (IEEE 1800-2023 8.10)
|
||||
%Error: t/t_class_misstatic_bad.v:23:10: Cannot call non-static member function 'nonstatic' without object (IEEE 1800-2023 8.10)
|
||||
: ... note: In instance 't'
|
||||
38 | Cls::nonstatic();
|
||||
23 | Cls::nonstatic();
|
||||
| ^~~~~~~~~
|
||||
%Error: t/t_class_misstatic_bad.v:44:10: Cannot call non-static member function 'nonstatic' without object (IEEE 1800-2023 8.10)
|
||||
... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance.
|
||||
%Error: t/t_class_misstatic_bad.v:24:10: Cannot call non-static member function 'nonstatic_retcls' without object (IEEE 1800-2023 8.10)
|
||||
: ... note: In instance 't'
|
||||
44 | Cls::nonstatic();
|
||||
24 | Cls::nonstatic_retcls();
|
||||
| ^~~~~~~~~~~~~~~~
|
||||
%Error: t/t_class_misstatic_bad.v:35:5: Cannot call non-static member function 'nonstatic' without object (IEEE 1800-2023 8.10)
|
||||
: ... note: In instance 't'
|
||||
35 | nonstatic();
|
||||
| ^~~~~~~~~
|
||||
%Error: t/t_class_misstatic_bad.v:45:10: Cannot call non-static member function 'nonstatic' without object (IEEE 1800-2023 8.10)
|
||||
: ... note: In instance 't'
|
||||
45 | Cls::nonstatic();
|
||||
| ^~~~~~~~~
|
||||
%Error: t/t_class_misstatic_bad.v:51:10: Cannot call non-static member function 'nonstatic' without object (IEEE 1800-2023 8.10)
|
||||
: ... note: In instance 't'
|
||||
51 | Cls::nonstatic();
|
||||
| ^~~~~~~~~
|
||||
%Error: Exiting due to
|
||||
|
|
|
|||
|
|
@ -11,6 +11,9 @@ class Cls;
|
|||
endfunction
|
||||
function void nonstatic();
|
||||
endfunction
|
||||
function Cls nonstatic_retcls();
|
||||
return null;
|
||||
endfunction
|
||||
static function void isst();
|
||||
endfunction
|
||||
endclass
|
||||
|
|
@ -18,6 +21,7 @@ endclass
|
|||
class Bar;
|
||||
function void bar();
|
||||
Cls::nonstatic(); // <--- bad static ref
|
||||
Cls::nonstatic_retcls(); // <--- bad static ref
|
||||
Cls::isst();
|
||||
endfunction
|
||||
endclass
|
||||
|
|
@ -31,6 +35,9 @@ class Extends extends Cls;
|
|||
nonstatic(); // <--- bad static ref
|
||||
isst();
|
||||
endfunction
|
||||
function new();
|
||||
Cls c = super.nonstatic_retcls();
|
||||
endfunction
|
||||
endclass
|
||||
|
||||
module t;
|
||||
|
|
|
|||
Loading…
Reference in New Issue