From 1b439703ffc16e50ef63d1bc3110b27579c541f4 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Wed, 30 May 2012 23:17:55 -0400 Subject: [PATCH] Fix leak issues, bug521 --- src/V3Broken.cpp | 6 +++--- src/V3Const.cpp | 2 +- src/V3Tristate.cpp | 2 ++ src/V3Unroll.cpp | 1 + src/V3Width.cpp | 4 +++- src/V3WidthSel.cpp | 6 +++++- src/verilog.y | 42 ++++++++++++++++++++++-------------------- 7 files changed, 37 insertions(+), 26 deletions(-) diff --git a/src/V3Broken.cpp b/src/V3Broken.cpp index cc0c37f5f..db0f046ff 100644 --- a/src/V3Broken.cpp +++ b/src/V3Broken.cpp @@ -56,7 +56,7 @@ public: // METHODS static void deleted(const AstNode* nodep) { // Called by operator delete on any node - only if VL_LEAK_CHECKS - if (debug()) cout<<"-nodeDel: "<<(void*)(nodep)<=9) cout<<"-nodeDel: "<<(void*)(nodep)<second & FLAG_ALLOCATED)) { ((AstNode*)(nodep))->v3fatalSrc("Deleting AstNode object that was never tracked or already deleted\n"); @@ -65,7 +65,7 @@ public: } static void addNewed(const AstNode* nodep) { // Called by operator new on any node - only if VL_LEAK_CHECKS - if (debug()) cout<<"-nodeNew: "<<(void*)(nodep)<=9) cout<<"-nodeNew: "<<(void*)(nodep)<second & FLAG_ALLOCATED)) { ((AstNode*)(nodep))->v3fatalSrc("Newing AstNode object that is already allocated\n"); @@ -146,7 +146,7 @@ public: && (it->first->backp() ? backs==1 : backs==0)) { // Use only AstNode::dump instead of the virtual one, as there // may be varp() and other cross links that are bad. - if (debug()) { + if (v3Global.opt.debugCheck()) { cerr<<"%Error: LeakedNode"<<(it->first->backp()?"Back: ":": "); ((AstNode*)(it->first))->AstNode::dump(cerr); cerr<lhsp()->unlinkFrBack(); // fromp->lhsp(new AstSel(nodep->fileline(), - bilhsp, lsbp->cloneTree(true), widthp->cloneTree(true))); + bilhsp, lsbp, widthp)); fromp->dtypeFrom(nodep); nodep->replaceWith(fromp); nodep->deleteTree(); nodep=NULL; } diff --git a/src/V3Tristate.cpp b/src/V3Tristate.cpp index 212fab52a..0aa17b64d 100644 --- a/src/V3Tristate.cpp +++ b/src/V3Tristate.cpp @@ -609,6 +609,8 @@ class TristateVisitor : public TristateBaseVisitor { undrivenp = new AstAnd(nodep->fileline(), undrivenp, new AstConst(nodep->fileline(), pull)); orp = new AstOr(nodep->fileline(), orp, undrivenp); + } else { + undrivenp->deleteTree(); undrivenp=NULL; } if (envarp) { nodep->addStmtp(new AstAssignW(enp->fileline(), diff --git a/src/V3Unroll.cpp b/src/V3Unroll.cpp index eae50b9e2..84c9b6c5a 100644 --- a/src/V3Unroll.cpp +++ b/src/V3Unroll.cpp @@ -310,6 +310,7 @@ private: if (bodysp) { pushDeletep(bodysp); bodysp=NULL; } if (precondsp) { pushDeletep(precondsp); precondsp=NULL; } if (initp) { pushDeletep(initp); initp=NULL; } + if (incp && !incp->backp()) { pushDeletep(incp); incp=NULL; } if (debug()>=9) newbodysp->dumpTree(cout,"- _new: "); } diff --git a/src/V3Width.cpp b/src/V3Width.cpp index 18a8abc4c..f60334968 100644 --- a/src/V3Width.cpp +++ b/src/V3Width.cpp @@ -1301,6 +1301,7 @@ private: string format; if (pinp->castConst()) format = pinp->castConst()->num().toString(); else pinp->v3error("Format to $display-like function must have constant format string"); + pushDeletep(pinp); pinp=NULL; AstSFormatF* newp = new AstSFormatF(nodep->fileline(), format, false, argsp); if (!newp->scopeNamep() && newp->formatScopeTracking()) { newp->scopeNamep(new AstScopeName(newp->fileline())); @@ -1749,7 +1750,7 @@ private: num.isSigned(expDTypep->isSigned()); AstNode* newp = new AstConst(nodep->fileline(), num); constp->replaceWith(newp); - pushDeletep(constp); constp=NULL; + pushDeletep(constp); constp=NULL; nodep=NULL; nodep=newp; } else if (expWidthwidth()) { // Trunc - Extract @@ -1787,6 +1788,7 @@ private: num.isSigned(expSigned); AstNode* newp = new AstConst(nodep->fileline(), num); constp->replaceWith(newp); + constp->deleteTree(); constp=NULL; nodep=NULL; nodep=newp; } else { AstNRelinker linker; diff --git a/src/V3WidthSel.cpp b/src/V3WidthSel.cpp index 564bf8499..f4a2d3716 100644 --- a/src/V3WidthSel.cpp +++ b/src/V3WidthSel.cpp @@ -235,6 +235,7 @@ private: // How to recover? We'll strip a dimension. nodep->replaceWith(fromp); pushDeletep(nodep); nodep=NULL; } + if (!bitp->backp()) pushDeletep(bitp); bitp=NULL; } virtual void visit(AstSelExtract* nodep, AstNUser*) { @@ -285,13 +286,16 @@ private: UINFO(6," new "<=9) newp->dumpTree(cout,"--SLEXnew: "); nodep->replaceWith(newp); pushDeletep(nodep); nodep=NULL; - pushDeletep(msbp); msbp=NULL; } else { // NULL=bad extract, or unknown node type nodep->v3error("Illegal range select; variable already selected, or bad dimension"); // How to recover? We'll strip a dimension. nodep->replaceWith(fromp); pushDeletep(nodep); nodep=NULL; } + // delete whataver we didn't use in reconstruction + if (!fromp->backp()) pushDeletep(fromp); fromp=NULL; + if (!msbp->backp()) pushDeletep(msbp); msbp=NULL; + if (!lsbp->backp()) pushDeletep(lsbp); lsbp=NULL; } void replaceSelPlusMinus(AstNodePreSel* nodep) { diff --git a/src/verilog.y b/src/verilog.y index a3ef77e66..1571c53b1 100644 --- a/src/verilog.y +++ b/src/verilog.y @@ -178,6 +178,8 @@ const AstBasicDTypeKwd LOGIC_IMPLICIT = AstBasicDTypeKwd::LOGIC_IMPLICIT; #define INSTPREP(modname,paramsp) { GRAMMARP->m_impliedDecl = true; GRAMMARP->m_instModule = modname; GRAMMARP->m_instParamp = paramsp; } +#define DEL(nodep) { if (nodep) nodep->deleteTree(); } + static void ERRSVKWD(FileLine* fileline, const string& tokname) { static int toldonce = 0; fileline->v3error((string)"Unexpected \""+tokname+"\": \""+tokname+"\" is a SystemVerilog keyword misused as an identifier."); @@ -1586,7 +1588,7 @@ delay_value: // ==IEEE:delay_value ; delayExpr: - expr { } + expr { DEL($1); } // // Verilator doesn't support yaTIMENUM, so not in expr | yaTIMENUM { } ; @@ -2165,9 +2167,9 @@ system_t_call: // IEEE: system_tf_call (as task) | yD_FFLUSH parenE { $1->v3error("Unsupported: $fflush of all handles does not map to C++."); } | yD_FFLUSH '(' idClassSel ')' { $$ = new AstFFlush($1, $3); } | yD_FINISH parenE { $$ = new AstFinish($1); } - | yD_FINISH '(' expr ')' { $$ = new AstFinish($1); } + | yD_FINISH '(' expr ')' { $$ = new AstFinish($1); DEL($3); } | yD_STOP parenE { $$ = new AstStop($1); } - | yD_STOP '(' expr ')' { $$ = new AstStop($1); } + | yD_STOP '(' expr ')' { $$ = new AstStop($1); DEL($3); } // | yD_SFORMAT '(' expr ',' str commaEListE ')' { $$ = new AstSFormat($1,$3,*$5,$6); } | yD_SWRITE '(' expr ',' str commaEListE ')' { $$ = new AstSFormat($1,$3,*$5,$6); } @@ -2187,8 +2189,8 @@ system_t_call: // IEEE: system_tf_call (as task) | yD_ERROR parenE { $$ = GRAMMARP->createDisplayError($1); } | yD_ERROR '(' str commaEListE ')' { $$ = new AstDisplay($1,AstDisplayType::DT_ERROR, *$3,NULL,$4); $$->addNext(new AstStop($1)); } | yD_FATAL parenE { $$ = new AstDisplay($1,AstDisplayType::DT_FATAL, "", NULL,NULL); $$->addNext(new AstStop($1)); } - | yD_FATAL '(' expr ')' { $$ = new AstDisplay($1,AstDisplayType::DT_FATAL, "", NULL,NULL); $$->addNext(new AstStop($1)); if ($3) $3->deleteTree(); } - | yD_FATAL '(' expr ',' str commaEListE ')' { $$ = new AstDisplay($1,AstDisplayType::DT_FATAL, *$5,NULL,$6); $$->addNext(new AstStop($1)); if ($3) $3->deleteTree(); } + | yD_FATAL '(' expr ')' { $$ = new AstDisplay($1,AstDisplayType::DT_FATAL, "", NULL,NULL); $$->addNext(new AstStop($1)); DEL($3); } + | yD_FATAL '(' expr ',' str commaEListE ')' { $$ = new AstDisplay($1,AstDisplayType::DT_FATAL, *$5,NULL,$6); $$->addNext(new AstStop($1)); DEL($3); } // | yD_READMEMB '(' expr ',' varRefMem ')' { $$ = new AstReadMem($1,false,$3,$5,NULL,NULL); } | yD_READMEMB '(' expr ',' varRefMem ',' expr ')' { $$ = new AstReadMem($1,false,$3,$5,$7,NULL); } @@ -2792,60 +2794,60 @@ gateUnsupList: gateBuf: gateIdE instRangeE '(' variable_lvalue ',' expr ')' - { $$ = new AstAssignW ($3,$4,$6); } + { $$ = new AstAssignW ($3,$4,$6); DEL($2); } ; gateBufif0: gateIdE instRangeE '(' variable_lvalue ',' expr ',' expr ')' - { $$ = new AstAssignW ($3,$4,new AstBufIf1($3,new AstNot($3,$8),$6)); } + { $$ = new AstAssignW ($3,$4,new AstBufIf1($3,new AstNot($3,$8),$6)); DEL($2); } ; gateBufif1: gateIdE instRangeE '(' variable_lvalue ',' expr ',' expr ')' - { $$ = new AstAssignW ($3,$4,new AstBufIf1($3,$8,$6)); } + { $$ = new AstAssignW ($3,$4,new AstBufIf1($3,$8,$6)); DEL($2); } ; gateNot: gateIdE instRangeE '(' variable_lvalue ',' expr ')' - { $$ = new AstAssignW ($3,$4,new AstNot($5,$6)); } + { $$ = new AstAssignW ($3,$4,new AstNot($5,$6)); DEL($2); } ; gateNotif0: gateIdE instRangeE '(' variable_lvalue ',' expr ',' expr ')' - { $$ = new AstAssignW ($3,$4,new AstBufIf1($3,new AstNot($3,$8), new AstNot($3, $6))); } + { $$ = new AstAssignW ($3,$4,new AstBufIf1($3,new AstNot($3,$8), new AstNot($3, $6))); DEL($2); } ; gateNotif1: gateIdE instRangeE '(' variable_lvalue ',' expr ',' expr ')' - { $$ = new AstAssignW ($3,$4,new AstBufIf1($3,$8, new AstNot($3,$6))); } + { $$ = new AstAssignW ($3,$4,new AstBufIf1($3,$8, new AstNot($3,$6))); DEL($2); } ; gateAnd: gateIdE instRangeE '(' variable_lvalue ',' gateAndPinList ')' - { $$ = new AstAssignW ($3,$4,$6); } + { $$ = new AstAssignW ($3,$4,$6); DEL($2); } ; gateNand: gateIdE instRangeE '(' variable_lvalue ',' gateAndPinList ')' - { $$ = new AstAssignW ($3,$4,new AstNot($5,$6)); } + { $$ = new AstAssignW ($3,$4,new AstNot($5,$6)); DEL($2); } ; gateOr: gateIdE instRangeE '(' variable_lvalue ',' gateOrPinList ')' - { $$ = new AstAssignW ($3,$4,$6); } + { $$ = new AstAssignW ($3,$4,$6); DEL($2); } ; gateNor: gateIdE instRangeE '(' variable_lvalue ',' gateOrPinList ')' - { $$ = new AstAssignW ($3,$4,new AstNot($5,$6)); } + { $$ = new AstAssignW ($3,$4,new AstNot($5,$6)); DEL($2); } ; gateXor: gateIdE instRangeE '(' variable_lvalue ',' gateXorPinList ')' - { $$ = new AstAssignW ($3,$4,$6); } + { $$ = new AstAssignW ($3,$4,$6); DEL($2); } ; gateXnor: gateIdE instRangeE '(' variable_lvalue ',' gateXorPinList ')' - { $$ = new AstAssignW ($3,$4,new AstNot($5,$6)); } + { $$ = new AstAssignW ($3,$4,new AstNot($5,$6)); DEL($2); } ; gatePullup: - gateIdE instRangeE '(' variable_lvalue ')' { $$ = new AstPull ($3, $4, true); } + gateIdE instRangeE '(' variable_lvalue ')' { $$ = new AstPull ($3, $4, true); DEL($2); } ; gatePulldown: - gateIdE instRangeE '(' variable_lvalue ')' { $$ = new AstPull ($3, $4, false); } + gateIdE instRangeE '(' variable_lvalue ')' { $$ = new AstPull ($3, $4, false); DEL($2); } ; gateUnsup: - gateIdE instRangeE '(' gateUnsupPinList ')' { $$ = new AstImplicit ($3,$4); } + gateIdE instRangeE '(' gateUnsupPinList ')' { $$ = new AstImplicit ($3,$4); DEL($2); } ; gateIdE: