Fix memory leaks in assignment pattern processing (#6437).
This commit is contained in:
parent
9187b4d552
commit
ef458be855
|
|
@ -4744,25 +4744,30 @@ class WidthVisitor final : public VNVisitor {
|
||||||
userIterate(dtypep, WidthVP{SELF, BOTH}.p());
|
userIterate(dtypep, WidthVP{SELF, BOTH}.p());
|
||||||
|
|
||||||
if (auto* const vdtypep = VN_CAST(dtypep, NodeUOrStructDType)) {
|
if (auto* const vdtypep = VN_CAST(dtypep, NodeUOrStructDType)) {
|
||||||
VL_DO_DANGLING(patternUOrStruct(nodep, vdtypep, defaultp), nodep);
|
patternUOrStruct(nodep, vdtypep, defaultp);
|
||||||
} else if (auto* const vdtypep = VN_CAST(dtypep, NodeArrayDType)) {
|
} else if (auto* const vdtypep = VN_CAST(dtypep, NodeArrayDType)) {
|
||||||
VL_DO_DANGLING(patternArray(nodep, vdtypep, defaultp), nodep);
|
patternArray(nodep, vdtypep, defaultp);
|
||||||
} else if (auto* const vdtypep = VN_CAST(dtypep, AssocArrayDType)) {
|
} else if (auto* const vdtypep = VN_CAST(dtypep, AssocArrayDType)) {
|
||||||
VL_DO_DANGLING(patternAssoc(nodep, vdtypep, defaultp), nodep);
|
patternAssoc(nodep, vdtypep, defaultp);
|
||||||
} else if (auto* const vdtypep = VN_CAST(dtypep, WildcardArrayDType)) {
|
} else if (auto* const vdtypep = VN_CAST(dtypep, WildcardArrayDType)) {
|
||||||
VL_DO_DANGLING(patternWildcard(nodep, vdtypep, defaultp), nodep);
|
patternWildcard(nodep, vdtypep, defaultp);
|
||||||
} else if (auto* const vdtypep = VN_CAST(dtypep, DynArrayDType)) {
|
} else if (auto* const vdtypep = VN_CAST(dtypep, DynArrayDType)) {
|
||||||
VL_DO_DANGLING(patternDynArray(nodep, vdtypep, defaultp), nodep);
|
patternDynArray(nodep, vdtypep, defaultp);
|
||||||
} else if (auto* const vdtypep = VN_CAST(dtypep, QueueDType)) {
|
} else if (auto* const vdtypep = VN_CAST(dtypep, QueueDType)) {
|
||||||
VL_DO_DANGLING(patternQueue(nodep, vdtypep, defaultp), nodep);
|
patternQueue(nodep, vdtypep, defaultp);
|
||||||
} else if (VN_IS(dtypep, BasicDType) && VN_AS(dtypep, BasicDType)->isRanged()) {
|
} else if (VN_IS(dtypep, BasicDType) && VN_AS(dtypep, BasicDType)->isRanged()) {
|
||||||
VL_DO_DANGLING(patternBasic(nodep, dtypep, defaultp), nodep);
|
patternBasic(nodep, dtypep, defaultp);
|
||||||
} else {
|
} else {
|
||||||
nodep->v3warn(
|
nodep->v3warn(
|
||||||
E_UNSUPPORTED,
|
E_UNSUPPORTED,
|
||||||
"Unsupported: Assignment pattern applies against non struct/union data type: "
|
"Unsupported: Assignment pattern applies against non struct/union data type: "
|
||||||
<< dtypep->prettyDTypeNameQ());
|
<< dtypep->prettyDTypeNameQ());
|
||||||
|
nodep->unlinkFrBack();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Done with the Pattern
|
||||||
|
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||||
|
if (defaultp) VL_DO_DANGLING(pushDeletep(defaultp), defaultp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void patternUOrStruct(AstPattern* nodep, AstNodeUOrStructDType* vdtypep,
|
void patternUOrStruct(AstPattern* nodep, AstNodeUOrStructDType* vdtypep,
|
||||||
|
|
@ -4802,11 +4807,8 @@ class WidthVisitor final : public VNVisitor {
|
||||||
// data_type: default_value
|
// data_type: default_value
|
||||||
userIterate(nodedtypep, WidthVP{SELF, BOTH}.p());
|
userIterate(nodedtypep, WidthVP{SELF, BOTH}.p());
|
||||||
const string dtype = nodedtypep->dtypep()->prettyDTypeName(true);
|
const string dtype = nodedtypep->dtypep()->prettyDTypeName(true);
|
||||||
const auto pair = dtypemap.emplace(dtype, patp);
|
// Override stored default_value
|
||||||
if (!pair.second) {
|
dtypemap[dtype] = patp;
|
||||||
// Override stored default_value
|
|
||||||
pair.first->second = patp->cloneTree(false);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// Undefined pattern
|
// Undefined pattern
|
||||||
patp->keyp()->v3error(
|
patp->keyp()->v3error(
|
||||||
|
|
@ -4836,20 +4838,19 @@ class WidthVisitor final : public VNVisitor {
|
||||||
for (AstMemberDType* memp = vdtypep->membersp(); memp;
|
for (AstMemberDType* memp = vdtypep->membersp(); memp;
|
||||||
memp = VN_AS(memp->nextp(), MemberDType)) {
|
memp = VN_AS(memp->nextp(), MemberDType)) {
|
||||||
const auto it = patmap.find(memp);
|
const auto it = patmap.find(memp);
|
||||||
AstPatMember* patp = nullptr;
|
|
||||||
if (it == patmap.end()) { // default or default_type assignment
|
if (it == patmap.end()) { // default or default_type assignment
|
||||||
if (AstNodeUOrStructDType* const memp_nested_vdtypep
|
if (AstNodeUOrStructDType* const memp_nested_vdtypep
|
||||||
= VN_CAST(memp->virtRefDTypep(), NodeUOrStructDType)) {
|
= VN_CAST(memp->virtRefDTypep(), NodeUOrStructDType)) {
|
||||||
newp = nestedvalueConcat_patternUOrStruct(memp_nested_vdtypep, defaultp,
|
newp = nestedvalueConcat_patternUOrStruct(memp_nested_vdtypep, defaultp,
|
||||||
newp, nodep, dtypemap);
|
newp, nodep, dtypemap);
|
||||||
} else {
|
} else {
|
||||||
patp = defaultPatp_patternUOrStruct(nodep, memp, patp, vdtypep, defaultp,
|
AstPatMember* const patp = defaultPatp_patternUOrStruct(
|
||||||
dtypemap);
|
nodep, memp, vdtypep, defaultp, dtypemap);
|
||||||
newp = valueConcat_patternUOrStruct(patp, newp, memp, nodep);
|
newp = valueConcat_patternUOrStruct(patp, newp, memp, nodep);
|
||||||
|
if (patp) VL_DO_DANGLING(pushDeletep(patp), patp);
|
||||||
}
|
}
|
||||||
} else { // member assignment
|
} else { // member assignment
|
||||||
patp = it->second;
|
newp = valueConcat_patternUOrStruct(it->second, newp, memp, nodep);
|
||||||
newp = valueConcat_patternUOrStruct(patp, newp, memp, nodep);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else { // Unpacked
|
} else { // Unpacked
|
||||||
|
|
@ -4859,8 +4860,8 @@ class WidthVisitor final : public VNVisitor {
|
||||||
const auto it = patmap.find(memp);
|
const auto it = patmap.find(memp);
|
||||||
AstPatMember* patp = nullptr;
|
AstPatMember* patp = nullptr;
|
||||||
if (it == patmap.end()) { // Default or default_type assignment
|
if (it == patmap.end()) { // Default or default_type assignment
|
||||||
patp = defaultPatp_patternUOrStruct(nodep, memp, patp, vdtypep, defaultp,
|
patp = defaultPatp_patternUOrStruct(nodep, memp, vdtypep, defaultp, dtypemap);
|
||||||
dtypemap);
|
pushDeletep(patp);
|
||||||
} else {
|
} else {
|
||||||
patp = it->second; // Member assignment
|
patp = it->second; // Member assignment
|
||||||
}
|
}
|
||||||
|
|
@ -4877,13 +4878,11 @@ class WidthVisitor final : public VNVisitor {
|
||||||
} else {
|
} else {
|
||||||
nodep->v3error("Assignment pattern with no members");
|
nodep->v3error("Assignment pattern with no members");
|
||||||
}
|
}
|
||||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AstNodeExpr* nestedvalueConcat_patternUOrStruct(AstNodeUOrStructDType* memp_vdtypep,
|
AstNodeExpr* nestedvalueConcat_patternUOrStruct(AstNodeUOrStructDType* memp_vdtypep,
|
||||||
AstPatMember* defaultp, AstNodeExpr* newp,
|
AstPatMember* defaultp, AstNodeExpr* newp,
|
||||||
AstPattern* nodep, const DTypeMap& dtypemap) {
|
AstPattern* nodep, const DTypeMap& dtypemap) {
|
||||||
AstPatMember* patp = nullptr;
|
|
||||||
for (AstMemberDType* memp_nested = memp_vdtypep->membersp(); memp_nested;
|
for (AstMemberDType* memp_nested = memp_vdtypep->membersp(); memp_nested;
|
||||||
memp_nested = VN_AS(memp_nested->nextp(), MemberDType)) {
|
memp_nested = VN_AS(memp_nested->nextp(), MemberDType)) {
|
||||||
if (AstNodeUOrStructDType* const memp_multinested_vdtypep
|
if (AstNodeUOrStructDType* const memp_multinested_vdtypep
|
||||||
|
|
@ -4893,34 +4892,34 @@ class WidthVisitor final : public VNVisitor {
|
||||||
newp = nestedvalueConcat_patternUOrStruct(memp_multinested_vdtypep, defaultp, newp,
|
newp = nestedvalueConcat_patternUOrStruct(memp_multinested_vdtypep, defaultp, newp,
|
||||||
nodep, dtypemap);
|
nodep, dtypemap);
|
||||||
} else {
|
} else {
|
||||||
patp = defaultPatp_patternUOrStruct(nodep, memp_nested, patp, memp_vdtypep,
|
AstPatMember* const patp = defaultPatp_patternUOrStruct(
|
||||||
defaultp, dtypemap);
|
nodep, memp_nested, memp_vdtypep, defaultp, dtypemap);
|
||||||
newp = valueConcat_patternUOrStruct(patp, newp, memp_nested, nodep);
|
newp = valueConcat_patternUOrStruct(patp, newp, memp_nested, nodep);
|
||||||
|
if (patp) VL_DO_DANGLING(pushDeletep(patp), patp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return newp;
|
return newp;
|
||||||
}
|
}
|
||||||
|
|
||||||
AstPatMember* defaultPatp_patternUOrStruct(AstPattern* nodep, AstMemberDType* memp,
|
AstPatMember* defaultPatp_patternUOrStruct(AstPattern* nodep, AstMemberDType* memp,
|
||||||
AstPatMember* patp,
|
|
||||||
AstNodeUOrStructDType* memp_vdtypep,
|
AstNodeUOrStructDType* memp_vdtypep,
|
||||||
AstPatMember* defaultp, const DTypeMap& dtypemap) {
|
AstPatMember* defaultp, const DTypeMap& dtypemap) {
|
||||||
const string memp_DType = memp->virtRefDTypep()->prettyDTypeName(true);
|
const string memp_DType = memp->virtRefDTypep()->prettyDTypeName(true);
|
||||||
const auto it = dtypemap.find(memp_DType);
|
const auto it = dtypemap.find(memp_DType);
|
||||||
if (it != dtypemap.end()) {
|
if (it != dtypemap.end()) {
|
||||||
// default_value for data_type
|
// default_value for data_type
|
||||||
patp = it->second->cloneTree(false);
|
return it->second->cloneTree(false);
|
||||||
} else if (defaultp) {
|
|
||||||
// default_value for any unmatched member yet
|
|
||||||
patp = defaultp->cloneTree(false);
|
|
||||||
} else {
|
|
||||||
if (!VN_IS(memp_vdtypep, UnionDType)) {
|
|
||||||
nodep->v3error("Assignment pattern missed initializing elements: "
|
|
||||||
<< memp->virtRefDTypep()->prettyDTypeNameQ() << " "
|
|
||||||
<< memp->prettyNameQ());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return patp;
|
if (defaultp) {
|
||||||
|
// default_value for any unmatched member yet
|
||||||
|
return defaultp->cloneTree(false);
|
||||||
|
}
|
||||||
|
if (!VN_IS(memp_vdtypep, UnionDType)) {
|
||||||
|
nodep->v3error("Assignment pattern missed initializing elements: "
|
||||||
|
<< memp->virtRefDTypep()->prettyDTypeNameQ() << " "
|
||||||
|
<< memp->prettyNameQ());
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
AstNodeExpr* valueConcat_patternUOrStruct(AstPatMember* patp, AstNodeExpr* newp,
|
AstNodeExpr* valueConcat_patternUOrStruct(AstPatMember* patp, AstNodeExpr* newp,
|
||||||
|
|
@ -5004,7 +5003,6 @@ class WidthVisitor final : public VNVisitor {
|
||||||
nodep->v3error("Assignment pattern with no members");
|
nodep->v3error("Assignment pattern with no members");
|
||||||
}
|
}
|
||||||
// UINFOTREE(9, newp, "", "apat-out");
|
// UINFOTREE(9, newp, "", "apat-out");
|
||||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
|
||||||
}
|
}
|
||||||
void patternAssoc(AstPattern* nodep, AstAssocArrayDType* arrayDtp, AstPatMember* defaultp) {
|
void patternAssoc(AstPattern* nodep, AstAssocArrayDType* arrayDtp, AstPatMember* defaultp) {
|
||||||
AstNode* defaultValuep = nullptr;
|
AstNode* defaultValuep = nullptr;
|
||||||
|
|
@ -5033,7 +5031,6 @@ class WidthVisitor final : public VNVisitor {
|
||||||
}
|
}
|
||||||
nodep->replaceWith(newp);
|
nodep->replaceWith(newp);
|
||||||
// UINFOTREE(9, newp, "", "apat-out");
|
// UINFOTREE(9, newp, "", "apat-out");
|
||||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
|
||||||
}
|
}
|
||||||
void patternWildcard(AstPattern* nodep, AstWildcardArrayDType* arrayDtp,
|
void patternWildcard(AstPattern* nodep, AstWildcardArrayDType* arrayDtp,
|
||||||
AstPatMember* defaultp) {
|
AstPatMember* defaultp) {
|
||||||
|
|
@ -5053,9 +5050,8 @@ class WidthVisitor final : public VNVisitor {
|
||||||
}
|
}
|
||||||
nodep->replaceWith(newp);
|
nodep->replaceWith(newp);
|
||||||
// UINFOTREE(9, newp, "", "apat-out");
|
// UINFOTREE(9, newp, "", "apat-out");
|
||||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
|
||||||
}
|
}
|
||||||
void patternDynArray(AstPattern* nodep, AstDynArrayDType* arrayp, AstPatMember*) {
|
void patternDynArray(AstPattern* nodep, AstDynArrayDType* arrayp, AstPatMember* defaultp) {
|
||||||
AstNode* newp = new AstConsDynArray{nodep->fileline()};
|
AstNode* newp = new AstConsDynArray{nodep->fileline()};
|
||||||
newp->dtypeFrom(arrayp);
|
newp->dtypeFrom(arrayp);
|
||||||
for (AstPatMember* patp = VN_AS(nodep->itemsp(), PatMember); patp;
|
for (AstPatMember* patp = VN_AS(nodep->itemsp(), PatMember); patp;
|
||||||
|
|
@ -5072,9 +5068,8 @@ class WidthVisitor final : public VNVisitor {
|
||||||
}
|
}
|
||||||
nodep->replaceWith(newp);
|
nodep->replaceWith(newp);
|
||||||
// UINFOTREE(9, newp, "", "apat-out");
|
// UINFOTREE(9, newp, "", "apat-out");
|
||||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
|
||||||
}
|
}
|
||||||
void patternQueue(AstPattern* nodep, AstQueueDType* arrayp, AstPatMember*) {
|
void patternQueue(AstPattern* nodep, AstQueueDType* arrayp, AstPatMember* defaultp) {
|
||||||
AstNode* newp = new AstConsQueue{nodep->fileline()};
|
AstNode* newp = new AstConsQueue{nodep->fileline()};
|
||||||
newp->dtypeFrom(arrayp);
|
newp->dtypeFrom(arrayp);
|
||||||
for (AstPatMember* patp = VN_AS(nodep->itemsp(), PatMember); patp;
|
for (AstPatMember* patp = VN_AS(nodep->itemsp(), PatMember); patp;
|
||||||
|
|
@ -5093,7 +5088,6 @@ class WidthVisitor final : public VNVisitor {
|
||||||
}
|
}
|
||||||
nodep->replaceWith(newp);
|
nodep->replaceWith(newp);
|
||||||
// UINFOTREE(9, newp, "", "apat-out");
|
// UINFOTREE(9, newp, "", "apat-out");
|
||||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
|
||||||
}
|
}
|
||||||
void patternBasic(AstPattern* nodep, AstNodeDType* vdtypep, AstPatMember* defaultp) {
|
void patternBasic(AstPattern* nodep, AstNodeDType* vdtypep, AstPatMember* defaultp) {
|
||||||
const AstBasicDType* bdtypep = VN_AS(vdtypep, BasicDType);
|
const AstBasicDType* bdtypep = VN_AS(vdtypep, BasicDType);
|
||||||
|
|
@ -5142,7 +5136,6 @@ class WidthVisitor final : public VNVisitor {
|
||||||
nodep->v3error("Assignment pattern with no members");
|
nodep->v3error("Assignment pattern with no members");
|
||||||
}
|
}
|
||||||
// UINFOTREE(9, newp, "", "apat-out");
|
// UINFOTREE(9, newp, "", "apat-out");
|
||||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
|
||||||
}
|
}
|
||||||
AstNodeExpr* patternMemberValueIterate(AstPatMember* patp) {
|
AstNodeExpr* patternMemberValueIterate(AstPatMember* patp) {
|
||||||
// Determine values - might be another InitArray
|
// Determine values - might be another InitArray
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue