From 168f0ed9e514f74087cee0e70963c711fe7dbed3 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Tue, 1 Apr 2025 08:12:34 -0400 Subject: [PATCH] Fix `new this` (#5909). --- Changes | 1 + src/V3AstNodeDType.h | 16 ++++++---------- src/V3AstNodes.cpp | 9 +++++++++ test_regress/t/t_class_new_this.v | 10 ++++++++++ 4 files changed, 26 insertions(+), 10 deletions(-) diff --git a/Changes b/Changes index 8fe7f28df..bde74e7e6 100644 --- a/Changes +++ b/Changes @@ -62,6 +62,7 @@ Verilator 5.035 devel * Fix process comparisons (#5896). * Fix ccache with clang (#5899). [Geza Lore] * Fix delayed assignment malformed LHS assertion (#5904). +* Fix `new this` (#5909). Verilator 5.034 2025-02-24 diff --git a/src/V3AstNodeDType.h b/src/V3AstNodeDType.h index 32959e228..21a16d8cd 100644 --- a/src/V3AstNodeDType.h +++ b/src/V3AstNodeDType.h @@ -120,15 +120,7 @@ public: // Iff has second dtype, set as generic node function virtual void virtRefDType2p(AstNodeDType* nodep) {} // Assignable equivalence. Calls skipRefToNonRefp() during comparisons. - bool similarDType(const AstNodeDType* samep) const { - const AstNodeDType* nodep = this; - nodep = nodep->skipRefToNonRefp(); - samep = samep->skipRefToNonRefp(); - if (nodep == samep) return true; - if (nodep->type() != samep->type()) return false; - return nodep->similarDTypeNode(samep); - } - + bool similarDType(const AstNodeDType* samep) const; // Iff has a non-null subDTypep(), as generic node function virtual AstNodeDType* subDTypep() const VL_MT_STABLE { return nullptr; } virtual bool isFourstate() const; @@ -581,7 +573,11 @@ public: const AstClassRefDType* const asamep = VN_DBG_AS(samep, ClassRefDType); return (m_classp == asamep->m_classp && m_classOrPackagep == asamep->m_classOrPackagep); } - bool similarDTypeNode(const AstNodeDType* samep) const override { return sameNode(samep); } + bool similarDTypeNode(const AstNodeDType* samep) const override { + // Doesn't need to compare m_classOrPackagep + const AstClassRefDType* const asamep = VN_DBG_AS(samep, ClassRefDType); + return m_classp == asamep->m_classp; + } void dump(std::ostream& str = std::cout) const override; void dumpJson(std::ostream& str = std::cout) const override; void dumpSmall(std::ostream& str) const override; diff --git a/src/V3AstNodes.cpp b/src/V3AstNodes.cpp index 13c4b0f87..16f50636d 100644 --- a/src/V3AstNodes.cpp +++ b/src/V3AstNodes.cpp @@ -848,6 +848,15 @@ const AstNodeDType* AstNodeDType::skipRefIterp(bool skipConst, bool skipEnum, } } +bool AstNodeDType::similarDType(const AstNodeDType* samep) const { + const AstNodeDType* nodep = this; + nodep = nodep->skipRefToNonRefp(); + samep = samep->skipRefToNonRefp(); + if (nodep == samep) return true; + if (nodep->type() != samep->type()) return false; + return nodep->similarDTypeNode(samep); +} + bool AstNodeDType::isFourstate() const { return basicp() && basicp()->isFourstate(); } class AstNodeDType::CTypeRecursed final { diff --git a/test_regress/t/t_class_new_this.v b/test_regress/t/t_class_new_this.v index facd8235c..ec3af532e 100644 --- a/test_regress/t/t_class_new_this.v +++ b/test_regress/t/t_class_new_this.v @@ -21,16 +21,26 @@ class Testcase implements ICls; virtual function string get(); return "In ICls"; endfunction + function Testcase clone(); + Testcase a = new this; + return a; + endfunction endclass module t(/*AUTOARG*/); initial begin Testcase test; + Testcase cloned; test = new; if (test.cls.name != "test_class") $stop; if (test.cls.icls.get() != "In ICls") $stop; + + cloned = test.clone(); + if (cloned.cls.name != "test_class") $stop; + test.cls.icls = null; // Prevent leak + $write("*-* All Finished *-*\n"); $finish; end