diff --git a/src/V3Param.cpp b/src/V3Param.cpp index b10521f90..977a0a803 100644 --- a/src/V3Param.cpp +++ b/src/V3Param.cpp @@ -546,6 +546,9 @@ class ParamProcessor final { } void replaceRefsRecurse(AstNode* const nodep, const AstClass* const oldClassp, AstClass* const newClassp) { + // Some of the nodes may be already marked as visited, because they were copied. They + // should be marked as unvisited, because parameterized references have to be handled. + nodep->user5(false); if (AstClassRefDType* const classRefp = VN_CAST(nodep, ClassRefDType)) { if (classRefp->classp() == oldClassp) classRefp->classp(newClassp); } else if (AstClassOrPackageRef* const classRefp = VN_CAST(nodep, ClassOrPackageRef)) { diff --git a/test_regress/t/t_class_param_type.v b/test_regress/t/t_class_param_type.v index 45a1b78ed..31402e10a 100644 --- a/test_regress/t/t_class_param_type.v +++ b/test_regress/t/t_class_param_type.v @@ -27,6 +27,23 @@ endclass typedef Cls cls_t; typedef cls_t cls2_t; +class Singleton #(type T=int); + static function Singleton#(T) self; + Singleton#(T) c = new; + return c; + endfunction + function int get_size; + return $bits(T); + endfunction +endclass + +class SingletonUnusedDefault #(type T=int); + static function SingletonUnusedDefault#(T) self; + SingletonUnusedDefault#(T) c = new; + return c; + endfunction +endclass + module t (/*AUTOARG*/); initial begin @@ -37,11 +54,25 @@ module t (/*AUTOARG*/); automatic Parcls#(cls_t) p2 = p1; automatic Parcls#(cls2_t) p3 = p2; + automatic Singleton #(int) s_int1 = Singleton#(int)::self(); + automatic Singleton #(int) s_int2 = Singleton#(int)::self(); + automatic Singleton #(bit) s_bit1 = Singleton#(bit)::self(); + automatic Singleton #(bit) s_bit2 = Singleton#(bit)::self(); + automatic SingletonUnusedDefault #(bit) sud1 = SingletonUnusedDefault#(bit)::self(); + automatic SingletonUnusedDefault #(bit) sud2 = SingletonUnusedDefault#(bit)::self(); + if (pdt1 != pdt2) $stop; if (pdt2 != pdt3) $stop; if (p1 != p2) $stop; if (p2 != p3) $stop; + if (s_int1 != s_int2) $stop; + if (s_bit1 != s_bit2) $stop; + if (sud1 != sud2) $stop; + + if (s_int1.get_size() != 32) $stop; + if (s_bit1.get_size() != 1) $stop; + if (p1.get_p() != 20) $stop; if (pdt1.get_p() != 20) $stop; if (Parcls#(cls2_t)::get_p() != 20) $stop;