Internals: Redo post-error additional information to be part of error calls.

This commit is contained in:
Wilson Snyder 2025-05-10 16:20:12 -04:00
parent 0f528d136d
commit 680236b03e
17 changed files with 128 additions and 117 deletions

View File

@ -122,6 +122,13 @@ void V3ErrorGuarded::suppressThisWarning() VL_REQUIRES(m_mutex) {
errorSuppressed(true);
}
void V3ErrorGuarded::v3errorPrep(V3ErrorCode code) VL_REQUIRES(m_mutex) {
m_errorStr.str("");
m_errorCode = code;
m_errorContexted = false;
m_errorSuppressed = false;
}
// cppcheck-has-bug-suppress constParameter
void V3ErrorGuarded::v3errorEnd(std::ostringstream& sstr, const string& extra)
VL_REQUIRES(m_mutex) {
@ -303,7 +310,6 @@ std::ostringstream& V3Error::v3errorPrepFileLine(V3ErrorCode code, const char* f
v3errorPrep(code) << file << ":" << std::dec << line << ": ";
return v3errorStr();
}
std::ostringstream& V3Error::v3errorStr() VL_REQUIRES(s().m_mutex) { return s().v3errorStr(); }
void V3Error::v3errorEnd(std::ostringstream& sstr, const string& extra) VL_RELEASE(s().m_mutex) {
s().v3errorEnd(sstr, extra);
V3Error::s().m_mutex.unlock();

View File

@ -325,7 +325,7 @@ private:
= V3ErrorCode::EC_FATAL; // Error string being formed will abort
bool m_errorSuppressed VL_GUARDED_BY(m_mutex)
= false; // Error being formed should be suppressed
MessagesSet m_messages VL_GUARDED_BY(m_mutex); // What errors we've outputted
MessagesSet m_messages VL_GUARDED_BY(m_mutex); // Errors outputted, to remove dups
ErrorExitCb m_errorExitCb VL_GUARDED_BY(m_mutex)
= nullptr; // Callback when error occurs for dumping
bool m_errorContexted VL_GUARDED_BY(m_mutex) = false; // Error being formed got context
@ -341,12 +341,7 @@ private:
bool m_warnFatal VL_GUARDED_BY(m_mutex) = true; // Option: --warnFatal Warnings are fatal
std::ostringstream m_errorStr VL_GUARDED_BY(m_mutex); // Error string being formed
void v3errorPrep(V3ErrorCode code) VL_REQUIRES(m_mutex) {
m_errorStr.str("");
m_errorCode = code;
m_errorContexted = false;
m_errorSuppressed = false;
}
void v3errorPrep(V3ErrorCode code) VL_REQUIRES(m_mutex);
std::ostringstream& v3errorStr() VL_REQUIRES(m_mutex) { return m_errorStr; }
void v3errorEnd(std::ostringstream& sstr, const string& extra = "") VL_REQUIRES(m_mutex);
@ -363,9 +358,9 @@ public:
bool isError(V3ErrorCode code, bool supp) VL_REQUIRES(m_mutex);
void vlAbortOrExit() VL_REQUIRES(m_mutex);
void errorContexted(bool flag) VL_REQUIRES(m_mutex) { m_errorContexted = flag; }
void incWarnings() VL_REQUIRES(m_mutex) { m_warnCount++; }
void incWarnings() VL_REQUIRES(m_mutex) { ++m_warnCount; }
void incErrors() VL_REQUIRES(m_mutex) {
m_errCount++;
++m_errCount;
if (errorCount() == errorLimit()) { // Not >= as would otherwise recurse
v3errorEnd(
(v3errorPrep(V3ErrorCode::EC_FATALMANY),
@ -509,14 +504,6 @@ public:
// When printing an error/warning, print prefix for multiline message
static string warnMore() VL_REQUIRES(s().m_mutex) { return s().warnMore(); }
// This function should only be used when it is impossible to
// generate whole error message inside v3warn macros and it needs to be
// streamed directly to cerr.
// Use with caution as this function isn't MT_SAFE.
static string warnMoreStandalone() VL_EXCLUDES(s().m_mutex) VL_MT_UNSAFE {
const V3RecursiveLockGuard guard{s().m_mutex};
return s().warnMore();
}
// This function marks place in error message from which point message
// should be printed after information on the error code.
// The post-processing is done in v3errorEnd function.
@ -532,7 +519,7 @@ public:
static std::ostringstream& v3errorPrep(V3ErrorCode code) VL_ACQUIRE(s().m_mutex);
static std::ostringstream& v3errorPrepFileLine(V3ErrorCode code, const char* file, int line)
VL_ACQUIRE(s().m_mutex);
static std::ostringstream& v3errorStr() VL_REQUIRES(s().m_mutex);
static std::ostringstream& v3errorStr() VL_REQUIRES(s().m_mutex) { return s().v3errorStr(); }
// static, but often overridden in classes.
static void v3errorEnd(std::ostringstream& sstr, const string& extra = "")
VL_RELEASE(s().m_mutex);

View File

@ -464,10 +464,6 @@ string FileLine::warnOther() const VL_REQUIRES(V3Error::s().m_mutex) {
return V3Error::s().warnMore();
}
};
string FileLine::warnOtherStandalone() const VL_EXCLUDES(V3Error::s().m_mutex) VL_MT_UNSAFE {
const V3RecursiveLockGuard guard{V3Error::s().m_mutex};
return warnOther();
}
string FileLine::source() const VL_MT_SAFE {
if (VL_UNCOVERABLE(!m_contentp)) { // LCOV_EXCL_START

View File

@ -301,7 +301,6 @@ public:
void warnUnusedOff(bool flag);
void warnStateFrom(const FileLine& from) { m_msgEnIdx = from.m_msgEnIdx; }
void warnResetDefault() { warnStateFrom(defaultFileLine()); }
bool lastWarnWaived() const { return m_waive; }
// Specific flag ACCESSORS/METHODS
bool celldefineOn() const { return msgEn().test(V3ErrorCode::I_CELLDEFINE); }
@ -356,7 +355,6 @@ public:
/// When building an error, prefix for printing secondary information
/// from a different FileLine than the original error
string warnOther() const VL_REQUIRES(V3Error::s().m_mutex);
string warnOtherStandalone() const VL_EXCLUDES(V3Error::s().m_mutex) VL_MT_UNSAFE;
/// 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 VL_REQUIRES(V3Error::s().m_mutex) {

View File

@ -233,13 +233,16 @@ void V3Graph::clearColors() {
//======================================================================
// Dumping
void V3Graph::loopsMessageCb(V3GraphVertex* vertexp) {
vertexp->v3fatalSrc("Loops detected in graph: " << vertexp);
void V3Graph::loopsMessageCb(V3GraphVertex* vertexp, V3EdgeFuncP edgeFuncp) {
vertexp->v3fatalSrc("Loops detected in graph: " << vertexp << "\n"
<< reportLoops(edgeFuncp, vertexp));
}
void V3Graph::loopsVertexCb(V3GraphVertex* vertexp) {
string V3Graph::loopsVertexCb(V3GraphVertex* vertexp) {
// Needed here as V3GraphVertex<< isn't defined until later in header
if (debug()) std::cerr << "-Info-Loop: " << cvtToHex(vertexp) << " " << vertexp << endl;
if (debug())
return "-Info-Loop: "s + cvtToHex(vertexp) + ' ' + cvtToStr(vertexp) + '\n';
else
return "";
}
void V3Graph::dump(std::ostream& os) const {

View File

@ -430,7 +430,7 @@ public:
/// Call loopsVertexCb on any one loop starting where specified
/// Side-effect: changes user()
void reportLoops(V3EdgeFuncP edgeFuncp, V3GraphVertex* vertexp) VL_MT_DISABLED;
string reportLoops(V3EdgeFuncP edgeFuncp, V3GraphVertex* vertexp) VL_MT_DISABLED;
/// Build a subgraph of all loops starting where specified
/// Side-effect: changes user()
@ -484,8 +484,8 @@ public:
parallelismReport(std::function<uint64_t(const V3GraphVertex*)> vertexCost) VL_MT_DISABLED;
// CALLBACKS
virtual void loopsMessageCb(V3GraphVertex* vertexp) VL_MT_DISABLED;
virtual void loopsVertexCb(V3GraphVertex* vertexp) VL_MT_DISABLED;
virtual void loopsMessageCb(V3GraphVertex* vertexp, V3EdgeFuncP edgeFuncp) VL_MT_DISABLED;
virtual string loopsVertexCb(V3GraphVertex* vertexp) VL_MT_DISABLED;
};
//============================================================================

View File

@ -343,10 +343,9 @@ void GraphAcyc::simplifyOut(GraphAcycVertex* avertexp) {
V3GraphVertex* inVertexp = inEdgep->fromp();
if (inVertexp == avertexp) {
if (debug()) v3error("Non-cutable vertex=" << avertexp); // LCOV_EXCL_LINE
v3error("Circular logic when ordering code (non-cutable edge loop)");
m_origGraphp->reportLoops(
&V3GraphEdge::followNotCutable,
avertexp->origVertexp()); // calls OrderGraph::loopsVertexCb
v3error("Circular logic when ordering code (non-cutable edge loop)\n"
<< m_origGraphp->reportLoops( // calls OrderGraph::loopsVertexCb
&V3GraphEdge::followNotCutable, avertexp->origVertexp()));
// Things are unlikely to end well at this point,
// but we'll try something to get to further errors...
inEdgep->cutable(true);

View File

@ -29,6 +29,7 @@
#include <algorithm>
#include <list>
#include <map>
#include <numeric>
#include <vector>
VL_DEFINE_DEBUG_FUNCTIONS;
@ -281,8 +282,7 @@ class GraphAlgRank final : GraphAlg<> {
// If larger rank is found, assign it and loop back through
// If we hit a back node make a list of all loops
if (vertexp->user() == 1) {
m_graphp->reportLoops(m_edgeFuncp, vertexp);
m_graphp->loopsMessageCb(vertexp);
m_graphp->loopsMessageCb(vertexp, m_edgeFuncp);
return; // LCOV_EXCL_LINE // gcc gprof bug misses this return
}
if (vertexp->rank() >= currentRank) return; // Already processed it
@ -313,6 +313,7 @@ void V3Graph::rank(V3EdgeFuncP edgeFuncp) { GraphAlgRank{this, edgeFuncp}; }
class GraphAlgRLoops final : GraphAlg<> {
std::vector<V3GraphVertex*> m_callTrace; // List of everything we hit processing so far
std::vector<string> m_msgs; // Output messages
bool m_done = false; // Exit algorithm
void main(V3GraphVertex* vertexp) {
@ -333,9 +334,8 @@ class GraphAlgRLoops final : GraphAlg<> {
m_callTrace[currentRank++] = vertexp;
if (vertexp->user() == 1) {
for (unsigned i = 0; i < currentRank; i++) { //
m_graphp->loopsVertexCb(m_callTrace[i]);
}
for (unsigned i = 0; i < currentRank; i++)
m_msgs.emplace_back(m_graphp->loopsVertexCb(m_callTrace[i]));
m_done = true;
return;
}
@ -353,10 +353,13 @@ public:
main(vertexp);
}
~GraphAlgRLoops() = default;
string message() const {
return std::accumulate(m_msgs.begin(), m_msgs.end(), std::string{""});
}
};
void V3Graph::reportLoops(V3EdgeFuncP edgeFuncp, V3GraphVertex* vertexp) {
GraphAlgRLoops{this, edgeFuncp, vertexp};
string V3Graph::reportLoops(V3EdgeFuncP edgeFuncp, V3GraphVertex* vertexp) {
return GraphAlgRLoops{this, edgeFuncp, vertexp}.message();
}
//######################################################################

View File

@ -43,7 +43,7 @@ class LinkCellsGraph final : public V3Graph {
public:
LinkCellsGraph() = default;
~LinkCellsGraph() override = default;
void loopsMessageCb(V3GraphVertex* vertexp) override;
void loopsMessageCb(V3GraphVertex* vertexp, V3EdgeFuncP edgeFuncp) override;
};
class LinkCellsVertex final : public V3GraphVertex {
@ -73,7 +73,7 @@ public:
string name() const override VL_MT_STABLE { return "*LIBRARY*"; }
};
void LinkCellsGraph::loopsMessageCb(V3GraphVertex* vertexp) {
void LinkCellsGraph::loopsMessageCb(V3GraphVertex* vertexp, V3EdgeFuncP edgeFuncp) {
if (const LinkCellsVertex* const vvertexp = vertexp->cast<LinkCellsVertex>()) {
vvertexp->modp()->v3warn(E_UNSUPPORTED,
"Unsupported: Recursive multiple modules (module instantiates "

View File

@ -3422,11 +3422,11 @@ class LinkDotResolveVisitor final : public VNVisitor {
<< (!baddot.empty() ? AstNode::prettyNameQ(baddot)
: nodep->prettyNameQ())
<< " in dotted " << expectWhat << ": '"
<< m_ds.m_dotText + "." + nodep->prettyName() << "'");
if (okSymp) {
okSymp->cellErrorScopes(nodep,
AstNode::prettyName(m_ds.m_dotText));
}
<< m_ds.m_dotText + "." + nodep->prettyName() << "'\n"
<< nodep->warnContextPrimary()
<< (okSymp ? okSymp->cellErrorScopes(
nodep, AstNode::prettyName(m_ds.m_dotText))
: ""));
}
m_ds.m_dotErr = true;
}
@ -3611,8 +3611,9 @@ class LinkDotResolveVisitor final : public VNVisitor {
if (!nodep->varp()) {
nodep->v3error("Can't find definition of "
<< AstNode::prettyNameQ(baddot) << " in dotted signal: '"
<< nodep->dotted() + "." + nodep->prettyName() << "'");
okSymp->cellErrorScopes(nodep);
<< nodep->dotted() + "." + nodep->prettyName() << "'\n"
<< nodep->warnContextPrimary()
<< okSymp->cellErrorScopes(nodep));
return;
}
// V3Inst may have expanded arrays of interfaces to
@ -3636,8 +3637,9 @@ class LinkDotResolveVisitor final : public VNVisitor {
if (!vscp) {
nodep->v3error("Can't find varpin scope of "
<< AstNode::prettyNameQ(baddot) << " in dotted signal: '"
<< nodep->dotted() + "." + nodep->prettyName() << "'");
okSymp->cellErrorScopes(nodep);
<< nodep->dotted() + "." + nodep->prettyName() << "'\n"
<< nodep->warnContextPrimary()
<< okSymp->cellErrorScopes(nodep));
} else {
while (vscp->user2p()) { // If V3Inline aliased it, pick up the new signal
UINFO(7, indent() << "Resolved pre-alias " << vscp
@ -3844,10 +3846,11 @@ class LinkDotResolveVisitor final : public VNVisitor {
dotSymp = m_statep->findDotted(nodep->fileline(), dotSymp, inl, baddot, okSymp,
true);
if (!dotSymp) {
okSymp->cellErrorScopes(nodep);
nodep->v3fatalSrc("Couldn't resolve inlined scope "
<< AstNode::prettyNameQ(baddot)
<< " in: " << nodep->inlinedDots());
<< " in: " << nodep->inlinedDots() << '\n'
<< nodep->warnContextPrimary()
<< okSymp->cellErrorScopes(nodep));
}
}
dotSymp = m_statep->findDotted(nodep->fileline(), dotSymp, nodep->dotted(), baddot,
@ -3974,8 +3977,9 @@ class LinkDotResolveVisitor final : public VNVisitor {
nodep->v3error("Can't find definition of "
<< AstNode::prettyNameQ(baddot) << " in dotted task/function: '"
<< nodep->dotted() + "." + nodep->prettyName() << "'\n"
<< (suggest.empty() ? "" : nodep->warnMore() + suggest));
okSymp->cellErrorScopes(nodep);
<< (suggest.empty() ? "" : nodep->warnMore() + suggest) << '\n'
<< nodep->warnContextPrimary()
<< okSymp->cellErrorScopes(nodep));
}
}
}

View File

@ -595,40 +595,41 @@ string V3Options::filePath(FileLine* fl, const string& modname, const string& la
// Warn and return not found
if (errmsg != "") {
fl->v3error(errmsg + "'"s + filename + "'"s);
filePathLookedMsg(fl, filename);
fl->v3error(errmsg << "'"s << filename << "'\n"s << fl->warnContextPrimary()
<< V3Error::warnAdditionalInfo() << filePathLookedMsg(fl, filename));
}
return "";
}
void V3Options::filePathLookedMsg(FileLine* fl, const string& modname) {
string V3Options::filePathLookedMsg(FileLine* fl, const string& modname) {
static bool shown_notfound_msg = false;
std::ostringstream ss;
if (modname.find("__Vhsh") != string::npos) {
std::cerr << V3Error::warnMoreStandalone()
<< "... Note: Name is longer than 127 characters; automatic"
<< " file lookup may have failed due to OS filename length limits.\n";
std::cerr << V3Error::warnMoreStandalone()
<< "... Suggest putting filename with this module/package"
<< " onto command line instead.\n";
ss << V3Error::warnMore() << "... Note: Name is longer than 127 characters; automatic"
<< " file lookup may have failed due to OS filename length limits.\n";
ss << V3Error::warnMore() << "... Suggest putting filename with this module/package"
<< " onto command line instead.\n";
} else if (!shown_notfound_msg) {
shown_notfound_msg = true;
if (m_impp->m_incDirUsers.empty()) {
fl->v3error("This may be because there's no search path specified with -I<dir>.");
ss << V3Error::warnMore()
<< "... This may be because there's no search path specified with -I<dir>.\n";
}
std::cerr << V3Error::warnMoreStandalone() << "... Looked in:" << endl;
ss << V3Error::warnMore() << "... Looked in:\n";
for (const string& dir : m_impp->m_incDirUsers) {
for (const string& ext : m_impp->m_libExtVs) {
const string fn = V3Os::filenameJoin(dir, modname + ext);
std::cerr << V3Error::warnMoreStandalone() << " " << fn << endl;
ss << V3Error::warnMore() << " " << fn << "\n";
}
}
for (const string& dir : m_impp->m_incDirFallbacks) {
for (const string& ext : m_impp->m_libExtVs) {
const string fn = V3Os::filenameJoin(dir, modname + ext);
std::cerr << V3Error::warnMoreStandalone() << " " << fn << endl;
ss << V3Error::warnMore() << " " << fn << "\n";
}
}
}
return ss.str();
}
//! Determine what language is associated with a filename

View File

@ -779,7 +779,7 @@ public:
string fileExists(const string& filename);
string filePath(FileLine* fl, const string& modname, const string& lastpath,
const string& errmsg);
void filePathLookedMsg(FileLine* fl, const string& modname);
string filePathLookedMsg(FileLine* fl, const string& modname);
V3LangCode fileLanguage(const string& filename);
static bool fileStatNormal(const string& filename);

View File

@ -100,17 +100,16 @@ public:
};
class Graph final : public V3Graph {
void loopsVertexCb(V3GraphVertex* vtxp) override {
// TODO: 'typeName' is an internal thing. This should be more human readable.
string loopsVertexCb(V3GraphVertex* vtxp) override {
if (SchedAcyclicLogicVertex* const lvtxp = vtxp->cast<SchedAcyclicLogicVertex>()) {
AstNode* const logicp = lvtxp->logicp();
std::cerr << logicp->fileline()->warnOtherStandalone()
<< " Example path: " << logicp->typeName() << endl;
return logicp->fileline()->warnOther()
+ " Example path: " + logicp->prettyTypeName() + "\n";
} else {
SchedAcyclicVarVertex* const vvtxp = vtxp->as<SchedAcyclicVarVertex>();
AstVarScope* const vscp = vvtxp->vscp();
std::cerr << vscp->fileline()->warnOtherStandalone()
<< " Example path: " << vscp->prettyName() << endl;
return vscp->fileline()->warnOther() + " Example path: " + vscp->prettyName()
+ "\n";
}
}
};
@ -268,7 +267,8 @@ void gatherSCCCandidates(V3GraphVertex* vtxp, std::vector<Candidate>& candidates
}
// Find all variables in a loop (SCC) that are candidates for splitting to break loops.
void reportLoopVars(Graph* graphp, SchedAcyclicVarVertex* vvtxp) {
std::string reportLoopVars(FileLine* warnFl, Graph* graphp, SchedAcyclicVarVertex* vvtxp) {
std::ostringstream ss;
// Vector of variables in UNOPTFLAT loop that are candidates for splitting.
std::vector<Candidate> candidates;
{
@ -281,47 +281,51 @@ void reportLoopVars(Graph* graphp, SchedAcyclicVarVertex* vvtxp) {
}
// Possible we only have candidates the user cannot do anything about, so don't bother them.
if (candidates.empty()) return;
if (candidates.empty()) return "";
// There may be a very large number of candidates, so only report up to 10 of the "most
// important" signals.
unsigned splittable = 0;
const auto reportFirst10 = [&](std::function<bool(const Candidate&, const Candidate&)> less) {
const auto reportFirst10
= [&](std::function<bool(const Candidate&, const Candidate&)> less) -> string {
std::stable_sort(candidates.begin(), candidates.end(), less);
std::ostringstream ss2;
for (size_t i = 0; i < 10; i++) {
if (i == candidates.size()) break;
const Candidate& candidate = candidates[i];
AstVar* const varp = candidate.first->varp();
std::cerr << V3Error::warnMoreStandalone() << " " << varp->fileline() << " "
<< varp->prettyName() << ", width " << std::dec << varp->width()
<< ", circular fanout " << candidate.second;
ss2 << V3Error::warnMore() << " " << varp->fileline() << ' ' << varp->prettyName()
<< ", width " << std::dec << varp->width() << ", circular fanout "
<< candidate.second;
if (V3SplitVar::canSplitVar(varp)) {
std::cerr << ", can split_var";
ss2 << ", can split_var";
++splittable;
}
std::cerr << '\n';
ss2 << '\n';
}
return ss2.str();
};
// Widest variables
std::cerr << V3Error::warnMoreStandalone() << "... Widest variables candidate to splitting:\n";
reportFirst10([](const Candidate& a, const Candidate& b) {
return a.first->varp()->width() > b.first->varp()->width();
});
ss << V3Error::warnMore() << "... Widest variables candidate to splitting:\n"
<< reportFirst10([](const Candidate& a, const Candidate& b) {
return a.first->varp()->width() > b.first->varp()->width();
});
// Highest fanout
std::cerr << V3Error::warnMoreStandalone() << "... Candidates with the highest fanout:\n";
reportFirst10([](const Candidate& a, const Candidate& b) { //
return a.second > b.second;
});
ss << V3Error::warnMore() << "... Candidates with the highest fanout:\n"
<< reportFirst10([](const Candidate& a, const Candidate& b) { //
return a.second > b.second;
});
if (splittable) {
std::cerr << V3Error::warnMoreStandalone()
<< "... Suggest add /*verilator split_var*/ or /*verilator "
"isolate_assignments*/ to appropriate variables above."
<< std::endl;
ss << V3Error::warnMore()
<< "... Suggest add /*verilator split_var*/ or /*verilator "
"isolate_assignments*/ to appropriate variables above.\n";
}
V3Stats::addStat("Scheduling, split_var, candidates", splittable);
return ss.str();
}
void reportCycles(Graph* graphp, const std::vector<SchedAcyclicVarVertex*>& cutVertices) {
@ -330,17 +334,26 @@ void reportCycles(Graph* graphp, const std::vector<SchedAcyclicVarVertex*>& cutV
FileLine* const flp = vscp->fileline();
// First v3warn not inside warnIsOff so we can see the suppressions with --debug
vscp->v3warn(UNOPTFLAT, "Signal unoptimizable: Circular combinational logic: "
<< vscp->prettyNameQ());
if (!flp->warnIsOff(V3ErrorCode::UNOPTFLAT) && !flp->lastWarnWaived()) {
if (flp->warnIsOff(V3ErrorCode::UNOPTFLAT)) {
// First v3warn not inside warnIsOff so we can see the suppressions with --debug
vscp->v3warn(UNOPTFLAT, "Signal unoptimizable: Circular combinational logic: "
<< vscp->prettyNameQ());
} else {
vscp->v3warn(UNOPTFLAT,
"Signal unoptimizable: Circular combinational logic: "
<< vscp->prettyNameQ() << '\n'
<< vscp->warnContextPrimary()
<< V3Error::warnAdditionalInfo()
// Calls Graph::loopsVertexCb
<< graphp->reportLoops(&V3GraphEdge::followAlwaysTrue, vvtxp)
// Report candidate variables for splitting
<< (v3Global.opt.reportUnoptflat()
? reportLoopVars(vscp->fileline(), graphp, vvtxp)
: ""));
// Complain just once
flp->modifyWarnOff(V3ErrorCode::UNOPTFLAT, true);
// Calls Graph::loopsVertexCb
graphp->reportLoops(&V3GraphEdge::followAlwaysTrue, vvtxp);
// Create a subgraph for the UNOPTFLAT loop
if (v3Global.opt.reportUnoptflat()) {
// Report candidate variables for splitting
reportLoopVars(graphp, vvtxp);
// Create a subgraph for the UNOPTFLAT loop
V3Graph loopGraph;
graphp->subtreeLoops(&V3GraphEdge::followAlwaysTrue, vvtxp, &loopGraph);
loopGraph.dumpDotFilePrefixedAlways("unoptflat");

View File

@ -256,7 +256,7 @@ public:
}
}
}
void cellErrorScopes(AstNode* lookp, string prettyName = "") {
string cellErrorScopes(AstNode* lookp, string prettyName = "") {
if (prettyName == "") prettyName = lookp->prettyName();
string scopes;
for (IdNameMap::iterator it = m_idNameMap.begin(); it != m_idNameMap.end(); ++it) {
@ -267,9 +267,9 @@ public:
}
}
if (scopes == "") scopes = "<no instances found>";
std::cerr << V3Error::warnMoreStandalone() << "... Known scopes under '" << prettyName
<< "': " << scopes << endl;
if (debug()) dumpSelf(std::cerr, " KnownScope: ", 1);
return V3Error::warnMore() + "... Known scopes under '" + prettyName + "': " + scopes
+ '\n';
}
};

View File

@ -5876,9 +5876,12 @@ class WidthVisitor final : public VNVisitor {
// We've resolved parameters and hit a module that we couldn't resolve. It's
// finally time to report it.
// Note only here in V3Width as this is first visitor after V3Dead.
nodep->modNameFileline()->v3error("Cannot find file containing module: '"
<< nodep->modName() << "'");
v3Global.opt.filePathLookedMsg(nodep->modNameFileline(), nodep->modName());
nodep->modNameFileline()->v3error(
"Cannot find file containing module: '"
<< nodep->modName() << "'\n"
<< nodep->modNameFileline()->warnContextPrimary()
<< V3Error::warnAdditionalInfo()
<< v3Global.opt.filePathLookedMsg(nodep->modNameFileline(), nodep->modName()));
}
if (nodep->rangep()) userIterateAndNext(nodep->rangep(), WidthVP{SELF, BOTH}.p());
userIterateAndNext(nodep->pinsp(), nullptr);

View File

@ -2,9 +2,7 @@
8 | nfound nfound();
| ^~~~~~
... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance.
%Error: t/t_gen_nonconst_bad.v:8:4: This may be because there's no search path specified with -I<dir>.
8 | nfound nfound();
| ^~~~~~
... This may be because there's no search path specified with -I<dir>.
... Looked in:
nfound
nfound.v

View File

@ -1,6 +1,6 @@
%Error: t/t_interface_mismodport_bad.v:32:12: Can't find definition of 'bad' in dotted signal: 'isub.bad'
32 | isub.bad = i_value;
| ^~~
... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance.
... Known scopes under 'bad': <no instances found>
... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance.
%Error: Exiting due to