Fix use-after-free of captured interface typedef reference during parameter cloning (#8076)

This commit is contained in:
em2machine
2026-08-15 06:07:01 -04:00
committed by GitHub
parent 93401038c0
commit d2f62fda93
5 changed files with 88 additions and 17 deletions
+11 -6
View File
@@ -2190,6 +2190,11 @@ class WidthVisitor final : public VNVisitor {
if (nodep->stmtsp()) nodep->addNextHere(nodep->stmtsp()->unlinkFrBack());
VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep);
}
// Delete a subtree after removing any saved references that point into it.
static void deleteTreeCaptured(AstNode* nodep) {
V3LinkDotIfaceCapture::purgeDeletedSubtree(nodep);
nodep->deleteTree();
}
void visit(AstAttrOf* nodep) override {
VL_RESTORER(m_attrp);
m_attrp = nodep;
@@ -2206,7 +2211,7 @@ class WidthVisitor final : public VNVisitor {
= (nodep->attrType() == VAttrType::DIM_UNPK_DIMENSIONS ? dim.second
: (dim.first + dim.second));
nodep->replaceWith(new AstConst(nodep->fileline(), AstConst::Signed32{}, val));
VL_DO_DANGLING(nodep->deleteTree(), nodep);
VL_DO_DANGLING(deleteTreeCaptured(nodep), nodep);
break;
}
case VAttrType::DIM_BITS_OR_NUMBER: {
@@ -2249,7 +2254,7 @@ class WidthVisitor final : public VNVisitor {
case VAttrType::DIM_LOW: {
AstNode* const newp = new AstConst(nodep->fileline(), AstConst::Signed32{}, 0);
nodep->replaceWith(newp);
VL_DO_DANGLING(nodep->deleteTree(), nodep);
VL_DO_DANGLING(deleteTreeCaptured(nodep), nodep);
break;
}
case VAttrType::DIM_RIGHT:
@@ -2271,7 +2276,7 @@ class WidthVisitor final : public VNVisitor {
AstNodeExpr* const newp
= new AstConst(nodep->fileline(), AstConst::Signed32{}, -1);
nodep->replaceWith(newp);
VL_DO_DANGLING(nodep->deleteTree(), nodep);
VL_DO_DANGLING(deleteTreeCaptured(nodep), nodep);
break;
}
case VAttrType::DIM_BITS: {
@@ -2304,14 +2309,14 @@ class WidthVisitor final : public VNVisitor {
AstConst* const newp = dimensionValue(nodep->fileline(), baseDTypep,
nodep->attrType(), dim);
nodep->replaceWith(newp);
VL_DO_DANGLING(nodep->deleteTree(), nodep);
VL_DO_DANGLING(deleteTreeCaptured(nodep), nodep);
}
} else if (VN_IS(nodep->dimp(), Const)) {
const int dim = VN_AS(nodep->dimp(), Const)->toSInt();
AstConst* const newp
= dimensionValue(nodep->fileline(), dtypep, nodep->attrType(), dim);
nodep->replaceWith(newp);
VL_DO_DANGLING(nodep->deleteTree(), nodep);
VL_DO_DANGLING(deleteTreeCaptured(nodep), nodep);
} else { // Need a runtime lookup table. Yuk.
UASSERT_OBJ(nodep->fromp() && dtypep, nodep, "Unsized expression");
AstVar* const varp = dimensionVarp(dtypep, nodep->attrType(), msbdim);
@@ -2319,7 +2324,7 @@ class WidthVisitor final : public VNVisitor {
AstNodeExpr* const newp
= new AstArraySel{nodep->fileline(), newVarRefDollarUnit(varp), dimp};
nodep->replaceWith(newp);
VL_DO_DANGLING(nodep->deleteTree(), nodep);
VL_DO_DANGLING(deleteTreeCaptured(nodep), nodep);
}
}
break;