From d34aa10fafef343d03ae940e20448b83d955b95b Mon Sep 17 00:00:00 2001 From: Ryszard Rozak Date: Fri, 10 Feb 2023 13:44:14 +0100 Subject: [PATCH] Fix class field linking when a super classes is a param (#3949) --- src/V3LinkDot.cpp | 19 +++++++++++++++++-- test_regress/t/t_class_extends_param.v | 24 ++++++++++++++++++------ 2 files changed, 35 insertions(+), 8 deletions(-) diff --git a/src/V3LinkDot.cpp b/src/V3LinkDot.cpp index e0926534a..311809d68 100644 --- a/src/V3LinkDot.cpp +++ b/src/V3LinkDot.cpp @@ -1999,10 +1999,13 @@ private: // Cleared on global // *::user1p() -> See LinkDotState // *::user2p() -> See LinkDotState - // *::user3() // bool. Processed + // *::user3() // bool. Processed // *::user4() -> See LinkDotState // Cleared on Cell - // AstVar::user5() // bool. True if pin used in this cell + // AstVar::user5() // bool. True if pin used in this cell + // AstClass::user5() // bool. True if class has a parameter + // as a (possibly indirect) base class. + // Used only in LDS_PRIMARY pass const VNUser3InUse m_inuser3; const VNUser5InUse m_inuser5; @@ -3230,6 +3233,7 @@ private: iterateChildren(nodep); } void visit(AstClass* nodep) override { + nodep->user3SetOnce(); UINFO(5, " " << nodep << endl); checkNoDot(nodep); VL_RESTORER(m_curSymp); @@ -3261,6 +3265,16 @@ private: AstClassRefDType* classRefDtypep = nullptr; AstClass* classp = VN_CAST(foundp->nodep(), Class); if (classp) { + if (classp != nodep) { + // Case with recursive inheritance is handled later in this + // function + iterate(classp); + } + if (classp->user5()) { + // Has a parameter as its base class + nodep->user5(true); + return; + } AstPin* paramsp = cpackagerefp->paramsp(); if (paramsp) paramsp = paramsp->cloneTree(true); classRefDtypep @@ -3271,6 +3285,7 @@ private: // Extending has to be handled after V3Param.cpp, but the type // reference has to be visited iterate(paramp); + nodep->user5(true); return; } else { AstNodeDType* const paramTypep = paramp->getChildDTypep(); diff --git a/test_regress/t/t_class_extends_param.v b/test_regress/t/t_class_extends_param.v index 056985bc5..0d5e8cf36 100644 --- a/test_regress/t/t_class_extends_param.v +++ b/test_regress/t/t_class_extends_param.v @@ -7,7 +7,7 @@ module t (/*AUTOARG*/ ); - class foo; + class Foo; int x = 1; function int get_x; return x; @@ -17,10 +17,10 @@ module t (/*AUTOARG*/ endfunction endclass - class bar #(type T=foo) extends T; + class Bar #(type T=Foo) extends T; endclass - class baz; + class Baz; int x = 2; function int get_x; return x; @@ -30,14 +30,26 @@ module t (/*AUTOARG*/ endfunction endclass - bar bar_foo_i; - bar #(baz) bar_baz_i; + class ExtendBar extends Bar; + function int get_x; + return super.get_x(); + endfunction + function int get_6; + return 2 * get_3(); + endfunction + endclass + + Bar bar_foo_i; + Bar #(Baz) bar_baz_i; + ExtendBar extend_bar_i; initial begin bar_foo_i = new; bar_baz_i = new; + extend_bar_i = new; if (bar_foo_i.get_x() == 1 && bar_foo_i.get_3() == 3 && - bar_baz_i.get_x() == 2 && bar_baz_i.get_4() == 4) begin + bar_baz_i.get_x() == 2 && bar_baz_i.get_4() == 4 && + extend_bar_i.get_x() == 1 && extend_bar_i.get_6() == 6) begin $write("*-* All Finished *-*\n"); $finish; end