From 3d073c9534d9f84acf8ae6b9e3e692bb21ae47da Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Sun, 23 Aug 2020 20:00:39 -0400 Subject: [PATCH] Fix class extends to use virtual destruction --- src/V3AstNodes.cpp | 6 +++++- src/V3AstNodes.h | 3 +++ src/V3CCtors.cpp | 4 +++- src/V3LinkDot.cpp | 2 ++ 4 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/V3AstNodes.cpp b/src/V3AstNodes.cpp index b3b9c2d32..8f140aa9e 100644 --- a/src/V3AstNodes.cpp +++ b/src/V3AstNodes.cpp @@ -1095,7 +1095,11 @@ void AstClass::repairCache() { clearCache(); for (AstNode* itemp = membersp(); itemp; itemp = itemp->nextp()) { insertCache(itemp); } } -void AstClass::dump(std::ostream& str) const { this->AstNode::dump(str); } +void AstClass::dump(std::ostream& str) const { + this->AstNode::dump(str); + if (isExtended()) str << " [EXT]"; + if (isVirtual()) str << " [VIRT]"; +} AstClass* AstClassExtends::classp() const { AstClassRefDType* refp = VN_CAST(dtypep(), ClassRefDType); UASSERT_OBJ(refp, this, "class extends non-ref"); diff --git a/src/V3AstNodes.h b/src/V3AstNodes.h index 2ce8f2ffb..f4dd547ff 100644 --- a/src/V3AstNodes.h +++ b/src/V3AstNodes.h @@ -305,6 +305,7 @@ class AstClass : public AstNodeModule { MemberNameMap m_members; // Members or method children AstClassPackage* m_packagep = nullptr; // Class package this is under bool m_virtual = false; // Virtual class + bool m_extended = false; // Is extension or extended by other classes void insertCache(AstNode* nodep); public: @@ -336,6 +337,8 @@ public: const auto it = m_members.find(name); return (it == m_members.end()) ? nullptr : it->second; } + bool isExtended() const { return m_extended; } + void isExtended(bool flag) { m_extended = flag; } bool isVirtual() const { return m_virtual; } void isVirtual(bool flag) { m_virtual = flag; } }; diff --git a/src/V3CCtors.cpp b/src/V3CCtors.cpp index 14d99fc86..55c60685e 100644 --- a/src/V3CCtors.cpp +++ b/src/V3CCtors.cpp @@ -170,10 +170,12 @@ void V3CCtors::cctorsAll() { } } } - if (VN_IS(modp, Class)) { + if (AstClass* classp = VN_CAST(modp, Class)) { AstCFunc* funcp = new AstCFunc(modp->fileline(), "~", nullptr, ""); funcp->isDestructor(true); funcp->isStatic(false); + // If can be referred to by base pointer, need virtual delete + funcp->isVirtual(classp->isExtended()); funcp->slow(false); modp->addStmtp(funcp); } diff --git a/src/V3LinkDot.cpp b/src/V3LinkDot.cpp index 985eb8e26..f6916a082 100644 --- a/src/V3LinkDot.cpp +++ b/src/V3LinkDot.cpp @@ -2709,6 +2709,8 @@ private: AstClassRefDType* newp = new AstClassRefDType{nodep->fileline(), classp}; cextp->childDTypep(newp); + classp->isExtended(true); + nodep->isExtended(true); VL_DO_DANGLING(cpackagerefp->unlinkFrBack()->deleteTree(), cpackagerefp); ok = true;