Fix handling of super.new calls (#4366)

This commit is contained in:
Ryszard Rozak 2023-07-17 13:30:42 +02:00 committed by GitHub
parent 4bdda3f240
commit 4de1b22672
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 38 additions and 16 deletions

View File

@ -234,6 +234,21 @@ public:
string optionalProcArg(const T* const nodep) { string optionalProcArg(const T* const nodep) {
return (nodep && constructorNeedsProcess(nodep)) ? "vlProcess, " : ""; return (nodep && constructorNeedsProcess(nodep)) ? "vlProcess, " : "";
} }
const AstCNew* getSuperNewCallRecursep(AstNode* const nodep) {
// Get the super.new call
if (!nodep) return nullptr;
if (const AstCNew* const cnewp = VN_CAST(nodep, CNew)) return cnewp;
if (const AstStmtExpr* const stmtp = VN_CAST(nodep, StmtExpr)) {
if (const AstCNew* const cnewp = VN_CAST(stmtp->exprp(), CNew)) return cnewp;
}
if (const AstJumpBlock* const blockp = VN_CAST(nodep, JumpBlock)) {
if (const AstCNew* const cnewp = getSuperNewCallRecursep(blockp->stmtsp())) {
return cnewp;
}
}
if (const AstCNew* const cnewp = getSuperNewCallRecursep(nodep->nextp())) return cnewp;
return nullptr;
}
// VISITORS // VISITORS
using EmitCConstInit::visit; using EmitCConstInit::visit;
@ -256,24 +271,16 @@ public:
puts(": "); puts(": ");
puts(nodep->baseCtors()); puts(nodep->baseCtors());
const AstClass* const classp = VN_CAST(nodep->scopep()->modp(), Class); const AstClass* const classp = VN_CAST(nodep->scopep()->modp(), Class);
bool baseCtorCall = false;
// Find call to super.new to get the arguments // Find call to super.new to get the arguments
for (AstNode* stmtp = nodep->stmtsp(); stmtp; stmtp = stmtp->nextp()) { if (classp && constructorNeedsProcess(classp)) {
AstNode* exprp; puts("(vlProcess, vlSymsp");
if (VN_IS(stmtp, StmtExpr)) {
exprp = VN_CAST(stmtp, StmtExpr)->exprp();
} else { } else {
exprp = stmtp; puts("(vlSymsp");
} }
if (AstCNew* const newRefp = VN_CAST(exprp, CNew)) { const AstCNew* const superNewCallp = getSuperNewCallRecursep(nodep->stmtsp());
puts("(" + optionalProcArg(classp) + "vlSymsp"); UASSERT_OBJ(superNewCallp, nodep, "super.new call not found");
baseCtorCall = true; putCommaIterateNext(superNewCallp->argsp(), true);
putCommaIterateNext(newRefp->argsp(), true);
puts(")"); puts(")");
break;
}
}
if (!baseCtorCall) { puts("(" + optionalProcArg(classp) + "vlSymsp)"); }
} }
puts(" {\n"); puts(" {\n");

View File

@ -39,6 +39,16 @@ class BarArg extends FooArg;
endfunction endfunction
endclass endclass
class BarArgWithReturnInIf extends FooArg;
function new (int a);
super.new(a);
if (a < 10) begin
return;
end
this.x = 20;
endfunction
endclass
class BarExpr extends FooArg; class BarExpr extends FooArg;
function new (int a, string b); function new (int a, string b);
super.new(a + b.len()); super.new(a + b.len());
@ -114,6 +124,7 @@ module t (/*AUTOARG*/
NewWithoutSuper newWithoutSuper; NewWithoutSuper newWithoutSuper;
NoNewParam#(2) noNewParam; NoNewParam#(2) noNewParam;
NewWithoutSuperParam#(1) newWithoutSuperParam; NewWithoutSuperParam#(1) newWithoutSuperParam;
BarArgWithReturnInIf barIf1, barIf10;
initial begin initial begin
bar = new; bar = new;
@ -136,6 +147,10 @@ module t (/*AUTOARG*/
`checkh(noNewParam.x, 1); `checkh(noNewParam.x, 1);
newWithoutSuperParam = new; newWithoutSuperParam = new;
`checkh(newWithoutSuperParam.x, 1); `checkh(newWithoutSuperParam.x, 1);
barIf1 = new(1);
`checkh(barIf1.x, 1);
barIf10 = new(10);
`checkh(barIf10.x, 20);
$write("*-* All Finished *-*\n"); $write("*-* All Finished *-*\n");
$finish; $finish;