diff --git a/src/V3Ast.cpp b/src/V3Ast.cpp index 64e127d2c..7d7cf6d86 100644 --- a/src/V3Ast.cpp +++ b/src/V3Ast.cpp @@ -1044,6 +1044,11 @@ void AstNode::v3errorEnd(ostringstream& str) const { } } +string AstNode::warnMore() const { + if (this) return this->fileline()->warnMore(); + else return V3Error::warnMore(); +} + //====================================================================== // Data type conversion diff --git a/src/V3Ast.h b/src/V3Ast.h index 5737d367d..b3727927b 100644 --- a/src/V3Ast.h +++ b/src/V3Ast.h @@ -1079,6 +1079,7 @@ public: // METHODS - dump and error void v3errorEnd(ostringstream& str) const; + string warnMore() const; virtual void dump(ostream& str=cout); void dumpGdb(); // For GDB only void dumpGdbHeader() const; diff --git a/src/V3Changed.cpp b/src/V3Changed.cpp index e3ae73d7c..9c95772a9 100644 --- a/src/V3Changed.cpp +++ b/src/V3Changed.cpp @@ -94,8 +94,9 @@ private: int lsb = isArray ? arrayp->lsb() : 0; if (isArray && ((msb - lsb + 1) > DETECTARRAY_MAX_INDEXES)) { vscp->v3warn(E_DETECTARRAY, "Unsupported: Can't detect more than "<prettyName()); - vscp->v3warn(E_DETECTARRAY, "... Could recompile with DETECTARRAY_MAX_INDEXES increased to at least "<prettyName()<warnMore() + <<"... Could recompile with DETECTARRAY_MAX_INDEXES increased to at least "<dtypeSkipRefp()->castBasicDType()) { if (debug()) varp->dumpTree(cout,"-DETECTARRAY-"); diff --git a/src/V3Const.cpp b/src/V3Const.cpp index 97b21e166..a2e876fed 100644 --- a/src/V3Const.cpp +++ b/src/V3Const.cpp @@ -977,7 +977,7 @@ private: AstNode* errorp = simvis.whyNotNodep(); if (!errorp) errorp = nodep; nodep->v3error("Expecting expression to be constant, but can't determine constant for " <prettyTypeName()<fileline()<<"... Location of non-constant " + <warnMore()<<"... Location of non-constant " <prettyTypeName()<<": "<sensesp() != m_activep->sensesp()) { if (!varrefp->varp()->fileline()->warnIsOff(V3ErrorCode::MULTIDRIVEN) && !varrefp->varp()->user2()) { - varrefp->varp()->v3warn(MULTIDRIVEN,"Signal has multiple driving blocks: "<varp()->prettyName()); - varrefp->v3warn(MULTIDRIVEN,"... Location of first driving block"); - oldactivep->v3warn(MULTIDRIVEN,"... Location of other driving block"); + varrefp->varp()->v3warn(MULTIDRIVEN,"Signal has multiple driving blocks: "<varp()->prettyName()<warnMore()<<"... Location of first driving block"<warnMore()<<"... Location of other driving block"); varrefp->varp()->user2(true); } UINFO(4,"AssignDupDlyVar: "< FileLineCheckSet; FileLineCheckSet fileLineLeakChecks; @@ -370,7 +378,9 @@ bool V3Error::isError(V3ErrorCode code, bool supp) { else return false; } -string V3Error::msgPrefix(V3ErrorCode code, bool supp) { +string V3Error::msgPrefix() { + V3ErrorCode code=s_errorCode; + bool supp=s_errorSuppressed; if (supp) return "-arning-suppressed: "; else if (code==V3ErrorCode::EC_INFO) return "-Info: "; else if (code==V3ErrorCode::EC_FATAL) return "%Error: "; @@ -395,18 +405,6 @@ void V3Error::vlAbort () { //====================================================================== // Global Functions -string V3Error::v3sform (const char* format, ...) { - static char msg[1000] = ""; - - va_list ap; - va_start(ap,format); - vsprintf(msg,format,ap); - va_end(ap); - - string out = msg; - return out; -} - void V3Error::suppressThisWarning() { if (s_errorCode>=V3ErrorCode::EC_MIN) { V3Stats::addStatSum(string("Warnings, Suppressed ")+s_errorCode.ascii(), 1); @@ -414,6 +412,10 @@ void V3Error::suppressThisWarning() { } } +string V3Error::warnMore() { + return msgPrefix(); +} + void V3Error::v3errorEnd (ostringstream& sstr) { #if defined(__COVERITY__) || defined(__cppcheck__) if (s_errorCode==V3ErrorCode::EC_FATAL) __coverity_panic__(x); diff --git a/src/V3Error.h b/src/V3Error.h index 8c451102d..f6677c061 100644 --- a/src/V3Error.h +++ b/src/V3Error.h @@ -196,7 +196,7 @@ class V3Error { // ACCESSORS static void debugDefault(int level) { s_debugDefault = level; } static int debugDefault() { return s_debugDefault; } - static string msgPrefix(V3ErrorCode code=s_errorCode, bool supp=s_errorSuppressed); // returns %Error/%Warn + static string msgPrefix(); // returns %Error/%Warn static int errorCount() { return s_errCount; } static int warnCount() { return s_warnCount; } static int errorOrWarnCount() { return errorCount()+warnCount(); } @@ -209,15 +209,17 @@ class V3Error { static void suppressThisWarning(); // Suppress next %Warn if user has it off static void pretendError(V3ErrorCode code, bool flag) { s_pretendError[code]=flag; } static bool isError(V3ErrorCode code, bool supp); - static string v3sform (const char* format, ...); static string lineStr (const char* filename, int lineno); static V3ErrorCode errorCode() { return s_errorCode; } + // When printing an error/warning, print prefix for multiline message + static string warnMore(); + // Internals for v3error()/v3fatal() macros only // Error end takes the string stream to output, be careful to seek() as needed - static ostringstream& v3errorPrep (V3ErrorCode code) { - s_errorStr.str(""); s_errorCode=code; s_errorSuppressed=false; return s_errorStr; } - static ostringstream& v3errorStr () { return s_errorStr; } + static void v3errorPrep(V3ErrorCode code) { + s_errorStr.str(""); s_errorCode=code; s_errorSuppressed=false; } + static ostringstream& v3errorStr() { return s_errorStr; } static void vlAbort(); static void v3errorEnd(ostringstream& sstr); // static, but often overridden in classes. }; @@ -228,7 +230,9 @@ inline void v3errorEnd(ostringstream& sstr) { V3Error::v3errorEnd(sstr); } // These allow errors using << operators: v3error("foo"<<"bar"); // Careful, you can't put () around msg, as you would in most macro definitions -#define v3warnCode(code,msg) v3errorEnd(((V3Error::v3errorPrep(code)<fileline()->warnIsOff(V3ErrorCode::SYNCASYNCNET) ) { vscp->varp()->user2(true); // Warn only once per signal - vscp->v3warn(SYNCASYNCNET,"Signal flopped as both synchronous and async: "<prettyName()); - ap->v3warn(SYNCASYNCNET,"... Location of async usage"); - sp->v3warn(SYNCASYNCNET,"... Location of sync usage"); + vscp->v3warn(SYNCASYNCNET,"Signal flopped as both synchronous and async: "<prettyName()<warnMore()<<"... Location of async usage"<warnMore()<<"... Location of sync usage"<type() == foundp->type()) { - nodep->v3error("Duplicate declaration of "<prettyName()); - foundp->v3error("... Location of original declaration"); + nodep->v3error("Duplicate declaration of "<prettyName()<warnMore()<<"... Location of original declaration"); } else { nodep->v3error("Unsupported in C: "<prettyName()); - foundp->v3error("... Location of original declaration"); + <prettyName()<warnMore()<<"... Location of original declaration"); } } @@ -324,16 +324,16 @@ private: } nodep->unlinkFrBack()->deleteTree(); nodep=NULL; } else { - nodep->v3error("Duplicate declaration of signal: "<prettyName()); - findvarp->v3error("... Location of original declaration"); + nodep->v3error("Duplicate declaration of signal: "<prettyName()<warnMore()<<"... Location of original declaration"); } } else { // User can disable the message at either point if (!(m_ftaskp && m_ftaskp->dpiImport()) && !nodep->fileline()->warnIsOff(V3ErrorCode::VARHIDDEN) && !foundp->fileline()->warnIsOff(V3ErrorCode::VARHIDDEN)) { - nodep->v3warn(VARHIDDEN,"Declaration of signal hides declaration in upper scope: "<name()); - foundp->v3warn(VARHIDDEN,"... Location of original declaration"); + nodep->v3warn(VARHIDDEN,"Declaration of signal hides declaration in upper scope: "<name()<warnMore()<<"... Location of original declaration"); } ins = true; } @@ -400,14 +400,14 @@ private: } else if (findvarp != nodep) { UINFO(4,"DupVar: "<user3p() == m_curVarsp) { // Only when on same level - nodep->v3error("Duplicate declaration of enum value: "<prettyName()); - findvarp->v3error("... Location of original declaration"); + nodep->v3error("Duplicate declaration of enum value: "<prettyName()<warnMore()<<"... Location of original declaration"); } else { // User can disable the message at either point if (!nodep->fileline()->warnIsOff(V3ErrorCode::VARHIDDEN) && !foundp->fileline()->warnIsOff(V3ErrorCode::VARHIDDEN)) { - nodep->v3warn(VARHIDDEN,"Declaration of enum value hides declaration in upper scope: "<name()); - foundp->v3warn(VARHIDDEN,"... Location of original declaration"); + nodep->v3warn(VARHIDDEN,"Declaration of enum value hides declaration in upper scope: "<name()<warnMore()<<"... Location of original declaration"); } ins = true; } @@ -658,8 +658,9 @@ private: } else { nodep->modVarp(refp); if (refp->user5p() && refp->user5p()->castNode()!=nodep) { - nodep->v3error("Duplicate pin connection: "<prettyName()); - refp->user5p()->castNode()->v3error("... Location of original pin connection"); + nodep->v3error("Duplicate pin connection: "<prettyName()<user5p()->castNode()->warnMore() + <<"... Location of original pin connection"); } else { refp->user5p(nodep); } diff --git a/src/V3LinkCells.cpp b/src/V3LinkCells.cpp index b41dce2b5..095bca528 100644 --- a/src/V3LinkCells.cpp +++ b/src/V3LinkCells.cpp @@ -294,8 +294,8 @@ private: AstNode* foundp = m_mods.findIdUpward(nodep->name()); if (foundp && foundp != nodep) { if (!(foundp->fileline()->warnIsOff(V3ErrorCode::MODDUP) || nodep->fileline()->warnIsOff(V3ErrorCode::MODDUP))) { - nodep->v3warn(MODDUP,"Duplicate declaration of module: "<prettyName()); - foundp->v3warn(MODDUP,"... Location of original declaration"); + nodep->v3warn(MODDUP,"Duplicate declaration of module: "<prettyName()<warnMore()<<"... Location of original declaration"); } nodep->unlinkFrBack(); pushDeletep(nodep); nodep=NULL; diff --git a/src/V3Task.cpp b/src/V3Task.cpp index 2a747f472..8ab276ca2 100644 --- a/src/V3Task.cpp +++ b/src/V3Task.cpp @@ -144,8 +144,8 @@ public: } void checkPurity(AstNodeFTask* nodep, TaskBaseVertex* vxp) { if (!vxp->pure()) { - nodep->v3warn(IMPURE,"Unsupported: External variable referenced by non-inlined function/task: "<prettyName()); - vxp->impureNode()->v3warn(IMPURE,"... Location of the external reference: "<impureNode()->prettyName()); + nodep->v3warn(IMPURE,"Unsupported: External variable referenced by non-inlined function/task: "<prettyName()<impureNode()->warnMore()<<"... Location of the external reference: "<impureNode()->prettyName()); } // And, we need to check all tasks this task calls for (V3GraphEdge* edgep = vxp->outBeginp(); edgep; edgep=edgep->outNextp()) { @@ -914,9 +914,9 @@ private: m_dpiNames.insert(make_pair(nodep->cname(), make_pair(dpip, dpiproto))); } else if (iter->second.second != dpiproto) { - nodep->v3error("Duplicate declaration of DPI function with different formal arguments: "<prettyName()); - nodep->v3error("... New prototype: "<second.first->v3error("... Original prototype: "<second.second); + nodep->v3error("Duplicate declaration of DPI function with different formal arguments: "<prettyName()<warnMore()<<"... New prototype: "<second.first->warnMore()<<"... Original prototype: "<second.second); } } @@ -932,8 +932,8 @@ private: if (dpip) { dpip->addArgsp(portp->cloneTree(false)); if (!portp->basicp() || portp->basicp()->keyword().isDpiUnsupported()) { - portp->v3error("Unsupported: DPI argument of type "<basicp()->prettyTypeName()); - portp->v3error("... For best portability, use bit, byte, int, or longint"); + portp->v3error("Unsupported: DPI argument of type "<basicp()->prettyTypeName()<warnMore()<<"... For best portability, use bit, byte, int, or longint"); } } } else { diff --git a/src/V3Width.cpp b/src/V3Width.cpp index 83df5b5f3..9708e5991 100644 --- a/src/V3Width.cpp +++ b/src/V3Width.cpp @@ -875,8 +875,9 @@ private: num.opAssign(itemp->valuep()->castConst()->num()); // Look for duplicates if (inits.find(num) != inits.end()) { // IEEE says illegal - itemp->v3error("Overlapping enumeration value: "<prettyName()); - inits.find(num)->second->v3error("... Location of original declaration"); + itemp->v3error("Overlapping enumeration value: "<prettyName()<second->warnMore() + <<"... Location of original declaration"); } else { inits.insert(make_pair(num,itemp)); } diff --git a/test_regress/t/t_lint_multidriven_bad.pl b/test_regress/t/t_lint_multidriven_bad.pl index 7b3a3aad3..bfdfa9906 100755 --- a/test_regress/t/t_lint_multidriven_bad.pl +++ b/test_regress/t/t_lint_multidriven_bad.pl @@ -17,9 +17,9 @@ compile ( make_main => 0, expect=> '%Warning-MULTIDRIVEN: t/t_lint_multidriven_bad.v:\d+: Signal has multiple driving blocks: v.mem -%Warning-MULTIDRIVEN: Use ".*" and lint_on around source to disable this message. %Warning-MULTIDRIVEN: t/t_lint_multidriven_bad.v:\d+: ... Location of first driving block %Warning-MULTIDRIVEN: t/t_lint_multidriven_bad.v:\d+: ... Location of other driving block +%Warning-MULTIDRIVEN: Use ".*" and lint_on around source to disable this message. %Warning-MULTIDRIVEN: t/t_lint_multidriven_bad.v:\d+: Signal has multiple driving blocks: out2 %Warning-MULTIDRIVEN: t/t_lint_multidriven_bad.v:\d+: ... Location of first driving block %Warning-MULTIDRIVEN: t/t_lint_multidriven_bad.v:\d+: ... Location of other driving block diff --git a/test_regress/t/t_lint_syncasyncnet_bad.pl b/test_regress/t/t_lint_syncasyncnet_bad.pl index 960cf65ff..0864e64c2 100755 --- a/test_regress/t/t_lint_syncasyncnet_bad.pl +++ b/test_regress/t/t_lint_syncasyncnet_bad.pl @@ -17,9 +17,9 @@ compile ( make_main => 0, expect=> '%Warning-SYNCASYNCNET: t/t_lint_syncasyncnet_bad.v:\d+: Signal flopped as both synchronous and async: rst_both_l -%Warning-SYNCASYNCNET: Use .* around source to disable this message. %Warning-SYNCASYNCNET: t/t_lint_syncasyncnet_bad.v:\d+: ... Location of async usage %Warning-SYNCASYNCNET: t/t_lint_syncasyncnet_bad.v:\d+: ... Location of sync usage +%Warning-SYNCASYNCNET: Use .* around source to disable this message. %Error: Exiting due to.*', ); diff --git a/test_regress/t/t_var_bad_hide2.pl b/test_regress/t/t_var_bad_hide2.pl index cffe32469..737577c6c 100755 --- a/test_regress/t/t_var_bad_hide2.pl +++ b/test_regress/t/t_var_bad_hide2.pl @@ -12,8 +12,8 @@ compile ( fails=>$Self->{v3}, expect=> '%Warning-VARHIDDEN: t/t_var_bad_hide2.v:\d+: Declaration of signal hides declaration in upper scope: t -.* %Warning-VARHIDDEN: t/t_var_bad_hide2.v:\d+: ... Location of original declaration +.* %Error: Exiting due to.*', );