Don't call randomize on null field (#4023)

Signed-off-by: Ryszard Rozak <rrozak@antmicro.com>
This commit is contained in:
Ryszard Rozak 2023-03-14 14:48:06 +01:00 committed by GitHub
parent a8ce272e4a
commit 80b7b8bbdb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 24 additions and 15 deletions

View File

@ -232,9 +232,9 @@ private:
AstFunc* const funcp = V3Randomize::newRandomizeFunc(nodep);
AstVar* const fvarp = VN_AS(funcp->fvarp(), Var);
addPrePostCall(nodep, funcp, "pre_randomize");
funcp->addStmtsp(new AstAssign{
nodep->fileline(), new AstVarRef{nodep->fileline(), fvarp, VAccess::WRITE},
new AstConst{nodep->fileline(), AstConst::WidthedValue{}, 32, 1}});
FileLine* fl = nodep->fileline();
funcp->addStmtsp(new AstAssign{fl, new AstVarRef{fl, fvarp, VAccess::WRITE},
new AstConst{fl, AstConst::WidthedValue{}, 32, 1}});
for (AstClass* classp = nodep; classp;
classp = classp->extendsp() ? classp->extendsp()->classp() : nullptr) {
for (auto* memberp = classp->stmtsp(); memberp; memberp = memberp->nextp()) {
@ -242,24 +242,25 @@ private:
if (!memberVarp || !memberVarp->isRand()) continue;
const AstNodeDType* const dtypep = memberp->dtypep()->skipRefp();
if (VN_IS(dtypep, BasicDType) || VN_IS(dtypep, StructDType)) {
AstVarRef* const refp
= new AstVarRef{nodep->fileline(), memberVarp, VAccess::WRITE};
AstNodeStmt* const stmtp = newRandStmtsp(nodep->fileline(), refp);
AstVarRef* const refp = new AstVarRef{fl, memberVarp, VAccess::WRITE};
AstNodeStmt* const stmtp = newRandStmtsp(fl, refp);
funcp->addStmtsp(stmtp);
} else if (const auto* const classRefp = VN_CAST(dtypep, ClassRefDType)) {
AstVarRef* const refp
= new AstVarRef{nodep->fileline(), memberVarp, VAccess::WRITE};
AstVarRef* const refp = new AstVarRef{fl, memberVarp, VAccess::WRITE};
AstFunc* const memberFuncp
= V3Randomize::newRandomizeFunc(classRefp->classp());
AstMethodCall* const callp
= new AstMethodCall{nodep->fileline(), refp, "randomize", nullptr};
AstMethodCall* const callp = new AstMethodCall{fl, refp, "randomize", nullptr};
callp->taskp(memberFuncp);
callp->dtypeFrom(memberFuncp);
funcp->addStmtsp(new AstAssign{
nodep->fileline(), new AstVarRef{nodep->fileline(), fvarp, VAccess::WRITE},
new AstAnd{nodep->fileline(),
new AstVarRef{nodep->fileline(), fvarp, VAccess::READ},
callp}});
AstAssign* const assignp = new AstAssign{
fl, new AstVarRef{fl, fvarp, VAccess::WRITE},
new AstAnd{fl, new AstVarRef{fl, fvarp, VAccess::READ}, callp}};
AstIf* const assignIfNotNullp
= new AstIf{fl,
new AstNeq{fl, new AstVarRef{fl, memberVarp, VAccess::READ},
new AstConst{fl, AstConst::Null{}}},
assignp};
funcp->addStmtsp(assignIfNotNullp);
} else {
memberp->v3warn(E_UNSUPPORTED,
"Unsupported: random member variables with type "

View File

@ -78,6 +78,10 @@ class OtherCls;
endclass
class ContainsNull;
rand BaseCls b;
endclass
module t (/*AUTOARG*/);
bit ok = 0;
longint checksum;
@ -89,6 +93,7 @@ module t (/*AUTOARG*/);
DerivedCls derived;
OtherCls other;
BaseCls base;
ContainsNull cont;
initial begin
int rand_result;
@ -96,15 +101,18 @@ module t (/*AUTOARG*/);
for (int i = 0; i < 10; i++) begin
derived = new;
other = new;
cont = new;
base = derived;
rand_result = base.randomize();
rand_result = other.randomize();
rand_result = cont.randomize();
if (!(derived.l inside {ONE, TWO, THREE, FOUR})) $stop;
if (!(other.str.s.c inside {ONE, TWO, THREE, FOUR})) $stop;
if (!(other.str.y inside {ONE, TWO, THREE, FOUR})) $stop;
if (derived.i.e != 0) $stop;
if (derived.k != 0) $stop;
if (other.v != 0) $stop;
if (cont.b != null) $stop;
checksum = 0;
checksum_next(longint'(derived.i.a));
checksum_next(longint'(derived.i.b));