From d753f36ebc625222e119b082a74ac6866f351743 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Sun, 12 Dec 2021 18:10:52 -0500 Subject: [PATCH] Internals: Add missing broken assertions & cloneTrees --- src/V3Ast.h | 7 ++-- src/V3AstInlines.h | 6 --- src/V3AstNodes.cpp | 23 +++++++++++- src/V3AstNodes.h | 50 +++++++++++++++++++++++++ src/V3Dead.cpp | 1 + test_regress/t/t_func_tasknsvar_bad.out | 2 +- 6 files changed, 78 insertions(+), 11 deletions(-) diff --git a/src/V3Ast.h b/src/V3Ast.h index 52429b154..14d58d1f7 100644 --- a/src/V3Ast.h +++ b/src/V3Ast.h @@ -1826,6 +1826,9 @@ public: virtual AstNodeDType* getChild2DTypep() const { return nullptr; } // Another AstNode* may have a pointer into this node, other then normal front/back/etc. virtual bool maybePointedTo() const { return false; } + // Don't reclaim this node in V3Dead + virtual bool undead() const { return false; } + // Check if node is consistent, return nullptr if ok, else reason string virtual const char* broken() const { return nullptr; } // INVOKERS @@ -2867,9 +2870,7 @@ protected: public: ASTNODE_BASE_FUNCS(NodeFTaskRef) virtual const char* broken() const override; - virtual void cloneRelink() override { - if (m_taskp && m_taskp->clonep()) m_taskp = m_taskp->clonep(); - } + virtual void cloneRelink() override; virtual void dump(std::ostream& str = std::cout) const override; virtual string name() const override { return m_name; } // * = Var name virtual bool isGateOptimizable() const override { diff --git a/src/V3AstInlines.h b/src/V3AstInlines.h index 6058da776..154c0914d 100644 --- a/src/V3AstInlines.h +++ b/src/V3AstInlines.h @@ -78,12 +78,6 @@ inline int AstNodeArrayDType::lo() const { return rangep()->loConst(); } inline int AstNodeArrayDType::elementsConst() const { return rangep()->elementsConst(); } inline VNumRange AstNodeArrayDType::declRange() const { return VNumRange{left(), right()}; } -inline const char* AstNodeFTaskRef::broken() const { - BROKEN_RTN(m_taskp && !m_taskp->brokeExists()); - BROKEN_RTN(m_classOrPackagep && !m_classOrPackagep->brokeExists()); - return nullptr; -} - inline void AstIfaceRefDType::cloneRelink() { if (m_cellp && m_cellp->clonep()) m_cellp = m_cellp->clonep(); if (m_ifacep && m_ifacep->clonep()) m_ifacep = m_ifacep->clonep(); diff --git a/src/V3AstNodes.cpp b/src/V3AstNodes.cpp index bbafbc259..4288eb34c 100644 --- a/src/V3AstNodes.cpp +++ b/src/V3AstNodes.cpp @@ -47,14 +47,32 @@ AstIface* AstIfaceRefDType::ifaceViaCellp() const { return ((m_cellp && m_cellp->modp()) ? VN_AS(m_cellp->modp(), Iface) : m_ifacep); } +const char* AstNodeFTaskRef::broken() const { + BROKEN_RTN(m_taskp && !m_taskp->brokeExists()); + BROKEN_RTN(m_classOrPackagep && !m_classOrPackagep->brokeExists()); + return nullptr; +} + +void AstNodeFTaskRef::cloneRelink() { + if (m_taskp && m_taskp->clonep()) m_taskp = m_taskp->clonep(); + if (m_classOrPackagep && m_classOrPackagep->clonep()) { + m_classOrPackagep = m_classOrPackagep->clonep(); + } +} + const char* AstNodeVarRef::broken() const { - BROKEN_RTN(m_varScopep && !m_varScopep->brokeExists()); BROKEN_RTN(m_varp && !m_varp->brokeExists()); + BROKEN_RTN(m_varScopep && !m_varScopep->brokeExists()); + BROKEN_RTN(m_classOrPackagep && !m_classOrPackagep->brokeExists()); return nullptr; } void AstNodeVarRef::cloneRelink() { if (m_varp && m_varp->clonep()) m_varp = m_varp->clonep(); + if (m_varScopep && m_varScopep->clonep()) m_varScopep = m_varScopep->clonep(); + if (m_classOrPackagep && m_classOrPackagep->clonep()) { + m_classOrPackagep = m_classOrPackagep->clonep(); + } } string AstNodeVarRef::selfPointerProtect(bool useSelfForThis) const { @@ -1278,6 +1296,9 @@ const char* AstClassPackage::broken() const { BROKEN_RTN(m_classp && !m_classp->brokeExists()); return nullptr; } +void AstClassPackage::cloneRelink() { + if (m_classp && m_classp->clonep()) m_classp = m_classp->clonep(); +} void AstClass::insertCache(AstNode* nodep) { const bool doit = (VN_IS(nodep, Var) || VN_IS(nodep, EnumItemRef) || (VN_IS(nodep, NodeFTask) && !VN_AS(nodep, NodeFTask)->isExternProto())); diff --git a/src/V3AstNodes.h b/src/V3AstNodes.h index a9c204666..99925319e 100644 --- a/src/V3AstNodes.h +++ b/src/V3AstNodes.h @@ -307,6 +307,7 @@ public: ASTNODE_NODE_FUNCS(ClassPackage) virtual string verilogKwd() const override { return "/*class*/package"; } virtual const char* broken() const override; + virtual void cloneRelink() override; virtual bool timescaleMatters() const override { return false; } AstClass* classp() const { return m_classp; } void classp(AstClass* classp) { m_classp = classp; } @@ -334,6 +335,12 @@ public: BROKEN_RTN(m_classOrPackagep && !m_classOrPackagep->brokeExists()); return nullptr; } + virtual void cloneRelink() override { + AstNodeModule::cloneRelink(); + if (m_classOrPackagep && m_classOrPackagep->clonep()) { + m_classOrPackagep = m_classOrPackagep->clonep(); + } + } virtual bool timescaleMatters() const override { return false; } // op1/op2/op3 in AstNodeModule AstClassPackage* classOrPackagep() const { return m_classOrPackagep; } @@ -1034,10 +1041,14 @@ public: // METHODS virtual const char* broken() const override { BROKEN_RTN(m_classp && !m_classp->brokeExists()); + BROKEN_RTN(m_classOrPackagep && !m_classOrPackagep->brokeExists()); return nullptr; } virtual void cloneRelink() override { if (m_classp && m_classp->clonep()) m_classp = m_classp->clonep(); + if (m_classOrPackagep && m_classOrPackagep->clonep()) { + m_classOrPackagep = m_classOrPackagep->clonep(); + } } virtual bool same(const AstNode* samep) const override { const AstClassRefDType* const asamep = static_cast(samep); @@ -1218,11 +1229,15 @@ public: virtual const char* broken() const override { BROKEN_RTN(m_typedefp && !m_typedefp->brokeExists()); BROKEN_RTN(m_refDTypep && !m_refDTypep->brokeExists()); + BROKEN_RTN(m_classOrPackagep && !m_classOrPackagep->brokeExists()); return nullptr; } virtual void cloneRelink() override { if (m_typedefp && m_typedefp->clonep()) m_typedefp = m_typedefp->clonep(); if (m_refDTypep && m_refDTypep->clonep()) m_refDTypep = m_refDTypep->clonep(); + if (m_classOrPackagep && m_classOrPackagep->clonep()) { + m_classOrPackagep = m_classOrPackagep->clonep(); + } } virtual bool same(const AstNode* samep) const override { const AstRefDType* const asamep = static_cast(samep); @@ -1339,6 +1354,13 @@ public: virtual string name() const override { return m_name; } // * = Var name virtual bool hasDType() const override { return true; } virtual bool maybePointedTo() const override { return true; } + virtual const char* broken() const override { + BROKEN_RTN(m_refDTypep && !m_refDTypep->brokeExists()); + return nullptr; + } + virtual void cloneRelink() override { + if (m_refDTypep && m_refDTypep->clonep()) m_refDTypep = m_refDTypep->clonep(); + } virtual AstNodeDType* getChildDTypep() const override { return childDTypep(); } // op1 = Range of variable AstNodeDType* childDTypep() const { return VN_AS(op1p(), NodeDType); } @@ -1388,6 +1410,7 @@ public: virtual void dumpSmall(std::ostream& str) const override; virtual bool hasDType() const override { return true; } virtual bool maybePointedTo() const override { return true; } + virtual bool undead() const { return true; } virtual AstNodeDType* subDTypep() const override { return nullptr; } virtual AstNodeDType* virtRefDTypep() const override { return nullptr; } virtual void virtRefDTypep(AstNodeDType* nodep) override {} @@ -1415,6 +1438,7 @@ public: virtual void dumpSmall(std::ostream& str) const override; virtual bool hasDType() const override { return true; } virtual bool maybePointedTo() const override { return true; } + virtual bool undead() const { return true; } virtual AstNodeDType* subDTypep() const override { return nullptr; } virtual AstNodeDType* virtRefDTypep() const override { return nullptr; } virtual void virtRefDTypep(AstNodeDType* nodep) override {} @@ -1469,6 +1493,11 @@ public: virtual void dump(std::ostream& str) const override; virtual string name() const override { return itemp()->name(); } virtual int instrCount() const override { return 0; } + virtual const char* broken() const override { + BROKEN_RTN(m_itemp && !m_itemp->brokeExists()); + BROKEN_RTN(m_classOrPackagep && !m_classOrPackagep->brokeExists()); + return nullptr; + } virtual void cloneRelink() override { if (m_itemp->clonep()) m_itemp = m_itemp->clonep(); } @@ -8858,6 +8887,9 @@ public: BROKEN_RTN((m_scopep && !m_scopep->brokeExists())); return nullptr; } + virtual void cloneRelink() override { + if (m_scopep && m_scopep->clonep()) m_scopep = m_scopep->clonep(); + } virtual bool maybePointedTo() const override { return true; } virtual void dump(std::ostream& str = std::cout) const override; virtual bool same(const AstNode* samep) const override { @@ -9169,6 +9201,14 @@ class AstTypeTable final : public AstNode { public: explicit AstTypeTable(FileLine* fl); ASTNODE_NODE_FUNCS(TypeTable) + virtual bool maybePointedTo() const override { return true; } + virtual const char* broken() const override { + BROKEN_RTN(m_emptyQueuep && !m_emptyQueuep->brokeExists()); + BROKEN_RTN(m_queueIndexp && !m_queueIndexp->brokeExists()); + BROKEN_RTN(m_voidp && !m_voidp->brokeExists()); + return nullptr; + } + virtual void cloneRelink() override { V3ERROR_NA; } AstNodeDType* typesp() const { return VN_AS(op1p(), NodeDType); } // op1 = List of dtypes void addTypesp(AstNodeDType* nodep) { addOp1p(nodep); } AstBasicDType* findBasicDType(FileLine* fl, AstBasicDTypeKwd kwd); @@ -9197,6 +9237,13 @@ class AstConstPool final : public AstNode { public: explicit AstConstPool(FileLine* fl); ASTNODE_NODE_FUNCS(ConstPool) + virtual bool maybePointedTo() const override { return true; } + virtual const char* broken() const override { + BROKEN_RTN(m_modp && !m_modp->brokeExists()); + BROKEN_RTN(m_scopep && !m_scopep->brokeExists()); + return nullptr; + } + virtual void cloneRelink() override { V3ERROR_NA; } AstModule* modp() const { return m_modp; } // Find a table (unpacked array) within the constant pool which is initialized with the @@ -9236,12 +9283,15 @@ public: AstNetlist(); ASTNODE_NODE_FUNCS(Netlist) virtual const char* broken() const override { + BROKEN_RTN(m_typeTablep && !m_typeTablep->brokeExists()); + BROKEN_RTN(m_constPoolp && !m_constPoolp->brokeExists()); BROKEN_RTN(m_dollarUnitPkgp && !m_dollarUnitPkgp->brokeExists()); BROKEN_RTN(m_evalp && !m_evalp->brokeExists()); BROKEN_RTN(m_dpiExportTriggerp && !m_dpiExportTriggerp->brokeExists()); BROKEN_RTN(m_topScopep && !m_topScopep->brokeExists()); return nullptr; } + virtual void cloneRelink() override { V3ERROR_NA; } virtual string name() const override { return "$root"; } virtual void dump(std::ostream& str) const override; AstNodeModule* modulesp() const { // op1 = List of modules diff --git a/src/V3Dead.cpp b/src/V3Dead.cpp index 6b9b44c9e..deffed45f 100644 --- a/src/V3Dead.cpp +++ b/src/V3Dead.cpp @@ -114,6 +114,7 @@ private: if (!nodep->generic() // Don't remove generic types && m_elimDTypes // dtypes stick around until post-widthing && !VN_IS(nodep, MemberDType) // Keep member names iff upper type exists + && !nodep->undead() // VoidDType or something Netlist points to ) { m_dtypesp.push_back(nodep); } diff --git a/test_regress/t/t_func_tasknsvar_bad.out b/test_regress/t/t_func_tasknsvar_bad.out index 723df5dc4..241d8b71a 100644 --- a/test_regress/t/t_func_tasknsvar_bad.out +++ b/test_regress/t/t_func_tasknsvar_bad.out @@ -2,7 +2,7 @@ 16 | foo(bus_we_select_from[2]); | ^ ... For error description see https://verilator.org/warn/TASKNSVAR?v=latest -%Error: Internal Error: t/t_func_tasknsvar_bad.v:10:7: ../V3Broken.cpp:#: Broken link in node (or something without maybePointedTo): 'm_varScopep && !m_varScopep->brokeExists()' @ ../V3AstNodes.cpp:51 +%Error: Internal Error: t/t_func_tasknsvar_bad.v:10:7: ../V3Broken.cpp:#: Broken link in node (or something without maybePointedTo): 'm_varp && !m_varp->brokeExists()' @ ../V3AstNodes.cpp:64 10 | sig = '1; | ^~~ ... See the manual at https://verilator.org/verilator_doc.html for more assistance.