diff --git a/src/V3Randomize.cpp b/src/V3Randomize.cpp index 9dfb2a536..a244e1c68 100644 --- a/src/V3Randomize.cpp +++ b/src/V3Randomize.cpp @@ -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 " diff --git a/test_regress/t/t_randomize_method.v b/test_regress/t/t_randomize_method.v index 126f0785e..fdbc8cd5d 100644 --- a/test_regress/t/t_randomize_method.v +++ b/test_regress/t/t_randomize_method.v @@ -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));