From 47803c35911680dc3debc8ee07ef12a928eac37a Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Tue, 14 Jan 2020 17:49:04 -0500 Subject: [PATCH 01/13] Tests: Better message for contributors. --- test_regress/t/t_dist_contributors.pl | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/test_regress/t/t_dist_contributors.pl b/test_regress/t/t_dist_contributors.pl index b31b8b4ff..8450c47ae 100755 --- a/test_regress/t/t_dist_contributors.pl +++ b/test_regress/t/t_dist_contributors.pl @@ -34,7 +34,10 @@ sub check { for my $author (sort keys %Authors) { print "Check: $author\n" if $Self->{verbose}; if (!$Contributors{$author}) { - error("Certify your contribution by appending '$author' to CONTRIBUTORS"); + error("Certify your contribution by appending '$author' to docs/CONTRIBUTORS.\n" + ." If '$author' is not your real name, please fix 'name=' in ~/.gitconfig\n" + ." Also check your https://github.com account's Settings->Profile->Name\n" + ." matches your ~/.gitconfig 'name='.\n"); } } } From 81e8127168b4c8634d4bd4ff32ad9fd67634b71d Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Tue, 14 Jan 2020 18:51:20 -0500 Subject: [PATCH 02/13] Add parameter values in XML. #2110. --- Changes | 2 + src/V3Dead.cpp | 2 +- src/V3EmitXml.cpp | 2 + test_regress/t/t_xml_first.out | 69 +++++++++++++++++++--------------- test_regress/t/t_xml_first.v | 33 ++++++++-------- 5 files changed, 60 insertions(+), 48 deletions(-) diff --git a/Changes b/Changes index dbccd7377..6445c228c 100644 --- a/Changes +++ b/Changes @@ -11,6 +11,8 @@ The contributors that suggested a given feature are shown in []. Thanks! *** Support $readmem/$writemem with assoc arrarys. Closes #2100. [agrobman] +**** Add parameter values in XML. #2110. [Pieter Kapsenberg] + **** Add error on misused define. [Topa Tota] diff --git a/src/V3Dead.cpp b/src/V3Dead.cpp index 265738e2a..cc16421c3 100644 --- a/src/V3Dead.cpp +++ b/src/V3Dead.cpp @@ -299,7 +299,7 @@ private: return (!nodep->isSigPublic() // Can't elim publics! && !nodep->isIO() && ((nodep->isTemp() && !nodep->isTrace()) - || (nodep->isParam() && !nodep->isTrace()) + || (nodep->isParam() && !nodep->isTrace() && !v3Global.opt.xmlOnly()) || m_elimUserVars)); // Post-Trace can kill most anything } diff --git a/src/V3EmitXml.cpp b/src/V3EmitXml.cpp index 86985506a..c1f09316c 100644 --- a/src/V3EmitXml.cpp +++ b/src/V3EmitXml.cpp @@ -140,6 +140,8 @@ class EmitXmlFileVisitor : public AstNVisitor { if (nodep->isSigPublic()) puts(" public=\"true\""); if (nodep->isSigUserRdPublic()) puts(" public_flat_rd=\"true\""); if (nodep->isSigUserRWPublic()) puts(" public_flat_rw=\"true\""); + if (nodep->isGParam()) puts(" param=\"true\""); + else if (nodep->isParam()) puts(" localparam=\"true\""); if (nodep->attrScBv()) puts(" sc_bv=\"true\""); if (nodep->attrScClocked()) puts(" sc_clock=\"true\""); if (nodep->attrSFormat()) puts(" sformat=\"true\""); diff --git a/test_regress/t/t_xml_first.out b/test_regress/t/t_xml_first.out index 064080960..d40bc7c59 100644 --- a/test_regress/t/t_xml_first.out +++ b/test_regress/t/t_xml_first.out @@ -12,7 +12,7 @@ - + @@ -22,57 +22,64 @@ - - - + + + - - + + - - + + - - + + - - + + - - - - - - - - + + + + + + + + + + + + + + - - - + + + - - - - - - - + + + + + + + - + + diff --git a/test_regress/t/t_xml_first.v b/test_regress/t/t_xml_first.v index cf58091f8..8c87572c5 100644 --- a/test_regress/t/t_xml_first.v +++ b/test_regress/t/t_xml_first.v @@ -13,29 +13,30 @@ module t (/*AUTOARG*/ input [3:0] d; output wire [3:0] q; - logic [3:0] between; + logic [3:0] between; - mod1 cell1 (.q(between), - /*AUTOINST*/ - // Inputs - .clk (clk), - .d (d[3:0])); + mod1 #(.WIDTH(4)) + cell1 (.q(between), + .clk (clk), + .d (d[3:0])); - mod2 cell2 (.d(between), - /*AUTOINST*/ - // Outputs - .q (q[3:0]), - // Inputs - .clk (clk)); + mod2 + cell2 (.d(between), + .q (q[3:0]), + .clk (clk)); endmodule module mod1 - ( - input clk, - input [3:0] d, - output logic [3:0] q + #(parameter WIDTH = 32) + ( + input clk, + input [WIDTH-1:0] d, + output logic [WIDTH-1:0] q ); + + localparam IGNORED = 1; + always @(posedge clk) q <= d; From e9a309ea8dac1375ec14d4afee845ce8585029ef Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Wed, 15 Jan 2020 07:27:04 -0500 Subject: [PATCH 03/13] Clang warning fix. --- include/verilated.cpp | 4 +--- include/verilated_heavy.h | 2 -- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/include/verilated.cpp b/include/verilated.cpp index 14521d7b9..8677f3154 100644 --- a/include/verilated.cpp +++ b/include/verilated.cpp @@ -1740,9 +1740,7 @@ void VlReadMem::setData(void* valuep, const std::string& rhs) { } VlWriteMem::VlWriteMem(bool hex, int bits, const std::string& filename, QData start, QData end) - : m_hex(hex) - , m_bits(bits) - , m_filename(filename) + : m_bits(bits) , m_addr(0) { if (VL_UNLIKELY(!hex)) { VL_FATAL_MT(filename.c_str(), 0, "", diff --git a/include/verilated_heavy.h b/include/verilated_heavy.h index f1e61a185..c04ee3214 100644 --- a/include/verilated_heavy.h +++ b/include/verilated_heavy.h @@ -65,9 +65,7 @@ public: }; class VlWriteMem { - bool m_hex; // Hex format int m_bits; // Bit width of values - const std::string& m_filename; // Filename FILE* m_fp; // File handle for filename QData m_addr; // Next address to write public: From 4443ab34fd17b01ed9013cfefeb7f0ffb53d93e9 Mon Sep 17 00:00:00 2001 From: Pieter Kapsenberg Date: Wed, 15 Jan 2020 07:32:45 -0500 Subject: [PATCH 04/13] Support left justified . Closes #2101. --- Changes | 8 +++++--- docs/CONTRIBUTORS | 1 + include/verilated.cpp | 34 ++++++++++++++++++++++------------ src/V3Const.cpp | 2 +- src/V3EmitC.cpp | 3 ++- src/V3LinkResolve.cpp | 2 +- src/V3Number.cpp | 19 ++++++++++++------- src/V3Number.h | 2 +- src/V3Width.cpp | 2 +- test_regress/t/t_display.out | 14 ++++++++++++++ test_regress/t/t_display.v | 19 +++++++++++++++++++ 11 files changed, 79 insertions(+), 27 deletions(-) diff --git a/Changes b/Changes index 6445c228c..6d0b6c432 100644 --- a/Changes +++ b/Changes @@ -5,11 +5,13 @@ The contributors that suggested a given feature are shown in []. Thanks! * Verilator 4.027 devel -** Support attributes (public, isolate_assignments, etc.) in configuration files. +** Support attributes (public, isolate_assignments, etc.) in configuration files. -** Add -match to lint_off to waive warnings. [Philipp Wagner] +** Add -match to lint_off to waive warnings. [Philipp Wagner] -*** Support $readmem/$writemem with assoc arrarys. Closes #2100. [agrobman] +*** Support $readmem/$writemem with assoc arrarys. Closes #2100. [agrobman] + +**** Support left justified $display. Closes #2101. [Pieter Kapsenberg] **** Add parameter values in XML. #2110. [Pieter Kapsenberg] diff --git a/docs/CONTRIBUTORS b/docs/CONTRIBUTORS index ab88d1a58..9ca30b58e 100644 --- a/docs/CONTRIBUTORS +++ b/docs/CONTRIBUTORS @@ -27,6 +27,7 @@ Mike Popoloski Peter Monsson Patrick Stewart Philipp Wagner +Pieter Kapsenberg Richard Myers Sebastien Van Cauwenberghe Stefan Wallentowitz diff --git a/include/verilated.cpp b/include/verilated.cpp index 8677f3154..2f04393e1 100644 --- a/include/verilated.cpp +++ b/include/verilated.cpp @@ -618,6 +618,7 @@ void _vl_vsformat(std::string& output, const char* formatp, va_list ap) VL_MT_SA const char* pctp = NULL; // Most recent %##.##g format bool inPct = false; bool widthSet = false; + bool left = false; int width = 0; for (const char* pos = formatp; *pos; ++pos) { if (!inPct && pos[0]=='%') { @@ -643,6 +644,10 @@ void _vl_vsformat(std::string& output, const char* formatp, va_list ap) VL_MT_SA widthSet = true; width = width*10 + (fmt - '0'); break; + case '-': + left = true; + inPct = true; // Get more digits + break; case '.': inPct = true; // Get more digits break; @@ -662,8 +667,9 @@ void _vl_vsformat(std::string& output, const char* formatp, va_list ap) VL_MT_SA case '@': { // Verilog/C++ string va_arg(ap, int); // # bits is ignored const std::string* cstrp = va_arg(ap, const std::string*); - if (width > cstrp->size()) output += std::string(width - cstrp->size(), ' '); - output += *cstrp; + std::string padding; + if (width > cstrp->size()) padding.append(width - cstrp->size(), ' '); + output += left ? (*cstrp + padding) : (padding + *cstrp); break; } case 'e': @@ -721,8 +727,9 @@ void _vl_vsformat(std::string& output, const char* formatp, va_list ap) VL_MT_SA IData charval = VL_BITRSHIFT_W(lwp, lsb) & 0xff; field += (charval==0)?' ':charval; } - if (width > field.size()) output += std::string(width - field.size(), ' '); - output += field; + std::string padding; + if (width > field.size()) padding.append(width - field.size(), ' '); + output += left ? (field + padding) : (padding + field); break; } case 'd': { // Signed decimal @@ -743,14 +750,15 @@ void _vl_vsformat(std::string& output, const char* formatp, va_list ap) VL_MT_SA digits = append.length(); } int needmore = width-digits; + std::string padding; if (needmore>0) { if (pctp && pctp[0] && pctp[1]=='0') { // %0 - output.append(needmore, '0'); // Pre-pad zero + padding.append(needmore, '0'); // Pre-pad zero } else { - output.append(needmore, ' '); // Pre-pad spaces + padding.append(needmore, ' '); // Pre-pad spaces } } - output += append; + output += left ? (append + padding) : (padding + append); break; } case '#': { // Unsigned decimal @@ -764,14 +772,15 @@ void _vl_vsformat(std::string& output, const char* formatp, va_list ap) VL_MT_SA digits = append.length(); } int needmore = width-digits; + std::string padding; if (needmore>0) { if (pctp && pctp[0] && pctp[1]=='0') { // %0 - output.append(needmore, '0'); // Pre-pad zero + padding.append(needmore, '0'); // Pre-pad zero } else { - output.append(needmore, ' '); // Pre-pad spaces + padding.append(needmore, ' '); // Pre-pad spaces } } - output += append; + output += left ? (append + padding) : (padding + append); break; } case 't': { // Time @@ -786,8 +795,9 @@ void _vl_vsformat(std::string& output, const char* formatp, va_list ap) VL_MT_SA VL_FATAL_MT(__FILE__, __LINE__, "", "Unsupported VL_TIME_MULTIPLIER"); } int needmore = width-digits; - if (needmore>0) output.append(needmore, ' '); // Pre-pad spaces - output += tmp; + std::string padding; + if (needmore>0) padding.append(needmore, ' '); // Pad with spaces + output += left ? (tmp + padding) : (padding + tmp); break; } case 'b': diff --git a/src/V3Const.cpp b/src/V3Const.cpp index e5825110d..10d48e1da 100644 --- a/src/V3Const.cpp +++ b/src/V3Const.cpp @@ -2069,7 +2069,7 @@ private: if (!inPct && ch=='%') { inPct = true; fmt = ch; - } else if (inPct && (isdigit(ch) || ch=='.')) { + } else if (inPct && (isdigit(ch) || ch=='.' || ch=='-')) { fmt += ch; } else if (inPct) { inPct = false; diff --git a/src/V3EmitC.cpp b/src/V3EmitC.cpp index 0f69d91f7..a5e3edd97 100644 --- a/src/V3EmitC.cpp +++ b/src/V3EmitC.cpp @@ -1797,7 +1797,8 @@ void EmitCStmts::displayNode(AstNode* nodep, AstScopeName* scopenamep, switch (tolower(pos[0])) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': - case '.': + case '.': // FALLTHRU + case '-': // Digits, like %5d, etc. vfmt += pos[0]; inPct = true; // Get more digits diff --git a/src/V3LinkResolve.cpp b/src/V3LinkResolve.cpp index edf2d6dd4..8dba07d89 100644 --- a/src/V3LinkResolve.cpp +++ b/src/V3LinkResolve.cpp @@ -270,7 +270,7 @@ private: if (!inPct && ch=='%') { inPct = true; fmt = ch; - } else if (inPct && (isdigit(ch) || ch=='.')) { + } else if (inPct && (isdigit(ch) || ch=='.' || ch=='-')) { fmt += ch; } else if (inPct) { inPct = false; diff --git a/src/V3Number.cpp b/src/V3Number.cpp index 65f579654..f90b80e91 100644 --- a/src/V3Number.cpp +++ b/src/V3Number.cpp @@ -497,10 +497,10 @@ bool V3Number::displayedFmtLegal(char format) { } } -string V3Number::displayPad(size_t fmtsize, char pad, const string& in) { - string prefix; - if (in.length() < fmtsize) prefix = string(fmtsize - in.length(), pad); - return prefix + in; +string V3Number::displayPad(size_t fmtsize, char pad, bool left, const string& in) { + string padding; + if (in.length() < fmtsize) padding = string(fmtsize - in.length(), pad); + return left ? (in + padding) : (padding + in); } string V3Number::displayed(AstNode* nodep, const string& vformat) const { @@ -512,6 +512,11 @@ string V3Number::displayed(FileLine* fl, const string& vformat) const { UASSERT(pos != vformat.end() && pos[0]=='%', "$display-like function with non format argument "<<*this); ++pos; + bool left = false; + if (pos[0] == '-') { + left = true; + ++pos; + } string fmtsize; for (; pos != vformat.end() && (isdigit(pos[0]) || pos[0]=='.'); ++pos) { fmtsize += pos[0]; @@ -574,7 +579,7 @@ string V3Number::displayed(FileLine* fl, const string& vformat) const { } } size_t fmtsizen = static_cast(atoi(fmtsize.c_str())); - str = displayPad(fmtsizen, ' ', str); + str = displayPad(fmtsizen, ' ', left, str); return str; } case '~': // Signed decimal @@ -604,7 +609,7 @@ string V3Number::displayed(FileLine* fl, const string& vformat) const { bool zeropad = fmtsize.length()>0 && fmtsize[0]=='0'; // fmtsize might have changed since we parsed the %fmtsize size_t fmtsizen = static_cast(atoi(fmtsize.c_str())); - str = displayPad(fmtsizen, (zeropad ? '0' : ' '), str); + str = displayPad(fmtsizen, (zeropad ? '0' : ' '), left, str); return str; } case 'e': @@ -651,7 +656,7 @@ string V3Number::displayed(FileLine* fl, const string& vformat) const { } case '@': { // Packed string size_t fmtsizen = static_cast(atoi(fmtsize.c_str())); - str = displayPad(fmtsizen, ' ', toString()); + str = displayPad(fmtsizen, ' ', left, toString()); return str; } default: diff --git a/src/V3Number.h b/src/V3Number.h index 508a8db9a..73a2f4907 100644 --- a/src/V3Number.h +++ b/src/V3Number.h @@ -175,7 +175,7 @@ private: for (int i=0; i return [0] Embedded multiline +'23 23 23' +'23 23 23 ' +'23 23 23' +'23 23 23 ' +' 24' +'24 ' +' 0' +'0 ' +' sv-str' +'sv-str ' +' meep' +'meep ' +' beep' +'beep ' log10(2) = 2 *-* All Finished *-* diff --git a/test_regress/t/t_display.v b/test_regress/t/t_display.v index 691660ee6..90b80c6eb 100644 --- a/test_regress/t/t_display.v +++ b/test_regress/t/t_display.v @@ -13,7 +13,10 @@ module t; reg [31:0] str; initial str = "\000\277\021\n"; reg [47:0] str2; initial str2 = "\000what!"; reg [79:0] str3; initial str3 = "\000hmmm!1234"; + int n; initial n = 23; + reg [7:0] m; initial m = 24; string svs = "sv-str"; + reg [31:0] regstr = "meep"; sub sub (); sub2 sub2 (); @@ -144,6 +147,22 @@ multiline", $time); if (str !== 32'h00_bf_11_0a) $stop; `endif + // Padding + $write("'%0d %2d %8d'\n", 23, 23, 23); + $write("'%-0d %-2d %-8d'\n", 23, 23, 23); + $write("'%0d %2d %8d'\n", n, n, n); + $write("'%-0d %-2d %-8d'\n", n, n, n); + $write("'%8d'\n", m); + $write("'%-8d'\n", m); + $write("'%8t'\n", $time); + $write("'%-8t'\n", $time); + $write("'%8s'\n", svs); + $write("'%-8s'\n", svs); + $write("'%8s'\n", regstr); + $write("'%-8s'\n", regstr); + $write("'%8s'\n", "beep"); + $write("'%-8s'\n", "beep"); + // $itord conversion bug, note a %d instead of proper float $display("log10(2) = %d", $log10(100)); From b41b9417b9026a96d617788bc061e9b27c809a82 Mon Sep 17 00:00:00 2001 From: Tobias Rosenkranz Date: Wed, 15 Jan 2020 07:40:22 -0500 Subject: [PATCH 05/13] Fix sign compare warning. Closes #2112. --- docs/CONTRIBUTORS | 3 ++- include/verilated.cpp | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/CONTRIBUTORS b/docs/CONTRIBUTORS index 9ca30b58e..0f7156136 100644 --- a/docs/CONTRIBUTORS +++ b/docs/CONTRIBUTORS @@ -24,13 +24,14 @@ Lukasz Dalek Maarten De Braekeleer Matthew Ballance Mike Popoloski -Peter Monsson Patrick Stewart +Peter Monsson Philipp Wagner Pieter Kapsenberg Richard Myers Sebastien Van Cauwenberghe Stefan Wallentowitz +Tobias Rosenkranz Todd Strader Wilson Snyder Yutetsu TAKATSUKASA diff --git a/include/verilated.cpp b/include/verilated.cpp index 2f04393e1..b9b408b60 100644 --- a/include/verilated.cpp +++ b/include/verilated.cpp @@ -619,7 +619,7 @@ void _vl_vsformat(std::string& output, const char* formatp, va_list ap) VL_MT_SA bool inPct = false; bool widthSet = false; bool left = false; - int width = 0; + size_t width = 0; for (const char* pos = formatp; *pos; ++pos) { if (!inPct && pos[0]=='%') { pctp = pos; From e2ba1c041f07e00a1cb47b0f60f71c1e4696b85c Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Wed, 15 Jan 2020 20:09:19 -0500 Subject: [PATCH 06/13] Commentary --- docs/CONTRIBUTING.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/CONTRIBUTING.adoc b/docs/CONTRIBUTING.adoc index 3bdc65084..2770d8136 100644 --- a/docs/CONTRIBUTING.adoc +++ b/docs/CONTRIBUTING.adoc @@ -11,7 +11,7 @@ contributions flow more efficiently. https://verilator.org/issues[Verilator Issues]. * If you're unable to find an open issue addressing the problem, - https://verilator.org/issues/new[open a new issue]. + https://verilator.org/issues/new[open a new Verilator issue]. ** Be sure to include a **code sample** or an **executable test case** demonstrating the bug and expected behavior that is not occurring. From 023526ad4b43d4bda785a5d0bc834ab3cd068d8b Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Wed, 15 Jan 2020 20:18:12 -0500 Subject: [PATCH 07/13] Internals: Minor refactoring from class branch. --- src/V3AstNodes.cpp | 6 ++++++ src/V3AstNodes.h | 1 + src/V3LinkResolve.cpp | 6 +++--- src/V3Task.cpp | 5 ++--- src/verilog.y | 10 +++++++--- 5 files changed, 19 insertions(+), 9 deletions(-) diff --git a/src/V3AstNodes.cpp b/src/V3AstNodes.cpp index 367486b05..e0c4a906c 100644 --- a/src/V3AstNodes.cpp +++ b/src/V3AstNodes.cpp @@ -999,6 +999,12 @@ void AstJumpGo::dump(std::ostream& str) const { if (labelp()) { labelp()->dump(str); } else { str<<"%Error:UNLINKED"; } } +void AstMemberSel::dump(std::ostream& str) const { + this->AstNode::dump(str); + str << " -> "; + if (varp()) { varp()->dump(str); } + else { str << "%Error:UNLINKED"; } +} void AstModportFTaskRef::dump(std::ostream& str) const { this->AstNode::dump(str); if (isExport()) str<<" EXPORT"; diff --git a/src/V3AstNodes.h b/src/V3AstNodes.h index b0254ae52..b60e4b383 100644 --- a/src/V3AstNodes.h +++ b/src/V3AstNodes.h @@ -2064,6 +2064,7 @@ public: virtual void cloneRelink() { if (m_varp && m_varp->clonep()) { m_varp = m_varp->clonep(); } } virtual const char* broken() const { BROKEN_RTN(m_varp && !m_varp->brokeExists()); return NULL; } + virtual void dump(std::ostream& str) const; virtual string name() const { return m_name; } virtual V3Hash sameHash() const { return V3Hash(m_name); } virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { diff --git a/src/V3LinkResolve.cpp b/src/V3LinkResolve.cpp index 8dba07d89..512400143 100644 --- a/src/V3LinkResolve.cpp +++ b/src/V3LinkResolve.cpp @@ -49,12 +49,12 @@ private: // NODE STATE // Entire netlist: // AstCaseItem::user2() // bool Moved default caseitems - AstUser2InUse m_inuser2; + AstUser2InUse m_inuser2; // STATE // Below state needs to be preserved between each module call. - AstNodeModule* m_modp; // Current module - AstNodeFTask* m_ftaskp; // Function or task we're inside + AstNodeModule* m_modp; // Current module + AstNodeFTask* m_ftaskp; // Function or task we're inside AstNodeCoverOrAssert* m_assertp; // Current assertion int m_senitemCvtNum; // Temporary signal counter diff --git a/src/V3Task.cpp b/src/V3Task.cpp index 80a97c9ac..223c5f6c2 100644 --- a/src/V3Task.cpp +++ b/src/V3Task.cpp @@ -129,15 +129,14 @@ public: return iter->second; } bool ftaskNoInline(AstNodeFTask* nodep) { - return (getFTaskVertex(nodep)->noInline()); + return getFTaskVertex(nodep)->noInline(); } AstCFunc* ftaskCFuncp(AstNodeFTask* nodep) { - return (getFTaskVertex(nodep)->cFuncp()); + return getFTaskVertex(nodep)->cFuncp(); } void ftaskCFuncp(AstNodeFTask* nodep, AstCFunc* cfuncp) { getFTaskVertex(nodep)->cFuncp(cfuncp); } - void checkPurity(AstNodeFTask* nodep) { checkPurity(nodep, getFTaskVertex(nodep)); } diff --git a/src/verilog.y b/src/verilog.y index 2a7d882e1..137038e87 100644 --- a/src/verilog.y +++ b/src/verilog.y @@ -5354,13 +5354,17 @@ classExtendsE: // IEEE: part of class_declaration classExtendsList: // IEEE: part of class_declaration classExtendsOne { $$ = $1; } - | classExtendsList ',' classExtendsOne { $$ = AstNode::addNextNull($1, $3); } + | classExtendsList ',' classExtendsOne + { $$ = $3; BBUNSUP($3, "Multiple inheritance illegal on non-interface classes (IEEE 8.13)" + ", and unsupported for interface classes."); } ; classExtendsOne: // IEEE: part of class_declaration - class_typeWithoutId { $$ = NULL; BBUNSUP($1, "Unsupported: extends"); } + class_typeWithoutId + { $$ = NULL; BBUNSUP($1, "Unsupported: extends"); } // // IEEE: Might not be legal to have more than one set of parameters in an extends - | class_typeWithoutId '(' list_of_argumentsE ')' { $$ = NULL; BBUNSUP($1, "Unsupported: extends"); } + | class_typeWithoutId '(' list_of_argumentsE ')' + { $$ = NULL; BBUNSUP($1, "Unsupported: extends"); } ; classImplementsE: // IEEE: part of class_declaration From 623c4ec10361920d9f8acc4fc4cac1bffbc8aa19 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Thu, 16 Jan 2020 20:17:11 -0500 Subject: [PATCH 08/13] Internals: Create VL_DO_DANGLING. No functional change intended. --- include/verilated_cov.cpp | 4 +- include/verilated_unordered_set_map.h | 2 +- include/verilated_vpi.cpp | 2 +- include/verilatedos.h | 8 +- src/V3Active.cpp | 16 +-- src/V3ActiveTop.cpp | 2 +- src/V3Assert.cpp | 6 +- src/V3AssertPre.cpp | 4 +- src/V3Ast.cpp | 6 +- src/V3AstNodes.cpp | 8 +- src/V3Begin.cpp | 2 +- src/V3Case.cpp | 20 +-- src/V3Changed.cpp | 2 +- src/V3Clock.cpp | 14 +- src/V3Combine.cpp | 12 +- src/V3Const.cpp | 189 +++++++++++++------------ src/V3Coverage.cpp | 2 +- src/V3CoverageJoin.cpp | 2 +- src/V3Dead.cpp | 18 +-- src/V3Delayed.cpp | 6 +- src/V3EmitC.cpp | 2 +- src/V3Expand.cpp | 34 ++--- src/V3Gate.cpp | 32 ++--- src/V3GenClk.cpp | 2 +- src/V3Graph.cpp | 4 +- src/V3GraphAcyc.cpp | 26 ++-- src/V3GraphAlg.cpp | 6 +- src/V3GraphDfa.cpp | 10 +- src/V3GraphPathChecker.cpp | 2 +- src/V3Inline.cpp | 14 +- src/V3Inst.cpp | 9 +- src/V3Life.cpp | 16 +-- src/V3LifePost.cpp | 4 +- src/V3LinkCells.cpp | 4 +- src/V3LinkDot.cpp | 58 ++++---- src/V3LinkJump.cpp | 10 +- src/V3LinkParse.cpp | 38 ++--- src/V3LinkResolve.cpp | 20 +-- src/V3Order.cpp | 6 +- src/V3Param.cpp | 16 +-- src/V3ParseGrammar.cpp | 2 +- src/V3ParseImp.cpp | 4 +- src/V3Partition.cpp | 8 +- src/V3PreProc.cpp | 2 +- src/V3Reloop.cpp | 6 +- src/V3Scope.cpp | 2 +- src/V3Slice.cpp | 4 +- src/V3Split.cpp | 4 +- src/V3StatsReport.cpp | 3 +- src/V3Subst.cpp | 8 +- src/V3Table.cpp | 4 +- src/V3Task.cpp | 26 ++-- src/V3Trace.cpp | 2 +- src/V3Tristate.cpp | 26 ++-- src/V3Unknown.cpp | 28 ++-- src/V3Unroll.cpp | 28 ++-- src/V3Width.cpp | 148 +++++++++---------- src/V3WidthCommit.h | 8 +- src/V3WidthSel.cpp | 48 +++---- src/astgen | 2 +- src/verilog.y | 4 +- test_regress/t/t_clk_inp_init.cpp | 2 +- test_regress/t/t_dpi_var.cpp | 2 +- test_regress/t/t_leak.cpp | 2 +- test_regress/t/t_var_overwidth_bad.cpp | 2 +- test_regress/t/t_vpi_get.cpp | 2 +- test_regress/t/t_vpi_memory.cpp | 2 +- test_regress/t/t_vpi_module.cpp | 2 +- test_regress/t/t_vpi_time_cb.cpp | 2 +- test_regress/t/t_vpi_unimpl.cpp | 2 +- test_regress/t/t_vpi_var.cpp | 2 +- test_regress/t/t_vpi_zero_time_cb.cpp | 2 +- 72 files changed, 519 insertions(+), 508 deletions(-) diff --git a/include/verilated_cov.cpp b/include/verilated_cov.cpp index 2ea9351d4..35d2ea2cc 100644 --- a/include/verilated_cov.cpp +++ b/include/verilated_cov.cpp @@ -222,7 +222,7 @@ private: void clearGuts() VL_REQUIRES(m_mutex) { for (ItemList::const_iterator it=m_items.begin(); it!=m_items.end(); ++it) { VerilatedCovImpItem* itemp = *(it); - delete itemp; + VL_DO_DANGLING(delete itemp, itemp); } m_items.clear(); m_indexValues.clear(); @@ -244,7 +244,7 @@ public: for (ItemList::iterator it=m_items.begin(); it!=m_items.end(); ++it) { VerilatedCovImpItem* itemp = *(it); if (!itemMatchesString(itemp, matchp)) { - delete itemp; + VL_DO_DANGLING(delete itemp, itemp); } else { newlist.push_back(itemp); } diff --git a/include/verilated_unordered_set_map.h b/include/verilated_unordered_set_map.h index 4a3ed007f..6c185462d 100644 --- a/include/verilated_unordered_set_map.h +++ b/include/verilated_unordered_set_map.h @@ -212,7 +212,7 @@ public: } } ~vl_unordered_set() { - delete [] m_bucketsp; VL_DANGLING(m_bucketsp); + VL_DO_DANGLING(delete [] m_bucketsp, m_bucketsp); } vl_unordered_set& operator=(const vl_unordered_set& other) { diff --git a/include/verilated_vpi.cpp b/include/verilated_vpi.cpp index cd2ea7751..1de5908c0 100644 --- a/include/verilated_vpi.cpp +++ b/include/verilated_vpi.cpp @@ -2008,7 +2008,7 @@ PLI_INT32 vpi_release_handle(vpiHandle object) { _VL_VPI_ERROR_RESET(); if (VL_UNLIKELY(!vop)) return 0; vpi_remove_cb(object); // May not be a callback, but that's ok - delete vop; + VL_DO_DANGLING(delete vop, vop); return 1; } diff --git a/include/verilatedos.h b/include/verilatedos.h index 68d478555..37c816e0a 100644 --- a/include/verilatedos.h +++ b/include/verilatedos.h @@ -154,11 +154,15 @@ #define VL_UL(c) (static_cast(c##UL)) ///< Add appropriate suffix to 32-bit constant #if defined(VL_CPPCHECK) || defined(__clang_analyzer__) -# define VL_DANGLING(v) +# define VL_DANGLING(var) #else -# define VL_DANGLING(v) do { (v) = NULL; } while(0) ///< After e.g. delete, set variable to NULL to indicate must not use later +///< After e.g. delete, set variable to NULL to indicate must not use later +# define VL_DANGLING(var) do { (var) = NULL; } while(0) #endif +///< Perform an e.g. delete, then set variable to NULL to indicate must not use later +#define VL_DO_DANGLING(stmt, var) do { do { stmt; } while(0); VL_DANGLING(var); } while(0) + //========================================================================= // C++-2011 diff --git a/src/V3Active.cpp b/src/V3Active.cpp index b93630a62..7510050cb 100644 --- a/src/V3Active.cpp +++ b/src/V3Active.cpp @@ -81,7 +81,7 @@ private: } virtual void visit(AstSenTree* nodep) { // Simplify sensitivity list - V3Const::constifyExpensiveEdit(nodep); VL_DANGLING(nodep); + VL_DO_DANGLING(V3Const::constifyExpensiveEdit(nodep), nodep); } // Empty visitors, speed things up virtual void visit(AstNodeStmt* nodep) { } @@ -181,7 +181,7 @@ private: nodep->lhsp()->unlinkFrBack(), nodep->rhsp()->unlinkFrBack()); nodep->replaceWith(newp); - nodep->deleteTree(); VL_DANGLING(nodep); + VL_DO_DANGLING(nodep->deleteTree(), nodep); } } virtual void visit(AstAssign* nodep) { @@ -284,7 +284,7 @@ private: // Relink to CFUNC for the final UINFO(4," FINAL "<bodysp()) { // Empty, Kill it. - nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep); + VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); return; } ActiveDlyVisitor dlyvisitor (nodep, ActiveDlyVisitor::CT_INITIAL); @@ -303,7 +303,7 @@ private: nodep->unlinkFrBack(); m_scopeFinalp->addStmtsp(new AstComment(nodep->fileline(), nodep->typeName(), true)); m_scopeFinalp->addStmtsp(nodep->bodysp()->unlinkFrBackWithNext()); - nodep->deleteTree(); VL_DANGLING(nodep); + VL_DO_DANGLING(nodep->deleteTree(), nodep); } // METHODS @@ -316,7 +316,7 @@ private: // Never executing. Kill it. UASSERT_OBJ(!oldsensesp->sensesp()->nextp(), nodep, "Never senitem should be alone, else the never should be eliminated."); - nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep); + VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); return; } @@ -353,7 +353,7 @@ private: // Delete sensitivity list if (oldsensesp) { - oldsensesp->unlinkFrBackWithNext()->deleteTree(); VL_DANGLING(oldsensesp); + VL_DO_DANGLING(oldsensesp->unlinkFrBackWithNext()->deleteTree(), oldsensesp); } // Move node to new active @@ -379,7 +379,7 @@ private: if (!nodep->bodysp()) { // Empty always. Kill it. - nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep); + VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); return; } visitAlways(nodep, nodep->sensesp(), nodep->keyword()); @@ -403,7 +403,7 @@ private: m_itemCombo = true; // Delete the sensitivity // We'll add it as a generic COMBO SenItem in a moment. - nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep); + VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); } else if (nodep->varrefp()) { // V3LinkResolve should have cleaned most of these up if (!nodep->varrefp()->width1()) { diff --git a/src/V3ActiveTop.cpp b/src/V3ActiveTop.cpp index 172691cd5..8be5c9b4f 100644 --- a/src/V3ActiveTop.cpp +++ b/src/V3ActiveTop.cpp @@ -79,7 +79,7 @@ private: // Never executing. Kill it. UASSERT_OBJ(!sensesp->sensesp()->nextp(), nodep, "Never senitem should be alone, else the never should be eliminated."); - nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep); + VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); return; } // Copy combo tree to settlement tree with duplicated statements diff --git a/src/V3Assert.cpp b/src/V3Assert.cpp index 3b00f4bf6..953367966 100644 --- a/src/V3Assert.cpp +++ b/src/V3Assert.cpp @@ -164,13 +164,13 @@ private: if (selfDestruct) { // Delete it after making the tree. This way we can tell the user // if it wasn't constructed nicely or has other errors without needing --coverage. - newp->deleteTree(); + VL_DO_DANGLING(newp->deleteTree(), newp); nodep->unlinkFrBack(); } else { nodep->replaceWith(newp); } // Bye - pushDeletep(nodep); VL_DANGLING(nodep); + VL_DO_DANGLING(pushDeletep(nodep), nodep); } // VISITORS @@ -352,7 +352,7 @@ private: virtual void visit(AstRestrict* nodep) { iterateChildren(nodep); // IEEE says simulator ignores these - pushDeletep(nodep->unlinkFrBack()); VL_DANGLING(nodep); + VL_DO_DANGLING(pushDeletep(nodep->unlinkFrBack()), nodep); } virtual void visit(AstNodeModule* nodep) { diff --git a/src/V3AssertPre.cpp b/src/V3AssertPre.cpp index 364010c7d..37372511c 100644 --- a/src/V3AssertPre.cpp +++ b/src/V3AssertPre.cpp @@ -81,7 +81,7 @@ private: } else { nodep->unlinkFrBack(); } - pushDeletep(nodep); VL_DANGLING(nodep); + VL_DO_DANGLING(pushDeletep(nodep), nodep); } virtual void visit(AstAlways* nodep) { iterateAndNextNull(nodep->sensesp()); @@ -130,7 +130,7 @@ private: // Unlink and just keep a pointer to it, convert to sentree as needed m_senip = nodep->sensesp(); nodep->replaceWith(blockp); - pushDeletep(nodep); VL_DANGLING(nodep); + VL_DO_DANGLING(pushDeletep(nodep), nodep); } virtual void visit(AstNodeModule* nodep) { iterateChildren(nodep); diff --git a/src/V3Ast.cpp b/src/V3Ast.cpp index 3bc088946..6235efc1e 100644 --- a/src/V3Ast.cpp +++ b/src/V3Ast.cpp @@ -865,10 +865,10 @@ AstNode* AstNode::iterateSubtreeReturnEdits(AstNVisitor& v) { // track, then delete it on completion AstBegin* tempp = new AstBegin(nodep->fileline(), "[EditWrapper]", nodep); { - tempp->stmtsp()->accept(v); VL_DANGLING(nodep); // nodep to null as may be replaced + VL_DO_DANGLING(tempp->stmtsp()->accept(v), nodep); // nodep to null as may be replaced } nodep = tempp->stmtsp()->unlinkFrBackWithNext(); - tempp->deleteTree(); VL_DANGLING(tempp); + VL_DO_DANGLING(tempp->deleteTree(), tempp); } else { // Use back to determine who's pointing at us (IE assume new node // grafts into same place as old one) @@ -880,7 +880,7 @@ AstNode* AstNode::iterateSubtreeReturnEdits(AstNVisitor& v) { else if (this->m_backp->m_nextp == this) nextnodepp = &(this->m_backp->m_nextp); UASSERT_OBJ(nextnodepp, this, "Node's back doesn't point to forward to node itself"); { - nodep->accept(v); VL_DANGLING(nodep); // nodep to null as may be replaced + VL_DO_DANGLING(nodep->accept(v), nodep); // nodep to null as may be replaced } nodep = *nextnodepp; // Grab new node from point where old was connected } diff --git a/src/V3AstNodes.cpp b/src/V3AstNodes.cpp index e0c4a906c..5da84c5c8 100644 --- a/src/V3AstNodes.cpp +++ b/src/V3AstNodes.cpp @@ -172,7 +172,7 @@ AstExecGraph::AstExecGraph(FileLine* fileline) m_depGraphp = new V3Graph; } AstExecGraph::~AstExecGraph() { - delete m_depGraphp; VL_DANGLING(m_depGraphp); + VL_DO_DANGLING(delete m_depGraphp, m_depGraphp); } bool AstVar::isSigPublic() const { @@ -798,7 +798,7 @@ AstBasicDType* AstTypeTable::findBasicDType(FileLine* fl, AstBasicDTypeKwd kwd) // check the detailed map for this same node // Also adds this new node to the detailed map AstBasicDType* newp = findInsertSameDType(new1p); - if (newp != new1p) new1p->deleteTree(); + if (newp != new1p) VL_DO_DANGLING(new1p->deleteTree(), new1p); else addTypesp(newp); // m_basicps[kwd] = newp; @@ -809,7 +809,7 @@ AstBasicDType* AstTypeTable::findLogicBitDType(FileLine* fl, AstBasicDTypeKwd kw int width, int widthMin, AstNumeric numeric) { AstBasicDType* new1p = new AstBasicDType(fl, kwd, numeric, width, widthMin); AstBasicDType* newp = findInsertSameDType(new1p); - if (newp != new1p) new1p->deleteTree(); + if (newp != new1p) VL_DO_DANGLING(new1p->deleteTree(), new1p); else addTypesp(newp); return newp; } @@ -818,7 +818,7 @@ AstBasicDType* AstTypeTable::findLogicBitDType(FileLine* fl, AstBasicDTypeKwd kw VNumRange range, int widthMin, AstNumeric numeric) { AstBasicDType* new1p = new AstBasicDType(fl, kwd, numeric, range, widthMin); AstBasicDType* newp = findInsertSameDType(new1p); - if (newp != new1p) new1p->deleteTree(); + if (newp != new1p) VL_DO_DANGLING(new1p->deleteTree(), new1p); else addTypesp(newp); return newp; } diff --git a/src/V3Begin.cpp b/src/V3Begin.cpp index 4c51b35b1..ae4c4ef3f 100644 --- a/src/V3Begin.cpp +++ b/src/V3Begin.cpp @@ -157,7 +157,7 @@ private: } else { nodep->unlinkFrBack(); } - pushDeletep(nodep); VL_DANGLING(nodep); + VL_DO_DANGLING(pushDeletep(nodep), nodep); } virtual void visit(AstVar* nodep) { if (m_unnamedScope != "") { diff --git a/src/V3Case.cpp b/src/V3Case.cpp index d19ad6f89..abc94ed38 100644 --- a/src/V3Case.cpp +++ b/src/V3Case.cpp @@ -250,7 +250,7 @@ private: if (m_valueItem[a] != m_valueItem[b]) { same = false; break; } } if (same) { - tree1p->deleteTree(); VL_DANGLING(tree1p); + VL_DO_DANGLING(tree1p->deleteTree(), tree1p); return tree0p; } @@ -299,8 +299,8 @@ private: if (ifrootp) nodep->replaceWith(ifrootp); else nodep->unlinkFrBack(); - nodep->deleteTree(); VL_DANGLING(nodep); - cexprp->deleteTree(); VL_DANGLING(cexprp); + VL_DO_DANGLING(nodep->deleteTree(), nodep); + VL_DO_DANGLING(cexprp->deleteTree(), cexprp); if (debug()>=9) ifrootp->dumpTree(cout, " _simp: "); } @@ -331,7 +331,7 @@ private: AstConst* iconstp = VN_CAST(icondp, Const); if (iconstp && neverItem(nodep, iconstp)) { // X in casez can't ever be executed - icondp->deleteTree(); VL_DANGLING(icondp); VL_DANGLING(iconstp); + VL_DO_DANGLING(icondp->deleteTree(), icondp); VL_DANGLING(iconstp); // For simplicity, make expression that is not equal, and let later // optimizations remove it condp = new AstConst(itemp->fileline(), AstConst::LogicFalse()); @@ -357,7 +357,7 @@ private: AstNode* and2p = new AstAnd(itemp->fileline(), new AstConst(itemp->fileline(), numval), new AstConst(itemp->fileline(), nummask)); - icondp->deleteTree(); VL_DANGLING(icondp); VL_DANGLING(iconstp); + VL_DO_DANGLING(icondp->deleteTree(), icondp); VL_DANGLING(iconstp); condp = AstEq::newTyped(itemp->fileline(), and1p, and2p); } else { // Not a caseX mask, we can simply build CASEEQ(cexpr icond) @@ -375,7 +375,7 @@ private: itemp->condsp(ifexprp); } } - cexprp->deleteTree(); VL_DANGLING(cexprp); + VL_DO_DANGLING(cexprp->deleteTree(), cexprp); if (!hadDefault) { // If there was no default, add a empty one, this greatly simplifies below code // and constant propagation will just eliminate it for us later. @@ -418,7 +418,7 @@ private: { // Make the new lower IF and attach in the tree AstNode* itemexprp = ifexprp; VL_DANGLING(ifexprp); if (depth == (CASE_ENCODER_GROUP_DEPTH)) { // End of group - can skip the condition - itemexprp->deleteTree(); VL_DANGLING(itemexprp); + VL_DO_DANGLING(itemexprp->deleteTree(), itemexprp); itemexprp = new AstConst(itemp->fileline(), AstConst::LogicTrue()); } AstIf* newp = new AstIf(itemp->fileline(), itemexprp, istmtsp, NULL); @@ -434,7 +434,7 @@ private: if (debug()>=9 && grouprootp) grouprootp->dumpTree(cout, " _new: "); if (grouprootp) nodep->replaceWith(grouprootp); else nodep->unlinkFrBack(); - nodep->deleteTree(); VL_DANGLING(nodep); + VL_DO_DANGLING(nodep->deleteTree(), nodep); } void replaceCaseParallel(AstCase* nodep, bool noOverlapsAllCovered) { @@ -468,10 +468,10 @@ private: // It's a simple priority encoder or complete statement // we can make a tree of statements to avoid extra comparisons ++m_statCaseFast; - replaceCaseFast(nodep); VL_DANGLING(nodep); + VL_DO_DANGLING(replaceCaseFast(nodep), nodep); } else { ++m_statCaseSlow; - replaceCaseComplicated(nodep); VL_DANGLING(nodep); + VL_DO_DANGLING(replaceCaseComplicated(nodep), nodep); } } //-------------------- diff --git a/src/V3Changed.cpp b/src/V3Changed.cpp index 3efdb2b9e..9b51f8487 100644 --- a/src/V3Changed.cpp +++ b/src/V3Changed.cpp @@ -97,7 +97,7 @@ public: new AstLogOr(m_scopetopp->fileline(), callp, returnp->lhsp()->unlinkFrBack())); returnp->replaceWith(newp); - returnp->deleteTree(); VL_DANGLING(returnp); + VL_DO_DANGLING(returnp->deleteTree(), returnp); } m_numStmts = 0; } diff --git a/src/V3Clock.cpp b/src/V3Clock.cpp index 1b9d07cc6..39d6fc889 100644 --- a/src/V3Clock.cpp +++ b/src/V3Clock.cpp @@ -278,7 +278,7 @@ private: stmtsp->unlinkFrBackWithNext(); cmtp->addNextHere(stmtsp); } - nodep->deleteTree(); VL_DANGLING(nodep); + VL_DO_DANGLING(nodep->deleteTree(), nodep); } virtual void visit(AstAlwaysPost* nodep) { AstNode* cmtp = new AstComment(nodep->fileline(), nodep->typeName(), true); @@ -287,7 +287,7 @@ private: stmtsp->unlinkFrBackWithNext(); cmtp->addNextHere(stmtsp); } - nodep->deleteTree(); VL_DANGLING(nodep); + VL_DO_DANGLING(nodep->deleteTree(), nodep); } virtual void visit(AstCoverToggle* nodep) { //nodep->dumpTree(cout, "ct:"); @@ -307,7 +307,7 @@ private: newp->addIfsp(new AstAssign(nodep->fileline(), changep->cloneTree(false), origp->cloneTree(false))); - nodep->replaceWith(newp); nodep->deleteTree(); VL_DANGLING(nodep); + nodep->replaceWith(newp); VL_DO_DANGLING(nodep->deleteTree(), nodep); } virtual void visit(AstInitial* nodep) { AstNode* cmtp = new AstComment(nodep->fileline(), nodep->typeName(), true); @@ -316,7 +316,7 @@ private: stmtsp->unlinkFrBackWithNext(); cmtp->addNextHere(stmtsp); } - nodep->deleteTree(); VL_DANGLING(nodep); + VL_DO_DANGLING(nodep->deleteTree(), nodep); } virtual void visit(AstCFunc* nodep) { iterateChildren(nodep); @@ -349,7 +349,7 @@ private: // Not at the top or empty block... // Only empty blocks should be leftover on the non-top. Killem. UASSERT_OBJ(!nodep->stmtsp(), nodep, "Non-empty lower active"); - nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep); + VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); } else if (m_mtaskBodyp) { UINFO(4," TR ACTIVE "<stmtsp()->unlinkFrBackWithNext(); @@ -374,7 +374,7 @@ private: clearLastSen(); m_mtaskBodyp->addStmtsp(stmtsp); } - nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep); + VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); } else { UINFO(4," ACTIVE "<stmtsp()->unlinkFrBackWithNext(); @@ -407,7 +407,7 @@ private: // Move statements to function addToEvalLoop(stmtsp); } - nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep); + VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); } } virtual void visit(AstExecGraph* nodep) { diff --git a/src/V3Combine.cpp b/src/V3Combine.cpp index 45516957b..b8ae192ad 100644 --- a/src/V3Combine.cpp +++ b/src/V3Combine.cpp @@ -107,7 +107,7 @@ public: callp->unlinkFrBack(); } callp->user3(true); // Dead now - pushDeletep(callp); VL_DANGLING(callp); + VL_DO_DANGLING(pushDeletep(callp), callp); m_callMmap.erase(eqit); // Fix the table } } @@ -228,7 +228,7 @@ private: CombMarkVisitor visitor(oldfuncp); m_call.replaceFunc(oldfuncp, NULL); oldfuncp->unlinkFrBack(); - pushDeletep(oldfuncp); VL_DANGLING(oldfuncp); + VL_DO_DANGLING(pushDeletep(oldfuncp), oldfuncp); } } } @@ -260,7 +260,7 @@ private: CombMarkVisitor visitor(oldfuncp); m_call.replaceFunc(oldfuncp, newfuncp); oldfuncp->unlinkFrBack(); - pushDeletep(oldfuncp); VL_DANGLING(oldfuncp); + VL_DO_DANGLING(pushDeletep(oldfuncp), oldfuncp); } void replaceOnlyCallFunc(AstCCall* nodep) { if (AstCFunc* oldfuncp = VN_CAST(nodep->backp(), CFunc)) { @@ -272,7 +272,7 @@ private: UINFO(9," Function only has call "<funcp()); VL_DANGLING(nodep); + VL_DO_DANGLING(replaceFuncWFunc(oldfuncp, nodep->funcp()), nodep); } } } @@ -384,8 +384,8 @@ private: m_call.addCall(call2p); // If either new statement makes a func with only a single call, replace // the above callers to call it directly - replaceOnlyCallFunc(call1p); VL_DANGLING(call1p); - replaceOnlyCallFunc(call2p); VL_DANGLING(call2p); + VL_DO_DANGLING(replaceOnlyCallFunc(call1p), call1p); + VL_DO_DANGLING(replaceOnlyCallFunc(call2p), call2p); } // VISITORS diff --git a/src/V3Const.cpp b/src/V3Const.cpp index 10d48e1da..668fbb34c 100644 --- a/src/V3Const.cpp +++ b/src/V3Const.cpp @@ -212,7 +212,7 @@ private: if (!operandsSame(ap, bp)) return false; // Do it cp->unlinkFrBack(); - andp->unlinkFrBack()->deleteTree(); VL_DANGLING(andp); VL_DANGLING(notp); + VL_DO_DANGLING(andp->unlinkFrBack()->deleteTree(), andp); VL_DANGLING(notp); // Replace whichever branch is now dangling if (nodep->rhsp()) nodep->lhsp(cp); else nodep->rhsp(cp); @@ -240,7 +240,7 @@ private: newp->dtypeFrom(nodep); newp->expr1p()->dtypeFrom(nodep); // As And might have been to change widths newp->expr2p()->dtypeFrom(nodep); - nodep->replaceWith(newp); nodep->deleteTree(); VL_DANGLING(nodep); + nodep->replaceWith(newp); VL_DO_DANGLING(nodep->deleteTree(), nodep); return true; } static bool operandShiftSame(const AstNode* nodep) { @@ -343,7 +343,7 @@ private: && nodep->lsbConst()==0 && static_cast(nodep->widthConst()) == extendp->lhsp()->width() )) return false; - replaceWChild(nodep, extendp->lhsp()); VL_DANGLING(nodep); + VL_DO_DANGLING(replaceWChild(nodep, extendp->lhsp()), nodep); return true; } bool operandSelBiLower(AstSel* nodep) { @@ -362,7 +362,7 @@ private: bip->lhsp(new AstSel(nodep->fileline(), bilhsp, 0, nodep->widthConst())); bip->rhsp(new AstSel(nodep->fileline(), birhsp, 0, nodep->widthConst())); if (debug()>=9) bip->dumpTree(cout, "SEL(BI)-ou:"); - replaceWChild(nodep, bip); VL_DANGLING(nodep); + VL_DO_DANGLING(replaceWChild(nodep, bip), nodep); return true; } bool operandSelShiftLower(AstSel* nodep) { @@ -390,7 +390,7 @@ private: newLsb, nodep->widthConst()); newp->dtypeFrom(nodep); if (debug()>=9) newp->dumpTree(cout, "SEL(SH)-ou:"); - nodep->replaceWith(newp); VL_DANGLING(nodep); + VL_DO_DANGLING(nodep->replaceWith(newp), nodep); return true; } @@ -409,14 +409,14 @@ private: // if (debug()>=9) nodep->dumpTree(cout, "BI(EXTEND)-in:"); smallerp->unlinkFrBack(); - extendp->unlinkFrBack()->deleteTree(); // aka nodep->lhsp. + VL_DO_DANGLING(extendp->unlinkFrBack()->deleteTree(), extendp); // aka nodep->lhsp. nodep->rhsp(smallerp); constp->unlinkFrBack(); V3Number num (constp, subsize); num.opAssign(constp->num()); nodep->lhsp(new AstConst(constp->fileline(), num)); - constp->deleteTree(); VL_DANGLING(constp); + VL_DO_DANGLING(constp->deleteTree(), constp); if (debug()>=9) nodep->dumpTree(cout, "BI(EXTEND)-ou:"); return true; } @@ -622,11 +622,11 @@ private: if (debug()>5) oldp->dumpTree(cout, " const_old: "); if (debug()>5) newp->dumpTree(cout, " _new: "); oldp->replaceWith(newp); - oldp->deleteTree(); VL_DANGLING(oldp); + VL_DO_DANGLING(oldp->deleteTree(), oldp); } void replaceNum(AstNode* nodep, uint32_t val) { V3Number num (nodep, nodep->width(), val); - replaceNum(nodep, num); VL_DANGLING(nodep); + VL_DO_DANGLING(replaceNum(nodep, num), nodep); } void replaceNumSigned(AstNodeBiop* nodep, uint32_t val) { // We allow both sides to be constant, as one may have come from @@ -634,48 +634,48 @@ private: if (m_warn && !(VN_IS(nodep->lhsp(), Const) && VN_IS(nodep->rhsp(), Const))) { nodep->v3warn(UNSIGNED, "Comparison is constant due to unsigned arithmetic"); } - replaceNum(nodep, val); VL_DANGLING(nodep); + VL_DO_DANGLING(replaceNum(nodep, val), nodep); } void replaceNumLimited(AstNodeBiop* nodep, uint32_t val) { // Avoids gcc warning about same if (m_warn) nodep->v3warn(CMPCONST, "Comparison is constant due to limited range"); - replaceNum(nodep, val); VL_DANGLING(nodep); + VL_DO_DANGLING(replaceNum(nodep, val), nodep); } void replaceZero(AstNode* nodep) { - replaceNum(nodep, 0); VL_DANGLING(nodep); + VL_DO_DANGLING(replaceNum(nodep, 0), nodep); } void replaceZeroChkPure(AstNode* nodep, AstNode* checkp) { // For example, "0 * n" -> 0 if n has no side effects // Else strength reduce it to 0 & n. // If ever change the operation note AstAnd rule specially ignores this created pattern if (isTPure(checkp)) { - replaceNum(nodep, 0); VL_DANGLING(nodep); + VL_DO_DANGLING(replaceNum(nodep, 0), nodep); } else { AstNode* newp = new AstAnd(nodep->fileline(), new AstConst(nodep->fileline(), 0), checkp->unlinkFrBack()); newp->dtypeFrom(nodep); nodep->replaceWith(newp); - nodep->deleteTree(); VL_DANGLING(nodep); + VL_DO_DANGLING(nodep->deleteTree(), nodep); } } void replaceAllOnes(AstNode* nodep) { V3Number ones (nodep, nodep->width(), 0); ones.setMask(nodep->width()); - replaceNum(nodep, ones); VL_DANGLING(nodep); + VL_DO_DANGLING(replaceNum(nodep, ones), nodep); } void replaceConst(AstNodeUniop* nodep) { V3Number num (nodep, nodep->width()); nodep->numberOperate(num, VN_CAST(nodep->lhsp(), Const)->num()); UINFO(4,"UNICONST -> "<width()); nodep->numberOperate(num, VN_CAST(nodep->lhsp(), Const)->num(), VN_CAST(nodep->rhsp(), Const)->num()); UINFO(4,"BICONST -> "<width()); @@ -683,7 +683,7 @@ private: VN_CAST(nodep->rhsp(), Const)->num(), VN_CAST(nodep->thsp(), Const)->num()); UINFO(4,"TRICONST -> "<5) oldp->dumpTree(cout, " const_old: "); if (debug()>5) newp->dumpTree(cout, " _new: "); oldp->replaceWith(newp); - oldp->deleteTree(); VL_DANGLING(oldp); + VL_DO_DANGLING(oldp->deleteTree(), oldp); } //---------------------------------------- // Replacement functions. @@ -706,7 +706,7 @@ private: // This may adversely affect the operation of the node being replaced. childp->dtypeFrom(nodep); nodep->replaceWith(childp); - nodep->deleteTree(); VL_DANGLING(nodep); + VL_DO_DANGLING(nodep->deleteTree(), nodep); } //! Replace a ternary node with its RHS after iterating @@ -794,15 +794,15 @@ private: lp->rhsp(nodep); nodep->lhsp(lrp); nodep->rhsp(rrp); - rp->deleteTree(); - rlp->deleteTree(); + VL_DO_DANGLING(rp->deleteTree(), rp); + VL_DO_DANGLING(rlp->deleteTree(), rlp); } else if (operandsSame(lrp, rrp)) { lp->lhsp(nodep); lp->rhsp(rrp); nodep->lhsp(llp); nodep->rhsp(rlp); - rp->deleteTree(); - lrp->deleteTree(); + VL_DO_DANGLING(rp->deleteTree(), rp); + VL_DO_DANGLING(lrp->deleteTree(), lrp); } else { nodep->v3fatalSrc("replaceAndOr on something operandAndOrSame shouldn't have matched"); } @@ -822,8 +822,8 @@ private: lp->rhsp(lrp); nodep->lhsp(llp); nodep->rhsp(rlp); - rp->deleteTree(); - rrp->deleteTree(); + VL_DO_DANGLING(rp->deleteTree(), rp); + VL_DO_DANGLING(rrp->deleteTree(), rrp); //nodep->dumpTree(cout, " repShiftSame_new: "); } void replaceConcatSel(AstConcat* nodep) { @@ -842,9 +842,9 @@ private: UINFO(5, "merged two adjacent sel "<replaceWith(newselp); - lselp->deleteTree(); VL_DANGLING(lselp); - rselp->deleteTree(); VL_DANGLING(rselp); - nodep->deleteTree(); VL_DANGLING(nodep); + VL_DO_DANGLING(lselp->deleteTree(), lselp); + VL_DO_DANGLING(rselp->deleteTree(), rselp); + VL_DO_DANGLING(nodep->deleteTree(), nodep); } void replaceConcatMerge(AstConcat* nodep) { AstNodeBiop* lp = VN_CAST(nodep->lhsp(), NodeBiop); @@ -861,8 +861,8 @@ private: lp->rhsp()->replaceWith(newrp); lp->dtypeChgWidthSigned(newlp->width(), newlp->width(), AstNumeric::UNSIGNED); UINFO(5, "merged "<< nodep <unlinkFrBack()->deleteTree(); VL_DANGLING(rp); - nodep->replaceWith(lp->unlinkFrBack()); nodep->deleteTree(); VL_DANGLING(nodep); + VL_DO_DANGLING(rp->unlinkFrBack()->deleteTree(), rp); + nodep->replaceWith(lp->unlinkFrBack()); VL_DO_DANGLING(nodep->deleteTree(), nodep); iterate(lp->lhsp()); iterate(lp->rhsp()); } else nodep->v3fatalSrc("tried to merge two Concat which are not adjacent"); @@ -875,7 +875,7 @@ private: ? static_cast(new AstExtendS(nodep->fileline(), arg0p)) : static_cast(new AstExtend (nodep->fileline(), arg0p))); newp->dtypeFrom(nodep); - nodep->replaceWith(newp); nodep->deleteTree(); VL_DANGLING(nodep); + nodep->replaceWith(newp); VL_DO_DANGLING(nodep->deleteTree(), nodep); } void replacePowShift(AstNodeBiop* nodep) { // Pow or PowS UINFO(5,"POW(2,b)->SHIFTL(1,b) "<dtypeFrom(nodep); newp->lhsp()->dtypeFrom(nodep); - nodep->replaceWith(newp); nodep->deleteTree(); VL_DANGLING(nodep); + nodep->replaceWith(newp); VL_DO_DANGLING(nodep->deleteTree(), nodep); } void replaceMulShift(AstMul* nodep) { // Mul, but not MulS as not simple shift UINFO(5,"MUL(2^n,b)->SHIFTL(b,n) "<fileline(), opp, new AstConst(nodep->fileline(), amount)); newp->dtypeFrom(nodep); - nodep->replaceWith(newp); nodep->deleteTree(); VL_DANGLING(nodep); + nodep->replaceWith(newp); VL_DO_DANGLING(nodep->deleteTree(), nodep); } void replaceDivShift(AstDiv* nodep) { // Mul, but not MulS as not simple shift UINFO(5,"DIV(b,2^n)->SHIFTR(b,n) "<fileline(), opp, new AstConst(nodep->fileline(), amount)); newp->dtypeFrom(nodep); - nodep->replaceWith(newp); nodep->deleteTree(); VL_DANGLING(nodep); + nodep->replaceWith(newp); VL_DO_DANGLING(nodep->deleteTree(), nodep); } void replaceModAnd(AstModDiv* nodep) { // Mod, but not ModS as not simple shift UINFO(5,"MOD(b,2^n)->AND(b,2^n-1) "<fileline(), opp, new AstConst(nodep->fileline(), mask)); newp->dtypeFrom(nodep); - nodep->replaceWith(newp); nodep->deleteTree(); VL_DANGLING(nodep); + nodep->replaceWith(newp); VL_DO_DANGLING(nodep->deleteTree(), nodep); } void replaceShiftOp(AstNodeBiop* nodep) { UINFO(5,"SHIFT(AND(a,b),CONST)->AND(SHIFT(a,CONST),SHIFT(b,CONST)) "<toUInt(); int shift2 = VN_CAST(shift2p, Const)->toUInt(); int newshift = shift1+shift2; - shift1p->deleteTree(); VL_DANGLING(shift1p); - shift2p->deleteTree(); VL_DANGLING(shift2p); + VL_DO_DANGLING(shift1p->deleteTree(), shift1p); + VL_DO_DANGLING(shift2p->deleteTree(), shift2p); nodep->lhsp(ap); nodep->rhsp(new AstConst(nodep->fileline(), newshift)); iterate(nodep); // Further reduce, either node may have more reductions. @@ -958,8 +958,8 @@ private: int shift2 = VN_CAST(shift2p, Const)->toUInt(); if (VN_IS(nodep, ShiftR)) shift2=-shift2; int newshift = shift1+shift2; - shift1p->deleteTree(); VL_DANGLING(shift1p); - shift2p->deleteTree(); VL_DANGLING(shift2p); + VL_DO_DANGLING(shift1p->deleteTree(), shift1p); + VL_DO_DANGLING(shift2p->deleteTree(), shift2p); AstNode* newp; V3Number mask1 (nodep, nodep->width()); V3Number ones (nodep, nodep->width()); @@ -987,11 +987,11 @@ private: newp, new AstConst(nodep->fileline(), mask)); newp->dtypeFrom(nodep); - nodep->replaceWith(newp); nodep->deleteTree(); VL_DANGLING(nodep); + nodep->replaceWith(newp); VL_DO_DANGLING(nodep->deleteTree(), nodep); //newp->dumpTree(cout, " repShiftShift_new: "); iterate(newp); // Further reduce, either node may have more reductions. } - lhsp->deleteTree(); VL_DANGLING(lhsp); + VL_DO_DANGLING(lhsp->deleteTree(), lhsp); } bool replaceAssignMultiSel(AstNodeAssign* nodep) { @@ -1033,8 +1033,9 @@ private: new AstConcat(rhs1p->fileline(), rhs1p, rhs2p)); } //pnewp->dumpTree(cout, "conew: "); - nodep->replaceWith(newp); nodep->deleteTree(); - nextp->unlinkFrBack()->deleteTree(); + nodep->replaceWith(newp); + VL_DO_DANGLING(nodep->deleteTree(), nodep); + VL_DO_DANGLING(nextp->unlinkFrBack()->deleteTree(), nextp); return true; } @@ -1062,7 +1063,7 @@ private: nodep->v3error("Wire inputs its own output, creating circular logic (wire x=x)"); return false; // Don't delete the assign, or V3Gate will freak out } else { - nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep); + VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); return true; } } @@ -1156,8 +1157,8 @@ private: if (debug()>=9 && newp) newp->dumpTreeAndNext(cout, " _new: "); nodep->addNextHere(newp); // Cleanup - nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep); - conp->deleteTree(); VL_DANGLING(conp); + VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); + VL_DO_DANGLING(conp->deleteTree(), conp); // Further reduce, either node may have more reductions. return true; } @@ -1170,8 +1171,8 @@ private: AstNode* streamp = VN_CAST(nodep->rhsp(), StreamR)->unlinkFrBack(); nodep->rhsp(srcp); // Cleanup - sizep->deleteTree(); VL_DANGLING(sizep); - streamp->deleteTree(); VL_DANGLING(streamp); + VL_DO_DANGLING(sizep->deleteTree(), sizep); + VL_DO_DANGLING(streamp->deleteTree(), streamp); // Further reduce, any of the nodes may have more reductions. return true; } @@ -1213,8 +1214,8 @@ private: nodep->lhsp(dstp); nodep->rhsp(srcp); // Cleanup - sizep->deleteTree(); VL_DANGLING(sizep); - streamp->deleteTree(); VL_DANGLING(streamp); + VL_DO_DANGLING(sizep->deleteTree(), sizep); + VL_DO_DANGLING(streamp->deleteTree(), streamp); // Further reduce, any of the nodes may have more reductions. return true; } @@ -1250,7 +1251,7 @@ private: // widthMin no longer applicable if different C-expanded width newp->dtypeSetLogicSized(nodep->width(), AstNumeric::UNSIGNED); nodep->replaceWith(newp); - nodep->deleteTree(); VL_DANGLING(nodep); + VL_DO_DANGLING(nodep->deleteTree(), nodep); if (debug()>=9) newp->dumpTree(cout, " _new: "); } @@ -1264,7 +1265,7 @@ private: <prettyTypeName()<warnOther()<<"... Location of non-constant " <prettyTypeName()<<": "<dtypeFrom(nodep); newp->fileline(nodep->fileline()); UINFO(4, "Simulate->"<replaceWith(newp); nodep->deleteTree(); VL_DANGLING(nodep); + nodep->replaceWith(newp); VL_DO_DANGLING(nodep->deleteTree(), nodep); } } @@ -1354,7 +1355,7 @@ private: // If bp was a concat, then we have this exact same form again! // Recurse rather then calling node->iterate to prevent 2^n recursion! if (operandConcatMove(abConcp)) moveConcat(abConcp); - bcConcp->deleteTree(); VL_DANGLING(bcConcp); + VL_DO_DANGLING(bcConcp->deleteTree(), bcConcp); } else { AstConcat* abConcp = VN_CAST(nodep->lhsp(), Concat); abConcp->unlinkFrBack(); AstNode* ap = abConcp->lhsp()->unlinkFrBack(); @@ -1365,7 +1366,7 @@ private: nodep->lhsp(ap); nodep->rhsp(bcConcp); if (operandConcatMove(bcConcp)) moveConcat(bcConcp); - abConcp->deleteTree(); VL_DANGLING(abConcp); + VL_DO_DANGLING(abConcp->deleteTree(), abConcp); } } @@ -1397,7 +1398,7 @@ private: rhsp->cloneTree(false)), lhsp->cloneTree(false))); newp->dtypeFrom(nodep); - nodep->replaceWith(newp); nodep->deleteTree(); VL_DANGLING(nodep); + nodep->replaceWith(newp); VL_DO_DANGLING(nodep->deleteTree(), nodep); } void replaceSelSel(AstSel* nodep) { @@ -1414,8 +1415,8 @@ private: newlsbp = new AstConst(lsb1p->fileline(), VN_CAST(lsb1p, Const)->toUInt() + VN_CAST(lsb2p, Const)->toUInt()); - lsb1p->deleteTree(); VL_DANGLING(lsb1p); - lsb2p->deleteTree(); VL_DANGLING(lsb2p); + VL_DO_DANGLING(lsb1p->deleteTree(), lsb1p); + VL_DO_DANGLING(lsb2p->deleteTree(), lsb2p); } else { // Width is important, we need the width of the fromp's // expression, not the potentially smaller lsb1p's width @@ -1429,7 +1430,7 @@ private: newlsbp, widthp); nodep->replaceWith(newp); - nodep->deleteTree(); VL_DANGLING(nodep); + VL_DO_DANGLING(nodep->deleteTree(), nodep); } void replaceSelConcat(AstSel* nodep) { @@ -1469,7 +1470,7 @@ private: conRhsp->width()-nodep->lsbConst())); nodep->replaceWith(newp); } - nodep->deleteTree(); VL_DANGLING(nodep); + VL_DO_DANGLING(nodep->deleteTree(), nodep); } bool operandSelReplicate(AstSel* nodep) { // SEL(REPLICATE(from,rep),lsb,width) => SEL(from,0,width) as long @@ -1489,7 +1490,7 @@ private: new AstConst(lsbp->fileline(), lsbp->toUInt() % fromp->width()), widthp); newp->dtypeFrom(nodep); - nodep->replaceWith(newp); nodep->deleteTree(); VL_DANGLING(nodep); + nodep->replaceWith(newp); VL_DO_DANGLING(nodep->deleteTree(), nodep); return true; } bool operandRepRep(AstReplicate* nodep) { @@ -1505,7 +1506,7 @@ private: AstReplicate* newp = new AstReplicate(nodep->fileline(), from2p, cnt1p->toUInt()*cnt2p->toUInt()); newp->dtypeFrom(nodep); - nodep->replaceWith(newp); nodep->deleteTree(); VL_DANGLING(nodep); + nodep->replaceWith(newp); VL_DO_DANGLING(nodep->deleteTree(), nodep); return true; } bool operandConcatSame(AstConcat* nodep) { @@ -1532,7 +1533,7 @@ private: from1p->unlinkFrBack(); AstReplicate* newp = new AstReplicate(nodep->fileline(), from1p, cnt1+cnt2); newp->dtypeFrom(nodep); - nodep->replaceWith(newp); nodep->deleteTree(); VL_DANGLING(nodep); + nodep->replaceWith(newp); VL_DO_DANGLING(nodep->deleteTree(), nodep); return true; } void replaceSelIntoBiop(AstSel* nodep) { @@ -1550,7 +1551,7 @@ private: fromp->rhsp(new AstSel(nodep->fileline(), birhsp, lsbp, widthp)); fromp->dtypeFrom(nodep); - nodep->replaceWith(fromp); nodep->deleteTree(); VL_DANGLING(nodep); + nodep->replaceWith(fromp); VL_DO_DANGLING(nodep->deleteTree(), nodep); } void replaceSelIntoUniop(AstSel* nodep) { // SEL(NOT(a),1,bit) => NOT(SEL(a,bit)) @@ -1564,7 +1565,7 @@ private: fromp->lhsp(new AstSel(nodep->fileline(), bilhsp, lsbp, widthp)); fromp->dtypeFrom(nodep); - nodep->replaceWith(fromp); nodep->deleteTree(); VL_DANGLING(nodep); + nodep->replaceWith(fromp); VL_DO_DANGLING(nodep->deleteTree(), nodep); } virtual void visit(AstAttrOf* nodep) { @@ -1595,7 +1596,7 @@ private: fromp->dtypeFrom(VN_CAST(fromp->dtypep()->skipRefp(), NodeArrayDType)->subDTypep()); } - nodep->deleteTree(); VL_DANGLING(nodep); + VL_DO_DANGLING(nodep->deleteTree(), nodep); } } m_selp = NULL; @@ -1621,7 +1622,7 @@ private: if (operandConst(valuep)) { const V3Number& num = VN_CAST(valuep, Const)->num(); //UINFO(2,"constVisit "<num(); //UINFO(2,"constVisit "<cloneTree(false); - nodep->replaceWith(newp); nodep->deleteTree(); VL_DANGLING(nodep); + nodep->replaceWith(newp); VL_DO_DANGLING(nodep->deleteTree(), nodep); did = true; } } @@ -1666,7 +1667,7 @@ private: } if (AstConst* valuep = VN_CAST(nodep->itemp()->valuep(), Const)) { const V3Number& num = valuep->num(); - replaceNum(nodep, num); VL_DANGLING(nodep); + VL_DO_DANGLING(replaceNum(nodep, num), nodep); did = true; } } @@ -1694,13 +1695,13 @@ private: if (nodep->isClocked()) { // A constant can never get a pos/negedge if (onlySenItemInSenTree(nodep)) { nodep->replaceWith(new AstSenItem(nodep->fileline(), AstSenItem::Never())); - nodep->deleteTree(); VL_DANGLING(nodep); + VL_DO_DANGLING(nodep->deleteTree(), nodep); } else { - nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep); + VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); } } else { // Otherwise it may compute a result that needs to settle out nodep->replaceWith(new AstSenItem(nodep->fileline(), AstSenItem::Combo())); - nodep->deleteTree(); VL_DANGLING(nodep); + VL_DO_DANGLING(nodep->deleteTree(), nodep); } } else if (m_doNConst && VN_IS(nodep->sensp(), Not)) { // V3Gate may propagate NOTs into clocks... Just deal with it @@ -1716,7 +1717,7 @@ private: AstNodeVarRef* senvarp = VN_CAST(lastSensp->unlinkFrBack(), NodeVarRef); UASSERT_OBJ(senvarp, sensp, "Non-varref sensitivity variable"); sensp->replaceWith(senvarp); - sensp->deleteTree(); VL_DANGLING(sensp); + VL_DO_DANGLING(sensp->deleteTree(), sensp); } else if (!m_doNConst // Deal with later when doNConst missing && (VN_IS(nodep->sensp(), EnumItemRef) || VN_IS(nodep->sensp(), Const))) { @@ -1733,15 +1734,15 @@ private: UINFO(4,"SENGATE(...,0)->NEVER"<replaceWith(new AstSenItem(nodep->fileline(), AstSenItem::Never())); - nodep->deleteTree(); VL_DANGLING(nodep); + VL_DO_DANGLING(nodep->deleteTree(), nodep); } else { - nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep); + VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); } } else { UINFO(4,"SENGATE(SENITEM,0)->ALWAYS SENITEM"<sensesp()->unlinkFrBack(); nodep->replaceWith(senitemp); - nodep->deleteTree(); VL_DANGLING(nodep); + VL_DO_DANGLING(nodep->deleteTree(), nodep); } } } @@ -1813,7 +1814,8 @@ private: // Found, push this item up to the top itemp->unlinkFrBack(); nodep->addSensesp(itemp); - gatep->unlinkFrBack()->deleteTree(); VL_DANGLING(gatep); VL_DANGLING(senp); + VL_DO_DANGLING(gatep->unlinkFrBack()->deleteTree(), gatep); + VL_DANGLING(senp); } } } @@ -1874,7 +1876,8 @@ private: && ritemp->edgeType() == VEdgeType::ET_NEGEDGE) litemp->edgeType(VEdgeType::ET_BOTHEDGE); // Remove redundant node - ritemp->unlinkFrBack()->deleteTree(); VL_DANGLING(ritemp); VL_DANGLING(cmpp); + VL_DO_DANGLING(ritemp->unlinkFrBack()->deleteTree(), ritemp); + VL_DANGLING(cmpp); // Try to collapse again nextp = litemp; } @@ -1917,7 +1920,7 @@ private: new AstAssign(nodep->fileline(), varrefp, exprp)); m_modp->addStmtp(newinitp); - nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep); + VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); // Set the initial value right in the variable so we can constant propagate AstNode* initvaluep = exprp->cloneTree(false); varrefp->varp()->valuep(initvaluep); @@ -1942,13 +1945,13 @@ private: } else { nodep->unlinkFrBack(); } - nodep->deleteTree(); VL_DANGLING(nodep); + VL_DO_DANGLING(nodep->deleteTree(), nodep); } else if (!afterComment(nodep->ifsp()) && !afterComment(nodep->elsesp())) { // Empty block, remove it // Note if we support more C++ then there might be side // effects in the condition itself - nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep); + VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); } else if (!afterComment(nodep->ifsp())) { UINFO(4,"IF({x}) NULL {...} => IF(NOT{x}}: "<fileline(), condp, elsesp, ifsp); ifp->branchPred(nodep->branchPred().invert()); nodep->replaceWith(ifp); - nodep->deleteTree(); VL_DANGLING(nodep); + VL_DO_DANGLING(nodep->deleteTree(), nodep); } else if (ifSameAssign(nodep)) { UINFO(4,"IF({a}) ASSIGN({b},{c}) else ASSIGN({b},{d}) => ASSIGN({b}, {a}?{c}:{d})"<rhsp(new AstCond(truep->fileline(), condp, truep, falsep)); nodep->replaceWith(ifp); - nodep->deleteTree(); VL_DANGLING(nodep); + VL_DO_DANGLING(nodep->deleteTree(), nodep); } else if (0 // Disabled, as vpm assertions are faster without due to short-circuiting && operandIfIf(nodep)) { @@ -1995,7 +1998,7 @@ private: nodep->condp(new AstLogAnd(lowerIfp->fileline(), condp, lowerCondp)); lowerIfp->replaceWith(lowerIfsp); - lowerIfp->deleteTree(); VL_DANGLING(lowerIfp); + VL_DO_DANGLING(lowerIfp->deleteTree(), lowerIfp); } else if (operandBoolShift(nodep->condp())) { replaceBoolShift(nodep->condp()); @@ -2045,7 +2048,7 @@ private: if (!prevp->addNewline() && nodep->addNewline()) { pformatp->text(pformatp->text()+"\n"); } - nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep); + VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); return true; } virtual void visit(AstSFormatF* nodep) { @@ -2087,7 +2090,7 @@ private: <<" for "<unlinkFrBack()->deleteTree(); VL_DANGLING(argp); + VL_DO_DANGLING(argp->unlinkFrBack()->deleteTree(), argp); } argp = nextp; } @@ -2107,7 +2110,7 @@ private: && nodep->name().find('%') == string::npos && !nodep->hidden()) { // Just a simple constant string - the formatting is pointless - replaceConstString(nodep, nodep->name()); VL_DANGLING(nodep); + VL_DO_DANGLING(replaceConstString(nodep, nodep->name()), nodep); } } @@ -2134,7 +2137,7 @@ private: UINFO(4,"WHILE(0) => nop "<precondsp()) nodep->replaceWith(nodep->precondsp()); else nodep->unlinkFrBack(); - nodep->deleteTree(); VL_DANGLING(nodep); + VL_DO_DANGLING(nodep->deleteTree(), nodep); } else if (nodep->condp()->isNeqZero()) { if (!thisWhileHasJumpGo) { @@ -2162,7 +2165,7 @@ private: virtual void visit(AstSysIgnore* nodep) { iterateChildren(nodep); if (m_doNConst) { - nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep); + VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); } } @@ -2185,7 +2188,7 @@ private: if (AstJumpLabel* aboveLabelp = VN_CAST(nodep->abovep(), JumpLabel)) { if (aboveLabelp == nodep->labelp()) { UINFO(4, "JUMPGO => last remove "<unlinkFrBack()->deleteTree(); VL_DANGLING(nodep); + VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); return; } } @@ -2206,7 +2209,7 @@ private: if (nodep->stmtsp()) underp = nodep->stmtsp()->unlinkFrBackWithNext(); if (underp) nodep->replaceWith(underp); else nodep->unlinkFrBack(); - nodep->deleteTree(); VL_DANGLING(nodep); + VL_DO_DANGLING(nodep->deleteTree(), nodep); } } diff --git a/src/V3Coverage.cpp b/src/V3Coverage.cpp index 9927d1c47..465d939ef 100644 --- a/src/V3Coverage.cpp +++ b/src/V3Coverage.cpp @@ -373,7 +373,7 @@ private: // Skip all NEXT nodes under this block, and skip this if/case branch UINFO(4," OFF: "<unlinkFrBack()->deleteTree(); VL_DANGLING(nodep); + VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); } else { if (m_checkBlock) iterateChildren(nodep); } diff --git a/src/V3CoverageJoin.cpp b/src/V3CoverageJoin.cpp index fb66a9b12..999ca97de 100644 --- a/src/V3CoverageJoin.cpp +++ b/src/V3CoverageJoin.cpp @@ -92,7 +92,7 @@ private: UINFO(8," new "<incp()->declp()<unlinkFrBack(); pushDeletep(removep); VL_DANGLING(removep); + removep->unlinkFrBack(); VL_DO_DANGLING(pushDeletep(removep), removep); // Remove node from comparison so don't hit it again hashed.erase(dupit); ++m_statToggleJoins; diff --git a/src/V3Dead.cpp b/src/V3Dead.cpp index cc16421c3..921d18261 100644 --- a/src/V3Dead.cpp +++ b/src/V3Dead.cpp @@ -212,7 +212,7 @@ private: iterateChildren(nodep); if (m_elimCells) { if (!nodep->varsp()) { - pushDeletep(nodep->unlinkFrBack()); VL_DANGLING(nodep); + VL_DO_DANGLING(pushDeletep(nodep->unlinkFrBack()), nodep); return; } } @@ -221,7 +221,7 @@ private: virtual void visit(AstTypedef* nodep) { iterateChildren(nodep); if (m_elimCells && !nodep->attrPublic()) { - pushDeletep(nodep->unlinkFrBack()); VL_DANGLING(nodep); + VL_DO_DANGLING(pushDeletep(nodep->unlinkFrBack()), nodep); return; } checkAll(nodep); @@ -289,7 +289,7 @@ private: if (!modp->dead()) { // If was dead didn't increment user1's DeadModVisitor visitor(modp); } - modp->unlinkFrBack()->deleteTree(); VL_DANGLING(modp); + VL_DO_DANGLING(modp->unlinkFrBack()->deleteTree(), modp); retry = true; } } @@ -317,7 +317,7 @@ private: if (scp->dtypep()) { scp->dtypep()->user1Inc(-1); } - scp->unlinkFrBack()->deleteTree(); VL_DANGLING(scp); + VL_DO_DANGLING(scp->unlinkFrBack()->deleteTree(), scp); *it = NULL; retry = true; } @@ -330,7 +330,7 @@ private: AstCell* cellp = *it; if (cellp->user1() == 0 && !cellp->modp()->stmtsp()) { cellp->modp()->user1Inc(-1); - cellp->unlinkFrBack()->deleteTree(); VL_DANGLING(cellp); + VL_DO_DANGLING(cellp->unlinkFrBack()->deleteTree(), cellp); } } } @@ -347,11 +347,11 @@ private: AstNodeAssign* assp = itr->second; UINFO(4," Dead assign "<dtypep()->user1Inc(-1); - assp->unlinkFrBack()->deleteTree(); VL_DANGLING(assp); + VL_DO_DANGLING(assp->unlinkFrBack()->deleteTree(), assp); } if (vscp->scopep()) vscp->scopep()->user1Inc(-1); vscp->dtypep()->user1Inc(-1); - vscp->unlinkFrBack()->deleteTree(); VL_DANGLING(vscp); + VL_DO_DANGLING(vscp->unlinkFrBack()->deleteTree(), vscp); } } for (bool retry=true; retry; ) { @@ -365,7 +365,7 @@ private: if (varp->dtypep()) { varp->dtypep()->user1Inc(-1); } - varp->unlinkFrBack()->deleteTree(); VL_DANGLING(varp); + VL_DO_DANGLING(varp->unlinkFrBack()->deleteTree(), varp); *it = NULL; retry = true; } @@ -389,7 +389,7 @@ private: if (!cont) continue; } - (*it)->unlinkFrBack()->deleteTree(); VL_DANGLING(*it); + VL_DO_DANGLING((*it)->unlinkFrBack()->deleteTree(), *it); } } } diff --git a/src/V3Delayed.cpp b/src/V3Delayed.cpp index 40ef7954f..7844db7bd 100644 --- a/src/V3Delayed.cpp +++ b/src/V3Delayed.cpp @@ -384,9 +384,9 @@ private: if (newlhsp) { nodep->lhsp(newlhsp); } else { - nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep); + VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); } - lhsp->deleteTree(); VL_DANGLING(lhsp); + VL_DO_DANGLING(lhsp->deleteTree(), lhsp); } else { iterateChildren(nodep); @@ -432,7 +432,7 @@ private: } AstVarRef* newrefp = new AstVarRef(nodep->fileline(), dlyvscp, true); newrefp->user2(true); // No reason to do it again - nodep->replaceWith(newrefp); nodep->deleteTree(); VL_DANGLING(nodep); + nodep->replaceWith(newrefp); VL_DO_DANGLING(nodep->deleteTree(), nodep); } else if (!m_inDly && nodep->lvalue()) { //UINFO(9,"NBA "<push_back(*kt); } } - delete statep; VL_DANGLING(statep); + VL_DO_DANGLING(delete statep, statep); } } diff --git a/src/V3Expand.cpp b/src/V3Expand.cpp index 4291f965e..825c27c69 100644 --- a/src/V3Expand.cpp +++ b/src/V3Expand.cpp @@ -80,7 +80,7 @@ private: void replaceWithDelete(AstNode* nodep, AstNode* newp) { newp->user1(1); // Already processed, don't need to re-iterate nodep->replaceWith(newp); - nodep->deleteTree(); VL_DANGLING(nodep); + VL_DO_DANGLING(nodep->deleteTree(), nodep); } AstNode* newWordAssign(AstNodeAssign* placep, int word, AstNode* lhsp, AstNode* rhsp) { AstAssign* newp = new AstAssign(placep->fileline(), @@ -328,7 +328,7 @@ private: "extending larger thing into smaller?"); lhsp->dtypeFrom(nodep); // Just mark it, else nop } - replaceWithDelete(nodep, newp); VL_DANGLING(nodep); + VL_DO_DANGLING(replaceWithDelete(nodep, newp), nodep); } } bool expandWide(AstNodeAssign* nodep, AstExtend* rhsp) { @@ -443,7 +443,7 @@ private: if (midp) newp = new AstOr(nodep->fileline(), midp, newp); if (hip) newp = new AstOr(nodep->fileline(), hip, newp); newp->dtypeFrom(nodep); - replaceWithDelete(nodep, newp); VL_DANGLING(nodep); + VL_DO_DANGLING(replaceWithDelete(nodep, newp), nodep); } else { // Long/Quad from Long/Quad UINFO(8," SEL->SHIFT "<fileline(), newp, nodep); } newp->dtypeFrom(nodep); - replaceWithDelete(nodep, newp); VL_DANGLING(nodep); + VL_DO_DANGLING(replaceWithDelete(nodep, newp), nodep); } } @@ -553,8 +553,8 @@ private: rhsp, lsb))); } } - rhsp->deleteTree(); VL_DANGLING(rhsp); - destp->deleteTree(); VL_DANGLING(destp); + VL_DO_DANGLING(rhsp->deleteTree(), rhsp); + VL_DO_DANGLING(destp->deleteTree(), destp); } else { UINFO(8," ASSIGNSEL(const,narrow) "<isQuad() && !rhsp->isQuad()) { @@ -693,7 +693,7 @@ private: nodep->width()), rhsp); newp->dtypeFrom(nodep); // Unsigned - replaceWithDelete(nodep, newp); VL_DANGLING(nodep); + VL_DO_DANGLING(replaceWithDelete(nodep, newp), nodep); } } bool expandWide(AstNodeAssign* nodep, AstConcat* rhsp) { @@ -746,10 +746,10 @@ private: newp); newp->dtypeFrom(nodep); // Unsigned } - lhsp->deleteTree(); // Never used + VL_DO_DANGLING(lhsp->deleteTree(), lhsp); // Never used } newp->dtypeFrom(nodep); // Unsigned - replaceWithDelete(nodep, newp); VL_DANGLING(nodep); + VL_DO_DANGLING(replaceWithDelete(nodep, newp), nodep); } } bool expandWide(AstNodeAssign* nodep, AstReplicate* rhsp) { @@ -791,7 +791,7 @@ private: newAstWordSelClone(nodep->rhsp(), w)); newp = (newp==NULL) ? eqp : (new AstOr(nodep->fileline(), newp, eqp)); } - replaceWithDelete(nodep, newp); VL_DANGLING(nodep); + VL_DO_DANGLING(replaceWithDelete(nodep, newp), nodep); } void visitEqNeq(AstNodeBiop* nodep) { @@ -816,7 +816,7 @@ private: new AstConst(nodep->fileline(), AstConst::SizedEData(), 0), newp); } - replaceWithDelete(nodep, newp); VL_DANGLING(nodep); + VL_DO_DANGLING(replaceWithDelete(nodep, newp), nodep); } } virtual void visit(AstEq* nodep) { visitEqNeq(nodep); } @@ -836,7 +836,7 @@ private: newp = new AstNeq(nodep->fileline(), new AstConst(nodep->fileline(), AstConst::SizedEData(), 0), newp); - replaceWithDelete(nodep, newp); VL_DANGLING(nodep); + VL_DO_DANGLING(replaceWithDelete(nodep, newp), nodep); } else { UINFO(8," REDOR->EQ "<lhsp()->unlinkFrBack(); @@ -844,7 +844,7 @@ private: new AstConst(nodep->fileline(), AstConst::WidthedValue(), longOrQuadWidth(nodep), 0), lhsp); - replaceWithDelete(nodep, newp); VL_DANGLING(nodep); + VL_DO_DANGLING(replaceWithDelete(nodep, newp), nodep); } } virtual void visit(AstRedAnd* nodep) { @@ -870,14 +870,14 @@ private: newp = new AstEq(nodep->fileline(), new AstConst(nodep->fileline(), AstConst::SizedEData(), ~VL_MASK_E(0)), newp); - replaceWithDelete(nodep, newp); VL_DANGLING(nodep); + VL_DO_DANGLING(replaceWithDelete(nodep, newp), nodep); } else { UINFO(8," REDAND->EQ "<lhsp()->unlinkFrBack(); AstNode* newp = new AstEq(nodep->fileline(), new AstConst(nodep->fileline(), wordMask(lhsp)), lhsp); - replaceWithDelete(nodep, newp); VL_DANGLING(nodep); + VL_DO_DANGLING(replaceWithDelete(nodep, newp), nodep); } } virtual void visit(AstRedXor* nodep) { @@ -893,7 +893,7 @@ private: } newp = new AstRedXor(nodep->fileline(), newp); UINFO(8," Wordize REDXORnew "<unlinkFrBack()->deleteTree(); VL_DANGLING(nodep); + VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); } m_stmtp = NULL; } diff --git a/src/V3Gate.cpp b/src/V3Gate.cpp index 475539d2f..8f8f70d44 100644 --- a/src/V3Gate.cpp +++ b/src/V3Gate.cpp @@ -666,7 +666,7 @@ void GateVisitor::optimizeSignals(bool allowMultiIn) { varvertexp->propagateAttrClocksFrom(vvertexp); } // Remove the edge - edgep->unlinkDelete(); VL_DANGLING(edgep); + VL_DO_DANGLING(edgep->unlinkDelete(), edgep); ++m_statRefs; edgep = vvertexp->outBeginp(); } @@ -674,7 +674,7 @@ void GateVisitor::optimizeSignals(bool allowMultiIn) { if (removedAllUsages) { // Remove input links while (V3GraphEdge* edgep = vvertexp->inBeginp()) { - edgep->unlinkDelete(); VL_DANGLING(edgep); + VL_DO_DANGLING(edgep->unlinkDelete(), edgep); } // Clone tree so we remember it for tracing, and keep the pointer // to the "ALWAYS" part of the tree as part of this statement @@ -731,25 +731,25 @@ void GateVisitor::replaceAssigns() { if (vscp->valuep() && !VN_IS(vscp->valuep(), NodeMath)) { //if (debug()>9) vscp->dumpTree(cout, "-vscPre: "); while (AstNode* delp = VN_CAST(vscp->valuep(), Comment)) { - delp->unlinkFrBack()->deleteTree(); VL_DANGLING(delp); + VL_DO_DANGLING(delp->unlinkFrBack()->deleteTree(), delp); } if (AstInitial* delp = VN_CAST(vscp->valuep(), Initial)) { AstNode* bodyp = delp->bodysp(); bodyp->unlinkFrBackWithNext(); delp->replaceWith(bodyp); - delp->deleteTree(); VL_DANGLING(delp); + VL_DO_DANGLING(delp->deleteTree(), delp); } if (AstAlways* delp = VN_CAST(vscp->valuep(), Always)) { AstNode* bodyp = delp->bodysp(); bodyp->unlinkFrBackWithNext(); delp->replaceWith(bodyp); - delp->deleteTree(); VL_DANGLING(delp); + VL_DO_DANGLING(delp->deleteTree(), delp); } if (AstNodeAssign* delp = VN_CAST(vscp->valuep(), NodeAssign)) { AstNode* rhsp = delp->rhsp(); rhsp->unlinkFrBack(); delp->replaceWith(rhsp); - delp->deleteTree(); VL_DANGLING(delp); + VL_DO_DANGLING(delp->deleteTree(), delp); } //if (debug()>9) {vscp->dumpTree(cout, "-vscDone: "); cout<valuep(), NodeMath) @@ -805,7 +805,7 @@ void GateVisitor::consumedMove() { // with "tracing-on" sensitivity UINFO(8," Remove unconsumed "<unlinkFrBack(); - pushDeletep(nodep); VL_DANGLING(nodep); + VL_DO_DANGLING(pushDeletep(nodep), nodep); } } } @@ -884,7 +884,7 @@ private: if (AstNodeVarRef* varrefp = VN_CAST(substp, NodeVarRef)) varrefp->lvalue(false); hashReplace(nodep, substp); nodep->replaceWith(substp); - nodep->deleteTree(); VL_DANGLING(nodep); + VL_DO_DANGLING(nodep->deleteTree(), nodep); } } virtual void visit(AstNode* nodep) { @@ -1207,7 +1207,7 @@ private: dupVvertexp->propagateAttrClocksFrom(vvertexp); // Remove inputs links while (V3GraphEdge* inedgep = vvertexp->inBeginp()) { - inedgep->unlinkDelete(); VL_DANGLING(inedgep); + VL_DO_DANGLING(inedgep->unlinkDelete(), inedgep); } // replaceAssigns() does the deleteTree on lvertexNodep in a later step AstNode* lvertexNodep = lvertexp->nodep(); @@ -1338,19 +1338,19 @@ private: UINFO(5, "assemble to new sel: "<replaceWith(newselp); - preselp->deleteTree(); VL_DANGLING(preselp); + VL_DO_DANGLING(preselp->deleteTree(), preselp); // create new rhs for pre assignment AstNode* newrhsp = new AstConcat( m_assignp->rhsp()->fileline(), m_assignp->rhsp()->cloneTree(false), assignp->rhsp()->cloneTree(false)); AstNode* oldrhsp = m_assignp->rhsp(); oldrhsp->replaceWith(newrhsp); - oldrhsp->deleteTree(); VL_DANGLING(oldrhsp); + VL_DO_DANGLING(oldrhsp->deleteTree(), oldrhsp); m_assignp->dtypeChgWidthSigned(m_assignp->width()+assignp->width(), m_assignp->width()+assignp->width(), AstNumeric::SIGNED); // don't need to delete, will be handled - //assignp->unlinkFrBack(); assignp->deleteTree(); VL_DANGLING(assignp); + //assignp->unlinkFrBack(); VL_DO_DANGLING(assignp->deleteTree(), assignp); // update the graph { @@ -1362,11 +1362,11 @@ private: GateEitherVertex* fromvp = dynamic_cast(oedgep->fromp()); new V3GraphEdge(m_graphp, fromvp, m_logicvp, 1); - oedgep->unlinkDelete(); VL_DANGLING(oedgep); + VL_DO_DANGLING(oedgep->unlinkDelete(), oedgep); } } // delete all outedges to lvertexp, only one - oldedgep->unlinkDelete(); VL_DANGLING(oldedgep); + VL_DO_DANGLING(oldedgep->unlinkDelete(), oldedgep); } ++m_numMergedAssigns; } else { @@ -1556,7 +1556,7 @@ private: AstNode* rhsp = assignp->rhsp(); rhsp->replaceWith(new AstVarRef(rhsp->fileline(), m_clk_vsp, false)); for (V3GraphEdge* edgep = lvertexp->inBeginp(); edgep; ) { - edgep->unlinkDelete(); VL_DANGLING(edgep); + VL_DO_DANGLING(edgep->unlinkDelete(), edgep); } new V3GraphEdge(m_graphp, m_clk_vvertexp, lvertexp, 1); m_total_decomposed_clk_vectors++; @@ -1623,7 +1623,7 @@ private: AstNode* valuep = assp->rhsp(); valuep->unlinkFrBack(); assp->replaceWith(valuep); - assp->deleteTree(); VL_DANGLING(assp); + VL_DO_DANGLING(assp->deleteTree(), assp); } } // Speedups diff --git a/src/V3GenClk.cpp b/src/V3GenClk.cpp index c2755b633..52c0b940c 100644 --- a/src/V3GenClk.cpp +++ b/src/V3GenClk.cpp @@ -105,7 +105,7 @@ private: AstVarScope* newvscp = genInpClk(vscp); AstVarRef* newrefp = new AstVarRef(nodep->fileline(), newvscp, nodep->lvalue()); nodep->replaceWith(newrefp); - pushDeletep(nodep); VL_DANGLING(nodep); + VL_DO_DANGLING(pushDeletep(nodep), nodep); } } } diff --git a/src/V3Graph.cpp b/src/V3Graph.cpp index d5ea1fea2..5233e4b6d 100644 --- a/src/V3Graph.cpp +++ b/src/V3Graph.cpp @@ -224,7 +224,7 @@ void V3Graph::clear() { for (V3GraphVertex* vertexp = verticesBeginp(); vertexp; vertexp=vertexp->verticesNextp()) { for (V3GraphEdge* edgep = vertexp->outBeginp(); edgep; /*BELOW*/) { V3GraphEdge* nextp = edgep->outNextp(); - delete edgep; + VL_DO_DANGLING(delete edgep, edgep); edgep = nextp; } vertexp->outUnlink(); @@ -232,7 +232,7 @@ void V3Graph::clear() { // Delete the old vertices for (V3GraphVertex* vertexp = verticesBeginp(); vertexp; /*BELOW*/) { V3GraphVertex* nextp = vertexp->verticesNextp(); - delete vertexp; + VL_DO_DANGLING(delete vertexp, vertexp); vertexp = nextp; } verticesUnlink(); diff --git a/src/V3GraphAcyc.cpp b/src/V3GraphAcyc.cpp index 1c15e170b..a36709075 100644 --- a/src/V3GraphAcyc.cpp +++ b/src/V3GraphAcyc.cpp @@ -275,7 +275,7 @@ void GraphAcyc::deleteMarked() { nextp = vertexp->verticesNextp(); GraphAcycVertex* avertexp = static_cast(vertexp); if (avertexp->isDelete()) { - avertexp->unlinkDelete(&m_breakGraph); VL_DANGLING(avertexp); + VL_DO_DANGLING(avertexp->unlinkDelete(&m_breakGraph), avertexp); } } } @@ -291,13 +291,13 @@ void GraphAcyc::simplifyNone(GraphAcycVertex* avertexp) { while (V3GraphEdge* edgep = avertexp->outBeginp()) { V3GraphVertex* otherVertexp = edgep->top(); //UINFO(9," out "<unlinkDelete(); VL_DANGLING(edgep); + VL_DO_DANGLING(edgep->unlinkDelete(), edgep); workPush(otherVertexp); } while (V3GraphEdge* edgep = avertexp->inBeginp()) { V3GraphVertex* otherVertexp = edgep->fromp(); //UINFO(9," in "<unlinkDelete(); VL_DANGLING(edgep); + VL_DO_DANGLING(edgep->unlinkDelete(), edgep); workPush(otherVertexp); } } @@ -328,8 +328,8 @@ void GraphAcyc::simplifyOne(GraphAcycVertex* avertexp) { // cppcheck-suppress leakReturnValNotUsed edgeFromEdge(templateEdgep, inVertexp, outVertexp); // Remove old edge - inEdgep->unlinkDelete(); VL_DANGLING(inEdgep); - outEdgep->unlinkDelete(); VL_DANGLING(outEdgep); VL_DANGLING(templateEdgep); + VL_DO_DANGLING(inEdgep->unlinkDelete(), inEdgep); + VL_DO_DANGLING(outEdgep->unlinkDelete(), outEdgep); VL_DANGLING(templateEdgep); workPush(inVertexp); workPush(outVertexp); } @@ -363,10 +363,10 @@ void GraphAcyc::simplifyOut(GraphAcycVertex* avertexp) { // cppcheck-suppress leakReturnValNotUsed edgeFromEdge(inEdgep, inVertexp, outVertexp); // Remove old edge - inEdgep->unlinkDelete(); VL_DANGLING(inEdgep); + VL_DO_DANGLING(inEdgep->unlinkDelete(), inEdgep); workPush(inVertexp); } - outEdgep->unlinkDelete(); VL_DANGLING(outEdgep); + VL_DO_DANGLING(outEdgep->unlinkDelete(), outEdgep); workPush(outVertexp); } } @@ -389,18 +389,18 @@ void GraphAcyc::simplifyDup(GraphAcycVertex* avertexp) { // !cutable duplicates prev !cutable: we can ignore it, redundant // cutable duplicates prev !cutable: know it's not a relevant loop, ignore it UINFO(8," DelDupEdge "< "<top()<unlinkDelete(); VL_DANGLING(edgep); + VL_DO_DANGLING(edgep->unlinkDelete(), edgep); } else if (!edgep->cutable()) { // !cutable duplicates prev cutable: delete the earlier cutable UINFO(8," DelDupPrev "< "<top()<unlinkDelete(); VL_DANGLING(prevEdgep); + VL_DO_DANGLING(prevEdgep->unlinkDelete(), prevEdgep); outVertexp->userp(edgep); } else { // cutable duplicates prev cutable: combine weights UINFO(8," DelDupComb "< "<top()<weight(prevEdgep->weight() + edgep->weight()); addOrigEdgep(prevEdgep, edgep); - edgep->unlinkDelete(); VL_DANGLING(edgep); + VL_DO_DANGLING(edgep->unlinkDelete(), edgep); } workPush(outVertexp); workPush(avertexp); @@ -418,7 +418,7 @@ void GraphAcyc::cutBasic(GraphAcycVertex* avertexp) { nextp = edgep->outNextp(); if (edgep->cutable() && edgep->top()==avertexp) { cutOrigEdge(edgep, " Cut Basic"); - edgep->unlinkDelete(); VL_DANGLING(edgep); + VL_DO_DANGLING(edgep->unlinkDelete(), edgep); workPush(avertexp); } } @@ -439,7 +439,7 @@ void GraphAcyc::cutBackward(GraphAcycVertex* avertexp) { nextp = edgep->outNextp(); if (edgep->cutable() && edgep->top()->user()) { cutOrigEdge(edgep, " Cut A->B->A"); - edgep->unlinkDelete(); VL_DANGLING(edgep); + VL_DO_DANGLING(edgep->unlinkDelete(), edgep); workPush(avertexp); } } @@ -506,7 +506,7 @@ void GraphAcyc::placeTryEdge(V3GraphEdge* edgep) { // Adding this edge would cause a loop, kill it edgep->cutable(true); // So graph still looks pretty cutOrigEdge(edgep, " Cut loop"); - edgep->unlinkDelete(); VL_DANGLING(edgep); + VL_DO_DANGLING(edgep->unlinkDelete(), edgep); // Back out the ranks we calculated while (GraphAcycVertex* vertexp = workBeginp()) { workPop(); diff --git a/src/V3GraphAlg.cpp b/src/V3GraphAlg.cpp index 6f82700da..d663e7e4e 100644 --- a/src/V3GraphAlg.cpp +++ b/src/V3GraphAlg.cpp @@ -110,10 +110,10 @@ private: } if (saveOld) { if (m_sumWeights) prevEdgep->weight(prevEdgep->weight() + edgep->weight()); - edgep->unlinkDelete(); VL_DANGLING(edgep); + VL_DO_DANGLING(edgep->unlinkDelete(), edgep); } else { if (m_sumWeights) edgep->weight(prevEdgep->weight() + edgep->weight()); - prevEdgep->unlinkDelete(); VL_DANGLING(prevEdgep); + VL_DO_DANGLING(prevEdgep->unlinkDelete(), prevEdgep); outVertexp->userp(edgep); } } @@ -162,7 +162,7 @@ public: } } if (deletep) { - deletep->unlinkDelete(); VL_DANGLING(deletep); + VL_DO_DANGLING(deletep->unlinkDelete(), deletep); } } } diff --git a/src/V3GraphDfa.cpp b/src/V3GraphDfa.cpp index a55fcec06..a7615bb09 100644 --- a/src/V3GraphDfa.cpp +++ b/src/V3GraphDfa.cpp @@ -354,7 +354,7 @@ private: for (V3GraphVertex* nextp,*vertexp = m_graphp->verticesBeginp(); vertexp; vertexp=nextp) { nextp = vertexp->verticesNextp(); if (nfaState(vertexp)) { - vertexp->unlinkDelete(m_graphp); VL_DANGLING(vertexp); + VL_DO_DANGLING(vertexp->unlinkDelete(m_graphp), vertexp); } } @@ -409,7 +409,7 @@ private: if (vvertexp->accepting()) { for (V3GraphEdge* nextp,*edgep = vertexp->outBeginp(); edgep; edgep=nextp) { nextp = edgep->outNextp(); - edgep->unlinkDelete(); VL_DANGLING(edgep); + VL_DO_DANGLING(edgep->unlinkDelete(), edgep); } } } @@ -445,7 +445,7 @@ private: for (V3GraphVertex* nextp,*vertexp = m_graphp->verticesBeginp(); vertexp; vertexp=nextp) { nextp = vertexp->verticesNextp(); if (!vertexp->user()) { - vertexp->unlinkDelete(m_graphp); VL_DANGLING(vertexp); + VL_DO_DANGLING(vertexp->unlinkDelete(m_graphp), vertexp); } } } @@ -487,7 +487,7 @@ private: } } // Transitions to this state removed by the unlink function - vertexp->unlinkDelete(m_graphp); VL_DANGLING(vertexp); + VL_DO_DANGLING(vertexp->unlinkDelete(m_graphp), vertexp); } } } @@ -566,7 +566,7 @@ private: DfaVertex* tovertexp = static_cast(edgep->top()); if (tovertexp->accepting()) { new DfaEdge(graphp(), vvertexp, m_tempNewerReject, vedgep); - edgep->unlinkDelete(); VL_DANGLING(edgep); + VL_DO_DANGLING(edgep->unlinkDelete(), edgep); } // NOT of all values goes to accept diff --git a/src/V3GraphPathChecker.cpp b/src/V3GraphPathChecker.cpp index 8e1699bae..e510e4b30 100644 --- a/src/V3GraphPathChecker.cpp +++ b/src/V3GraphPathChecker.cpp @@ -73,7 +73,7 @@ GraphPathChecker::~GraphPathChecker() { for (V3GraphVertex* vxp = m_graphp->verticesBeginp(); vxp; vxp = vxp->verticesNextp()) { GraphPCNode* nodep = static_cast(vxp->userp()); - delete nodep; VL_DANGLING(nodep); + VL_DO_DANGLING(delete nodep, nodep); vxp->userp(NULL); } } diff --git a/src/V3Inline.cpp b/src/V3Inline.cpp index aa9aef4a7..a38704c9c 100644 --- a/src/V3Inline.cpp +++ b/src/V3Inline.cpp @@ -129,14 +129,16 @@ private: || m_modp->user2() == CIL_NOTSOFT) { m_modp->user2(CIL_USER); } - nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep); // Remove so don't propagate to upper cell... + // Remove so don't propagate to upper cell... + VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); } else if (nodep->pragType() == AstPragmaType::NO_INLINE_MODULE) { if (!m_modp) { nodep->v3error("Inline pragma not under a module"); // LCOV_EXCL_LINE } else { cantInline("Pragma NO_INLINE_MODULE", false); } - nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep); // Remove so don't propagate to upper cell... + // Remove so don't propagate to upper cell... + VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); } else { iterateChildren(nodep); } @@ -401,7 +403,7 @@ private: AstVarRef* exprvarrefp = VN_CAST(nodep->varp()->user2p(), VarRef); if (exprconstp) { nodep->replaceWith(exprconstp->cloneTree(true)); - nodep->deleteTree(); VL_DANGLING(nodep); + VL_DO_DANGLING(nodep->deleteTree(), nodep); return; } else if (exprvarrefp) { @@ -597,9 +599,9 @@ private: if (stmtsp) stmtsp->unlinkFrBackWithNext(); if (stmtsp) m_modp->addStmtp(stmtsp); // Remove the cell - newmodp->deleteTree(); VL_DANGLING(newmodp); // Clear any leftover ports, etc + VL_DO_DANGLING(newmodp->deleteTree(), newmodp); // Clear any leftover ports, etc nodep->unlinkFrBack(); - pushDeletep(nodep); VL_DANGLING(nodep); + VL_DO_DANGLING(pushDeletep(nodep), nodep); if (debug()>=9) { m_modp->dumpTree(cout, "donemod:"); } } } @@ -746,7 +748,7 @@ void V3Inline::inlineAll(AstNetlist* nodep) { for (AstNodeModule* modp = v3Global.rootp()->modulesp(); modp; modp=nextmodp) { nextmodp = VN_CAST(modp->nextp(), NodeModule); if (modp->user1()) { // Was inlined - modp->unlinkFrBack()->deleteTree(); VL_DANGLING(modp); + VL_DO_DANGLING(modp->unlinkFrBack()->deleteTree(), modp); } } { diff --git a/src/V3Inst.cpp b/src/V3Inst.cpp index ce4a66bb8..4b58111a2 100644 --- a/src/V3Inst.cpp +++ b/src/V3Inst.cpp @@ -113,7 +113,7 @@ private: } // We're done with the pin - nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep); + VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); } virtual void visit(AstUdpTable* nodep) { @@ -303,9 +303,10 @@ private: // Done. Delete original m_cellRangep = NULL; if (isIface) { - ifaceVarp->unlinkFrBack(); pushDeletep(ifaceVarp); VL_DANGLING(ifaceVarp); + ifaceVarp->unlinkFrBack(); + VL_DO_DANGLING(pushDeletep(ifaceVarp), ifaceVarp); } - nodep->unlinkFrBack(); pushDeletep(nodep); VL_DANGLING(nodep); + nodep->unlinkFrBack(); VL_DO_DANGLING(pushDeletep(nodep), nodep); } else { m_cellRangep = NULL; iterateChildren(nodep); @@ -379,7 +380,7 @@ private: newp->dtypep(nodep->modVarp()->dtypep()); newp->packagep(varrefp->packagep()); arrselp->addNextHere(newp); - arrselp->unlinkFrBack()->deleteTree(); + VL_DO_DANGLING(arrselp->unlinkFrBack()->deleteTree(), arrselp); } } else { AstVar* pinVarp = nodep->modVarp(); diff --git a/src/V3Life.cpp b/src/V3Life.cpp index 138518f31..f77ef95ea 100644 --- a/src/V3Life.cpp +++ b/src/V3Life.cpp @@ -158,7 +158,7 @@ public: // above our current iteration point. if (debug()>4) oldassp->dumpTree(cout, " REMOVE/SAMEBLK "); entp->complexAssign(); - m_statep->pushUnlinkDeletep(oldassp); VL_DANGLING(oldassp); + VL_DO_DANGLING(m_statep->pushUnlinkDeletep(oldassp), oldassp); ++m_statep->m_statAssnDel; } } @@ -195,7 +195,7 @@ public: // We'll later constant propagate UINFO(4," replaceconst: "<replaceWith(constp->cloneTree(false)); - varrefp->deleteTree(); VL_DANGLING(varrefp); + VL_DO_DANGLING(varrefp->deleteTree(), varrefp); ++m_statep->m_statAssnCon; return; // **DONE, no longer a var reference** } @@ -307,7 +307,7 @@ private: m_sideEffect = true; // $sscanf etc may have RHS vars that are lvalues m_lifep->complexAssign(vscp); } else { - m_lifep->varUsageReplace(vscp, nodep); VL_DANGLING(nodep); + VL_DO_DANGLING(m_lifep->varUsageReplace(vscp, nodep), nodep); } } virtual void visit(AstNodeAssign* nodep) { @@ -358,8 +358,8 @@ private: // For the next assignments, clear any variables that were read or written in the block ifLifep->lifeToAbove(); elseLifep->lifeToAbove(); - delete ifLifep; - delete elseLifep; + VL_DO_DANGLING(delete ifLifep, ifLifep); + VL_DO_DANGLING(delete elseLifep, elseLifep); } virtual void visit(AstWhile* nodep) { @@ -388,8 +388,8 @@ private: // For the next assignments, clear any variables that were read or written in the block condLifep->lifeToAbove(); bodyLifep->lifeToAbove(); - delete condLifep; - delete bodyLifep; + VL_DO_DANGLING(delete condLifep, condLifep); + VL_DO_DANGLING(delete bodyLifep, bodyLifep); } virtual void visit(AstJumpLabel* nodep) { // As with While's we can't predict if a JumpGo will kill us or not @@ -408,7 +408,7 @@ private: UINFO(4," joinjump"<lifeToAbove(); - delete bodyLifep; + VL_DO_DANGLING(delete bodyLifep, bodyLifep); } virtual void visit(AstCCall* nodep) { //UINFO(4," CCALL "<fileline(), newvscp, nodep->lvalue()); nodep->replaceWith(newrefp); - nodep->deleteTree(); VL_DANGLING(nodep); + VL_DO_DANGLING(nodep->deleteTree(), nodep); } } virtual void visit(AstNodeModule* nodep) { @@ -253,7 +253,7 @@ private: // Delete and mark so LifePostElimVisitor will get it UINFO(4," DELETE "<nodep<user4p(origVarp); - app->nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(app->nodep); + VL_DO_DANGLING(app->nodep->unlinkFrBack()->deleteTree(), app->nodep); ++m_statAssnDel; } } diff --git a/src/V3LinkCells.cpp b/src/V3LinkCells.cpp index 361e70c41..a9b783897 100644 --- a/src/V3LinkCells.cpp +++ b/src/V3LinkCells.cpp @@ -354,7 +354,7 @@ private: if (pinStar) pinp->v3error("Duplicate .* in a cell"); pinStar = true; // Done with this fake pin - pinp->unlinkFrBack()->deleteTree(); VL_DANGLING(pinp); + VL_DO_DANGLING(pinp->unlinkFrBack()->deleteTree(), pinp); } } // Convert unnamed pins to pin number based assignments @@ -470,7 +470,7 @@ private: <warnContextSecondary()); } nodep->unlinkFrBack(); - pushDeletep(nodep); VL_DANGLING(nodep); + VL_DO_DANGLING(pushDeletep(nodep), nodep); } else if (!foundp) { m_mods.rootp()->insert(nodep->name(), new VSymEnt(&m_mods, nodep)); } diff --git a/src/V3LinkDot.cpp b/src/V3LinkDot.cpp index c56c3c7a1..ba05aaf6b 100644 --- a/src/V3LinkDot.cpp +++ b/src/V3LinkDot.cpp @@ -985,7 +985,7 @@ class LinkDotFindVisitor : public AstNVisitor { iterateChildren(nodep); if (m_ftaskp && nodep->isParam()) { nodep->v3error("Unsupported: Parameters in functions."); // Big3 unsupported too - nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep); + VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); return; } if (!m_statep->forScopeCreation()) { @@ -1038,12 +1038,12 @@ class LinkDotFindVisitor : public AstNVisitor { AstNodeDType* newdtypep = nodep->subDTypep(); UASSERT_OBJ(newdtypep && nodep->childDTypep(), findvarp, "No child type?"); - bdtypep->unlinkFrBack()->deleteTree(); + VL_DO_DANGLING(bdtypep->unlinkFrBack()->deleteTree(), bdtypep); newdtypep->unlinkFrBack(); findvarp->childDTypep(newdtypep); } } - nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep); + VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); } else { // User can disable the message at either point if (!(m_ftaskp && m_ftaskp->dpiImport()) @@ -1075,7 +1075,7 @@ class LinkDotFindVisitor : public AstNVisitor { newp->valuep(valuep); UINFO(9," replace parameter "<replaceWith(newp); pushDeletep(nodep); VL_DANGLING(nodep); + nodep->replaceWith(newp); VL_DO_DANGLING(pushDeletep(nodep), nodep); nodep = newp; } } @@ -1299,7 +1299,7 @@ private: nodep->name(), exprp); cellp->addParamsp(pinp); - nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep); + VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); } } virtual void visit(AstPort* nodep) { @@ -1327,7 +1327,7 @@ private: symp->exported(false); } // Ports not needed any more - nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep); + VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); } virtual void visit(AstAssignW* nodep) { // Deal with implicit definitions @@ -1352,7 +1352,7 @@ private: // Unsupported gates need implicit creation pinImplicitExprRecurse(nodep); // We're done with implicit gates - nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep); + VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); } virtual void visit(AstNode* nodep) { // Default: Just iterate @@ -1497,7 +1497,7 @@ class LinkDotScopeVisitor : public AstNVisitor { // or maybe an alias of an alias m_statep->insertScopeAlias(LinkDotState::SAMN_IFTOP, lhsSymp, rhsSymp); // We have stored the link, we don't need these any more - nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep); + VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); } // For speed, don't recurse things that can't have scope // Note we allow AstNodeStmt's as generates may be under them @@ -1565,7 +1565,7 @@ class LinkDotIfaceVisitor : public AstNVisitor { if (m_statep->forScopeCreation()) { // Done with AstModportFTaskRef. // Delete to prevent problems if we dead-delete pointed to ftask - nodep->unlinkFrBack(); pushDeletep(nodep); VL_DANGLING(nodep); + nodep->unlinkFrBack(); VL_DO_DANGLING(pushDeletep(nodep), nodep); } } virtual void visit(AstModportVarRef* nodep) { @@ -1589,7 +1589,7 @@ class LinkDotIfaceVisitor : public AstNVisitor { if (m_statep->forScopeCreation()) { // Done with AstModportVarRef. // Delete to prevent problems if we dead-delete pointed to variable - nodep->unlinkFrBack(); pushDeletep(nodep); VL_DANGLING(nodep); + nodep->unlinkFrBack(); VL_DO_DANGLING(pushDeletep(nodep), nodep); } } virtual void visit(AstNode* nodep) { @@ -1801,7 +1801,7 @@ private: virtual void visit(AstCellInline* nodep) { checkNoDot(nodep); if (m_statep->forScopeCreation() && !v3Global.opt.vpi()) { - nodep->unlinkFrBack(); pushDeletep(nodep); VL_DANGLING(nodep); + nodep->unlinkFrBack(); VL_DO_DANGLING(pushDeletep(nodep), nodep); } } virtual void visit(AstCell* nodep) { @@ -1844,7 +1844,7 @@ private: if (!foundp) { if (nodep->name() == "__paramNumber1" && VN_IS(m_cellp->modp(), Primitive)) { // Primitive parameter is really a delay we can just ignore - nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep); + VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); return; } string suggest @@ -1923,7 +1923,7 @@ private: } if (debug()>=9) newp->dumpTree("-dot-out: "); nodep->replaceWith(newp); - pushDeletep(nodep); VL_DANGLING(nodep); + VL_DO_DANGLING(pushDeletep(nodep), nodep); } else { // Dot midpoint AstNode* newp = nodep->rhsp()->unlinkFrBack(); if (m_ds.m_unresolved) { @@ -1932,7 +1932,7 @@ private: newp = crp; } nodep->replaceWith(newp); - pushDeletep(nodep); VL_DANGLING(nodep); + VL_DO_DANGLING(pushDeletep(nodep), nodep); } } if (start) { @@ -1963,7 +1963,7 @@ private: VFlagChildDType(), nodep->name()); if (m_ds.m_dotErr) nodep->unlinkFrBack(); // Avoid circular node loop on errors else nodep->replaceWith(newp); - pushDeletep(nodep); VL_DANGLING(nodep); + VL_DO_DANGLING(pushDeletep(nodep), nodep); } else { // @@ -2042,7 +2042,7 @@ private: UINFO(9," cell -> iface varref "<nodep()<fileline(), ifaceRefVarp, false); - nodep->replaceWith(newp); pushDeletep(nodep); VL_DANGLING(nodep); + nodep->replaceWith(newp); VL_DO_DANGLING(pushDeletep(nodep), nodep); } else if (VN_IS(cellp->modp(), NotFoundModule)) { cellp->modNameFileline()->v3error("Cannot find file containing interface: " <modp()->prettyNameQ()); @@ -2060,7 +2060,7 @@ private: m_ds.m_dotPos = DP_SCOPE; ok = true; AstNode* newp = new AstVarRef(nodep->fileline(), varp, false); - nodep->replaceWith(newp); pushDeletep(nodep); VL_DANGLING(nodep); + nodep->replaceWith(newp); VL_DO_DANGLING(pushDeletep(nodep), nodep); } else if (allowVar) { AstNode* newp; @@ -2084,7 +2084,7 @@ private: newp = refp; } UINFO(9," new "<replaceWith(newp); pushDeletep(nodep); VL_DANGLING(nodep); + nodep->replaceWith(newp); VL_DO_DANGLING(pushDeletep(nodep), nodep); m_ds.m_dotPos = DP_MEMBER; ok = true; } @@ -2117,14 +2117,14 @@ private: AstVar* varp = makeIfaceModportVar(nodep->fileline(), cellp, ifacep, modportp); AstVarRef* refp = new AstVarRef(varp->fileline(), varp, false); - nodep->replaceWith(refp); pushDeletep(nodep); VL_DANGLING(nodep); + nodep->replaceWith(refp); VL_DO_DANGLING(pushDeletep(nodep), nodep); } } else if (AstEnumItem* valuep = VN_CAST(foundp->nodep(), EnumItem)) { if (allowVar) { AstNode* newp = new AstEnumItemRef(nodep->fileline(), valuep, foundp->packagep()); - nodep->replaceWith(newp); pushDeletep(nodep); VL_DANGLING(nodep); + nodep->replaceWith(newp); VL_DO_DANGLING(pushDeletep(nodep), nodep); ok = true; m_ds.m_dotText = ""; } @@ -2166,7 +2166,7 @@ private: // Create if implicit, and also if error (so only complain once) AstVarRef* newp = new AstVarRef(nodep->fileline(), nodep->name(), false); nodep->replaceWith(newp); - pushDeletep(nodep); VL_DANGLING(nodep); + VL_DO_DANGLING(pushDeletep(nodep), nodep); createImplicitVar(m_curSymp, newp, m_modp, m_modSymp, err); } } @@ -2237,7 +2237,7 @@ private: AstVarRef* newrefp = new AstVarRef(nodep->fileline(), nodep->varp(), nodep->lvalue()); nodep->replaceWith(newrefp); - nodep->deleteTree(); VL_DANGLING(nodep); + VL_DO_DANGLING(nodep->deleteTree(), nodep); } } } else { @@ -2262,7 +2262,7 @@ private: UINFO(7," Resolved "<fileline(), vscp, nodep->lvalue()); nodep->replaceWith(newvscp); - nodep->deleteTree(); VL_DANGLING(nodep); + VL_DO_DANGLING(nodep->deleteTree(), nodep); UINFO(9," new "<fileline(), varEtcp, VFlagChildDType(), nodep->name(), argsp); nodep->replaceWith(newp); - pushDeletep(nodep); VL_DANGLING(nodep); + VL_DO_DANGLING(pushDeletep(nodep), nodep); return; } else { checkNoDot(nodep); @@ -2425,7 +2425,7 @@ private: AstNode* exprp = nodep->bitp()->unlinkFrBack(); AstCellArrayRef* newp = new AstCellArrayRef(nodep->fileline(), nodep->fromp()->name(), exprp); - nodep->replaceWith(newp); pushDeletep(nodep); VL_DANGLING(nodep); + nodep->replaceWith(newp); VL_DO_DANGLING(pushDeletep(nodep), nodep); } } virtual void visit(AstNodePreSel* nodep) { @@ -2525,22 +2525,22 @@ private: taskp->dpiExport(true); if (nodep->cname()!="") taskp->cname(nodep->cname()); } - nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep); + VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); } virtual void visit(AstPackageImport* nodep) { // No longer needed checkNoDot(nodep); - nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep); + VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); } virtual void visit(AstPackageExport* nodep) { // No longer needed checkNoDot(nodep); - nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep); + VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); } virtual void visit(AstPackageExportStarStar* nodep) { // No longer needed checkNoDot(nodep); - nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep); + VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); } virtual void visit(AstCellRef* nodep) { UINFO(5," AstCellRef: "<addNext(newp); newp = initsp; nodep->replaceWith(newp); - nodep->deleteTree(); VL_DANGLING(nodep); + VL_DO_DANGLING(nodep->deleteTree(), nodep); } virtual void visit(AstWhile* nodep) { // Don't need to track AstRepeat/AstFor as they have already been converted @@ -193,7 +193,7 @@ private: AstJumpLabel* labelp = findAddLabel(m_ftaskp, false); nodep->addPrev(new AstJumpGo(nodep->fileline(), labelp)); } - nodep->unlinkFrBack(); pushDeletep(nodep); VL_DANGLING(nodep); + nodep->unlinkFrBack(); VL_DO_DANGLING(pushDeletep(nodep), nodep); } virtual void visit(AstBreak* nodep) { iterateChildren(nodep); @@ -203,7 +203,7 @@ private: AstJumpLabel* labelp = findAddLabel(m_loopp, false); nodep->addNextHere(new AstJumpGo(nodep->fileline(), labelp)); } - nodep->unlinkFrBack(); pushDeletep(nodep); VL_DANGLING(nodep); + nodep->unlinkFrBack(); VL_DO_DANGLING(pushDeletep(nodep), nodep); } virtual void visit(AstContinue* nodep) { iterateChildren(nodep); @@ -214,7 +214,7 @@ private: AstJumpLabel* labelp = findAddLabel(m_loopp, true); nodep->addNextHere(new AstJumpGo(nodep->fileline(), labelp)); } - nodep->unlinkFrBack(); pushDeletep(nodep); VL_DANGLING(nodep); + nodep->unlinkFrBack(); VL_DO_DANGLING(pushDeletep(nodep), nodep); } virtual void visit(AstDisable* nodep) { UINFO(8," DISABLE "<addNextHere(new AstJumpGo(nodep->fileline(), labelp)); } - nodep->unlinkFrBack(); pushDeletep(nodep); VL_DANGLING(nodep); + nodep->unlinkFrBack(); VL_DO_DANGLING(pushDeletep(nodep), nodep); //if (debug()>=9) { UINFO(0,"\n"); beginp->dumpTree(cout, " labelo: "); } } virtual void visit(AstVarRef* nodep) { diff --git a/src/V3LinkParse.cpp b/src/V3LinkParse.cpp index 66bdf0fb4..ce049fa8f 100644 --- a/src/V3LinkParse.cpp +++ b/src/V3LinkParse.cpp @@ -169,7 +169,7 @@ private: else addp = newp; } nodep->replaceWith(addp); - nodep->deleteTree(); + VL_DO_DANGLING(nodep->deleteTree(), nodep); } } @@ -187,7 +187,7 @@ private: AstNode* newp = new AstParamTypeDType(nodep->fileline(), nodep->varType(), nodep->name(), VFlagChildDType(), dtypep); - nodep->replaceWith(newp); nodep->deleteTree(); VL_DANGLING(nodep); + nodep->replaceWith(newp); VL_DO_DANGLING(nodep->deleteTree(), nodep); } return; } @@ -262,63 +262,63 @@ private: AstTypedef* typep = VN_CAST(nodep->backp(), Typedef); UASSERT_OBJ(typep, nodep, "Attribute not attached to typedef"); typep->attrPublic(true); - nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep); + VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); } else if (nodep->attrType() == AstAttrType::VAR_CLOCK) { UASSERT_OBJ(m_varp, nodep, "Attribute not attached to variable"); nodep->v3warn(DEPRECATED, "sc_clock is deprecated and will be removed"); m_varp->attrScClocked(true); - nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep); + VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); } else if (nodep->attrType() == AstAttrType::VAR_CLOCK_ENABLE) { UASSERT_OBJ(m_varp, nodep, "Attribute not attached to variable"); m_varp->attrClockEn(true); - nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep); + VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); } else if (nodep->attrType() == AstAttrType::VAR_PUBLIC) { UASSERT_OBJ(m_varp, nodep, "Attribute not attached to variable"); m_varp->sigUserRWPublic(true); m_varp->sigModPublic(true); - nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep); + VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); } else if (nodep->attrType() == AstAttrType::VAR_PUBLIC_FLAT) { UASSERT_OBJ(m_varp, nodep, "Attribute not attached to variable"); m_varp->sigUserRWPublic(true); - nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep); + VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); } else if (nodep->attrType() == AstAttrType::VAR_PUBLIC_FLAT_RD) { UASSERT_OBJ(m_varp, nodep, "Attribute not attached to variable"); m_varp->sigUserRdPublic(true); - nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep); + VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); } else if (nodep->attrType() == AstAttrType::VAR_PUBLIC_FLAT_RW) { UASSERT_OBJ(m_varp, nodep, "Attribute not attached to variable"); m_varp->sigUserRWPublic(true); - nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep); + VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); } else if (nodep->attrType() == AstAttrType::VAR_ISOLATE_ASSIGNMENTS) { UASSERT_OBJ(m_varp, nodep, "Attribute not attached to variable"); m_varp->attrIsolateAssign(true); - nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep); + VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); } else if (nodep->attrType() == AstAttrType::VAR_SFORMAT) { UASSERT_OBJ(m_varp, nodep, "Attribute not attached to variable"); m_varp->attrSFormat(true); - nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep); + VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); } else if (nodep->attrType() == AstAttrType::VAR_SC_BV) { UASSERT_OBJ(m_varp, nodep, "Attribute not attached to variable"); m_varp->attrScBv(true); - nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep); + VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); } else if (nodep->attrType() == AstAttrType::VAR_CLOCKER) { UASSERT_OBJ(m_varp, nodep, "Attribute not attached to variable"); m_varp->attrClocker(VVarAttrClocker::CLOCKER_YES); - nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep); + VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); } else if (nodep->attrType() == AstAttrType::VAR_NO_CLOCKER) { UASSERT_OBJ(m_varp, nodep, "Attribute not attached to variable"); m_varp->attrClocker(VVarAttrClocker::CLOCKER_NO); - nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep); + VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); } } @@ -363,7 +363,7 @@ private: if (VN_IS(backp, Typedef)) { // A typedef doesn't need us to make yet another level of typedefing // For typedefs just remove the AstRefDType level of abstraction nodep->replaceWith(dtypep); - nodep->deleteTree(); VL_DANGLING(nodep); + VL_DO_DANGLING(nodep->deleteTree(), nodep); return; } else { defp = new AstTypedef(nodep->fileline(), nodep->name(), NULL, @@ -373,14 +373,14 @@ private: } } nodep->replaceWith(new AstRefDType(nodep->fileline(), defp->name())); - nodep->deleteTree(); VL_DANGLING(nodep); + VL_DO_DANGLING(nodep->deleteTree(), nodep); } virtual void visit(AstTypedefFwd* nodep) { // We only needed the forward declaration in order to parse correctly. // We won't even check it was ever really defined, as it might have been in a header // file referring to a module we never needed - nodep->unlinkFrBack()->deleteTree(); + VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); } virtual void visit(AstForeach* nodep) { @@ -439,8 +439,8 @@ private: dimension--; } //newp->dumpTree(cout, "-foreach-new:"); - firstVarsp->deleteTree(); VL_DANGLING(firstVarsp); - nodep->replaceWith(newp); nodep->deleteTree(); VL_DANGLING(nodep); + VL_DO_DANGLING(firstVarsp->deleteTree(), firstVarsp); + nodep->replaceWith(newp); VL_DO_DANGLING(nodep->deleteTree(), nodep); } virtual void visit(AstNodeModule* nodep) { diff --git a/src/V3LinkResolve.cpp b/src/V3LinkResolve.cpp index 512400143..122acc27a 100644 --- a/src/V3LinkResolve.cpp +++ b/src/V3LinkResolve.cpp @@ -79,7 +79,7 @@ private: // Initial assignments under function/tasks can just be simple // assignments without the initial if (m_ftaskp) { - nodep->replaceWith(nodep->bodysp()->unlinkFrBackWithNext()); VL_DANGLING(nodep); + VL_DO_DANGLING(nodep->replaceWith(nodep->bodysp()->unlinkFrBackWithNext()), nodep); } } virtual void visit(AstNodeCoverOrAssert* nodep) { @@ -167,18 +167,18 @@ private: did = 0; if (AstNodeSel* selp = VN_CAST(nodep->sensp(), NodeSel)) { AstNode* fromp = selp->fromp()->unlinkFrBack(); - selp->replaceWith(fromp); selp->deleteTree(); VL_DANGLING(selp); + selp->replaceWith(fromp); VL_DO_DANGLING(selp->deleteTree(), selp); did = 1; } // NodeSel doesn't include AstSel.... if (AstSel* selp = VN_CAST(nodep->sensp(), Sel)) { AstNode* fromp = selp->fromp()->unlinkFrBack(); - selp->replaceWith(fromp); selp->deleteTree(); VL_DANGLING(selp); + selp->replaceWith(fromp); VL_DO_DANGLING(selp->deleteTree(), selp); did = 1; } if (AstNodePreSel* selp = VN_CAST(nodep->sensp(), NodePreSel)) { AstNode* fromp = selp->lhsp()->unlinkFrBack(); - selp->replaceWith(fromp); selp->deleteTree(); VL_DANGLING(selp); + selp->replaceWith(fromp); VL_DO_DANGLING(selp->deleteTree(), selp); did = 1; } } @@ -242,17 +242,17 @@ private: if (nodep->pragType() == AstPragmaType::PUBLIC_MODULE) { UASSERT_OBJ(m_modp, nodep, "PUBLIC_MODULE not under a module"); m_modp->modPublic(true); - nodep->unlinkFrBack(); pushDeletep(nodep); VL_DANGLING(nodep); + nodep->unlinkFrBack(); VL_DO_DANGLING(pushDeletep(nodep), nodep); } else if (nodep->pragType() == AstPragmaType::PUBLIC_TASK) { UASSERT_OBJ(m_ftaskp, nodep, "PUBLIC_TASK not under a task"); m_ftaskp->taskPublic(true); m_modp->modPublic(true); // Need to get to the task... - nodep->unlinkFrBack(); pushDeletep(nodep); VL_DANGLING(nodep); + nodep->unlinkFrBack(); VL_DO_DANGLING(pushDeletep(nodep), nodep); } else if (nodep->pragType() == AstPragmaType::COVERAGE_BLOCK_OFF) { if (!v3Global.opt.coverageLine()) { // No need for block statements; may optimize better without - nodep->unlinkFrBack(); pushDeletep(nodep); VL_DANGLING(nodep); + nodep->unlinkFrBack(); VL_DO_DANGLING(pushDeletep(nodep), nodep); } } else { @@ -343,7 +343,7 @@ private: } newFormat.append(str); AstNode *nextp = argp->nextp(); - argp->unlinkFrBack(); pushDeletep(argp); VL_DANGLING(argp); + argp->unlinkFrBack(); VL_DO_DANGLING(pushDeletep(argp), argp); argp = nextp; } else { newFormat.append("%?"); // V3Width to figure it out @@ -392,7 +392,7 @@ private: && VN_CAST(nodep->exprsp(), Const)->num().isFromString()) { AstConst* fmtp = VN_CAST(nodep->exprsp()->unlinkFrBack(), Const); nodep->text(fmtp->num().toString()); - pushDeletep(fmtp); VL_DANGLING(fmtp); + VL_DO_DANGLING(pushDeletep(fmtp), fmtp); } nodep->hasFormat(true); } @@ -432,7 +432,7 @@ private: } } } - nodep->unlinkFrBack(); pushDeletep(nodep); VL_DANGLING(nodep); + nodep->unlinkFrBack(); VL_DO_DANGLING(pushDeletep(nodep), nodep); } } diff --git a/src/V3Order.cpp b/src/V3Order.cpp index d962f729b..90356ddf1 100644 --- a/src/V3Order.cpp +++ b/src/V3Order.cpp @@ -1576,7 +1576,7 @@ void OrderVisitor::processDomainsIterate(OrderEitherVertex* vertexp) { domainp->dumpTree(cout); cout<deleteTree(); VL_DANGLING(newtreep); + VL_DO_DANGLING(newtreep->deleteTree(), newtreep); } } } // next input edgep @@ -1747,7 +1747,7 @@ void OrderVisitor::processMoveDoneOne(OrderMoveVertex* vertexp) { UINFO(9," Clear to "<<(toVertexp->inEmpty()?"[EMP] ":" ") <unlinkDelete(); VL_DANGLING(edgep); + VL_DO_DANGLING(edgep->unlinkDelete(), edgep); if (toVertexp->inEmpty()) { // If destination node now has all inputs resolved; recurse to move that vertex // This is thus depth first (before width) which keeps the @@ -1811,7 +1811,7 @@ AstActive* OrderVisitor::processMoveOneLogic(const OrderLogicVertex* lvertexp, nodep->unlinkFrBack(); if (domainp == m_deleteDomainp) { UINFO(4," Ordering deleting pre-settled "<addStmtsp(nodep); if (v3Global.opt.outputSplitCFuncs()) { diff --git a/src/V3Param.cpp b/src/V3Param.cpp index 517333012..99d74c4aa 100644 --- a/src/V3Param.cpp +++ b/src/V3Param.cpp @@ -256,7 +256,7 @@ private: AstCell* cellp = *it; if (string* genHierNamep = (string *) cellp->user5p()) { cellp->user5p(NULL); - delete genHierNamep; VL_DANGLING(genHierNamep); + VL_DO_DANGLING(delete genHierNamep, genHierNamep); } } m_cellps.clear(); @@ -335,7 +335,7 @@ private: } else if (AstPin* pinp = VN_CAST(candp, Pin)) { UINFO(9,"Found interface parameter: "<exprp(), pinp, "Interface parameter pin missing expression"); - nodep->replaceWith(pinp->exprp()->cloneTree(false)); VL_DANGLING(nodep); + VL_DO_DANGLING(nodep->replaceWith(pinp->exprp()->cloneTree(false)), nodep); return true; } } @@ -401,7 +401,7 @@ private: taskrefp->dotted(m_unlinkedTxt); } nodep->replaceWith(nodep->op1p()->unlinkFrBack()); - pushDeletep(nodep); VL_DANGLING(nodep); + VL_DO_DANGLING(pushDeletep(nodep), nodep); } virtual void visit(AstCellArrayRef* nodep) { V3Const::constifyParamsEdit(nodep->selp()); @@ -436,7 +436,7 @@ private: } else { nodep->unlinkFrBack(); } - nodep->deleteTree(); VL_DANGLING(nodep); + VL_DO_DANGLING(nodep->deleteTree(), nodep); } virtual void visit(AstGenIf* nodep) { UINFO(9," GENIF "<unlinkFrBack(); } - nodep->deleteTree(); VL_DANGLING(nodep); + VL_DO_DANGLING(nodep->deleteTree(), nodep); // Normal edit rules will now recurse the replacement } else { nodep->condp()->v3error("Generate If condition must evaluate to constant"); @@ -486,7 +486,7 @@ private: // Note V3Unroll will replace some AstVarRef's to the loop variable with constants // Don't remove any deleted nodes in m_unroller until whole process finishes, // (are held in m_unroller), as some AstXRefs may still point to old nodes. - m_unroller.unrollGen(forp, beginName); VL_DANGLING(forp); + VL_DO_DANGLING(m_unroller.unrollGen(forp, beginName), forp); // Blocks were constructed under the special begin, move them up // Note forp is null, so grab statements again if (AstNode* stmtsp = nodep->genforp()) { @@ -519,7 +519,7 @@ private: for (AstNode* ep = itemp->condsp(); ep; ) { AstNode* nextp = ep->nextp(); // May edit list iterateAndNextNull(ep); - V3Const::constifyParamsEdit(ep); VL_DANGLING(ep); // ep may change + VL_DO_DANGLING(V3Const::constifyParamsEdit(ep), ep); // ep may change ep = nextp; } } @@ -553,7 +553,7 @@ private: nodep->replaceWith(keepp); } else nodep->unlinkFrBack(); - nodep->deleteTree(); VL_DANGLING(nodep); + VL_DO_DANGLING(nodep->deleteTree(), nodep); } // Default: Just iterate diff --git a/src/V3ParseGrammar.cpp b/src/V3ParseGrammar.cpp index 15a0db6d0..b02b727cb 100644 --- a/src/V3ParseGrammar.cpp +++ b/src/V3ParseGrammar.cpp @@ -91,7 +91,7 @@ AstRange* V3ParseGrammar::scrubRange(AstNodeRange* nrangep) { nextp = VN_CAST(nodep->nextp(), NodeRange); if (!VN_IS(nodep, Range)) { nodep->v3error("Unsupported or syntax error: Unsized range in cell or other declaration"); - nodep->unlinkFrBack(); nodep->deleteTree(); VL_DANGLING(nodep); + nodep->unlinkFrBack(); VL_DO_DANGLING(nodep->deleteTree(), nodep); } } if (nrangep && nrangep->nextp()) { diff --git a/src/V3ParseImp.cpp b/src/V3ParseImp.cpp index 22913c3e8..aa14ecf92 100644 --- a/src/V3ParseImp.cpp +++ b/src/V3ParseImp.cpp @@ -181,7 +181,7 @@ double V3ParseImp::parseDouble(const char* textp, size_t length, bool* successp) if (successp) *successp = false; else yyerrorf("Syntax error parsing real: %s", strgp); } - delete[] strgp; + VL_DO_DANGLING(delete[] strgp, strgp); return d; } @@ -265,7 +265,7 @@ void V3ParseImp::parseFile(FileLine* fileline, const string& modfilename, bool i preprocDumps(*osp); if (ofp) { ofp->close(); - delete ofp; VL_DANGLING(ofp); + VL_DO_DANGLING(delete ofp, ofp); } } } diff --git a/src/V3Partition.cpp b/src/V3Partition.cpp index 0d728968a..33a7f66f1 100644 --- a/src/V3Partition.cpp +++ b/src/V3Partition.cpp @@ -1041,7 +1041,7 @@ static void partCheckCriticalPaths(V3Graph* mtasksp) { // Advance to nextp(way) and delete edge static V3GraphEdge* partBlastEdgep(GraphWay way, V3GraphEdge* edgep) { V3GraphEdge* nextp = edgep->nextp(way); - edgep->unlinkDelete(); VL_DANGLING(edgep); + VL_DO_DANGLING(edgep->unlinkDelete(), edgep); return nextp; } @@ -1965,7 +1965,7 @@ private: // Move edges from donorp to recipientp partMergeEdgesFrom(m_mtasksp, mergedp, donorp, NULL); // Remove donorp from the graph - donorp->unlinkDelete(m_mtasksp); VL_DANGLING(donorp); + VL_DO_DANGLING(donorp->unlinkDelete(m_mtasksp), donorp); m_mergesDone++; } @@ -2697,10 +2697,10 @@ void V3Partition::finalizeCosts(V3Graph* execMTaskGraphp) { outp->top(), 1); } } - mtp->unlinkDelete(execMTaskGraphp); VL_DANGLING(mtp); + VL_DO_DANGLING(mtp->unlinkDelete(execMTaskGraphp), mtp); // Also remove and delete the AstMTaskBody, otherwise it would // keep a dangling pointer to the ExecMTask. - bodyp->unlinkFrBack()->deleteTree(); VL_DANGLING(bodyp); + VL_DO_DANGLING(bodyp->unlinkFrBack()->deleteTree(), bodyp); } } diff --git a/src/V3PreProc.cpp b/src/V3PreProc.cpp index 8df36ba8c..fee13a6e8 100644 --- a/src/V3PreProc.cpp +++ b/src/V3PreProc.cpp @@ -1175,7 +1175,7 @@ int V3PreProcImp::getStateToken() { out = defineSubst(refp); //NOP: out = m_preprocp->defSubstitute(out); } - m_defRefs.pop(); VL_DANGLING(refp); + VL_DO_DANGLING(m_defRefs.pop(), refp); if (m_defRefs.empty()) { statePop(); if (state() == ps_JOIN) { // Handle {left}```FOO(ARG) where `FOO(ARG) might be empty diff --git a/src/V3Reloop.cpp b/src/V3Reloop.cpp index 8a8952a26..9d0f9b61b 100644 --- a/src/V3Reloop.cpp +++ b/src/V3Reloop.cpp @@ -120,11 +120,11 @@ private: // Replace constant index with new loop index AstNode* lbitp = m_mgSelLp->bitp(); lbitp->replaceWith(new AstVarRef(fl, itp, false)); - lbitp->deleteTree(); VL_DANGLING(lbitp); + VL_DO_DANGLING(lbitp->deleteTree(), lbitp); if (m_mgSelRp) { // else constant and no replace AstNode* rbitp = m_mgSelRp->bitp(); rbitp->replaceWith(new AstVarRef(fl, itp, false)); - rbitp->deleteTree(); VL_DANGLING(lbitp); + VL_DO_DANGLING(rbitp->deleteTree(), lbitp); } if (debug()>=9) initp->dumpTree(cout, "-new: "); if (debug()>=9) whilep->dumpTree(cout, "-new: "); @@ -133,7 +133,7 @@ private: for (AssVec::iterator it=m_mgAssignps.begin(); it!=m_mgAssignps.end(); ++it) { AstNodeAssign* assp = *it; if (assp != bodyp) { - assp->unlinkFrBack()->deleteTree(); VL_DANGLING(assp); + VL_DO_DANGLING(assp->unlinkFrBack()->deleteTree(), assp); } } } diff --git a/src/V3Scope.cpp b/src/V3Scope.cpp index 9c157c9a0..ba05669d8 100644 --- a/src/V3Scope.cpp +++ b/src/V3Scope.cpp @@ -337,7 +337,7 @@ private: // A block that was just moved under a scope, Kill it. // Certain nodes can be referenced later in this pass, notably // an FTaskRef needs to access the FTask to find the cloned task - pushDeletep(nodep->unlinkFrBack()); VL_DANGLING(nodep); + VL_DO_DANGLING(pushDeletep(nodep->unlinkFrBack()), nodep); } } diff --git a/src/V3Slice.cpp b/src/V3Slice.cpp index 553536850..594047fe4 100644 --- a/src/V3Slice.cpp +++ b/src/V3Slice.cpp @@ -146,7 +146,7 @@ class SliceVisitor : public AstNVisitor { newlistp = AstNode::addNextNull(newlistp, newp); } if (debug()>=9) { cout<dumpTree(cout, " Deslice-Dn: "); } - nodep->replaceWith(newlistp); nodep->deleteTree(); VL_DANGLING(nodep); + nodep->replaceWith(newlistp); VL_DO_DANGLING(nodep->deleteTree(), nodep); // Normal edit iterator will now iterate on all of the expansion assignments // This will potentially call this function again to resolve next level of slicing return; @@ -209,7 +209,7 @@ class SliceVisitor : public AstNVisitor { } UASSERT_OBJ(logp, nodep, "Unpacked array with empty indices range"); nodep->replaceWith(logp); - pushDeletep(nodep); VL_DANGLING(nodep); + VL_DO_DANGLING(pushDeletep(nodep), nodep); nodep = logp; } } diff --git a/src/V3Split.cpp b/src/V3Split.cpp index f14b58111..388b7307f 100644 --- a/src/V3Split.cpp +++ b/src/V3Split.cpp @@ -825,7 +825,7 @@ public: it != m_removeSet.end(); ++it) { AstNode* np = *it; np->unlinkFrBack(); // Without next - np->deleteTree(); VL_DANGLING(np); + VL_DO_DANGLING(np->deleteTree(), np); } } virtual ~RemovePlaceholdersVisitor() {} @@ -868,7 +868,7 @@ public: RemovePlaceholdersVisitor removePlaceholders(*addme); } origp->unlinkFrBack(); // Without next - origp->deleteTree(); VL_DANGLING(origp); + VL_DO_DANGLING(origp->deleteTree(), origp); } } diff --git a/src/V3StatsReport.cpp b/src/V3StatsReport.cpp index a470f1e64..a40fd5727 100644 --- a/src/V3StatsReport.cpp +++ b/src/V3StatsReport.cpp @@ -248,5 +248,6 @@ void V3Stats::statsReport() { StatsReport reporter (ofp); // Cleanup - ofp->close(); delete ofp; VL_DANGLING(ofp); + ofp->close(); + VL_DO_DANGLING(delete ofp, ofp); } diff --git a/src/V3Subst.cpp b/src/V3Subst.cpp index 0cd561c80..bd721b890 100644 --- a/src/V3Subst.cpp +++ b/src/V3Subst.cpp @@ -159,7 +159,7 @@ public: } void deleteAssign(AstNodeAssign* nodep) { UINFO(5, "Delete "<unlinkFrBack()->deleteTree(); VL_DANGLING(nodep); + VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); } void deleteUnusedAssign() { // If there are unused assignments in this var, kill them @@ -308,7 +308,7 @@ private: } if (debug()>5) newp->dumpTree(cout, " w_new: "); nodep->replaceWith(newp); - pushDeletep(nodep); VL_DANGLING(nodep); + VL_DO_DANGLING(pushDeletep(nodep), nodep); ++m_statSubsts; } virtual void visit(AstWordSel* nodep) { @@ -327,7 +327,7 @@ private: // Check that the RHS hasn't changed value since we recorded it. SubstUseVisitor visitor (substp, entryp->getWordStep(word)); if (visitor.ok()) { - replaceSubstEtc(nodep, substp); VL_DANGLING(nodep); + VL_DO_DANGLING(replaceSubstEtc(nodep, substp), nodep); } else { entryp->consumeWord(word); } @@ -355,7 +355,7 @@ private: SubstUseVisitor visitor (substp, entryp->getWholeStep()); if (visitor.ok()) { UINFO(8," USEwhole "<consumeWhole(); diff --git a/src/V3Table.cpp b/src/V3Table.cpp index c8ac2c7ea..67817b87e 100644 --- a/src/V3Table.cpp +++ b/src/V3Table.cpp @@ -371,7 +371,7 @@ private: const AstNode* init2p = VN_CAST(var2p->valuep(), InitArray); if (init1p->sameGateTree(init2p)) { UINFO(8," Duplicate table var "<pragType() == AstPragmaType::NO_INLINE_TASK) { // Just mark for the next steps, and we're done with it. m_curVxp->noInline(true); - nodep->unlinkFrBack()->deleteTree(); + VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); } else { iterateChildren(nodep); @@ -383,7 +383,7 @@ private: UINFO(9, " Port "<unlinkFrBack(); // Relinked to assignment below - argp->unlinkFrBack()->deleteTree(); // Args no longer needed + VL_DO_DANGLING(argp->unlinkFrBack()->deleteTree(), argp); // Args no longer needed // if (portp->isWritable() && VN_IS(pinp, Const)) { pinp->v3error("Function/task " @@ -470,7 +470,7 @@ private: { AstBegin* tempp = new AstBegin(beginp->fileline(), "[EditWrapper]", beginp); TaskRelinkVisitor visit (tempp); - tempp->stmtsp()->unlinkFrBackWithNext(); tempp->deleteTree(); VL_DANGLING(tempp); + tempp->stmtsp()->unlinkFrBackWithNext(); VL_DO_DANGLING(tempp->deleteTree(), tempp); } // if (debug()>=9) { beginp->dumpTreeAndNext(cout, "-iotask: "); } @@ -953,7 +953,7 @@ private: } if (nodep->dpiOpenParent()) { // No need to make more than just the c prototype, children will - pushDeletep(nodep); VL_DANGLING(nodep); + VL_DO_DANGLING(pushDeletep(nodep), nodep); return NULL; } } @@ -1073,10 +1073,10 @@ private: { AstBegin* tempp = new AstBegin(cfuncp->fileline(), "[EditWrapper]", cfuncp); TaskRelinkVisitor visit (tempp); - tempp->stmtsp()->unlinkFrBackWithNext(); tempp->deleteTree(); VL_DANGLING(tempp); + tempp->stmtsp()->unlinkFrBackWithNext(); VL_DO_DANGLING(tempp->deleteTree(), tempp); } // Delete rest of cloned task and return new func - pushDeletep(nodep); VL_DANGLING(nodep); + VL_DO_DANGLING(pushDeletep(nodep), nodep); if (debug()>=9) { cfuncp->dumpTree(cout, "-userFunc: "); } return cfuncp; } @@ -1183,7 +1183,7 @@ private: nodep->replaceWith(beginp); } // Cleanup - nodep->deleteTree(); VL_DANGLING(nodep); + VL_DO_DANGLING(nodep->deleteTree(), nodep); UINFO(4," FTask REF Done.\n"); // Visit nodes that normal iteration won't find if (visitp) iterateAndNextNull(visitp); @@ -1230,7 +1230,7 @@ private: if (AstVar* portp = VN_CAST(nodep->fvarp(), Var)) { AstVarScope* vscp = m_statep->findVarScope(m_scopep, portp); UINFO(9," funcremovevsc "<unlinkFrBack()); VL_DANGLING(vscp); + VL_DO_DANGLING(pushDeletep(vscp->unlinkFrBack()), vscp); } } for (AstNode* nextp, *stmtp = nodep->stmtsp(); stmtp; stmtp = nextp) { @@ -1238,13 +1238,13 @@ private: if (AstVar* portp = VN_CAST(stmtp, Var)) { AstVarScope* vscp = m_statep->findVarScope(m_scopep, portp); UINFO(9," funcremovevsc "<unlinkFrBack()); VL_DANGLING(vscp); + VL_DO_DANGLING(pushDeletep(vscp->unlinkFrBack()), vscp); } } // Just push for deletion, as other references to func may // remain until visitor exits nodep->unlinkFrBack(); - pushDeletep(nodep); VL_DANGLING(nodep); + VL_DO_DANGLING(pushDeletep(nodep), nodep); } m_insMode = prevInsMode; m_insStmtp = prevInsStmtp; @@ -1347,7 +1347,7 @@ V3TaskConnects V3Task::taskConnects(AstNodeFTaskRef* nodep, AstNode* taskStmtsp) pinp->v3error("No such argument "<prettyNameQ() <<" in function call to "<taskp()->prettyTypeName()); // We'll just delete it; seems less error prone than making a false argument - pinp->unlinkFrBack()->deleteTree(); VL_DANGLING(pinp); + VL_DO_DANGLING(pinp->unlinkFrBack()->deleteTree(), pinp); } else { if (tconnects[it->second].second) { pinp->v3error("Duplicate argument "<prettyNameQ() @@ -1367,7 +1367,7 @@ V3TaskConnects V3Task::taskConnects(AstNodeFTaskRef* nodep, AstNode* taskStmtsp) pinp->v3error("Too many arguments in function call to " <taskp()->prettyTypeName()); // We'll just delete it; seems less error prone than making a false argument - pinp->unlinkFrBack()->deleteTree(); VL_DANGLING(pinp); + VL_DO_DANGLING(pinp->unlinkFrBack()->deleteTree(), pinp); } } else { tconnects[ppinnum].second = argp; diff --git a/src/V3Trace.cpp b/src/V3Trace.cpp index ee2b2aed6..f1954221f 100644 --- a/src/V3Trace.cpp +++ b/src/V3Trace.cpp @@ -587,7 +587,7 @@ private: m_fullSubStmts += EmitCBaseCounterVisitor(nodep).count(); } else { // Duplicates don't need a TraceInc - pushDeletep(nodep); VL_DANGLING(nodep); + VL_DO_DANGLING(pushDeletep(nodep), nodep); } return incAddp; } diff --git a/src/V3Tristate.cpp b/src/V3Tristate.cpp index 8b982a908..ad30f8fd6 100644 --- a/src/V3Tristate.cpp +++ b/src/V3Tristate.cpp @@ -429,9 +429,9 @@ class TristateVisitor : public TristateBaseVisitor { VarMap::iterator it = m_lhsmap.find(key); UINFO(9," mapInsertLhsVarRef "<push_back(nodep); - m_lhsmap.insert(make_pair(key, refs)); + RefVec* refsp = new RefVec(); + refsp->push_back(nodep); + m_lhsmap.insert(make_pair(key, refsp)); } else { it->second->push_back(nodep); } @@ -512,14 +512,14 @@ class TristateVisitor : public TristateBaseVisitor { for (VarMap::iterator nextit, it = m_lhsmap.begin(); it != m_lhsmap.end(); it = nextit) { nextit = it; ++nextit; AstVar* invarp = it->first; - RefVec* refs = it->second; + RefVec* refsp = it->second; // Figure out if this var needs tristate expanded. if (!m_tgraph.isTristate(invarp)) { // This var has no tristate logic, so we leave it alone. UINFO(8, " NO TRISTATE ON:" << invarp << endl); m_lhsmap.erase(invarp); - delete refs; + VL_DO_DANGLING(delete refsp, refsp); continue; } @@ -559,7 +559,7 @@ class TristateVisitor : public TristateBaseVisitor { AstNode* undrivenp = NULL; // loop through the lhs drivers to build the driver resolution logic - for (RefVec::iterator ii=refs->begin(); ii != refs->end(); ++ii) { + for (RefVec::iterator ii = refsp->begin(); ii != refsp->end(); ++ii) { AstVarRef* refp = (*ii); int w = lhsp->width(); @@ -623,7 +623,7 @@ class TristateVisitor : public TristateBaseVisitor { new AstConst(invarp->fileline(), pull)); orp = new AstOr(invarp->fileline(), orp, undrivenp); } else { - undrivenp->deleteTree(); VL_DANGLING(undrivenp); + VL_DO_DANGLING(undrivenp->deleteTree(), undrivenp); } if (envarp) { nodep->addStmtp(new AstAssignW(enp->fileline(), @@ -641,7 +641,7 @@ class TristateVisitor : public TristateBaseVisitor { nodep->addStmtp(assp); // Delete the map and vector list now that we have expanded it. m_lhsmap.erase(invarp); - delete refs; + VL_DO_DANGLING(delete refsp, refsp); } } @@ -662,7 +662,7 @@ class TristateVisitor : public TristateBaseVisitor { AstNode* newp = new AstVarRef(nodep->fileline(), varp, true); UINFO(9," const->"<replaceWith(newp); - pushDeletep(nodep); VL_DANGLING(nodep); + VL_DO_DANGLING(pushDeletep(nodep), nodep); } else if (m_tgraph.isTristate(nodep)) { m_tgraph.didProcess(nodep); @@ -676,7 +676,7 @@ class TristateVisitor : public TristateBaseVisitor { AstConst* newconstp = new AstConst(fl, num1); AstConst* enp = new AstConst(fl, numz0); nodep->replaceWith(newconstp); - pushDeletep(nodep); VL_DANGLING(nodep); + VL_DO_DANGLING(pushDeletep(nodep), nodep); newconstp->user1p(enp); // Propagate up constant with non-Z bits as 1 } } @@ -841,7 +841,7 @@ class TristateVisitor : public TristateBaseVisitor { nodep->replaceWith(expr2p); UINFO(9," bufif datap="<=9) newp->dumpTree(cout, "-caseeq-new: "); nodep->replaceWith(newp); - pushDeletep(nodep); VL_DANGLING(nodep); + VL_DO_DANGLING(pushDeletep(nodep), nodep); } else { checkUnhandled(nodep); } @@ -1040,7 +1040,7 @@ class TristateVisitor : public TristateBaseVisitor { } if (!m_graphing) { nodep->unlinkFrBack(); - pushDeletep(nodep); VL_DANGLING(nodep); // Node must persist as user3p points to it + VL_DO_DANGLING(pushDeletep(nodep), nodep); // Node must persist as user3p points to it } } diff --git a/src/V3Unknown.cpp b/src/V3Unknown.cpp index 3960438a7..6e6fccf2a 100644 --- a/src/V3Unknown.cpp +++ b/src/V3Unknown.cpp @@ -152,12 +152,12 @@ private: } virtual void visit(AstAssignDly* nodep) { m_assigndlyp = nodep; - iterateChildren(nodep); VL_DANGLING(nodep); // May delete nodep. + VL_DO_DANGLING(iterateChildren(nodep), nodep); // May delete nodep. m_assigndlyp = NULL; } virtual void visit(AstAssignW* nodep) { m_assignwp = nodep; - iterateChildren(nodep); VL_DANGLING(nodep); // May delete nodep. + VL_DO_DANGLING(iterateChildren(nodep), nodep); // May delete nodep. m_assignwp = NULL; } virtual void visit(AstCaseItem* nodep) { @@ -177,7 +177,7 @@ private: V3Const::constifyEdit(nodep->rhsp()); // rhsp may change if (VN_IS(nodep->lhsp(), Const) && VN_IS(nodep->rhsp(), Const)) { // Both sides are constant, node can be constant - V3Const::constifyEdit(nodep); VL_DANGLING(nodep); + VL_DO_DANGLING(V3Const::constifyEdit(nodep), nodep); return; } else { AstNode* lhsp = nodep->lhsp()->unlinkFrBack(); @@ -188,15 +188,15 @@ private: || (VN_IS(rhsp, Const) && VN_CAST(rhsp, Const)->num().isFourState()))) { newp = new AstConst(nodep->fileline(), AstConst::WidthedValue(), 1, (VN_IS(nodep, EqCase) ? 0 : 1)); - lhsp->deleteTree(); VL_DANGLING(lhsp); - rhsp->deleteTree(); VL_DANGLING(rhsp); + VL_DO_DANGLING(lhsp->deleteTree(), lhsp); + VL_DO_DANGLING(rhsp->deleteTree(), rhsp); } else { if (VN_IS(nodep, EqCase)) { newp = new AstEq(nodep->fileline(), lhsp, rhsp); } else { newp = new AstNeq(nodep->fileline(), lhsp, rhsp); } } nodep->replaceWith(newp); - nodep->deleteTree(); VL_DANGLING(nodep); + VL_DO_DANGLING(nodep->deleteTree(), nodep); // Iterate tree now that we may have gotten rid of Xs iterateChildren(newp); } @@ -207,7 +207,7 @@ private: V3Const::constifyEdit(nodep->rhsp()); // rhsp may change if (VN_IS(nodep->lhsp(), Const) && VN_IS(nodep->rhsp(), Const)) { // Both sides are constant, node can be constant - V3Const::constifyEdit(nodep); VL_DANGLING(nodep); + VL_DO_DANGLING(V3Const::constifyEdit(nodep), nodep); return; } else { AstNode* lhsp = nodep->lhsp()->unlinkFrBack(); @@ -229,10 +229,10 @@ private: if (VN_IS(nodep, EqWild)) { newp = new AstEq(nodep->fileline(), and1p, and2p); } else { newp = new AstNeq(nodep->fileline(), and1p, and2p); } - rhsp->deleteTree(); VL_DANGLING(rhsp); + VL_DO_DANGLING(rhsp->deleteTree(), rhsp); } nodep->replaceWith(newp); - nodep->deleteTree(); VL_DANGLING(nodep); + VL_DO_DANGLING(nodep->deleteTree(), nodep); // Iterate tree now that we may have gotten rid of the compare iterateChildren(newp); } @@ -256,7 +256,7 @@ private: UINFO(4," ISUNKNOWN->0 "<fileline(), AstConst::LogicFalse()); nodep->replaceWith(newp); - nodep->deleteTree(); VL_DANGLING(nodep); + VL_DO_DANGLING(nodep->deleteTree(), nodep); } virtual void visit(AstConst* nodep) { if (m_constXCvt @@ -280,7 +280,7 @@ private: } AstConst* newp = new AstConst(nodep->fileline(), numnew); nodep->replaceWith(newp); - nodep->deleteTree(); VL_DANGLING(nodep); + VL_DO_DANGLING(nodep->deleteTree(), nodep); UINFO(4," -> "<=9) newref1p->dumpTree(cout, " _new: "); if (debug()>=9) newvarp->dumpTree(cout, " _new: "); if (debug()>=9) newinitp->dumpTree(cout, " _new: "); - nodep->deleteTree(); VL_DANGLING(nodep); + VL_DO_DANGLING(nodep->deleteTree(), nodep); } } } @@ -347,7 +347,7 @@ private: condp = V3Const::constifyEdit(condp); if (condp->isOne()) { // We don't need to add a conditional; we know the existing expression is ok - condp->deleteTree(); + VL_DO_DANGLING(condp->deleteTree(), condp); } else if (!lvalue) { // SEL(...) -> COND(LTE(bit<=maxmsb), ARRAYSEL(...), {width{1'bx}}) @@ -408,7 +408,7 @@ private: condp = V3Const::constifyEdit(condp); if (condp->isOne()) { // We don't need to add a conditional; we know the existing expression is ok - condp->deleteTree(); + VL_DO_DANGLING(condp->deleteTree(), condp); } else if (!lvalue // Making a scalar would break if we're making an array diff --git a/src/V3Unroll.cpp b/src/V3Unroll.cpp index 516d9331e..98cc2d35f 100644 --- a/src/V3Unroll.cpp +++ b/src/V3Unroll.cpp @@ -209,14 +209,14 @@ private: if (!simvis.optimizable()) { UINFO(3, "Unable to simulate" << endl); if (debug()>=9) nodep->dumpTree(cout, "- _simtree: "); - clonep->deleteTree(); VL_DANGLING(clonep); + VL_DO_DANGLING(clonep->deleteTree(), clonep); return false; } // Fetch the result V3Number* res = simvis.fetchNumberNull(clonep); if (!res) { UINFO(3, "No number returned from simulation" << endl); - clonep->deleteTree(); VL_DANGLING(clonep); + VL_DO_DANGLING(clonep->deleteTree(), clonep); return false; } // Patch up datatype @@ -224,11 +224,11 @@ private: AstConst new_con (clonep->fileline(), *res); new_con.dtypeFrom(dtypep); outNum = new_con.num(); - clonep->deleteTree(); VL_DANGLING(clonep); + VL_DO_DANGLING(clonep->deleteTree(), clonep); return true; } outNum = *res; - clonep->deleteTree(); VL_DANGLING(clonep); + VL_DO_DANGLING(clonep->deleteTree(), clonep); return true; } @@ -322,7 +322,7 @@ private: iterateAndNextNull(tempp->stmtsp()); m_varModeReplace = false; oneloopp = tempp->stmtsp()->unlinkFrBackWithNext(); - tempp->deleteTree(); VL_DANGLING(tempp); + VL_DO_DANGLING(tempp->deleteTree(), tempp); } if (m_generate) { string index = AstNode::encodeNumber(m_varValuep->toSInt()); @@ -359,10 +359,10 @@ private: // Replace the FOR() if (newbodysp) nodep->replaceWith(newbodysp); else nodep->unlinkFrBack(); - if (bodysp) { pushDeletep(bodysp); VL_DANGLING(bodysp); } - if (precondsp) { pushDeletep(precondsp); VL_DANGLING(precondsp); } - if (initp) { pushDeletep(initp); VL_DANGLING(initp); } - if (incp && !incp->backp()) { pushDeletep(incp); VL_DANGLING(incp); } + if (bodysp) { VL_DO_DANGLING(pushDeletep(bodysp), bodysp); } + if (precondsp) { VL_DO_DANGLING(pushDeletep(precondsp), precondsp); } + if (initp) { VL_DO_DANGLING(pushDeletep(initp), initp); } + if (incp && !incp->backp()) { VL_DO_DANGLING(pushDeletep(incp), incp); } if (debug()>=9 && newbodysp) newbodysp->dumpTree(cout, "- _new: "); return true; } @@ -377,7 +377,7 @@ private: // Grab initial value AstNode* initp = NULL; // Should be statement before the while. if (nodep->backp()->nextp() == nodep) initp = nodep->backp(); - if (initp) { V3Const::constifyEdit(initp); VL_DANGLING(initp); } + if (initp) { VL_DO_DANGLING(V3Const::constifyEdit(initp), initp); } if (nodep->backp()->nextp() == nodep) initp = nodep->backp(); // Grab assignment AstNode* incp = NULL; // Should be last statement @@ -385,14 +385,14 @@ private: if (nodep->incsp()) incp = nodep->incsp(); else { for (incp = nodep->bodysp(); incp && incp->nextp(); incp = incp->nextp()) {} - if (incp) { V3Const::constifyEdit(incp); VL_DANGLING(incp); } + if (incp) { VL_DO_DANGLING(V3Const::constifyEdit(incp), incp); } for (incp = nodep->bodysp(); incp && incp->nextp(); incp = incp->nextp()) {} // Again, as may have changed } // And check it if (forUnrollCheck(nodep, initp, nodep->precondsp(), nodep->condp(), incp, nodep->bodysp())) { - pushDeletep(nodep); VL_DANGLING(nodep); // Did replacement + VL_DO_DANGLING(pushDeletep(nodep), nodep); // Did replacement } } } @@ -414,11 +414,11 @@ private: // we'd need to initialize the variable to the initial // condition, but they'll become while's which can be // deleted by V3Const. - pushDeletep(nodep->unlinkFrBack()); VL_DANGLING(nodep); + VL_DO_DANGLING(pushDeletep(nodep->unlinkFrBack()), nodep); } else if (forUnrollCheck(nodep, nodep->initsp(), NULL, nodep->condp(), nodep->incsp(), nodep->bodysp())) { - pushDeletep(nodep); VL_DANGLING(nodep); // Did replacement + VL_DO_DANGLING(pushDeletep(nodep), nodep); // Did replacement } else { nodep->v3error("For loop doesn't have genvar index, or is malformed"); } diff --git a/src/V3Width.cpp b/src/V3Width.cpp index 0ec6a8de4..e8debc3ba 100644 --- a/src/V3Width.cpp +++ b/src/V3Width.cpp @@ -462,14 +462,14 @@ private: if (AstReplicate* repp = VN_CAST(nodep->lhsp(), Replicate)) { if (repp->width()==0) { // Keep rhs nodep->replaceWith(nodep->rhsp()->unlinkFrBack()); - pushDeletep(nodep); VL_DANGLING(nodep); + VL_DO_DANGLING(pushDeletep(nodep), nodep); return; } } if (AstReplicate* repp = VN_CAST(nodep->rhsp(), Replicate)) { if (repp->width()==0) { // Keep lhs nodep->replaceWith(nodep->lhsp()->unlinkFrBack()); - pushDeletep(nodep); VL_DANGLING(nodep); + VL_DO_DANGLING(pushDeletep(nodep), nodep); return; } } @@ -478,7 +478,7 @@ private: AstNode* newp = new AstConcatN(nodep->fileline(), nodep->lhsp()->unlinkFrBack(), nodep->rhsp()->unlinkFrBack()); nodep->replaceWith(newp); - pushDeletep(nodep); VL_DANGLING(nodep); + VL_DO_DANGLING(pushDeletep(nodep), nodep); return; } } @@ -543,7 +543,7 @@ private: AstNode* newp = new AstReplicateN(nodep->fileline(), nodep->lhsp()->unlinkFrBack(), nodep->rhsp()->unlinkFrBack()); nodep->replaceWith(newp); - pushDeletep(nodep); VL_DANGLING(nodep); + VL_DO_DANGLING(pushDeletep(nodep), nodep); return; } else { nodep->dtypeSetLogicUnsized((nodep->lhsp()->width() * times), @@ -983,7 +983,7 @@ private: if (nodep->lhsp()->isDouble() || nodep->rhsp()->isDouble()) { spliceCvtD(nodep->lhsp()); spliceCvtD(nodep->rhsp()); - replaceWithDVersion(nodep); VL_DANGLING(nodep); + VL_DO_DANGLING(replaceWithDVersion(nodep), nodep); return; } @@ -1012,7 +1012,7 @@ private: newp->dtypeFrom(nodep); UINFO(9,"powOld "<replaceWith(newp); VL_DANGLING(nodep); + VL_DO_DANGLING(nodep->replaceWith(newp), nodep); } } } @@ -1067,7 +1067,7 @@ private: int val = (nodep->attrType()==AstAttrType::DIM_UNPK_DIMENSIONS ? dim.second : (dim.first+dim.second)); nodep->replaceWith(new AstConst(nodep->fileline(), AstConst::Signed32(), val)); - nodep->deleteTree(); VL_DANGLING(nodep); + VL_DO_DANGLING(nodep->deleteTree(), nodep); break; } case AstAttrType::DIM_BITS: @@ -1086,13 +1086,13 @@ private: newp->dtypeSetSigned32(); newp->didWidth(true); newp->protect(false); - nodep->replaceWith(newp); nodep->deleteTree(); VL_DANGLING(nodep); + nodep->replaceWith(newp); VL_DO_DANGLING(nodep->deleteTree(), nodep); break; } case AstAttrType::DIM_LEFT: case AstAttrType::DIM_LOW: { AstNode* newp = new AstConst(nodep->fileline(), AstConst::Signed32(), 0); - nodep->replaceWith(newp); nodep->deleteTree(); VL_DANGLING(nodep); + nodep->replaceWith(newp); VL_DO_DANGLING(nodep->deleteTree(), nodep); break; } case AstAttrType::DIM_RIGHT: @@ -1105,12 +1105,12 @@ private: AstNode* newp = new AstSub(nodep->fileline(), sizep, new AstConst(nodep->fileline(), AstConst::Signed32(), 1)); - nodep->replaceWith(newp); nodep->deleteTree(); VL_DANGLING(nodep); + nodep->replaceWith(newp); VL_DO_DANGLING(nodep->deleteTree(), nodep); break; } case AstAttrType::DIM_INCREMENT: { AstNode* newp = new AstConst(nodep->fileline(), AstConst::Signed32(), -1); - nodep->replaceWith(newp); nodep->deleteTree(); VL_DANGLING(nodep); + nodep->replaceWith(newp); VL_DO_DANGLING(nodep->deleteTree(), nodep); break; } case AstAttrType::DIM_BITS: { @@ -1127,12 +1127,12 @@ private: int dim = 1; AstConst* newp = dimensionValue(nodep->fileline(), nodep->fromp()->dtypep(), nodep->attrType(), dim); - nodep->replaceWith(newp); nodep->deleteTree(); VL_DANGLING(nodep); + nodep->replaceWith(newp); VL_DO_DANGLING(nodep->deleteTree(), nodep); } else if (VN_IS(nodep->dimp(), Const)) { int dim = VN_CAST(nodep->dimp(), Const)->toSInt(); AstConst* newp = dimensionValue(nodep->fileline(), nodep->fromp()->dtypep(), nodep->attrType(), dim); - nodep->replaceWith(newp); nodep->deleteTree(); VL_DANGLING(nodep); + nodep->replaceWith(newp); VL_DO_DANGLING(nodep->deleteTree(), nodep); } else { // Need a runtime lookup table. Yuk. UASSERT_OBJ(nodep->fromp() && nodep->fromp()->dtypep(), nodep, @@ -1143,7 +1143,7 @@ private: AstVarRef* varrefp = new AstVarRef(nodep->fileline(), varp, false); varrefp->packagep(v3Global.rootp()->dollarUnitPkgAddp()); AstNode* newp = new AstArraySel(nodep->fileline(), varrefp, dimp); - nodep->replaceWith(newp); nodep->deleteTree(); VL_DANGLING(nodep); + nodep->replaceWith(newp); VL_DO_DANGLING(nodep->deleteTree(), nodep); } } break; @@ -1294,7 +1294,7 @@ private: AstNode* newp = new AstCastSize(nodep->fileline(), nodep->lhsp()->unlinkFrBack(), constp); nodep->replaceWith(newp); - pushDeletep(nodep); VL_DANGLING(nodep); + VL_DO_DANGLING(pushDeletep(nodep), nodep); userIterate(newp, m_vup); } else { nodep->v3error("Unsupported: Cast to "<dtp()->prettyTypeName()); @@ -1338,7 +1338,7 @@ private: //newp = newp; // Can just remove cast } nodep->replaceWith(newp); - pushDeletep(nodep); VL_DANGLING(nodep); + VL_DO_DANGLING(pushDeletep(nodep), nodep); //if (debug()) newp->dumpTree(cout, " CastOut: "); } virtual void visit(AstCastSize* nodep) { @@ -1387,7 +1387,7 @@ private: // CastSize not needed once sizes determined AstNode* underp = nodep->lhsp()->unlinkFrBack(); nodep->replaceWith(underp); - pushDeletep(nodep); VL_DANGLING(nodep); + VL_DO_DANGLING(pushDeletep(nodep), nodep); } //if (debug()) nodep->dumpTree(cout, " CastSizeOut: "); } @@ -1606,7 +1606,7 @@ private: if (VN_IS(enump, EnumDType)) break; } UASSERT_OBJ(enump, nodep, "EnumItemRef can't deref back to an Enum"); - userIterate(enump, m_vup); VL_DANGLING(enump); // parent's connection to enump may be relinked + VL_DO_DANGLING(userIterate(enump, m_vup), enump); // Parent enump maybe relinked } nodep->dtypeFrom(nodep->itemp()); } @@ -1630,7 +1630,7 @@ private: userIterateAndNext(nodep->exprp(), WidthVP(CONTEXT, PRELIM).p()); for (AstNode* nextip, *itemp = nodep->itemsp(); itemp; itemp=nextip) { nextip = itemp->nextp(); // Prelim may cause the node to get replaced - userIterate(itemp, WidthVP(CONTEXT, PRELIM).p()); VL_DANGLING(itemp); + VL_DO_DANGLING(userIterate(itemp, WidthVP(CONTEXT, PRELIM).p()), itemp); } // Take width as maximum across all items int width = nodep->exprp()->width(); @@ -1674,7 +1674,7 @@ private: } if (!newp) newp = new AstConst(nodep->fileline(), AstConst::LogicFalse()); if (debug()>=9) newp->dumpTree(cout, "-inside-out: "); - nodep->replaceWith(newp); pushDeletep(nodep); VL_DANGLING(nodep); + nodep->replaceWith(newp); VL_DO_DANGLING(pushDeletep(nodep), nodep); } virtual void visit(AstInsideRange* nodep) { // Just do each side; AstInside will rip these nodes out later @@ -1751,7 +1751,7 @@ private: AstNode* newp = new AstMethodCall(nodep->fileline(), nodep->fromp()->unlinkFrBack(), nodep->name(), NULL); nodep->replaceWith(newp); - pushDeletep(nodep); VL_DANGLING(nodep); + VL_DO_DANGLING(pushDeletep(nodep), nodep); userIterate(newp, m_vup); return; } else { @@ -1761,7 +1761,7 @@ private: } // Error handling nodep->replaceWith(new AstConst(nodep->fileline(), AstConst::LogicFalse())); - pushDeletep(nodep); VL_DANGLING(nodep); + VL_DO_DANGLING(pushDeletep(nodep), nodep); } bool memberSelStruct(AstMemberSel* nodep, AstNodeUOrStructDType* adtypep) { // Returns true if ok @@ -1778,7 +1778,7 @@ private: newp->didWidth(true); // Don't replace dtype with basic type UINFO(9, " MEMBERSEL -> " << newp << endl); UINFO(9, " dt-> " << newp->dtypep() << endl); - nodep->replaceWith(newp); pushDeletep(nodep); VL_DANGLING(nodep); + nodep->replaceWith(newp); VL_DO_DANGLING(pushDeletep(nodep), nodep); // Should be able to treat it as a normal-ish nodesel - maybe. // The lhsp() will be strange until this stage; create the number here? } @@ -1850,7 +1850,7 @@ private: for (; narg > maxArg; --narg) { AstNode* argp = nodep->pinsp(); while (argp->nextp()) argp = argp->nextp(); - argp->unlinkFrBack(); argp->deleteTree(); VL_DANGLING(argp); + argp->unlinkFrBack(); VL_DO_DANGLING(argp->deleteTree(), argp); } } } @@ -1884,7 +1884,7 @@ private: UASSERT_OBJ(newp, nodep, "Enum method (perhaps enum item) not const"); newp->fileline(nodep->fileline()); // Use method's filename/line number to be clearer; // may have warning disables - nodep->replaceWith(newp); pushDeletep(nodep); VL_DANGLING(nodep); + nodep->replaceWith(newp); VL_DO_DANGLING(pushDeletep(nodep), nodep); } else if (nodep->name() == "name" || nodep->name() == "next" || nodep->name() == "prev") { @@ -1930,7 +1930,7 @@ private: // Select in case widths are // off due to msblen!=width new AstSel(nodep->fileline(), nodep->fromp()->unlinkFrBack(), 0, selwidth)); - nodep->replaceWith(newp); nodep->deleteTree(); VL_DANGLING(nodep); + nodep->replaceWith(newp); VL_DO_DANGLING(nodep->deleteTree(), nodep); } else { nodep->v3error("Unknown built-in enum method " << nodep->prettyNameQ()); } @@ -1993,7 +1993,7 @@ private: } if (newp) { newp->didWidth(true); - nodep->replaceWith(newp); nodep->deleteTree(); VL_DANGLING(nodep); + nodep->replaceWith(newp); VL_DO_DANGLING(nodep->deleteTree(), nodep); } } AstNode* methodCallAssocIndexExpr(AstMethodCall* nodep, AstAssocArrayDType* adtypep) { @@ -2111,7 +2111,7 @@ private: } if (newp) { newp->didWidth(true); - nodep->replaceWith(newp); nodep->deleteTree(); VL_DANGLING(nodep); + nodep->replaceWith(newp); VL_DO_DANGLING(nodep->deleteTree(), nodep); } } AstNode* methodCallQueueIndexExpr(AstMethodCall* nodep) { @@ -2147,7 +2147,7 @@ private: } } nodep->replaceWith(newp); - nodep->deleteTree(); VL_DANGLING(nodep); + VL_DO_DANGLING(nodep->deleteTree(), nodep); } else { nodep->v3error("Unknown built-in array method " << nodep->prettyNameQ()); } @@ -2159,30 +2159,30 @@ private: methodOkArguments(nodep, 0, 0); AstNode* newp = new AstLenN(nodep->fileline(), nodep->fromp()->unlinkFrBack()); nodep->replaceWith(newp); - pushDeletep(nodep); VL_DANGLING(nodep); + VL_DO_DANGLING(pushDeletep(nodep), nodep); } else if (nodep->name() == "itoa") { methodOkArguments(nodep, 1, 1); - replaceWithSFormat(nodep, "%0d"); VL_DANGLING(nodep); + VL_DO_DANGLING(replaceWithSFormat(nodep, "%0d"), nodep); } else if (nodep->name() == "hextoa") { methodOkArguments(nodep, 1, 1); - replaceWithSFormat(nodep, "%0x"); VL_DANGLING(nodep); + VL_DO_DANGLING(replaceWithSFormat(nodep, "%0x"), nodep); } else if (nodep->name() == "octtoa") { methodOkArguments(nodep, 1, 1); - replaceWithSFormat(nodep, "%0o"); VL_DANGLING(nodep); + VL_DO_DANGLING(replaceWithSFormat(nodep, "%0o"), nodep); } else if (nodep->name() == "bintoa") { methodOkArguments(nodep, 1, 1); - replaceWithSFormat(nodep, "%0b"); VL_DANGLING(nodep); + VL_DO_DANGLING(replaceWithSFormat(nodep, "%0b"), nodep); } else if (nodep->name() == "realtoa") { methodOkArguments(nodep, 1, 1); - replaceWithSFormat(nodep, "%g"); VL_DANGLING(nodep); + VL_DO_DANGLING(replaceWithSFormat(nodep, "%g"), nodep); } else if (nodep->name() == "tolower") { methodOkArguments(nodep, 0, 0); AstNode* newp = new AstToLowerN(nodep->fileline(), nodep->fromp()->unlinkFrBack()); - nodep->replaceWith(newp); nodep->deleteTree(); VL_DANGLING(nodep); + nodep->replaceWith(newp); VL_DO_DANGLING(nodep->deleteTree(), nodep); } else if (nodep->name() == "toupper") { methodOkArguments(nodep, 0, 0); AstNode* newp = new AstToUpperN(nodep->fileline(), nodep->fromp()->unlinkFrBack()); - nodep->replaceWith(newp); nodep->deleteTree(); VL_DANGLING(nodep); + nodep->replaceWith(newp); VL_DO_DANGLING(nodep->deleteTree(), nodep); } else if (nodep->name() == "compare" || nodep->name() == "icompare") { const bool ignoreCase = nodep->name()[0] == 'i'; methodOkArguments(nodep, 1, 1); @@ -2190,7 +2190,7 @@ private: AstNode* lhs = nodep->fromp()->unlinkFrBack(); AstNode* rhs = argp->exprp()->unlinkFrBack(); AstNode* newp = new AstCompareNN(nodep->fileline(), lhs, rhs, ignoreCase); - nodep->replaceWith(newp); nodep->deleteTree(); VL_DANGLING(nodep); + nodep->replaceWith(newp); VL_DO_DANGLING(nodep->deleteTree(), nodep); } else if (nodep->name() == "putc" ) { methodOkArguments(nodep, 2, 2); AstArg* arg0p = VN_CAST(nodep->pinsp(), Arg); @@ -2202,14 +2202,14 @@ private: AstNode* newp = new AstAssign(nodep->fileline(), fromp, new AstPutcN(nodep->fileline(), varrefp, rhsp, thsp)); fromp->lvalue(true); - nodep->replaceWith(newp); nodep->deleteTree(); VL_DANGLING(nodep); + nodep->replaceWith(newp); VL_DO_DANGLING(nodep->deleteTree(), nodep); } else if (nodep->name() == "getc") { methodOkArguments(nodep, 1, 1); AstArg* arg0p = VN_CAST(nodep->pinsp(), Arg); AstNode* lhsp = nodep->fromp()->unlinkFrBack(); AstNode* rhsp = arg0p->exprp()->unlinkFrBack(); AstNode* newp = new AstGetcN(nodep->fileline(), lhsp, rhsp); - nodep->replaceWith(newp); nodep->deleteTree(); VL_DANGLING(nodep); + nodep->replaceWith(newp); VL_DO_DANGLING(nodep->deleteTree(), nodep); } else if (nodep->name() == "substr") { methodOkArguments(nodep, 2, 2); AstArg* arg0p = VN_CAST(nodep->pinsp(), Arg); @@ -2218,7 +2218,7 @@ private: AstNode* rhsp = arg0p->exprp()->unlinkFrBack(); AstNode* thsp = arg1p->exprp()->unlinkFrBack(); AstNode* newp = new AstSubstrN(nodep->fileline(), lhsp, rhsp, thsp); - nodep->replaceWith(newp); nodep->deleteTree(); VL_DANGLING(nodep); + nodep->replaceWith(newp); VL_DO_DANGLING(nodep->deleteTree(), nodep); } else if (nodep->name() == "atobin" || nodep->name() == "atohex" || nodep->name() == "atoi" @@ -2233,7 +2233,7 @@ private: else { V3ERROR_NA; fmt = AstAtoN::ATOI; } // dummy assignment to suppress compiler warning methodOkArguments(nodep, 0, 0); AstNode* newp = new AstAtoN(nodep->fileline(), nodep->fromp()->unlinkFrBack(), fmt); - nodep->replaceWith(newp); nodep->deleteTree(); VL_DANGLING(nodep); + nodep->replaceWith(newp); VL_DO_DANGLING(nodep->deleteTree(), nodep); } else { nodep->v3error("Unknown built-in string method "<prettyNameQ()); } @@ -2312,14 +2312,14 @@ private: dtypep = vdtypep->subDTypep()->skipRefp(); } if (AstNodeUOrStructDType* vdtypep = VN_CAST(dtypep, NodeUOrStructDType)) { - patternUOrStruct(nodep, vdtypep, defaultp); VL_DANGLING(nodep); + VL_DO_DANGLING(patternUOrStruct(nodep, vdtypep, defaultp), nodep); } else if (AstNodeArrayDType* vdtypep = VN_CAST(dtypep, NodeArrayDType)) { - patternArray(nodep, vdtypep, defaultp); VL_DANGLING(nodep); + VL_DO_DANGLING(patternArray(nodep, vdtypep, defaultp), nodep); } else if (VN_IS(dtypep, BasicDType) && VN_CAST(dtypep, BasicDType)->isRanged()) { - patternBasic(nodep, dtypep, defaultp); VL_DANGLING(nodep); + VL_DO_DANGLING(patternBasic(nodep, dtypep, defaultp), nodep); } else { nodep->v3error("Unsupported: Assignment pattern applies against non struct/union: " <prettyTypeName()); @@ -2407,7 +2407,7 @@ private: // Forming a AstConcat will cause problems with // unsized (uncommitted sized) constants if (AstNode* newp = WidthCommitVisitor::newIfConstCommitSize(VN_CAST(valuep, Const))) { - pushDeletep(valuep); VL_DANGLING(valuep); + VL_DO_DANGLING(pushDeletep(valuep), valuep); valuep = newp; } } @@ -2420,11 +2420,11 @@ private: nodep->dtypep()->numeric()); } } - if (newpatp) { pushDeletep(newpatp); VL_DANGLING(newpatp); } + if (newpatp) { VL_DO_DANGLING(pushDeletep(newpatp), newpatp); } } if (newp) nodep->replaceWith(newp); else nodep->v3error("Assignment pattern with no members"); - pushDeletep(nodep); VL_DANGLING(nodep); // Deletes defaultp also, if present + VL_DO_DANGLING(pushDeletep(nodep), nodep); // Deletes defaultp also, if present } void patternArray(AstPattern* nodep, AstNodeArrayDType* vdtypep, AstPatMember* defaultp) { AstNodeArrayDType* arrayp = VN_CAST(vdtypep, NodeArrayDType); @@ -2461,7 +2461,7 @@ private: // Forming a AstConcat will cause problems with // unsized (uncommitted sized) constants if (AstNode* newp = WidthCommitVisitor::newIfConstCommitSize(VN_CAST(valuep, Const))) { - pushDeletep(valuep); VL_DANGLING(valuep); + VL_DO_DANGLING(pushDeletep(valuep), valuep); valuep = newp; } } @@ -2483,13 +2483,13 @@ private: } } } - if (newpatp) { pushDeletep(newpatp); VL_DANGLING(newpatp); } + if (newpatp) { VL_DO_DANGLING(pushDeletep(newpatp), newpatp); } } if (!patmap.empty()) nodep->v3error("Assignment pattern with too many elements"); if (newp) nodep->replaceWith(newp); else nodep->v3error("Assignment pattern with no members"); //if (debug()>=9) newp->dumpTree("-apat-out: "); - pushDeletep(nodep); VL_DANGLING(nodep); // Deletes defaultp also, if present + VL_DO_DANGLING(pushDeletep(nodep), nodep); // Deletes defaultp also, if present } void patternBasic(AstPattern* nodep, AstNodeDType* vdtypep, AstPatMember* defaultp) { AstBasicDType* bdtypep = VN_CAST(vdtypep, BasicDType); @@ -2527,7 +2527,7 @@ private: // Forming a AstConcat will cause problems with // unsized (uncommitted sized) constants if (AstNode* newp = WidthCommitVisitor::newIfConstCommitSize(VN_CAST(valuep, Const))) { - pushDeletep(valuep); VL_DANGLING(valuep); + VL_DO_DANGLING(pushDeletep(valuep), valuep); valuep = newp; } } @@ -2542,13 +2542,13 @@ private: } } } - if (newpatp) { pushDeletep(newpatp); VL_DANGLING(newpatp); } + if (newpatp) { VL_DO_DANGLING(pushDeletep(newpatp), newpatp); } } if (!patmap.empty()) nodep->v3error("Assignment pattern with too many elements"); if (newp) nodep->replaceWith(newp); else nodep->v3error("Assignment pattern with no members"); //if (debug()>=9) newp->dumpTree("-apat-out: "); - pushDeletep(nodep); VL_DANGLING(nodep); // Deletes defaultp also, if present + VL_DO_DANGLING(pushDeletep(nodep), nodep); // Deletes defaultp also, if present } virtual void visit(AstPatMember* nodep) { AstNodeDType* vdtypep = m_vup->dtypeNullp(); @@ -2600,7 +2600,7 @@ private: if (!VN_IS(nodep, GenCase)) userIterateAndNext(itemp->bodysp(), NULL); for (AstNode* nextcp, *condp = itemp->condsp(); condp; condp=nextcp) { nextcp = condp->nextp(); // Prelim may cause the node to get replaced - userIterate(condp, WidthVP(CONTEXT, PRELIM).p()); VL_DANGLING(condp); + VL_DO_DANGLING(userIterate(condp, WidthVP(CONTEXT, PRELIM).p()), condp); } } @@ -2821,7 +2821,7 @@ private: break; default: UASSERT_OBJ(false, nodep, "Unexpected elaboration display type"); } - nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep); + VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); } } virtual void visit(AstFOpen* nodep) { @@ -3128,7 +3128,7 @@ private: userIterateAndNext(nodep->exprp(), m_vup); nodep->replaceWith(nodep->exprp()->unlinkFrBack()); } - pushDeletep(nodep); VL_DANGLING(nodep); + VL_DO_DANGLING(pushDeletep(nodep), nodep); } } virtual void visit(AstNodeFTask* nodep) { @@ -3215,7 +3215,7 @@ private: string format; if (VN_IS(pinp, Const)) format = VN_CAST(pinp, Const)->num().toString(); else pinp->v3error("Format to $display-like function must have constant format string"); - pushDeletep(argp); VL_DANGLING(argp); + VL_DO_DANGLING(pushDeletep(argp), argp); AstSFormatF* newp = new AstSFormatF(nodep->fileline(), format, false, argsp); if (!newp->scopeNamep() && newp->formatScopeTracking()) { newp->scopeNamep(new AstScopeName(newp->fileline())); @@ -3237,7 +3237,7 @@ private: pinp = newp; } // AstPattern requires assignments to pass datatype on PRELIM - userIterate(pinp, WidthVP(portp->dtypep(), PRELIM).p()); VL_DANGLING(pinp); + VL_DO_DANGLING(userIterate(pinp, WidthVP(portp->dtypep(), PRELIM).p()), pinp); } } while (0); // Stage 2 @@ -3250,7 +3250,7 @@ private: if (!pinp) continue; // Argument error we'll find later // Change data types based on above accept completion if (portp->isDouble()) { - spliceCvtD(pinp); VL_DANGLING(pinp); + VL_DO_DANGLING(spliceCvtD(pinp), pinp); } } } @@ -3616,7 +3616,7 @@ private: V3Number num (shiftp, 32, 0); num.opAssign(shiftp->num()); AstNode* shiftp = nodep->rhsp(); nodep->rhsp()->replaceWith(new AstConst(shiftp->fileline(), num)); - shiftp->deleteTree(); VL_DANGLING(shiftp); + VL_DO_DANGLING(shiftp->deleteTree(), shiftp); } } } @@ -3780,7 +3780,7 @@ private: num.isSigned(false); AstNode* newp = new AstConst(nodep->fileline(), num); constp->replaceWith(newp); - pushDeletep(constp); VL_DANGLING(constp); VL_DANGLING(nodep); + VL_DO_DANGLING(pushDeletep(constp), constp); VL_DANGLING(nodep); nodep = newp; } else if (expWidthwidth()) { // Trunc - Extract @@ -3833,7 +3833,7 @@ private: num.isSigned(expSigned); AstNode* newp = new AstConst(nodep->fileline(), num); constp->replaceWith(newp); - constp->deleteTree(); VL_DANGLING(constp); VL_DANGLING(nodep); + VL_DO_DANGLING(constp->deleteTree(), constp); VL_DANGLING(nodep); nodep = newp; } else { AstNRelinker linker; @@ -3858,7 +3858,7 @@ private: if (debug()>4) constp->dumpTree(cout, " fixAutoExtend_old: "); if (debug()>4) newp->dumpTree(cout, " _new: "); constp->replaceWith(newp); - constp->deleteTree(); VL_DANGLING(constp); + VL_DO_DANGLING(constp->deleteTree(), constp); // Tell caller the new constp, and that we changed it. nodepr = newp; return true; @@ -3876,7 +3876,7 @@ private: if (debug()>4) constp->dumpTree(cout, " fixUnszExtend_old: "); if (debug()>4) newp->dumpTree(cout, " _new: "); constp->replaceWith(newp); - constp->deleteTree(); VL_DANGLING(constp); + VL_DO_DANGLING(constp->deleteTree(), constp); // Tell caller the new constp, and that we changed it. nodepr = newp; return true; @@ -3997,7 +3997,7 @@ private: nodep->v3error("Logical Operator "<prettyTypeName() <<" expects a non-complex data type on the "<replaceWith(new AstConst(nodep->fileline(), AstConst::LogicFalse())); - pushDeletep(underp); VL_DANGLING(underp); + VL_DO_DANGLING(pushDeletep(underp), underp); } else { bool bad = widthBad(underp, nodep->findLogicBoolDType()); if (bad) { @@ -4010,7 +4010,7 @@ private: ?" or "+cvtToStr(underp->widthMin()):"") <<" bits."); } - fixWidthReduce(underp); VL_DANGLING(underp); //Changed + VL_DO_DANGLING(fixWidthReduce(underp), underp); //Changed } } } @@ -4154,7 +4154,7 @@ private: // V3Inst::pinReconnectSimple must deal UINFO(5,"pinInSizeMismatch: "<replaceWith(newp); newp->dtypeFrom(nodep); - pushDeletep(nodep); VL_DANGLING(nodep); + VL_DO_DANGLING(pushDeletep(nodep), nodep); return newp; } AstNodeBiop* replaceWithDVersion(AstNodeBiop* nodep) { @@ -4297,7 +4297,7 @@ private: UINFO(6," ReplaceWithDVersion: "<replaceWith(newp); // No width change; the default created type (bool or double) is correct - pushDeletep(nodep); VL_DANGLING(nodep); + VL_DO_DANGLING(pushDeletep(nodep), nodep); return newp; } AstNodeBiop* replaceWithNVersion(AstNodeBiop* nodep) { @@ -4325,7 +4325,7 @@ private: UINFO(6," ReplaceWithNVersion: "<replaceWith(newp); // No width change; the default created type (bool or string) is correct - pushDeletep(nodep); VL_DANGLING(nodep); + VL_DO_DANGLING(pushDeletep(nodep), nodep); return newp; } AstNodeUniop* replaceWithDVersion(AstNodeUniop* nodep) { @@ -4346,7 +4346,7 @@ private: UINFO(6," ReplaceWithDVersion: "<replaceWith(newp); newp->dtypeFrom(nodep); - pushDeletep(nodep); VL_DANGLING(nodep); + VL_DO_DANGLING(pushDeletep(nodep), nodep); return newp; } @@ -4367,7 +4367,7 @@ private: argp->exprp()->unlinkFrBack())); fromp->lvalue(true); nodep->replaceWith(newp); - pushDeletep(nodep); VL_DANGLING(nodep); + VL_DO_DANGLING(pushDeletep(nodep), nodep); } //---------------------------------------------------------------------- @@ -4667,7 +4667,7 @@ private: if (!VN_IS(nodep, Const)) { nodep->v3error(message); nodep->replaceWith(new AstConst(nodep->fileline(), AstConst::Unsized32(), 1)); - pushDeletep(nodep); VL_DANGLING(nodep); + VL_DO_DANGLING(pushDeletep(nodep), nodep); } } AstNode* nodeForUnsizedWarning(AstNode* nodep) { diff --git a/src/V3WidthCommit.h b/src/V3WidthCommit.h index a2afc81ea..d8be52295 100644 --- a/src/V3WidthCommit.h +++ b/src/V3WidthCommit.h @@ -40,10 +40,10 @@ class WidthRemoveVisitor : public AstNVisitor { private: // VISITORS virtual void visit(AstSigned* nodep) { - replaceWithSignedVersion(nodep, nodep->lhsp()->unlinkFrBack()); VL_DANGLING(nodep); + VL_DO_DANGLING(replaceWithSignedVersion(nodep, nodep->lhsp()->unlinkFrBack()), nodep); } virtual void visit(AstUnsigned* nodep) { - replaceWithSignedVersion(nodep, nodep->lhsp()->unlinkFrBack()); VL_DANGLING(nodep); + VL_DO_DANGLING(replaceWithSignedVersion(nodep, nodep->lhsp()->unlinkFrBack()), nodep); } virtual void visit(AstNode* nodep) { iterateChildren(nodep); @@ -52,7 +52,7 @@ private: UINFO(6," Replace "<replaceWith(newp); newp->dtypeFrom(nodep); - pushDeletep(nodep); VL_DANGLING(nodep); + VL_DO_DANGLING(pushDeletep(nodep), nodep); } public: // CONSTRUCTORS @@ -122,7 +122,7 @@ private: AstNode* oldp = nodep; nodep = newp; //if (debug()>4) oldp->dumpTree(cout, " fixConstSize_old: "); //if (debug()>4) newp->dumpTree(cout, " _new: "); - pushDeletep(oldp); VL_DANGLING(oldp); + VL_DO_DANGLING(pushDeletep(oldp), oldp); } editDType(nodep); } diff --git a/src/V3WidthSel.cpp b/src/V3WidthSel.cpp index db15b5798..f0ac952c6 100644 --- a/src/V3WidthSel.cpp +++ b/src/V3WidthSel.cpp @@ -60,7 +60,7 @@ private: if (!VN_IS(nodep, Const)) { nodep->v3error(message); nodep->replaceWith(new AstConst(nodep->fileline(), AstConst::Unsized32(), 1)); - pushDeletep(nodep); VL_DANGLING(nodep); + VL_DO_DANGLING(pushDeletep(nodep), nodep); } } @@ -219,7 +219,7 @@ private: fromp, subp); newp->dtypeFrom(adtypep->subDTypep()); // Need to strip off array reference if (debug()>=9) newp->dumpTree(cout, "--SELBTn: "); - nodep->replaceWith(newp); pushDeletep(nodep); VL_DANGLING(nodep); + nodep->replaceWith(newp); VL_DO_DANGLING(pushDeletep(nodep), nodep); } else if (AstPackArrayDType* adtypep = VN_CAST(ddtypep, PackArrayDType)) { // SELBIT(array, index) -> SEL(array, index*width-of-subindex, width-of-subindex) @@ -248,7 +248,7 @@ private: newp->declElWidth(elwidth); newp->dtypeFrom(adtypep->subDTypep()); // Need to strip off array reference if (debug()>=9) newp->dumpTree(cout, "--SELBTn: "); - nodep->replaceWith(newp); pushDeletep(nodep); VL_DANGLING(nodep); + nodep->replaceWith(newp); VL_DO_DANGLING(pushDeletep(nodep), nodep); } else if (AstAssocArrayDType* adtypep = VN_CAST(ddtypep, AssocArrayDType)) { // SELBIT(array, index) -> ASSOCSEL(array, index) @@ -257,7 +257,7 @@ private: fromp, subp); newp->dtypeFrom(adtypep->subDTypep()); // Need to strip off array reference if (debug()>=9) newp->dumpTree(cout, "--SELBTn: "); - nodep->replaceWith(newp); pushDeletep(nodep); VL_DANGLING(nodep); + nodep->replaceWith(newp); VL_DO_DANGLING(pushDeletep(nodep), nodep); } else if (AstQueueDType* adtypep = VN_CAST(ddtypep, QueueDType)) { // SELBIT(array, index) -> CMETHODCALL(queue, "at", index) @@ -266,7 +266,7 @@ private: fromp, "at", subp); newp->dtypeFrom(adtypep->subDTypep()); // Need to strip off queue reference if (debug()>=9) newp->dumpTree(cout, "--SELBTq: "); - nodep->replaceWith(newp); pushDeletep(nodep); VL_DANGLING(nodep); + nodep->replaceWith(newp); VL_DO_DANGLING(pushDeletep(nodep), nodep); } else if (VN_IS(ddtypep, BasicDType)) { // SELBIT(range, index) -> SEL(array, index, 1) @@ -278,7 +278,7 @@ private: newp->declRange(fromRange); UINFO(6," new "<=9) newp->dumpTree(cout, "--SELBTn: "); - nodep->replaceWith(newp); pushDeletep(nodep); VL_DANGLING(nodep); + nodep->replaceWith(newp); VL_DO_DANGLING(pushDeletep(nodep), nodep); } else if (VN_IS(ddtypep, NodeUOrStructDType)) { // A bit from the packed struct // SELBIT(range, index) -> SEL(array, index, 1) @@ -290,15 +290,15 @@ private: newp->declRange(fromRange); UINFO(6," new "<=9) newp->dumpTree(cout, "--SELBTn: "); - nodep->replaceWith(newp); pushDeletep(nodep); VL_DANGLING(nodep); + nodep->replaceWith(newp); VL_DO_DANGLING(pushDeletep(nodep), nodep); } else { // NULL=bad extract, or unknown node type nodep->v3error("Illegal bit or array select; type already selected, or bad dimension: type is" <prettyName()); // How to recover? We'll strip a dimension. - nodep->replaceWith(fromp); pushDeletep(nodep); VL_DANGLING(nodep); + nodep->replaceWith(fromp); VL_DO_DANGLING(pushDeletep(nodep), nodep); } - if (!rhsp->backp()) { pushDeletep(rhsp); VL_DANGLING(rhsp); } + if (!rhsp->backp()) { VL_DO_DANGLING(pushDeletep(rhsp), rhsp); } } virtual void visit(AstSelExtract* nodep) { // Select of a range specified part of an array, i.e. "array[2:3]" @@ -325,15 +325,15 @@ private: // Slice extraction if (fromRange.elements() == elem && fromRange.lo() == lsb) { // Extracting whole of original array - nodep->replaceWith(fromp); pushDeletep(nodep); VL_DANGLING(nodep); + nodep->replaceWith(fromp); VL_DO_DANGLING(pushDeletep(nodep), nodep); } else if (fromRange.elements() == 1) { // Extracting single element AstArraySel* newp = new AstArraySel(nodep->fileline(), fromp, lsbp); - nodep->replaceWith(newp); pushDeletep(nodep); VL_DANGLING(nodep); + nodep->replaceWith(newp); VL_DO_DANGLING(pushDeletep(nodep), nodep); } else { // Slice AstSliceSel* newp = new AstSliceSel(nodep->fileline(), fromp, VNumRange(VNumRange::LeftRight(), msb, lsb)); - nodep->replaceWith(newp); pushDeletep(nodep); VL_DANGLING(nodep); + nodep->replaceWith(newp); VL_DO_DANGLING(pushDeletep(nodep), nodep); } } else if (AstPackArrayDType* adtypep = VN_CAST(ddtypep, PackArrayDType)) { @@ -365,7 +365,7 @@ private: newp->dtypeFrom(sliceDType(adtypep, msb, lsb)); //if (debug()>=9) newp->dumpTree(cout, "--EXTBTn: "); UASSERT_OBJ(newp->widthMin() == newp->widthConst(), nodep, "Width mismatch"); - nodep->replaceWith(newp); pushDeletep(nodep); VL_DANGLING(nodep); + nodep->replaceWith(newp); VL_DO_DANGLING(pushDeletep(nodep), nodep); } else if (VN_IS(ddtypep, BasicDType)) { if (fromRange.littleEndian()) { @@ -387,7 +387,7 @@ private: newp->declRange(fromRange); UINFO(6," new "<=9) newp->dumpTree(cout, "--SELEXnew: "); - nodep->replaceWith(newp); pushDeletep(nodep); VL_DANGLING(nodep); + nodep->replaceWith(newp); VL_DO_DANGLING(pushDeletep(nodep), nodep); } else if (VN_IS(ddtypep, NodeUOrStructDType)) { // Classes aren't little endian @@ -406,19 +406,19 @@ private: newp->declRange(fromRange); UINFO(6," new "<=9) newp->dumpTree(cout, "--SELEXnew: "); - nodep->replaceWith(newp); pushDeletep(nodep); VL_DANGLING(nodep); + nodep->replaceWith(newp); VL_DO_DANGLING(pushDeletep(nodep), nodep); } else { // NULL=bad extract, or unknown node type nodep->v3error("Illegal range select; type already selected, or bad dimension: type is " <prettyName()); UINFO(1," Related ddtype: "<replaceWith(fromp); pushDeletep(nodep); VL_DANGLING(nodep); + nodep->replaceWith(fromp); VL_DO_DANGLING(pushDeletep(nodep), nodep); } // delete whatever we didn't use in reconstruction - if (!fromp->backp()) { pushDeletep(fromp); VL_DANGLING(fromp); } - if (!msbp->backp()) { pushDeletep(msbp); VL_DANGLING(msbp); } - if (!lsbp->backp()) { pushDeletep(lsbp); VL_DANGLING(lsbp); } + if (!fromp->backp()) { VL_DO_DANGLING(pushDeletep(fromp), fromp); } + if (!msbp->backp()) { VL_DO_DANGLING(pushDeletep(msbp), msbp); } + if (!lsbp->backp()) { VL_DO_DANGLING(pushDeletep(lsbp), lsbp); } } void replaceSelPlusMinus(AstNodePreSel* nodep) { @@ -479,18 +479,18 @@ private: newp->declElWidth(elwidth); UINFO(6," new "<=9) newp->dumpTree(cout, "--SELNEW: "); - nodep->replaceWith(newp); pushDeletep(nodep); VL_DANGLING(nodep); + nodep->replaceWith(newp); VL_DO_DANGLING(pushDeletep(nodep), nodep); } else { // NULL=bad extract, or unknown node type nodep->v3error("Illegal +: or -: select; type already selected, or bad dimension: type is " <prettyTypeName()); // How to recover? We'll strip a dimension. - nodep->replaceWith(fromp); pushDeletep(nodep); VL_DANGLING(nodep); + nodep->replaceWith(fromp); VL_DO_DANGLING(pushDeletep(nodep), nodep); } // delete whatever we didn't use in reconstruction - if (!fromp->backp()) { pushDeletep(fromp); VL_DANGLING(fromp); } - if (!rhsp->backp()) { pushDeletep(rhsp); VL_DANGLING(rhsp); } - if (!widthp->backp()) { pushDeletep(widthp); VL_DANGLING(widthp); } + if (!fromp->backp()) { VL_DO_DANGLING(pushDeletep(fromp), fromp); } + if (!rhsp->backp()) { VL_DO_DANGLING(pushDeletep(rhsp), rhsp); } + if (!widthp->backp()) { VL_DO_DANGLING(pushDeletep(widthp), widthp); } } virtual void visit(AstSelPlus* nodep) { replaceSelPlusMinus(nodep); diff --git a/src/astgen b/src/astgen index 863a05621..184f329f4 100644 --- a/src/astgen +++ b/src/astgen @@ -554,7 +554,7 @@ sub treeop_exec_func { $out .= "AstNode* newp = " . _exec_new_recurse($aref).";\n"; $out .= "nodep->replaceWith(newp);"; - $out .= "nodep->deleteTree(); VL_DANGLING(nodep);"; + $out .= "VL_DO_DANGLING(nodep->deleteTree(), nodep);"; #print "FF $out\n" if $Debug; } elsif ($func eq "NEVER") { $out .= "nodep->v3fatalSrc(\"Executing transform that was NEVERed\");"; diff --git a/src/verilog.y b/src/verilog.y index 137038e87..e0c0a6296 100644 --- a/src/verilog.y +++ b/src/verilog.y @@ -161,7 +161,7 @@ public: // It's no longer implicit but a wire logic type AstBasicDType* newp = new AstBasicDType(dtypep->fileline(), AstBasicDTypeKwd::LOGIC, dtypep->numeric(), dtypep->width(), dtypep->widthMin()); - dtypep->deleteTree(); VL_DANGLING(dtypep); + VL_DO_DANGLING(dtypep->deleteTree(), dtypep); dtypep = newp; } dtypep->rangep(finalRangep); @@ -2126,7 +2126,7 @@ loop_generate_construct: // ==IEEE: loop_generate_construct // for loop won't get an extra layer of hierarchy tacked on blkp->addGenforp(new AstGenFor($1,initp,$5,$7,lowerNoBegp)); $$ = blkp; - lowerBegp->deleteTree(); VL_DANGLING(lowerBegp); + VL_DO_DANGLING(lowerBegp->deleteTree(), lowerBegp); } ; diff --git a/test_regress/t/t_clk_inp_init.cpp b/test_regress/t/t_clk_inp_init.cpp index 9c267f64c..90e64a755 100644 --- a/test_regress/t/t_clk_inp_init.cpp +++ b/test_regress/t/t_clk_inp_init.cpp @@ -46,7 +46,7 @@ void oneTest(int seed) { } topp->final(); - delete topp; VL_DANGLING(topp); + VL_DO_DANGLING(delete topp, topp); } int main(int argc, char** argv, char** env) { diff --git a/test_regress/t/t_dpi_var.cpp b/test_regress/t/t_dpi_var.cpp index ce2fb5916..1f4f8b0a0 100644 --- a/test_regress/t/t_dpi_var.cpp +++ b/test_regress/t/t_dpi_var.cpp @@ -145,6 +145,6 @@ int main(int argc, char** argv, char** env) { } topp->final(); - delete topp; VL_DANGLING(topp); + VL_DO_DANGLING(delete topp, topp); exit(0L); } diff --git a/test_regress/t/t_leak.cpp b/test_regress/t/t_leak.cpp index 500a0a4cf..559a17ce8 100644 --- a/test_regress/t/t_leak.cpp +++ b/test_regress/t/t_leak.cpp @@ -57,7 +57,7 @@ void make_and_destroy() { topp->eval(); } - delete topp; VL_DANGLING(topp); + VL_DO_DANGLING(delete topp, topp); } int main(int argc, char* argv[]) { diff --git a/test_regress/t/t_var_overwidth_bad.cpp b/test_regress/t/t_var_overwidth_bad.cpp index 666a9baf0..ff7560b5c 100644 --- a/test_regress/t/t_var_overwidth_bad.cpp +++ b/test_regress/t/t_var_overwidth_bad.cpp @@ -37,6 +37,6 @@ int main(int argc, char** argv, char** env) { topp->eval(); topp->final(); - delete topp; VL_DANGLING(topp); + VL_DO_DANGLING(delete topp, topp); exit(0L); } diff --git a/test_regress/t/t_vpi_get.cpp b/test_regress/t/t_vpi_get.cpp index d44c6f35a..e2ba788e8 100644 --- a/test_regress/t/t_vpi_get.cpp +++ b/test_regress/t/t_vpi_get.cpp @@ -280,7 +280,7 @@ int main(int argc, char** argv, char** env) { if (tfp) tfp->close(); #endif - delete topp; VL_DANGLING(topp); + VL_DO_DANGLING(delete topp, topp); exit(0L); } diff --git a/test_regress/t/t_vpi_memory.cpp b/test_regress/t/t_vpi_memory.cpp index 6bab9ae2e..2da149eb1 100644 --- a/test_regress/t/t_vpi_memory.cpp +++ b/test_regress/t/t_vpi_memory.cpp @@ -250,7 +250,7 @@ int main(int argc, char** argv, char** env) { if (tfp) tfp->close(); #endif - delete topp; VL_DANGLING(topp); + VL_DO_DANGLING(delete topp, topp); exit(0L); } diff --git a/test_regress/t/t_vpi_module.cpp b/test_regress/t/t_vpi_module.cpp index e34879a85..81cfae35f 100644 --- a/test_regress/t/t_vpi_module.cpp +++ b/test_regress/t/t_vpi_module.cpp @@ -178,7 +178,7 @@ int main(int argc, char** argv, char** env) { if (tfp) tfp->close(); #endif - delete topp; VL_DANGLING(topp); + VL_DO_DANGLING(delete topp, topp); exit(0L); } diff --git a/test_regress/t/t_vpi_time_cb.cpp b/test_regress/t/t_vpi_time_cb.cpp index 4d277adb7..7a831de1f 100644 --- a/test_regress/t/t_vpi_time_cb.cpp +++ b/test_regress/t/t_vpi_time_cb.cpp @@ -257,7 +257,7 @@ int main(int argc, char** argv, char** env) { if (tfp) tfp->close(); #endif - delete topp; VL_DANGLING(topp); + VL_DO_DANGLING(delete topp, topp); exit(0L); } diff --git a/test_regress/t/t_vpi_unimpl.cpp b/test_regress/t/t_vpi_unimpl.cpp index 987e77300..9e3f9621d 100644 --- a/test_regress/t/t_vpi_unimpl.cpp +++ b/test_regress/t/t_vpi_unimpl.cpp @@ -187,6 +187,6 @@ int main(int argc, char** argv, char** env) { if (tfp) tfp->close(); #endif - delete topp; VL_DANGLING(topp); + VL_DO_DANGLING(delete topp, topp); exit(0L); } diff --git a/test_regress/t/t_vpi_var.cpp b/test_regress/t/t_vpi_var.cpp index 9fdd7dc1b..9f170cb9d 100644 --- a/test_regress/t/t_vpi_var.cpp +++ b/test_regress/t/t_vpi_var.cpp @@ -672,7 +672,7 @@ int main(int argc, char** argv, char** env) { if (tfp) tfp->close(); #endif - delete topp; VL_DANGLING(topp); + VL_DO_DANGLING(delete topp, topp); exit(0L); } diff --git a/test_regress/t/t_vpi_zero_time_cb.cpp b/test_regress/t/t_vpi_zero_time_cb.cpp index 610d7f5cb..5694db5a4 100644 --- a/test_regress/t/t_vpi_zero_time_cb.cpp +++ b/test_regress/t/t_vpi_zero_time_cb.cpp @@ -207,7 +207,7 @@ int main(int argc, char** argv, char** env) { if (tfp) tfp->close(); #endif - delete topp; VL_DANGLING(topp); + VL_DO_DANGLING(delete topp, topp); exit(0L); } From 7024ea8cb6f73d6af555e4166892b135e0cb0c66 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Sat, 18 Jan 2020 07:56:50 -0500 Subject: [PATCH 09/13] Cleaner tristate error. #2117. --- src/V3Tristate.cpp | 4 +++- test_regress/t/t_tri_compass_bad.out | 5 +++++ test_regress/t/t_tri_compass_bad.pl | 18 ++++++++++++++++++ test_regress/t/t_tri_compass_bad.v | 20 ++++++++++++++++++++ 4 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 test_regress/t/t_tri_compass_bad.out create mode 100755 test_regress/t/t_tri_compass_bad.pl create mode 100644 test_regress/t/t_tri_compass_bad.v diff --git a/src/V3Tristate.cpp b/src/V3Tristate.cpp index ad30f8fd6..587aa572c 100644 --- a/src/V3Tristate.cpp +++ b/src/V3Tristate.cpp @@ -1155,7 +1155,9 @@ class TristateVisitor : public TristateBaseVisitor { AstVar* outModVarp = static_cast(nodep->modVarp()->user4p()); if (!outModVarp) { // At top, no need for __out as might be input only. Otherwise resolvable. - UASSERT_OBJ(m_modp->isTop(), nodep, "Unlinked"); + if (!m_modp->isTop()) { + nodep->v3error("Unsupported: tristate in top-level IO: " << nodep->prettyNameQ()); + } } else { AstNode* outexprp = nodep->exprp()->cloneTree(false); // Note has lvalue() set outpinp = new AstPin(nodep->fileline(), diff --git a/test_regress/t/t_tri_compass_bad.out b/test_regress/t/t_tri_compass_bad.out new file mode 100644 index 000000000..ccfb73039 --- /dev/null +++ b/test_regress/t/t_tri_compass_bad.out @@ -0,0 +1,5 @@ +%Error: t/t_tri_compass_bad.v:15: Unsupported: tristate in top-level IO: '__pinNumber1' + : ... In instance t + sub sub(i, o); + ^ +%Error: Exiting due to diff --git a/test_regress/t/t_tri_compass_bad.pl b/test_regress/t/t_tri_compass_bad.pl new file mode 100755 index 000000000..3264f888b --- /dev/null +++ b/test_regress/t/t_tri_compass_bad.pl @@ -0,0 +1,18 @@ +#!/usr/bin/perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2003 by Wilson Snyder. This program is free software; you can +# redistribute it and/or modify it under the terms of either the GNU +# Lesser General Public License Version 3 or the Perl Artistic License +# Version 2.0. + +scenarios(vlt => 1); + +compile( + expect_filename => $Self->{golden_filename}, + fails => 1, + ); + +ok(1); +1; diff --git a/test_regress/t/t_tri_compass_bad.v b/test_regress/t/t_tri_compass_bad.v new file mode 100644 index 000000000..abe36c903 --- /dev/null +++ b/test_regress/t/t_tri_compass_bad.v @@ -0,0 +1,20 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed into the Public Domain, for any use, +// without warranty, 2020 by Wilson Snyder. + +module t(/*AUTOARG*/ + // Outputs + o, + // Inputs + i + ); + + input i; + output o; + sub sub(i, o); +endmodule + +module sub(input i, output o); + assign o = (i===1'bz) ? 1'b0 : i; +endmodule From 2f4954ca6836b899861dfcd12f29e5721637d394 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Sat, 18 Jan 2020 09:18:57 -0500 Subject: [PATCH 10/13] Commentary --- README.adoc | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/README.adoc b/README.adoc index 8d8f17814..395302e64 100644 --- a/README.adoc +++ b/README.adoc @@ -16,6 +16,7 @@ ifndef::env-github[] :link_verilator_contributing: https://github.com/verilator/verilator/blob/master/docs/CONTRIBUTING.adoc :link_verilator_install: https://verilator.org/install endif::[] +:link_verilator_commercial_support: https://verilator.org/verilator_commercial_support == Welcome to Verilator @@ -38,12 +39,18 @@ endif::[] +++
+++ • Out-of-the-box support from Arm, and RISC-V vendor IP <.^|image:https://www.veripool.org/img/verilator_usage_400x200-min.png[,400,200] ->.^|image:https://www.veripool.org/img/chips_alliance_logo_225x75-min.png[CHIPS Alliance,link=https://chipsalliance.org] -image:https://www.veripool.org/img/osi_logo_125x125-min.png[,125,125] +>.^|image:https://www.veripool.org/img/verilator_community_400x125-min.png[,400,125] ^.^| *Community Driven & Openly Licensed* +++
+++ • Guided by the https://chipsalliance.org/[CHIPS Alliance] and https://www.linuxfoundation.org/[Linux Foundation] +++
+++ • Open, and free as in both speech and beer +++
+++ • More simulation for your verification budget + +^.^| *Commercial Support Available* ++++
+++ • Commercial support contracts ++++
+++ • Design support contracts ++++
+++ • Enhancement contracts +<.^|image:https://www.veripool.org/img/verilator_support_400x125-min.png[,400,125] + |=== == What Verilator Does @@ -109,7 +116,7 @@ or https://verilator.org/verilator_doc.pdf[Verilator manual (PDF)] * https://verilator.org/issues[Verilator Issues] -== Community Supported +== Support Verilator is a community project, guided by the https://chipsalliance.org/[CHIPS Alliance] under the @@ -120,6 +127,10 @@ We appreciate and welcome your contributions in whatever form; please see https://verilator.org/verilator_doc.html#CONTRIBUTORS[Contributors and Sponsors]. +Verilator also supports and encourages commercial support models and +organizations; please see {link_verilator_commercial_support}[Verilator +Commercial Support]. + == Related Projects * http://gtkwave.sourceforge.net/[GTKwave] - Waveform viewer for Verilator From 09199f79a66c6f8f5f5a9c7d528ea43bc3c9a8f4 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Sat, 18 Jan 2020 10:29:49 -0500 Subject: [PATCH 11/13] Internals: Add VL_DO_CLEAR delete protections. No functional change intended. --- include/verilatedos.h | 6 +++++- src/V3Cdc.cpp | 2 +- src/V3Coverage.cpp | 4 ++-- src/V3EmitC.cpp | 10 +++++----- src/V3EmitCSyms.cpp | 3 +-- src/V3File.cpp | 2 +- src/V3GraphAlg.cpp | 4 +--- src/V3GraphDfa.cpp | 2 +- src/V3Life.cpp | 4 ++-- src/V3Options.cpp | 2 +- src/V3ParseImp.cpp | 6 +++--- src/V3ParseLex.cpp | 2 +- src/V3Partition.cpp | 4 ++-- src/V3PreLex.h | 2 +- src/V3PreProc.cpp | 2 +- src/V3Subst.cpp | 4 ++-- src/V3Task.cpp | 15 +++++++++------ src/V3TraceDecl.cpp | 8 ++++---- src/V3Unknown.cpp | 6 ++++-- src/V3Unroll.cpp | 6 +++--- src/Verilator.cpp | 2 +- src/VlcTest.h | 2 +- src/verilog.y | 7 +++++-- 23 files changed, 57 insertions(+), 48 deletions(-) diff --git a/include/verilatedos.h b/include/verilatedos.h index 37c816e0a..fa1811321 100644 --- a/include/verilatedos.h +++ b/include/verilatedos.h @@ -160,9 +160,13 @@ # define VL_DANGLING(var) do { (var) = NULL; } while(0) #endif -///< Perform an e.g. delete, then set variable to NULL to indicate must not use later +///< Perform an e.g. delete, then set variable to NULL to indicate must not use later. +///< Unlike VL_DO_CLEAR the setting of the variable is only for debug reasons. #define VL_DO_DANGLING(stmt, var) do { do { stmt; } while(0); VL_DANGLING(var); } while(0) +///< Perform an e.g. delete, then set variable to NULL as a requirement +#define VL_DO_CLEAR(stmt, stmt2) do { do { stmt; } while(0); do { stmt2; } while(0); } while(0) + //========================================================================= // C++-2011 diff --git a/src/V3Cdc.cpp b/src/V3Cdc.cpp index ac4c0a3af..0e840947e 100644 --- a/src/V3Cdc.cpp +++ b/src/V3Cdc.cpp @@ -761,7 +761,7 @@ public: } } virtual ~CdcVisitor() { - if (m_ofp) { delete m_ofp; m_ofp = NULL; } + if (m_ofp) VL_DO_CLEAR(delete m_ofp, m_ofp = NULL); } }; diff --git a/src/V3Coverage.cpp b/src/V3Coverage.cpp index 465d939ef..bdd8bb914 100644 --- a/src/V3Coverage.cpp +++ b/src/V3Coverage.cpp @@ -54,8 +54,8 @@ private: : m_comment(comment), m_varRefp(vp), m_chgRefp(cp) {} ~ToggleEnt() {} void cleanup() { - m_varRefp->deleteTree(); m_varRefp = NULL; - m_chgRefp->deleteTree(); m_chgRefp = NULL; + VL_DO_CLEAR(m_varRefp->deleteTree(), m_varRefp = NULL); + VL_DO_CLEAR(m_chgRefp->deleteTree(), m_chgRefp = NULL); } }; diff --git a/src/V3EmitC.cpp b/src/V3EmitC.cpp index 11195f3e9..9ba7c39ec 100644 --- a/src/V3EmitC.cpp +++ b/src/V3EmitC.cpp @@ -2813,7 +2813,7 @@ void EmitCImp::emitImp(AstNodeModule* modp) { void EmitCImp::maybeSplit(AstNodeModule* modp) { if (splitNeeded()) { // Close old file - delete m_ofp; m_ofp = NULL; + VL_DO_CLEAR(delete m_ofp, m_ofp = NULL); // Open a new file m_ofp = newOutCFile(modp, !m_fast, true/*source*/, splitFilenumInc()); emitImp(modp); @@ -2834,7 +2834,7 @@ void EmitCImp::main(AstNodeModule* modp, bool slow, bool fast) { if (m_fast) { m_ofp = newOutCFile(modp, !m_fast, false/*source*/); emitInt(modp); - delete m_ofp; m_ofp = NULL; + VL_DO_CLEAR(delete m_ofp, m_ofp = NULL); } m_ofp = newOutCFile(modp, !m_fast, true/*source*/); @@ -2865,7 +2865,7 @@ void EmitCImp::main(AstNodeModule* modp, bool slow, bool fast) { } } } - delete m_ofp; m_ofp = NULL; + VL_DO_CLEAR(delete m_ofp, m_ofp = NULL); } //###################################################################### @@ -3192,7 +3192,7 @@ class EmitCTrace : EmitCStmts { if (splitNeeded()) { // Close old file - delete m_ofp; m_ofp = NULL; + VL_DO_CLEAR(delete m_ofp, m_ofp = NULL); // Open a new file newOutCFile(splitFilenumInc()); } @@ -3273,7 +3273,7 @@ public: iterate(v3Global.rootp()); - delete m_ofp; m_ofp = NULL; + VL_DO_CLEAR(delete m_ofp, m_ofp = NULL); } }; diff --git a/src/V3EmitCSyms.cpp b/src/V3EmitCSyms.cpp index 84e9c6937..f1d497a40 100644 --- a/src/V3EmitCSyms.cpp +++ b/src/V3EmitCSyms.cpp @@ -480,8 +480,7 @@ void EmitCSyms::closeSplit() { if (!m_ofp || m_ofp == m_ofpBase) return; puts("}\n"); - delete m_ofp; - m_ofp = NULL; + VL_DO_CLEAR(delete m_ofp, m_ofp = NULL); } void EmitCSyms::checkSplit(bool usesVfinal) { diff --git a/src/V3File.cpp b/src/V3File.cpp index 81776d2e0..5347268b3 100644 --- a/src/V3File.cpp +++ b/src/V3File.cpp @@ -594,7 +594,7 @@ protected: // Just dispatch to the implementation VInFilter::VInFilter(const string& command) { m_impp = new VInFilterImp(command); } -VInFilter::~VInFilter() { if (m_impp) delete m_impp; m_impp = NULL; } +VInFilter::~VInFilter() { if (m_impp) VL_DO_CLEAR(delete m_impp, m_impp = NULL); } bool VInFilter::readWholefile(const string& filename, VInFilter::StrList& outl) { if (!m_impp) v3fatalSrc("readWholefile on invalid filter"); diff --git a/src/V3GraphAlg.cpp b/src/V3GraphAlg.cpp index d663e7e4e..aad179fe0 100644 --- a/src/V3GraphAlg.cpp +++ b/src/V3GraphAlg.cpp @@ -150,9 +150,7 @@ public: V3GraphEdge* deletep = NULL; for (V3GraphEdge* edgep = vxp->outBeginp(); edgep; edgep = edgep->outNextp()) { - if (deletep) { - deletep->unlinkDelete(); deletep = NULL; - } + if (deletep) VL_DO_CLEAR(deletep->unlinkDelete(), deletep = NULL); // It should be safe to modify the graph, despite using // the GraphPathChecker, as none of the modifications will // change what can be reached from what, nor should they diff --git a/src/V3GraphDfa.cpp b/src/V3GraphDfa.cpp index a7615bb09..1716f8657 100644 --- a/src/V3GraphDfa.cpp +++ b/src/V3GraphDfa.cpp @@ -595,7 +595,7 @@ public: add_complement_edges(); if (debug()>=6) m_graphp->dumpDotFilePrefixed("comp_preswap"); - m_tempNewerReject->unlinkDelete(graphp()); m_tempNewerReject = NULL; + VL_DO_CLEAR(m_tempNewerReject->unlinkDelete(graphp()), m_tempNewerReject = NULL); if (debug()>=6) m_graphp->dumpDotFilePrefixed("comp_out"); } ~DfaGraphComplement() {} diff --git a/src/V3Life.cpp b/src/V3Life.cpp index f77ef95ea..e6ca72832 100644 --- a/src/V3Life.cpp +++ b/src/V3Life.cpp @@ -453,11 +453,11 @@ public: { m_lifep = new LifeBlock(NULL, m_statep); iterate(nodep); - if (m_lifep) { delete m_lifep; m_lifep = NULL; } + if (m_lifep) VL_DO_CLEAR(delete m_lifep, m_lifep = NULL); } } virtual ~LifeVisitor() { - if (m_lifep) { delete m_lifep; m_lifep = NULL; } + if (m_lifep) VL_DO_CLEAR(delete m_lifep, m_lifep = NULL); } VL_UNCOPYABLE(LifeVisitor); }; diff --git a/src/V3Options.cpp b/src/V3Options.cpp index 455050a66..e70be3663 100644 --- a/src/V3Options.cpp +++ b/src/V3Options.cpp @@ -1553,7 +1553,7 @@ V3Options::V3Options() { } V3Options::~V3Options() { - delete m_impp; m_impp = NULL; + VL_DO_CLEAR(delete m_impp, m_impp = NULL); } void V3Options::setDebugMode(int level) { diff --git a/src/V3ParseImp.cpp b/src/V3ParseImp.cpp index aa14ecf92..fb317a61c 100644 --- a/src/V3ParseImp.cpp +++ b/src/V3ParseImp.cpp @@ -57,11 +57,11 @@ extern void yyerrorf(const char* format, ...); V3ParseImp::~V3ParseImp() { for (std::deque::iterator it = m_stringps.begin(); it != m_stringps.end(); ++it) { - delete (*it); + VL_DO_DANGLING(delete *it, *it); } m_stringps.clear(); for (std::deque::iterator it = m_numberps.begin(); it != m_numberps.end(); ++it) { - delete (*it); + VL_DO_DANGLING(delete *it, *it); } m_numberps.clear(); lexDestroy(); @@ -297,7 +297,7 @@ V3Parse::V3Parse(AstNetlist* rootp, VInFilter* filterp, V3ParseSym* symp) { m_impp = new V3ParseImp(rootp, filterp, symp); } V3Parse::~V3Parse() { - delete m_impp; m_impp = NULL; + VL_DO_CLEAR(delete m_impp, m_impp = NULL); } void V3Parse::parseFile(FileLine* fileline, const string& modname, bool inLibrary, const string& errmsg) { diff --git a/src/V3ParseLex.cpp b/src/V3ParseLex.cpp index 896c785f1..019e87fdb 100644 --- a/src/V3ParseLex.cpp +++ b/src/V3ParseLex.cpp @@ -82,5 +82,5 @@ void V3ParseImp::lexNew() { } void V3ParseImp::lexDestroy() { - if (m_lexerp) { delete m_lexerp; m_lexerp = NULL; } + if (m_lexerp) VL_DO_CLEAR(delete m_lexerp, m_lexerp = NULL); } diff --git a/src/V3Partition.cpp b/src/V3Partition.cpp index 33a7f66f1..99a3615fb 100644 --- a/src/V3Partition.cpp +++ b/src/V3Partition.cpp @@ -1411,7 +1411,7 @@ private: // Remove and free the connecting edge. Must do this before // propagating CP's below. m_sb.removeElem(mergeCanp); - mergeEdgep->unlinkDelete(); mergeEdgep=NULL; + VL_DO_CLEAR(mergeEdgep->unlinkDelete(), mergeEdgep=NULL); } // This also updates cost and stepCost on recipientp @@ -1467,7 +1467,7 @@ private: partMergeEdgesFrom(m_mtasksp, recipientp, donorp, &m_sb); // Delete the donorp mtask from the graph - donorp->unlinkDelete(m_mtasksp); donorp = NULL; + VL_DO_CLEAR(donorp->unlinkDelete(m_mtasksp), donorp = NULL); m_mergesSinceRescore++; diff --git a/src/V3PreLex.h b/src/V3PreLex.h index 3a3abbe1a..3b7de5b61 100644 --- a/src/V3PreLex.h +++ b/src/V3PreLex.h @@ -189,7 +189,7 @@ class V3PreLex { } ~V3PreLex() { while (!m_streampStack.empty()) { delete m_streampStack.top(); m_streampStack.pop(); } - yy_delete_buffer(m_bufferState); m_bufferState = NULL; + VL_DO_CLEAR(yy_delete_buffer(m_bufferState), m_bufferState = NULL); } // Called by V3PreLex.l from lexer diff --git a/src/V3PreProc.cpp b/src/V3PreProc.cpp index fee13a6e8..51796dba2 100644 --- a/src/V3PreProc.cpp +++ b/src/V3PreProc.cpp @@ -285,7 +285,7 @@ public: m_lexp->debug(debug()>=5 ? debug() : 0); // See also V3PreProc::debug() method } ~V3PreProcImp() { - if (m_lexp) { delete m_lexp; m_lexp = NULL; } + if (m_lexp) VL_DO_CLEAR(delete m_lexp, m_lexp = NULL); } }; diff --git a/src/V3Subst.cpp b/src/V3Subst.cpp index bd721b890..9e283e6cd 100644 --- a/src/V3Subst.cpp +++ b/src/V3Subst.cpp @@ -164,12 +164,12 @@ public: void deleteUnusedAssign() { // If there are unused assignments in this var, kill them if (!m_whole.m_use && !m_wordUse && m_whole.m_assignp) { - deleteAssign(m_whole.m_assignp); m_whole.m_assignp = NULL; + VL_DO_CLEAR(deleteAssign(m_whole.m_assignp), m_whole.m_assignp = NULL); } for (unsigned i=0; iconvertToAlways(); - pushDeletep(m_assignwp); m_assignwp = NULL; + VL_DO_CLEAR(pushDeletep(m_assignwp), m_assignwp = NULL); } // We make multiple edges if a task is called multiple times from another task. UASSERT_OBJ(nodep->taskp(), nodep, "Unlinked task"); @@ -470,7 +470,8 @@ private: { AstBegin* tempp = new AstBegin(beginp->fileline(), "[EditWrapper]", beginp); TaskRelinkVisitor visit (tempp); - tempp->stmtsp()->unlinkFrBackWithNext(); VL_DO_DANGLING(tempp->deleteTree(), tempp); + tempp->stmtsp()->unlinkFrBackWithNext(); + VL_DO_DANGLING(tempp->deleteTree(), tempp); } // if (debug()>=9) { beginp->dumpTreeAndNext(cout, "-iotask: "); } @@ -488,8 +489,8 @@ private: string("Function: ")+refp->name(), true); AstCCall* ccallp = new AstCCall(refp->fileline(), cfuncp, NULL); beginp->addNext(ccallp); - // Convert complicated outputs to temp signals + // Convert complicated outputs to temp signals V3TaskConnects tconnects = V3Task::taskConnects(refp, refp->taskp()->stmtsp()); for (V3TaskConnects::iterator it=tconnects.begin(); it!=tconnects.end(); ++it) { AstVar* portp = it->first; @@ -520,7 +521,7 @@ private: // Correct lvalue; we didn't know when we linked // This is slightly scary; are we sure no decisions were made // before here based on this not being a lvalue? - // Doesn't seem so; V3Unknown uses it earlier, but works ok. + // Seems correct assumption; V3Unknown uses it earlier, but works ok. V3LinkLValue::linkLValueSet(pinp); // Even if it's referencing a varref, we still make a temporary @@ -1073,7 +1074,8 @@ private: { AstBegin* tempp = new AstBegin(cfuncp->fileline(), "[EditWrapper]", cfuncp); TaskRelinkVisitor visit (tempp); - tempp->stmtsp()->unlinkFrBackWithNext(); VL_DO_DANGLING(tempp->deleteTree(), tempp); + tempp->stmtsp()->unlinkFrBackWithNext(); + VL_DO_DANGLING(tempp->deleteTree(), tempp); } // Delete rest of cloned task and return new func VL_DO_DANGLING(pushDeletep(nodep), nodep); @@ -1410,7 +1412,8 @@ V3TaskConnects V3Task::taskConnects(AstNodeFTaskRef* nodep, AstNode* taskStmtsp) UINFO(9,"Default pin for "<fileline(), portp->name(), newvaluep); if (tconnects[i].second) { // Have a "NULL" pin already defined for it - tconnects[i].second->unlinkFrBack()->deleteTree(); tconnects[i].second = NULL; + VL_DO_CLEAR(tconnects[i].second->unlinkFrBack()->deleteTree(), + tconnects[i].second = NULL); } tconnects[i].second = newp; reorganize = true; diff --git a/src/V3TraceDecl.cpp b/src/V3TraceDecl.cpp index 78a416c9f..3b8ef8919 100644 --- a/src/V3TraceDecl.cpp +++ b/src/V3TraceDecl.cpp @@ -227,7 +227,7 @@ private: iterate(varp->dtypeSkipRefp()); } // Cleanup - if (m_traValuep) { m_traValuep->deleteTree(); m_traValuep = NULL; } + if (m_traValuep) VL_DO_CLEAR(m_traValuep->deleteTree(), m_traValuep = NULL); } m_traVscp = NULL; m_traValuep = NULL; @@ -272,7 +272,7 @@ private: i - nodep->lsb()); iterate(subtypep); - m_traValuep->deleteTree(); m_traValuep = NULL; + VL_DO_CLEAR(m_traValuep->deleteTree(), m_traValuep = NULL); } m_traShowname = oldShowname; m_traValuep = oldValuep; @@ -298,7 +298,7 @@ private: (i - nodep->lsb())*subtypep->width(), subtypep->width()); iterate(subtypep); - m_traValuep->deleteTree(); m_traValuep = NULL; + VL_DO_CLEAR(m_traValuep->deleteTree(), m_traValuep = NULL); } m_traShowname = oldShowname; m_traValuep = oldValuep; @@ -329,7 +329,7 @@ private: m_traValuep->cloneTree(true), itemp->lsb(), subtypep->width()); iterate(subtypep); - m_traValuep->deleteTree(); m_traValuep = NULL; + VL_DO_CLEAR(m_traValuep->deleteTree(), m_traValuep = NULL); } else { // Else union, replicate fields iterate(subtypep); } diff --git a/src/V3Unknown.cpp b/src/V3Unknown.cpp index 6e6fccf2a..34d6cb2a7 100644 --- a/src/V3Unknown.cpp +++ b/src/V3Unknown.cpp @@ -86,7 +86,8 @@ private: // Wire assigns must become always statements to deal with insertion // of multiple statements. Perhaps someday make all wassigns into always's? UINFO(5," IM_WireRep "<convertToAlways(); pushDeletep(m_assignwp); m_assignwp = NULL; + m_assignwp->convertToAlways(); + VL_DO_CLEAR(pushDeletep(m_assignwp), m_assignwp = NULL); } bool needDly = (m_assigndlyp != NULL); if (m_assigndlyp) { @@ -95,7 +96,8 @@ private: AstNode* newp = new AstAssign(m_assigndlyp->fileline(), m_assigndlyp->lhsp()->unlinkFrBackWithNext(), m_assigndlyp->rhsp()->unlinkFrBackWithNext()); - m_assigndlyp->replaceWith(newp); pushDeletep(m_assigndlyp); m_assigndlyp = NULL; + m_assigndlyp->replaceWith(newp); + VL_DO_CLEAR(pushDeletep(m_assigndlyp), m_assigndlyp = NULL); } AstNode* prep = nodep; diff --git a/src/V3Unroll.cpp b/src/V3Unroll.cpp index 98cc2d35f..44e6ace30 100644 --- a/src/V3Unroll.cpp +++ b/src/V3Unroll.cpp @@ -184,7 +184,7 @@ private: SimulateVisitor simvis; AstNode* clonep = nodep->cloneTree(true); simvis.mainCheckTree(clonep); - pushDeletep(clonep); clonep = NULL; + VL_DO_CLEAR(pushDeletep(clonep), clonep = NULL); return simvis.optimizable(); } @@ -202,7 +202,7 @@ private: clonep = tempp->stmtsp()->unlinkFrBackWithNext(); tempp->deleteTree(); tempp = NULL; - pushDeletep(m_varValuep); m_varValuep = NULL; + VL_DO_CLEAR(pushDeletep(m_varValuep), m_varValuep = NULL); } SimulateVisitor simvis; simvis.mainParamEmulate(clonep); @@ -329,7 +329,7 @@ private: string nname = m_beginName + "__BRA__" + index + "__KET__"; oneloopp = new AstBegin(oneloopp->fileline(), nname, oneloopp, true); } - pushDeletep(m_varValuep); m_varValuep = NULL; + VL_DO_CLEAR(pushDeletep(m_varValuep), m_varValuep = NULL); if (newbodysp) newbodysp->addNext(oneloopp); else newbodysp = oneloopp; diff --git a/src/Verilator.cpp b/src/Verilator.cpp index b3ce68a12..80c3e7a2d 100644 --- a/src/Verilator.cpp +++ b/src/Verilator.cpp @@ -112,7 +112,7 @@ AstNetlist* V3Global::makeNetlist() { void V3Global::checkTree() { rootp()->checkTree(); } void V3Global::clear() { - if (m_rootp) { m_rootp->deleteTree(); m_rootp = NULL; } + if (m_rootp) VL_DO_CLEAR(m_rootp->deleteTree(), m_rootp = NULL); } void V3Global::readFiles() { diff --git a/src/VlcTest.h b/src/VlcTest.h index da20ad29e..3411f97e6 100644 --- a/src/VlcTest.h +++ b/src/VlcTest.h @@ -110,7 +110,7 @@ public: VlcTests() {} ~VlcTests() { for (VlcTests::ByName::iterator it=begin(); it!=end(); ++it) { - delete *it; *it=NULL; + VL_DO_CLEAR(delete *it, *it=NULL); } } diff --git a/src/verilog.y b/src/verilog.y index e0c0a6296..e502e49e4 100644 --- a/src/verilog.y +++ b/src/verilog.y @@ -123,7 +123,7 @@ public: } void setVarDecl(AstVarType type) { m_varDecl = type; } void setDType(AstNodeDType* dtypep) { - if (m_varDTypep) { m_varDTypep->deleteTree(); m_varDTypep=NULL; } // It was cloned, so this is safe. + if (m_varDTypep) VL_DO_CLEAR(m_varDTypep->deleteTree(), m_varDTypep=NULL); // It was cloned, so this is safe. m_varDTypep = dtypep; } AstPackage* unitPackage(FileLine* fl) { @@ -2362,7 +2362,10 @@ etcInst: // IEEE: module_instantiation + gate_instantiation + udp_insta instDecl: id parameter_value_assignmentE {INSTPREP($1,*$1,$2);} instnameList ';' { $$ = $4; GRAMMARP->m_impliedDecl=false; - if (GRAMMARP->m_instParamp) { GRAMMARP->m_instParamp->deleteTree(); GRAMMARP->m_instParamp = NULL; } } + if (GRAMMARP->m_instParamp) { + VL_DO_CLEAR(GRAMMARP->m_instParamp->deleteTree(), + GRAMMARP->m_instParamp = NULL); + } } // // IEEE: interface_identifier' .' modport_identifier list_of_interface_identifiers | id/*interface*/ '.' id/*modport*/ { VARRESET_NONLIST(AstVarType::IFACEREF); From 835f668aaa2dcb36c14646f36f8bcb7e3c4d0847 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Sat, 18 Jan 2020 13:02:42 -0500 Subject: [PATCH 12/13] Internals: Refactor statement tracking. No functional change intended. --- src/V3Ast.h | 17 ++++++++++------- src/V3AstNodes.h | 23 ++++++++++++----------- 2 files changed, 22 insertions(+), 18 deletions(-) diff --git a/src/V3Ast.h b/src/V3Ast.h index d500b3fd7..8145a5213 100644 --- a/src/V3Ast.h +++ b/src/V3Ast.h @@ -1723,12 +1723,15 @@ public: class AstNodeStmt : public AstNode { // Statement -- anything that's directly under a function + bool m_statement; // Really a statement (e.g. not a function with return) public: - explicit AstNodeStmt(FileLine* fl) - : AstNode(fl) {} + explicit AstNodeStmt(FileLine* fl, bool statement = true) + : AstNode(fl) + , m_statement(statement) {} ASTNODE_BASE_FUNCS(NodeStmt) // METHODS - virtual bool isStatement() const { return true; } // Really a statement + bool isStatement() const { return m_statement; } // Really a statement + void statement(bool flag) { m_statement = flag; } virtual void addNextStmt(AstNode* newp, AstNode* belowp); // Stop statement searchback here virtual void addBeforeStmt(AstNode* newp, AstNode* belowp); // Stop statement searchback here }; @@ -2170,13 +2173,13 @@ private: string m_inlinedDots; // Dotted hierarchy flattened out AstPackage* m_packagep; // Package hierarchy public: - AstNodeFTaskRef(FileLine* fl, AstNode* namep, AstNode* pinsp) - : AstNodeStmt(fl) + AstNodeFTaskRef(FileLine* fl, bool statement, AstNode* namep, AstNode* pinsp) + : AstNodeStmt(fl, statement) , m_taskp(NULL), m_packagep(NULL) { setOp1p(namep); addNOp2p(pinsp); } - AstNodeFTaskRef(FileLine* fl, const string& name, AstNode* pinsp) - : AstNodeStmt(fl) + AstNodeFTaskRef(FileLine* fl, bool statement, const string& name, AstNode* pinsp) + : AstNodeStmt(fl, statement) , m_taskp(NULL), m_name(name), m_packagep(NULL) { addNOp2p(pinsp); } diff --git a/src/V3AstNodes.h b/src/V3AstNodes.h index b60e4b383..a4ee6680f 100644 --- a/src/V3AstNodes.h +++ b/src/V3AstNodes.h @@ -1373,17 +1373,19 @@ class AstCMethodCall : public AstNodeStmt { private: string m_name; // Name of method bool m_pure; // Pure optimizable - bool m_statement; // Is a statement (AstNodeMath-like) versus AstNodeStmt-like public: AstCMethodCall(FileLine* fl, AstNode* fromp, VFlagChildDType, const string& name, AstNode* pinsp) - : AstNodeStmt(fl), m_name(name), m_pure(false), m_statement(false) { + : AstNodeStmt(fl, false) + , m_name(name) + , m_pure(false) { setOp1p(fromp); dtypep(NULL); // V3Width will resolve addNOp2p(pinsp); } AstCMethodCall(FileLine* fl, AstNode* fromp, const string& name, AstNode* pinsp) - : AstNodeStmt(fl), m_name(name), m_statement(false) { + : AstNodeStmt(fl, false) + , m_name(name) { setOp1p(fromp); addNOp2p(pinsp); } @@ -1395,10 +1397,9 @@ public: virtual bool same(const AstNode* samep) const { const AstCMethodCall* asamep = static_cast(samep); return (m_name == asamep->m_name); } - virtual bool isStatement() const { return m_statement; } virtual bool isPure() const { return m_pure; } void pure(bool flag) { m_pure = flag; } - void makeStatement() { m_statement = true; dtypeSetVoid(); } + void makeStatement() { statement(true); dtypeSetVoid(); } AstNode* fromp() const { return op1p(); } // op1 = Extracting what (NULL=TBD during parsing) void fromp(AstNode* nodep) { setOp1p(nodep); } AstNode* pinsp() const { return op2p(); } // op2 = Pin interconnection list @@ -2431,22 +2432,22 @@ class AstTaskRef : public AstNodeFTaskRef { // A reference to a task public: AstTaskRef(FileLine* fl, AstParseRef* namep, AstNode* pinsp) - : AstNodeFTaskRef(fl, namep, pinsp) {} + : AstNodeFTaskRef(fl, true, namep, pinsp) { + statement(true); + } AstTaskRef(FileLine* fl, const string& name, AstNode* pinsp) - : AstNodeFTaskRef(fl, name, pinsp) {} + : AstNodeFTaskRef(fl, true, name, pinsp) {} ASTNODE_NODE_FUNCS(TaskRef) - virtual bool isStatement() const { return true; } // A statement, unlike FuncRef }; class AstFuncRef : public AstNodeFTaskRef { // A reference to a function public: AstFuncRef(FileLine* fl, AstParseRef* namep, AstNode* pinsp) - : AstNodeFTaskRef(fl, namep, pinsp) {} + : AstNodeFTaskRef(fl, false, namep, pinsp) {} AstFuncRef(FileLine* fl, const string& name, AstNode* pinsp) - : AstNodeFTaskRef(fl, name, pinsp) {} + : AstNodeFTaskRef(fl, false, name, pinsp) {} ASTNODE_NODE_FUNCS(FuncRef) - virtual bool isStatement() const { return false; } // Not a statement, unlike TaskRef virtual bool hasDType() const { return true; } }; From 18e837336a3a0d1efcfded81b7c6776306d692aa Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Sat, 18 Jan 2020 14:11:05 -0500 Subject: [PATCH 13/13] Internals: Rename MethodCall. No functional change. --- src/V3AstNodes.h | 10 +++++----- src/V3Clean.cpp | 2 +- src/V3EmitC.cpp | 4 ++-- src/V3Width.cpp | 40 ++++++++++++++++++++-------------------- src/V3WidthSel.cpp | 2 +- 5 files changed, 29 insertions(+), 29 deletions(-) diff --git a/src/V3AstNodes.h b/src/V3AstNodes.h index a4ee6680f..865014825 100644 --- a/src/V3AstNodes.h +++ b/src/V3AstNodes.h @@ -1366,7 +1366,7 @@ public: void addPinsp(AstNode* nodep) { addOp2p(nodep); } }; -class AstCMethodCall : public AstNodeStmt { +class AstCMethodHard : public AstNodeStmt { // A reference to a "C" hardocded member task (or function) // PARENTS: stmt/math // Not all calls are statments vs math. AstNodeStmt needs isStatement() to deal. @@ -1374,7 +1374,7 @@ private: string m_name; // Name of method bool m_pure; // Pure optimizable public: - AstCMethodCall(FileLine* fl, AstNode* fromp, VFlagChildDType, const string& name, + AstCMethodHard(FileLine* fl, AstNode* fromp, VFlagChildDType, const string& name, AstNode* pinsp) : AstNodeStmt(fl, false) , m_name(name) @@ -1383,19 +1383,19 @@ public: dtypep(NULL); // V3Width will resolve addNOp2p(pinsp); } - AstCMethodCall(FileLine* fl, AstNode* fromp, const string& name, AstNode* pinsp) + AstCMethodHard(FileLine* fl, AstNode* fromp, const string& name, AstNode* pinsp) : AstNodeStmt(fl, false) , m_name(name) { setOp1p(fromp); addNOp2p(pinsp); } - ASTNODE_NODE_FUNCS(CMethodCall) + ASTNODE_NODE_FUNCS(CMethodHard) virtual string name() const { return m_name; } // * = Var name virtual bool hasDType() const { return true; } virtual void name(const string& name) { m_name = name; } virtual V3Hash sameHash() const { return V3Hash(m_name); } virtual bool same(const AstNode* samep) const { - const AstCMethodCall* asamep = static_cast(samep); + const AstCMethodHard* asamep = static_cast(samep); return (m_name == asamep->m_name); } virtual bool isPure() const { return m_pure; } void pure(bool flag) { m_pure = flag; } diff --git a/src/V3Clean.cpp b/src/V3Clean.cpp index 27a7227c8..e59c909d7 100644 --- a/src/V3Clean.cpp +++ b/src/V3Clean.cpp @@ -282,7 +282,7 @@ private: insureCleanAndNext(nodep->argsp()); setClean(nodep, true); } - virtual void visit(AstCMethodCall* nodep) { + virtual void visit(AstCMethodHard* nodep) { iterateChildren(nodep); insureCleanAndNext(nodep->pinsp()); setClean(nodep, true); diff --git a/src/V3EmitC.cpp b/src/V3EmitC.cpp index 9ba7c39ec..fbf661d19 100644 --- a/src/V3EmitC.cpp +++ b/src/V3EmitC.cpp @@ -192,7 +192,7 @@ public: } else if (nodep->isWide() && VN_IS(nodep->lhsp(), VarRef) && !VN_IS(nodep->rhsp(), CMath) - && !VN_IS(nodep->rhsp(), CMethodCall) + && !VN_IS(nodep->rhsp(), CMethodHard) && !VN_IS(nodep->rhsp(), VarRef) && !VN_IS(nodep->rhsp(), AssocSel) && !VN_IS(nodep->rhsp(), ArraySel)) { @@ -257,7 +257,7 @@ public: puts(");\n"); } } - virtual void visit(AstCMethodCall* nodep) { + virtual void visit(AstCMethodHard* nodep) { iterate(nodep->fromp()); puts("."); puts(nodep->nameProtect()); diff --git a/src/V3Width.cpp b/src/V3Width.cpp index e8debc3ba..bc325c313 100644 --- a/src/V3Width.cpp +++ b/src/V3Width.cpp @@ -1081,7 +1081,7 @@ private: if (VN_IS(nodep->fromp()->dtypep(), QueueDType)) { switch (nodep->attrType()) { case AstAttrType::DIM_SIZE: { - AstNode* newp = new AstCMethodCall( + AstNode* newp = new AstCMethodHard( nodep->fileline(), nodep->fromp()->unlinkFrBack(), "size", NULL); newp->dtypeSetSigned32(); newp->didWidth(true); @@ -1097,7 +1097,7 @@ private: } case AstAttrType::DIM_RIGHT: case AstAttrType::DIM_HIGH: { - AstNode* sizep = new AstCMethodCall( + AstNode* sizep = new AstCMethodHard( nodep->fileline(), nodep->fromp()->unlinkFrBack(), "size", NULL); sizep->dtypeSetSigned32(); sizep->didWidth(true); @@ -1788,7 +1788,7 @@ private: return false; } - virtual void visit(AstCMethodCall* nodep) { + virtual void visit(AstCMethodHard* nodep) { // Never created before V3Width, so no need to redo it UASSERT_OBJ(nodep->dtypep(), nodep, "CMETHODCALLs should have already been sized"); } @@ -1936,11 +1936,11 @@ private: } } void methodCallAssoc(AstMethodCall* nodep, AstAssocArrayDType* adtypep) { - AstCMethodCall* newp = NULL; + AstCMethodHard* newp = NULL; if (nodep->name() == "num" // function int num() || nodep->name() == "size") { methodOkArguments(nodep, 0, 0); - newp = new AstCMethodCall(nodep->fileline(), + newp = new AstCMethodHard(nodep->fileline(), nodep->fromp()->unlinkFrBack(), "size", NULL); // So don't need num() newp->dtypeSetSigned32(); @@ -1952,7 +1952,7 @@ private: || nodep->name() == "prev") { methodOkArguments(nodep, 1, 1); AstNode* index_exprp = methodCallAssocIndexExpr(nodep, adtypep); - newp = new AstCMethodCall(nodep->fileline(), + newp = new AstCMethodHard(nodep->fileline(), nodep->fromp()->unlinkFrBack(), nodep->name(), // first/last/next/prev index_exprp->unlinkFrBack()); @@ -1963,7 +1963,7 @@ private: // IEEE really should have made this a "bit" return methodOkArguments(nodep, 1, 1); AstNode* index_exprp = methodCallAssocIndexExpr(nodep, adtypep); - newp = new AstCMethodCall(nodep->fileline(), + newp = new AstCMethodHard(nodep->fileline(), nodep->fromp()->unlinkFrBack(), "exists", index_exprp->unlinkFrBack()); newp->dtypeSetSigned32(); @@ -1974,14 +1974,14 @@ private: methodOkArguments(nodep, 0, 1); methodCallLValue(nodep, nodep->fromp(), true); if (!nodep->pinsp()) { - newp = new AstCMethodCall(nodep->fileline(), + newp = new AstCMethodHard(nodep->fileline(), nodep->fromp()->unlinkFrBack(), "clear", NULL); newp->protect(false); newp->makeStatement(); } else { AstNode* index_exprp = methodCallAssocIndexExpr(nodep, adtypep); - newp = new AstCMethodCall(nodep->fileline(), + newp = new AstCMethodHard(nodep->fileline(), nodep->fromp()->unlinkFrBack(), "erase", index_exprp->unlinkFrBack()); @@ -2013,11 +2013,11 @@ private: } } void methodCallQueue(AstMethodCall* nodep, AstQueueDType* adtypep) { - AstCMethodCall* newp = NULL; + AstCMethodHard* newp = NULL; if (nodep->name() == "at") { // Created internally for [] methodOkArguments(nodep, 1, 1); methodCallLValue(nodep, nodep->fromp(), true); - newp = new AstCMethodCall(nodep->fileline(), + newp = new AstCMethodHard(nodep->fileline(), nodep->fromp()->unlinkFrBack(), "at", NULL); newp->dtypeFrom(adtypep->subDTypep()); @@ -2026,7 +2026,7 @@ private: } else if (nodep->name() == "num" // function int num() || nodep->name() == "size") { methodOkArguments(nodep, 0, 0); - newp = new AstCMethodCall(nodep->fileline(), + newp = new AstCMethodHard(nodep->fileline(), nodep->fromp()->unlinkFrBack(), "size", NULL); newp->dtypeSetSigned32(); @@ -2036,7 +2036,7 @@ private: methodOkArguments(nodep, 0, 1); methodCallLValue(nodep, nodep->fromp(), true); if (!nodep->pinsp()) { - newp = new AstCMethodCall(nodep->fileline(), + newp = new AstCMethodHard(nodep->fileline(), nodep->fromp()->unlinkFrBack(), "clear", NULL); newp->protect(false); @@ -2044,7 +2044,7 @@ private: } else { AstNode* index_exprp = methodCallQueueIndexExpr(nodep); if (index_exprp->isZero()) { // delete(0) is a pop_front - newp = new AstCMethodCall(nodep->fileline(), + newp = new AstCMethodHard(nodep->fileline(), nodep->fromp()->unlinkFrBack(), "pop_front", NULL); newp->dtypeFrom(adtypep->subDTypep()); @@ -2053,7 +2053,7 @@ private: newp->makeStatement(); } else { nodep->v3error("Unsupported: Queue .delete(index) method, as is O(n) complexity and slow."); - newp = new AstCMethodCall(nodep->fileline(), + newp = new AstCMethodHard(nodep->fileline(), nodep->fromp()->unlinkFrBack(), "erase", index_exprp->unlinkFrBack()); newp->protect(false); @@ -2067,14 +2067,14 @@ private: AstArg* argp = VN_CAST(nodep->pinsp()->nextp(), Arg); iterateCheckTyped(nodep, "insert value", argp->exprp(), adtypep->subDTypep(), BOTH); if (index_exprp->isZero()) { // insert(0, ...) is a push_front - newp = new AstCMethodCall(nodep->fileline(), + newp = new AstCMethodHard(nodep->fileline(), nodep->fromp()->unlinkFrBack(), "push_front", argp->exprp()->unlinkFrBack()); newp->protect(false); newp->makeStatement(); } else { nodep->v3error("Unsupported: Queue .insert method, as is O(n) complexity and slow."); - newp = new AstCMethodCall(nodep->fileline(), + newp = new AstCMethodHard(nodep->fileline(), nodep->fromp()->unlinkFrBack(), nodep->name(), index_exprp->unlinkFrBack()); @@ -2086,7 +2086,7 @@ private: || nodep->name() == "pop_back") { methodOkArguments(nodep, 0, 0); methodCallLValue(nodep, nodep->fromp(), true); - newp = new AstCMethodCall(nodep->fileline(), + newp = new AstCMethodHard(nodep->fileline(), nodep->fromp()->unlinkFrBack(), nodep->name(), NULL); newp->dtypeFrom(adtypep->subDTypep()); @@ -2101,7 +2101,7 @@ private: methodCallLValue(nodep, nodep->fromp(), true); AstArg* argp = VN_CAST(nodep->pinsp(), Arg); iterateCheckTyped(nodep, "push value", argp->exprp(), adtypep->subDTypep(), BOTH); - newp = new AstCMethodCall(nodep->fileline(), + newp = new AstCMethodHard(nodep->fileline(), nodep->fromp()->unlinkFrBack(), nodep->name(), argp->exprp()->unlinkFrBack()); newp->protect(false); @@ -2737,7 +2737,7 @@ private: newFormat += "%@"; AstNRelinker handle; argp->unlinkFrBack(&handle); - AstCMethodCall* newp = new AstCMethodCall( + AstCMethodHard* newp = new AstCMethodHard( nodep->fileline(), argp, "to_string", NULL); newp->dtypeSetString(); newp->pure(true); diff --git a/src/V3WidthSel.cpp b/src/V3WidthSel.cpp index f0ac952c6..7610d550a 100644 --- a/src/V3WidthSel.cpp +++ b/src/V3WidthSel.cpp @@ -262,7 +262,7 @@ private: else if (AstQueueDType* adtypep = VN_CAST(ddtypep, QueueDType)) { // SELBIT(array, index) -> CMETHODCALL(queue, "at", index) AstNode* subp = rhsp; - AstCMethodCall* newp = new AstCMethodCall(nodep->fileline(), + AstCMethodHard* newp = new AstCMethodHard(nodep->fileline(), fromp, "at", subp); newp->dtypeFrom(adtypep->subDTypep()); // Need to strip off queue reference if (debug()>=9) newp->dumpTree(cout, "--SELBTq: ");