Fix super constructor calls with local variables, by using init functions (#6214) (#6933)

This commit is contained in:
Igor Zaworski
2026-03-04 17:55:55 -05:00
committed by GitHub
parent c34cd6ddf1
commit 7acd73fede
11 changed files with 122 additions and 94 deletions
+1 -13
View File
@@ -45,9 +45,6 @@ class LocalizeVisitor final : public VNVisitor {
// AstVarScope::user3p() -> Set of CFuncs referencing this VarScope. (via m_accessors)
// AstCFunc::user4p() -> Multimap of 'VarScope -> VarRefs that reference that VarScope'
// in this function. (via m_references)
// AstVarScope::user4() -> Bool indicating VarScope cannot be optimized
// - compared to AstVarScope::user1 this guarantees that this
// scope won't be optimized.
const VNUser1InUse m_user1InUse;
const VNUser3InUse m_user3InUse;
const VNUser4InUse m_user4InUse;
@@ -63,7 +60,6 @@ class LocalizeVisitor final : public VNVisitor {
// STATE - for current visit position (use VL_RESTORER)
AstCFunc* m_cfuncp = nullptr; // Current active function
uint32_t m_nodeDepth = 0; // Node depth under m_cfuncp
bool m_inSuperConstructorCallStmt = false; // If under super constructor call statement
// METHODS
bool isOptimizable(AstVarScope* nodep) {
@@ -76,7 +72,6 @@ class LocalizeVisitor final : public VNVisitor {
if (nodep->dtypep()->skipRefp()->isString()) return false;
// Variables used in super constructor call can't be localized, because
// in C++ there is no way to declare them before base class constructor call
if (nodep->user4()) return false;
return ((!nodep->user1() // Not marked as not optimizable, or ...
// .. a block temp used in a single CFunc
|| (nodep->varp()->varType() == VVarType::BLOCKTEMP
@@ -160,9 +155,6 @@ class LocalizeVisitor final : public VNVisitor {
}
void visit(AstCNew* nodep) override {
VL_RESTORER(m_inSuperConstructorCallStmt);
m_inSuperConstructorCallStmt
= m_cfuncp->isConstructor() && VN_IS(nodep->backp(), StmtExpr);
m_cfuncp->user1(true); // Mark caller as not a leaf function
iterateChildren(nodep);
}
@@ -216,11 +208,7 @@ class LocalizeVisitor final : public VNVisitor {
// Remember the reference so we can fix it up later (we always need this as well)
m_references(m_cfuncp).emplace(varScopep, nodep);
if (m_inSuperConstructorCallStmt) {
// Variable used in super constructor call can't be localized
varScopep->user1(true);
varScopep->user4(true);
} else if (!varScopep->user1()) { // Check if already marked as not optimizable
if (!varScopep->user1()) { // Check if already marked as not optimizable
// Note: we only check read variables, as it's ok to localize (and in fact discard)
// any variables that are only written but never read.
if (nodep->access().isReadOrRW() && !varScopep->user2()) {