From 913cf933e9562e9888a0e691a74f1a97d52a049e Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Fri, 16 Jan 2026 19:57:23 -0500 Subject: [PATCH] Fix segfault in missing extends (#6903). Fixes #6903. --- src/V3LinkDot.cpp | 46 ++++++++++++----------- test_regress/t/t_class_extends_nf_bad.out | 3 ++ test_regress/t/t_class_extends_nf_bad.v | 3 ++ 3 files changed, 30 insertions(+), 22 deletions(-) diff --git a/src/V3LinkDot.cpp b/src/V3LinkDot.cpp index 61f8ef4ac..af2c88826 100644 --- a/src/V3LinkDot.cpp +++ b/src/V3LinkDot.cpp @@ -4983,7 +4983,10 @@ class LinkDotResolveVisitor final : public VNVisitor { cprp = dotp->rhsp(); VSymEnt* const foundp = m_statep->resolveClassOrPackage( lookSymp, lookNodep, true, false, nodep->verilogKwd()); - if (!foundp) return; + if (!foundp) { + VL_DO_DANGLING(pushDeletep(nodep->unlinkFrBack()), nodep); + return; + } UASSERT_OBJ(lookNodep->classOrPackageSkipp(), nodep, "Bad package link"); lookSymp = m_statep->getNodeSym(lookNodep->classOrPackageSkipp()); } else { @@ -4995,34 +4998,33 @@ class LinkDotResolveVisitor final : public VNVisitor { if (VL_UNCOVERABLE(!cpackagerefp)) { // Linking the extend gives an error before this is hit nodep->v3error("Attempting to extend using non-class"); // LCOV_EXCL_LINE + VL_DO_DANGLING(pushDeletep(nodep->unlinkFrBack()), nodep); return; } VSymEnt* const foundp = m_statep->resolveClassOrPackage(lookSymp, cpackagerefp, true, true, nodep->verilogKwd()); - if (foundp) { - if (AstClass* const classp = VN_CAST(foundp->nodep(), Class)) { - AstPin* paramsp = cpackagerefp->paramsp(); - if (paramsp) { - paramsp = paramsp->cloneTree(true); - nodep->parameterized(true); - } - nodep->childDTypep(new AstClassRefDType{nodep->fileline(), classp, paramsp}); - // Link pins - iterate(nodep->childDTypep()); - } else if (AstParamTypeDType* const paramp - = VN_CAST(foundp->nodep(), ParamTypeDType)) { - AstRefDType* const refParamp - = new AstRefDType{nodep->fileline(), paramp->name()}; - refParamp->refDTypep(paramp); - nodep->childDTypep(refParamp); + if (!foundp) { + VL_DO_DANGLING(pushDeletep(nodep->unlinkFrBack()), nodep); + return; + } + if (AstClass* const classp = VN_CAST(foundp->nodep(), Class)) { + AstPin* paramsp = cpackagerefp->paramsp(); + if (paramsp) { + paramsp = paramsp->cloneTree(true); nodep->parameterized(true); - } else { - nodep->v3warn(E_UNSUPPORTED, - "Unsupported: " << foundp->nodep()->prettyTypeName() - << " in 'class extends'"); - return; } + nodep->childDTypep(new AstClassRefDType{nodep->fileline(), classp, paramsp}); + // Link pins + iterate(nodep->childDTypep()); + } else if (AstParamTypeDType* const paramp + = VN_CAST(foundp->nodep(), ParamTypeDType)) { + AstRefDType* const refParamp = new AstRefDType{nodep->fileline(), paramp->name()}; + refParamp->refDTypep(paramp); + nodep->childDTypep(refParamp); + nodep->parameterized(true); } else { + nodep->v3warn(E_UNSUPPORTED, "Unsupported: " << foundp->nodep()->prettyTypeName() + << " in 'class extends'"); return; } if (!nodep->childDTypep()) nodep->v3error("Attempting to extend using non-class"); diff --git a/test_regress/t/t_class_extends_nf_bad.out b/test_regress/t/t_class_extends_nf_bad.out index aa7a6cc54..d3a6993b3 100644 --- a/test_regress/t/t_class_extends_nf_bad.out +++ b/test_regress/t/t_class_extends_nf_bad.out @@ -7,4 +7,7 @@ : ... Suggested alternative: 'otFound2' 18 | class Cls2 extends Pkg::NotFound2; | ^~~~~~~~~ +%Error: t/t_class_extends_nf_bad.v:20:10: 'super' used on non-extended class (IEEE 1800-2023 8.15) + 20 | super.new(); + | ^ %Error: Exiting due to diff --git a/test_regress/t/t_class_extends_nf_bad.v b/test_regress/t/t_class_extends_nf_bad.v index bd62fa917..14420673e 100644 --- a/test_regress/t/t_class_extends_nf_bad.v +++ b/test_regress/t/t_class_extends_nf_bad.v @@ -16,6 +16,9 @@ class Cls extends IsNotFound; // BAD: not found endclass class Cls2 extends Pkg::NotFound2; // BAD: not found + function new; + super.new(); + endfunction endclass module t;