Fix class param static not found again error (#6768).

This commit is contained in:
Wilson Snyder 2025-12-08 20:11:28 -05:00
parent bd87dfc579
commit 29ae520e69
8 changed files with 73 additions and 3 deletions

View File

@ -82,6 +82,7 @@ Verilator 5.043 devel
* Fix `--lib-create` with multi-bit clocks (#6759). [Geza Lore]
* Fix DFG reusing volatile variables. [Geza Lore]
* Fix DFG assertion on out-of-bounds selects. [Geza Lore]
* Fix class param static not found again error (#6768).
* Fix crash when super.new() called without a base class (#6772). [Matthew Ballance]
* Fix class-in-class extends with parameters (#6773).
* Fix enum item references in class extends with parameters.

View File

@ -160,7 +160,13 @@ bool AstVar::sameNode(const AstNode* samep) const {
}
AstVarRef::AstVarRef(FileLine* fl, AstVar* varp, const VAccess& access)
: ASTGEN_SUPER_VarRef(fl, varp, access) {}
: ASTGEN_SUPER_VarRef(fl, varp, access) {
if (v3Global.assertDTypesResolved()) {
UASSERT_OBJ(varp, this, "Require non-null varp post resolution");
} else if (varp) {
m_name = varp->name();
}
}
AstVarRef::AstVarRef(FileLine* fl, AstNodeModule* pkgp, AstVar* varp, const VAccess& access)
: AstVarRef{fl, varp, access} {
classOrPackagep(pkgp);
@ -171,7 +177,7 @@ AstVarRef::AstVarRef(FileLine* fl, AstVarScope* varscp, const VAccess& access)
varScopep(varscp);
}
string AstVarRef::name() const { return varp() ? varp()->name() : "<null>"; }
string AstVarRef::name() const { return varp() ? varp()->name() : nameThis(); }
bool AstVarRef::sameNode(const AstVarRef* samep) const {
if (varScopep()) {

View File

@ -1299,6 +1299,7 @@ public:
ASTGEN_MEMBERS_AstEnumItemRef;
void dump(std::ostream& str) const override;
void dumpJson(std::ostream& str) const override;
const char* broken() const;
string name() const override VL_MT_STABLE { return itemp() ? itemp()->name() : m_name; }
int instrCount() const override { return 0; }
bool sameNode(const AstNode* samep) const override {
@ -5694,6 +5695,8 @@ public:
// === AstNodeVarRef ===
class AstVarRef final : public AstNodeVarRef {
// A reference to a variable (lvalue or rvalue)
std::string m_name; // Name of varref, though name() favors varp()->namep()
// if non-null pointer (e.g.: 'this')
public:
// This form only allowed post-link because output/wire compression may
// lead to deletion of AstVar's
@ -5703,7 +5706,9 @@ public:
// This form only allowed post-link (see above)
inline AstVarRef(FileLine* fl, AstVarScope* varscp, const VAccess& access);
ASTGEN_MEMBERS_AstVarRef;
std::string nameThis() const { return m_name; }
inline string name() const override; // * = Var name
void name(const string& name) override { m_name = name; }
void dump(std::ostream& str) const override;
void dumpJson(std::ostream& str) const override;
const char* broken() const override;

View File

@ -1921,6 +1921,10 @@ string AstEnumDType::prettyDTypeName(bool full) const {
result += "}" + prettyName();
return result;
}
const char* AstEnumItemRef::broken() const {
if (v3Global.assertDTypesResolved()) BROKEN_RTN(!itemp());
return nullptr;
}
void AstEnumItemRef::dump(std::ostream& str) const {
this->AstNodeExpr::dump(str);
str << " -> ";
@ -2743,7 +2747,8 @@ void AstVarRef::dump(std::ostream& str) const {
}
void AstVarRef::dumpJson(std::ostream& str) const { dumpJsonGen(str); }
const char* AstVarRef::broken() const {
BROKEN_RTN(!varp());
// Even after assertDTypesResolved(), V3Scope will set varp() to null, but name won't be ""
BROKEN_RTN(!varp() && name().empty());
return nullptr;
}
bool AstVarRef::sameNode(const AstNode* samep) const { return sameNode(VN_DBG_AS(samep, VarRef)); }

View File

@ -2007,6 +2007,8 @@ public:
resortNetlistModules(netlistp);
V3Global::dumpCheckGlobalTree("param-predel", 0, dumpTreeEitherLevel() >= 9);
// Remove defaulted classes
// Unlike modules, which we keep around and mark dead() for later V3Dead
std::unordered_set<AstClass*> removedClassps;

View File

@ -391,6 +391,8 @@ private:
editDType(nodep);
classEncapCheck(nodep, nodep->varp(), VN_CAST(nodep->classOrPackagep(), Class));
if (nodep->access().isWriteOrRW()) varLifetimeCheck(nodep, nodep->varp());
if (VN_IS(nodep, VarRef))
nodep->name(""); // Clear to save memory; nodep->name() will work via nodep->varp()
}
void visit(AstAssign* nodep) override {
iterateChildren(nodep);

View File

@ -0,0 +1,18 @@
#!/usr/bin/env python3
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2025 by Wilson Snyder. This program is free software; you
# can redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
import vltest_bootstrap
test.scenarios('simulator')
test.compile()
test.execute()
test.passes()

View File

@ -0,0 +1,31 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain, for
// any use, without warranty, 2025 by Wilson Snyder.
// SPDX-License-Identifier: CC0-1.0
module t;
class uvm_sequence_library #(
type REQ = int,
RSP = int
);
int sequences[$];
endclass
class Cls extends uvm_sequence_library;
static int m_typewide_sequences[$];
function void init_sequence_library();
foreach (m_typewide_sequences[i]) sequences.push_back(m_typewide_sequences[i]);
endfunction
endclass
initial begin
Cls c;
c = new;
$finish;
end
endmodule