Fix unpacked-in-class array reference assignments

This commit is contained in:
Wilson Snyder 2021-03-13 13:04:13 -05:00
parent ce79c4ebf9
commit e3788e871e
6 changed files with 15 additions and 7 deletions

View File

@ -788,7 +788,7 @@ int AstNodeDType::widthPow2() const {
} }
/// What is the base variable (or const) this dereferences? /// What is the base variable (or const) this dereferences?
AstNode* AstArraySel::baseFromp(AstNode* nodep) { AstNode* AstArraySel::baseFromp(AstNode* nodep, bool overMembers) {
// Else AstArraySel etc; search for the base // Else AstArraySel etc; search for the base
while (nodep) { while (nodep) {
if (VN_IS(nodep, ArraySel)) { if (VN_IS(nodep, ArraySel)) {
@ -797,6 +797,9 @@ AstNode* AstArraySel::baseFromp(AstNode* nodep) {
} else if (VN_IS(nodep, Sel)) { } else if (VN_IS(nodep, Sel)) {
nodep = VN_CAST(nodep, Sel)->fromp(); nodep = VN_CAST(nodep, Sel)->fromp();
continue; continue;
} else if (overMembers && VN_IS(nodep, MemberSel)) {
nodep = VN_CAST(nodep, MemberSel)->fromp();
continue;
} }
// AstNodeSelPre stashes the associated variable under an ATTROF // AstNodeSelPre stashes the associated variable under an ATTROF
// of AstAttrType::VAR_BASE/MEMBER_BASE so it isn't constified // of AstAttrType::VAR_BASE/MEMBER_BASE so it isn't constified

View File

@ -1595,8 +1595,8 @@ public:
virtual bool same(const AstNode* samep) const override { return true; } virtual bool same(const AstNode* samep) const override { return true; }
virtual int instrCount() const override { return widthInstrs(); } virtual int instrCount() const override { return widthInstrs(); }
// Special operators // Special operators
static AstNode* // Return base var (or const) nodep dereferences
baseFromp(AstNode* nodep); ///< What is the base variable (or const) this dereferences? static AstNode* baseFromp(AstNode* nodep, bool overMembers);
}; };
class AstAssocSel final : public AstNodeSel { class AstAssocSel final : public AstNodeSel {

View File

@ -218,7 +218,7 @@ private:
// variable we're extracting from (to determine MSB/LSB/endianness/etc.) // variable we're extracting from (to determine MSB/LSB/endianness/etc.)
// So we replicate it in another node // So we replicate it in another node
// Note that V3Param knows not to replace AstVarRef's under AstAttrOf's // Note that V3Param knows not to replace AstVarRef's under AstAttrOf's
AstNode* basefromp = AstArraySel::baseFromp(nodep); AstNode* basefromp = AstArraySel::baseFromp(nodep, false);
if (AstNodeVarRef* varrefp if (AstNodeVarRef* varrefp
= VN_CAST(basefromp, NodeVarRef)) { // Maybe varxref - so need to clone = VN_CAST(basefromp, NodeVarRef)) { // Maybe varxref - so need to clone
nodep->attrp(new AstAttrOf(nodep->fileline(), AstAttrType::VAR_BASE, nodep->attrp(new AstAttrOf(nodep->fileline(), AstAttrType::VAR_BASE,

View File

@ -357,7 +357,7 @@ private:
iterateChildren(nodep); iterateChildren(nodep);
if (!nodep->user1SetOnce()) { if (!nodep->user1SetOnce()) {
// Guard against reading/writing past end of bit vector array // Guard against reading/writing past end of bit vector array
AstNode* basefromp = AstArraySel::baseFromp(nodep); AstNode* basefromp = AstArraySel::baseFromp(nodep, true);
bool lvalue = false; bool lvalue = false;
if (const AstNodeVarRef* varrefp = VN_CAST(basefromp, NodeVarRef)) { if (const AstNodeVarRef* varrefp = VN_CAST(basefromp, NodeVarRef)) {
lvalue = varrefp->access().isWriteOrRW(); lvalue = varrefp->access().isWriteOrRW();
@ -405,7 +405,7 @@ private:
if (!nodep->user1SetOnce()) { if (!nodep->user1SetOnce()) {
if (debug() == 9) nodep->dumpTree(cout, "-in: "); if (debug() == 9) nodep->dumpTree(cout, "-in: ");
// Guard against reading/writing past end of arrays // Guard against reading/writing past end of arrays
AstNode* basefromp = AstArraySel::baseFromp(nodep->fromp()); AstNode* basefromp = AstArraySel::baseFromp(nodep->fromp(), true);
bool lvalue = false; bool lvalue = false;
if (const AstNodeVarRef* varrefp = VN_CAST(basefromp, NodeVarRef)) { if (const AstNodeVarRef* varrefp = VN_CAST(basefromp, NodeVarRef)) {
lvalue = varrefp->access().isWriteOrRW(); lvalue = varrefp->access().isWriteOrRW();

View File

@ -1,2 +1,2 @@
''{b:'h1, i:'h2a, carray4:'{'h0, 'h0, 'h0, 'h0} }' ''{b:'h1, i:'h2a, carray4:'{'h11, 'h22, 'h33, 'h44} }'
*-* All Finished *-* *-* All Finished *-*

View File

@ -23,6 +23,11 @@ module t (/*AUTOARG*/);
c = new; c = new;
c.b = '1; c.b = '1;
c.i = 42; c.i = 42;
c.carray4[0] = 16'h11;
c.carray4[1] = 16'h22;
c.carray4[2] = 16'h33;
c.carray4[3] = 16'h44;
$display("'%p'", c); $display("'%p'", c);
$write("*-* All Finished *-*\n"); $write("*-* All Finished *-*\n");