mirror of
https://github.com/verilator/verilator.git
synced 2026-10-06 18:13:50 +02:00
Fix copy constructor of classes with constraints (#8381)
This commit is contained in:
+44
-3
@@ -4583,6 +4583,43 @@ class RandomizeVisitor final : public VNVisitor {
|
||||
return resExprp;
|
||||
}
|
||||
|
||||
void addUpdateRandVarsBody(AstClass* const nodep, AstFunc* const randomizep) {
|
||||
UASSERT_OBJ(!nodep->hasRandVarsUpdate(), nodep, "__VupdateRandVars already exists");
|
||||
AstFunc* const updatep
|
||||
= new AstFunc{nodep->fileline(), "__VupdateRandVars", nullptr, nullptr};
|
||||
updatep->classMethod(true);
|
||||
updatep->isVirtual(true);
|
||||
updatep->keepAlive(true);
|
||||
updatep->needsSyms(false);
|
||||
nodep->addMembersp(updatep);
|
||||
nodep->hasRandVarsUpdate(true);
|
||||
|
||||
for (AstClass* classp = nodep; classp;
|
||||
classp = classp->extendsp() ? classp->extendsp()->classp() : nullptr) {
|
||||
AstNodeFTask* const newp = VN_AS(m_memberMap.findMember(classp, "new"), NodeFTask);
|
||||
for (AstNode* stmtp = newp->stmtsp(); stmtp; stmtp = stmtp->nextp()) {
|
||||
AstStmtExpr* const stmtExprp = VN_CAST(stmtp, StmtExpr);
|
||||
if (!stmtExprp) continue;
|
||||
AstCMethodHard* const methodp = VN_CAST(stmtExprp->exprp(), CMethodHard);
|
||||
if (!methodp || methodp->method() != VCMethod::RANDOMIZER_WRITE_VAR) continue;
|
||||
|
||||
AstNodeVarRef* const varRefp = VN_AS(methodp->pinsp(), NodeVarRef);
|
||||
if (varRefp->varp()->lifetime().isStatic()) {
|
||||
// There is no need to update pointer to a static variable
|
||||
continue;
|
||||
}
|
||||
AstCMethodHard* const updateMethodp = new AstCMethodHard{
|
||||
methodp->fileline(), methodp->fromp()->cloneTreePure(false),
|
||||
VCMethod::RANDOMIZER_UPDATE_VAR, varRefp->cloneTreePure(false)};
|
||||
updateMethodp->dtypeSetVoid();
|
||||
AstNodeExpr* const namep = VN_AS(varRefp->nextp()->nextp(), NodeExpr);
|
||||
updateMethodp->addPinsp(namep->cloneTreePure(false));
|
||||
updateMethodp->method(VCMethod::RANDOMIZER_UPDATE_VAR);
|
||||
updatep->addStmtsp(updateMethodp->makeStmt());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void addBasicRandomizeBody(AstFunc* const basicRandomizep, AstClass* const nodep,
|
||||
AstVar* randModeVarp) {
|
||||
UINFO(9, "addBasicRTB " << nodep);
|
||||
@@ -5782,6 +5819,8 @@ class RandomizeVisitor final : public VNVisitor {
|
||||
beginValp = new AstConst{fl, AstConst::WidthedValue{}, 32, 1};
|
||||
}
|
||||
|
||||
addUpdateRandVarsBody(nodep, randomizep);
|
||||
|
||||
AstFunc* const basicRandomizep
|
||||
= V3Randomize::newRandomizeFunc(m_memberMap, nodep, BASIC_RANDOMIZE_FUNC_NAME);
|
||||
addBasicRandomizeBody(basicRandomizep, nodep, randModeVarp);
|
||||
@@ -6337,9 +6376,10 @@ class RandomizeVisitor final : public VNVisitor {
|
||||
= newResizeConstrainedArrayTask(classp, m_constraintp->name());
|
||||
m_constraintp->user3p(resizerTaskp);
|
||||
}
|
||||
AstVarRef* const sizeVarRefp = new AstVarRef{
|
||||
fl, VN_AS(sizeVarp->user2p(), NodeModule), sizeVarp, VAccess::READ};
|
||||
AstCMethodHard* const resizep = new AstCMethodHard{
|
||||
fl, nodep->fromp()->unlinkFrBack(), VCMethod::DYN_RESIZE,
|
||||
new AstVarRef{fl, sizeVarp, VAccess::READ}};
|
||||
fl, nodep->fromp()->unlinkFrBack(), VCMethod::DYN_RESIZE, sizeVarRefp};
|
||||
resizep->dtypep(nodep->findVoidDType());
|
||||
resizerTaskp->addStmtsp(new AstStmtExpr{fl, resizep});
|
||||
}
|
||||
@@ -6348,7 +6388,8 @@ class RandomizeVisitor final : public VNVisitor {
|
||||
// to make sure it is always >= 0.
|
||||
m_constraintp->addItemsp(createSizeGteZeroConstraint(fl, sizeVarp));
|
||||
}
|
||||
AstVarRef* const sizeVarRefp = new AstVarRef{fl, sizeVarp, VAccess::READ};
|
||||
AstVarRef* const sizeVarRefp = new AstVarRef{fl, VN_AS(sizeVarp->user2p(), NodeModule),
|
||||
sizeVarp, VAccess::READ};
|
||||
sizeVarRefp->user1(true);
|
||||
nodep->replaceWith(sizeVarRefp);
|
||||
VL_DO_DANGLING(nodep->deleteTree(), nodep);
|
||||
|
||||
Reference in New Issue
Block a user