diff --git a/Changes b/Changes index 2987d3cc3..3a72014e3 100644 --- a/Changes +++ b/Changes @@ -4,6 +4,8 @@ The contributors that suggested a given feature are shown in []. Thanks! * Verilator 4.017 devel +**** Show included-from filenames in warnings, bug1439. [Todd Strader] + **** Fix not reporting some duplicate signals/ports, bug1462. [Peter Gerst] diff --git a/src/V3Ast.cpp b/src/V3Ast.cpp index 41fb419b9..e35dc8d22 100644 --- a/src/V3Ast.cpp +++ b/src/V3Ast.cpp @@ -1092,10 +1092,6 @@ void AstNode::v3errorEnd(std::ostringstream& str) const { } } -string AstNode::warnMore() const { - return fileline()->warnMore(); -} - //====================================================================== // Data type conversion diff --git a/src/V3Ast.h b/src/V3Ast.h index b989e66da..cf15d06eb 100644 --- a/src/V3Ast.h +++ b/src/V3Ast.h @@ -1408,7 +1408,10 @@ public: // METHODS - dump and error void v3errorEnd(std::ostringstream& str) const; void v3errorEndFatal(std::ostringstream& str) const VL_ATTR_NORETURN; - string warnMore() const; + string warnContextPrimary() const { return fileline()->warnContextPrimary(); } + string warnContextSecondary() const { return fileline()->warnContextSecondary(); } + string warnMore() const { return fileline()->warnMore(); } + virtual void dump(std::ostream& str=std::cout); void dumpGdb(); // For GDB only void dumpGdbHeader() const; diff --git a/src/V3Delayed.cpp b/src/V3Delayed.cpp index 2bfd5c66d..3886286e5 100644 --- a/src/V3Delayed.cpp +++ b/src/V3Delayed.cpp @@ -166,7 +166,10 @@ private: MULTIDRIVEN, "Signal has multiple driving blocks with different clocking: " <varp()->prettyName()<warnMore()<<"... Location of first driving block"<warnMore()<<"... Location of other driving block"); + <varp()->warnContextPrimary()<warnMore()<<"... Location of other driving block"<warnContextSecondary() + ); varrefp->varp()->user2(true); } UINFO(4,"AssignDupDlyVar: "<parent()) { + if (parentFl->filenameIsGlobal()) break; + out += parentFl->warnMore()+"... note: In file included from " + +parentFl->filebasename()+"\n"; + } + } + return out; +} + #ifdef VL_LEAK_CHECKS typedef vl_unordered_set FileLineCheckSet; FileLineCheckSet fileLineLeakChecks; diff --git a/src/V3FileLine.h b/src/V3FileLine.h index 1da9689cb..9f0626278 100644 --- a/src/V3FileLine.h +++ b/src/V3FileLine.h @@ -72,6 +72,7 @@ protected: class FileLine { int m_lineno; int m_filenameno; + FileLine* m_parent; // Parent line that included this line std::bitset m_warnOn; private: @@ -95,6 +96,7 @@ protected: void lineno(int num) { m_lineno = num; } void language(V3LangCode lang) { singleton().numberToLang(m_filenameno, lang); } void filename(const string& name) { m_filenameno = singleton().nameToNumber(name); } + void parent(FileLine* fileline) { m_parent = fileline; } void lineDirective(const char* textp, int& enterExitRef); void linenoInc() { m_lineno++; } void linenoIncInPlace() { m_lineno++; } @@ -103,11 +105,13 @@ public: FileLine(const string& filename, int lineno) { m_lineno = lineno; m_filenameno = singleton().nameToNumber(filename); + m_parent = NULL; m_warnOn = defaultFileLine().m_warnOn; } explicit FileLine(FileLine* fromp) { m_lineno = fromp->m_lineno; m_filenameno = fromp->m_filenameno; + m_parent = fromp->m_parent; m_warnOn = fromp->m_warnOn; } explicit FileLine(EmptySecret); @@ -121,6 +125,7 @@ public: #endif int lineno() const { return m_lineno; } + FileLine* parent() const { return m_parent; } V3LangCode language() const { return singleton().numberToLang(m_filenameno); } string ascii() const; const string filename() const { return singleton().numberToName(m_filenameno); } @@ -132,6 +137,7 @@ public: const string profileFuncname() const; const string xml() const { return "fl=\""+filenameLetters()+cvtToStr(lineno())+"\""; } string lineDirectiveStrg(int enterExit) const; + // Turn on/off warning messages on this line. void warnOn(V3ErrorCode code, bool flag) { m_warnOn.set(code, flag); } void warnOff(V3ErrorCode code, bool flag) { warnOn(code, !flag); } @@ -173,13 +179,21 @@ public: // OPERATORS void v3errorEnd(std::ostringstream& str); void v3errorEndFatal(std::ostringstream& str); + /// When building an error, prefix for printing continuation lines string warnMore() const; + /// When building an error, current location in include etc + /// If not used in a given error, automatically pasted at end of error + string warnContextPrimary() const { return warnContext(false); } + /// When building an error, additional location for additional references + /// Simplified information vs warnContextPrimary() to make dump clearer + string warnContextSecondary() const { return warnContext(true); } inline bool operator==(FileLine rhs) const { return (m_lineno==rhs.m_lineno && m_filenameno==rhs.m_filenameno && m_warnOn==rhs.m_warnOn); } private: void v3errorEndFatalGuts(std::ostringstream& str); + string warnContext(bool secondary) const; }; std::ostream& operator<<(std::ostream& os, FileLine* fileline); diff --git a/src/V3Gate.cpp b/src/V3Gate.cpp index 4e17bc6f2..b40187803 100644 --- a/src/V3Gate.cpp +++ b/src/V3Gate.cpp @@ -824,7 +824,9 @@ void GateVisitor::warnSignals() { vscp->v3warn(SYNCASYNCNET, "Signal flopped as both synchronous and async: " <prettyName()<warnMore()<<"... Location of async usage"<warnMore()<<"... Location of sync usage"<warnContextPrimary()<warnMore()<<"... Location of sync usage"<warnContextSecondary()); } } } diff --git a/src/V3LinkCells.cpp b/src/V3LinkCells.cpp index 1a83f3116..88574be48 100644 --- a/src/V3LinkCells.cpp +++ b/src/V3LinkCells.cpp @@ -464,7 +464,9 @@ private: || nodep->fileline()->warnIsOff(V3ErrorCode::MODDUP))) { nodep->v3warn(MODDUP, "Duplicate declaration of module: " <prettyName()<warnMore()<<"... Location of original declaration"); + <warnContextPrimary()<warnMore()<<"... Location of original declaration"<warnContextSecondary()); } nodep->unlinkFrBack(); pushDeletep(nodep); VL_DANGLING(nodep); diff --git a/src/V3LinkDot.cpp b/src/V3LinkDot.cpp index ed20dd2b2..cc18583e0 100644 --- a/src/V3LinkDot.cpp +++ b/src/V3LinkDot.cpp @@ -227,12 +227,16 @@ public: if (nodep->type() == fnodep->type()) { nodep->v3error("Duplicate declaration of "<prettyName()<warnMore()<<"... Location of original declaration"); + <warnContextPrimary()<warnMore()<<"... Location of original declaration\n" + <warnContextSecondary()); } else { nodep->v3error("Unsupported in C: "<prettyName()<warnMore()<<"... Location of original declaration"); + <warnContextPrimary()<warnMore()<<"... Location of original declaration\n" + <warnContextSecondary()); } } } @@ -945,7 +949,9 @@ class LinkDotFindVisitor : public AstNVisitor { <<(ansiWarn ? findvarp->warnMore()+"... note: ANSI ports must have type declared with the I/O (IEEE 2017 23.2.2.2)\n" : "") - <warnMore()<<"... Location of original declaration"); + <warnContextPrimary()<warnMore()<<"... Location of original declaration"<warnContextSecondary()); // Combining most likely reduce other errors findvarp->combineType(nodep); findvarp->fileline()->modifyStateInherit(nodep->fileline()); @@ -972,8 +978,10 @@ class LinkDotFindVisitor : public AstNVisitor { && !foundp->nodep()->fileline()->warnIsOff(V3ErrorCode::VARHIDDEN)) { nodep->v3warn(VARHIDDEN, "Declaration of signal hides declaration in upper scope: " <prettyName()<warnContextPrimary()<nodep()->warnMore() - <<"... Location of original declaration"); + <<"... Location of original declaration\n" + <nodep()->warnContextSecondary()); } ins = true; } @@ -1047,15 +1055,19 @@ class LinkDotFindVisitor : public AstNVisitor { if (foundp && foundp->parentp() == m_curSymp // Only when on same level && !foundp->imported()) { // and not from package nodep->v3error("Duplicate declaration of enum value: "<prettyName()<warnMore()<<"... Location of original declaration"); + <warnContextPrimary()<warnMore()<<"... Location of original declaration\n" + <warnContextSecondary()); } else { // User can disable the message at either point if (!nodep->fileline()->warnIsOff(V3ErrorCode::VARHIDDEN) && !foundp->nodep()->fileline()->warnIsOff(V3ErrorCode::VARHIDDEN)) { nodep->v3warn(VARHIDDEN, "Declaration of enum value hides declaration in upper scope: " <prettyName()<warnContextPrimary()<nodep()->warnMore() - <<"... Location of original declaration"); + <<"... Location of original declaration\n" + <warnContextSecondary()); } ins = true; } @@ -1229,7 +1241,9 @@ private: } else { if (refp->user4()) { nodep->v3error("Duplicate declaration of port: "<prettyName()<warnMore()<<"... Location of original declaration"); + <warnContextPrimary()<warnMore()<<"... Location of original declaration\n" + <warnContextSecondary()); } refp->user4(true); VSymEnt* symp = m_statep->insertSym(m_statep->getNodeSym(m_modp), @@ -1655,8 +1669,10 @@ private: void markAndCheckPinDup(AstNode* nodep, AstNode* refp, const char* whatp) { if (refp->user5p() && refp->user5p()!=nodep) { nodep->v3error("Duplicate "<prettyName()<warnContextPrimary()<user5p()->warnMore() - <<"... Location of original "<warnContextSecondary()); } else { refp->user5p(nodep); } diff --git a/src/V3ParseImp.cpp b/src/V3ParseImp.cpp index 4842bce77..81275f83f 100644 --- a/src/V3ParseImp.cpp +++ b/src/V3ParseImp.cpp @@ -74,8 +74,16 @@ V3ParseImp::~V3ParseImp() { void V3ParseImp::ppline(const char* textp) { // Handle `line directive + FileLine* prevFl = copyOrSameFileLine(); int enterExit; fileline()->lineDirective(textp, enterExit/*ref*/); + if (enterExit == 1) { // Enter + fileline()->parent(prevFl); + } else if (enterExit == 2) { // Exit + FileLine* upFl = fileline()->parent(); + if (upFl) upFl = upFl->parent(); + if (upFl) fileline()->parent(upFl); + } } void V3ParseImp::verilatorCmtLintSave() { diff --git a/src/V3Task.cpp b/src/V3Task.cpp index a2fb2062c..92df33120 100644 --- a/src/V3Task.cpp +++ b/src/V3Task.cpp @@ -145,8 +145,10 @@ public: if (!vxp->pure()) { nodep->v3warn(IMPURE, "Unsupported: External variable referenced by non-inlined function/task: " <prettyName()<warnContextPrimary()<impureNode()->warnMore()<<"... Location of the external reference: " - <impureNode()->prettyName()); + <impureNode()->prettyName()<impureNode()->warnContextSecondary()); } // And, we need to check all tasks this task calls for (V3GraphEdge* edgep = vxp->outBeginp(); edgep; edgep=edgep->outNextp()) { @@ -840,9 +842,11 @@ private: else if (iter->second.second != dpiproto) { nodep->v3error("Duplicate declaration of DPI function with different formal arguments: " <prettyName()<warnContextPrimary()<warnMore()<<"... New prototype: "<second.first->warnMore()<<"... Original prototype: " - <second.second); + <second.second<second.first->warnContextSecondary()); return true; } else { diff --git a/src/V3Tristate.cpp b/src/V3Tristate.cpp index ae89231f2..ffe3d7d8f 100644 --- a/src/V3Tristate.cpp +++ b/src/V3Tristate.cpp @@ -456,7 +456,9 @@ class TristateVisitor : public TristateBaseVisitor { } else { if (oldpullp->direction() != pullp->direction()) { pullp->v3error("Unsupported: Conflicting pull directions.\n" - <warnMore()<<"... Location of conflicting pull."); + <warnContextPrimary()<warnMore()<<"... Location of conflicting pull.\n" + <warnContextSecondary()); } } } diff --git a/src/V3Width.cpp b/src/V3Width.cpp index 3dbc97562..e7ef5d2b7 100644 --- a/src/V3Width.cpp +++ b/src/V3Width.cpp @@ -1382,9 +1382,12 @@ private: num.opAssign(VN_CAST(itemp->valuep(), Const)->num()); // Look for duplicates if (inits.find(num) != inits.end()) { // IEEE says illegal + AstNode* otherp = inits.find(num)->second; itemp->v3error("Overlapping enumeration value: "<prettyName()<second->warnMore() - <<"... Location of original declaration"); + <warnContextPrimary()<warnMore() + <<"... Location of original declaration\n" + <warnContextSecondary()); } else { inits.insert(make_pair(num, itemp)); } diff --git a/test_regress/t/t_lint_in_inc_bad.out b/test_regress/t/t_lint_in_inc_bad.out new file mode 100644 index 000000000..cd6904200 --- /dev/null +++ b/test_regress/t/t_lint_in_inc_bad.out @@ -0,0 +1,4 @@ +%Error: t/t_lint_in_inc_bad_2.vh:8: syntax error, unexpected if, expecting '(' + t/t_lint_in_inc_bad_1.vh:6: ... note: In file included from t_lint_in_inc_bad_1.vh + t/t_lint_in_inc_bad.v:6: ... note: In file included from t_lint_in_inc_bad.v +%Error: Exiting due to diff --git a/test_regress/t/t_lint_in_inc_bad.pl b/test_regress/t/t_lint_in_inc_bad.pl new file mode 100755 index 000000000..2ccfabd1d --- /dev/null +++ b/test_regress/t/t_lint_in_inc_bad.pl @@ -0,0 +1,22 @@ +#!/usr/bin/perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2008 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_all => 1); + +compile( + v_flags2 => ["--lint-only -Wall -Wno-DECLFILENAME --if-depth 10"], + fails => 1, + verilator_make_gcc => 0, + make_top_shell => 0, + make_main => 0, + expect_filename => $Self->{golden_filename}, + ); + +ok(1); +1; diff --git a/test_regress/t/t_lint_in_inc_bad.v b/test_regress/t/t_lint_in_inc_bad.v new file mode 100644 index 000000000..54cab8972 --- /dev/null +++ b/test_regress/t/t_lint_in_inc_bad.v @@ -0,0 +1,6 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed into the Public Domain, for any use, +// without warranty, 2019 by Wilson Snyder. + +`include "t_lint_in_inc_bad_1.vh" diff --git a/test_regress/t/t_lint_in_inc_bad_1.vh b/test_regress/t/t_lint_in_inc_bad_1.vh new file mode 100644 index 000000000..086d2890a --- /dev/null +++ b/test_regress/t/t_lint_in_inc_bad_1.vh @@ -0,0 +1,6 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed into the Public Domain, for any use, +// without warranty, 2019 by Wilson Snyder. + +`include "t_lint_in_inc_bad_2.vh" diff --git a/test_regress/t/t_lint_in_inc_bad_2.vh b/test_regress/t/t_lint_in_inc_bad_2.vh new file mode 100644 index 000000000..13e39c84e --- /dev/null +++ b/test_regress/t/t_lint_in_inc_bad_2.vh @@ -0,0 +1,9 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed into the Public Domain, for any use, +// without warranty, 2019 by Wilson Snyder. + +module x; + // Syntax error + if if if; +endmodule