From 6cf50e6579322911b9a8b7984fe4961dcf3b558d Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Sun, 8 Jun 2014 21:36:18 -0400 Subject: [PATCH] Fix string corruption, bug780. --- Changes | 2 ++ include/verilated.cpp | 6 +++--- include/verilated_save.cpp | 9 ++++++--- include/verilated_vcd_c.cpp | 14 ++++++++------ include/verilated_vpi.h | 23 ++++++++--------------- src/V3Ast.cpp | 4 ++-- src/V3Const.cpp | 5 +++-- src/V3EmitC.cpp | 22 ++++++++++++---------- src/V3EmitCSyms.cpp | 3 ++- src/V3EmitMk.cpp | 15 +++++++-------- src/V3File.cpp | 17 +++++++++++------ src/V3File.h | 5 +++-- src/V3Gate.cpp | 9 +++++---- src/V3LinkResolve.cpp | 4 ++-- src/V3Options.cpp | 5 +++-- src/V3Order.cpp | 4 ++-- src/V3PreLex.l | 2 +- src/V3PreProc.cpp | 24 +++++++++++++++--------- src/V3TraceDecl.cpp | 2 +- src/V3Undriven.cpp | 7 ++++--- src/V3Width.cpp | 5 +++-- src/Verilator.cpp | 8 ++++---- test_regress/t/t_dist_portability.pl | 19 +++++++++++++++++++ 23 files changed, 126 insertions(+), 88 deletions(-) diff --git a/Changes b/Changes index 11bc827bb..04e6a4305 100644 --- a/Changes +++ b/Changes @@ -29,6 +29,8 @@ indicates the contributor was also the author of the fix; Thanks! **** Fix ENDLABEL warnings on escaped identifiers. +**** Fix string corruption, bug780. [Derek Lockhart] + * Verilator 3.860 2014-05-11 diff --git a/include/verilated.cpp b/include/verilated.cpp index 8733c4367..ce1bcdcfd 100644 --- a/include/verilated.cpp +++ b/include/verilated.cpp @@ -1250,9 +1250,9 @@ void VerilatedScope::scopeDump() const { m_callbacksp[i], VerilatedImp::exportName(i)); } } - if (varsp()) { - for (VerilatedVarNameMap::const_iterator it = varsp()->begin(); - it != varsp()->end(); ++it) { + if (VerilatedVarNameMap* varsp = this->varsp()) { + for (VerilatedVarNameMap::const_iterator it = varsp->begin(); + it != varsp->end(); ++it) { VL_PRINTF(" VAR %p: %s\n", &(it->second), it->first); } } diff --git a/include/verilated_save.cpp b/include/verilated_save.cpp index b307ef4ab..14ad598d6 100644 --- a/include/verilated_save.cpp +++ b/include/verilated_save.cpp @@ -62,8 +62,9 @@ bool VerilatedDeserialize::readDiffers (const void* __restrict datap, size_t siz VerilatedDeserialize& VerilatedDeserialize::readAssert (const void* __restrict datap, size_t size) { if (VL_UNLIKELY(readDiffers(datap,size))) { + string fn = filename(); string msg = (string)"Can't deserialize save-restore file as was made from different model"; - vl_fatal(filename().c_str(), 0, "", msg.c_str()); + vl_fatal(fn.c_str(), 0, "", msg.c_str()); close(); } return *this; // For function chaining @@ -82,8 +83,9 @@ void VerilatedSerialize::header() { void VerilatedDeserialize::header() { VerilatedDeserialize& os = *this; // So can cut and paste standard >> code below if (VL_UNLIKELY(os.readDiffers(VLTSAVE_HEADER_STR, strlen(VLTSAVE_HEADER_STR)))) { + string fn = filename(); string msg = (string)"Can't deserialize; file has wrong header signature"; - vl_fatal(filename().c_str(), 0, "", msg.c_str()); + vl_fatal(fn.c_str(), 0, "", msg.c_str()); close(); } os.read(Verilated::serializedPtr(), Verilated::serializedSize()); @@ -98,8 +100,9 @@ void VerilatedSerialize::trailer() { void VerilatedDeserialize::trailer() { VerilatedDeserialize& os = *this; // So can cut and paste standard >> code below if (VL_UNLIKELY(os.readDiffers(VLTSAVE_TRAILER_STR, strlen(VLTSAVE_TRAILER_STR)))) { + string fn = filename(); string msg = (string)"Can't deserialize; file has wrong end-of-file signature"; - vl_fatal(filename().c_str(), 0, "", msg.c_str()); + vl_fatal(fn.c_str(), 0, "", msg.c_str()); close(); } } diff --git a/include/verilated_vcd_c.cpp b/include/verilated_vcd_c.cpp index e03b608fd..d0fb45017 100644 --- a/include/verilated_vcd_c.cpp +++ b/include/verilated_vcd_c.cpp @@ -172,8 +172,8 @@ void VerilatedVcd::makeNameMap() { // This comes from user instantiations with no name - IE Vtop(""). bool nullScope = false; for (NameMap::iterator it=m_namemapp->begin(); it!=m_namemapp->end(); ++it) { - const char* hiername = (*it).first.c_str(); - if (hiername[0] == '\t') nullScope=true; + const string& hiername = it->first; + if (hiername.size() >= 1 && hiername[0] == '\t') nullScope=true; } if (nullScope) { NameMap* newmapp = new NameMap; @@ -352,7 +352,8 @@ void VerilatedVcd::dumpHeader () { printStr("$date "); printStr(ctime(&time_str)); printStr(" $end\n"); printStr("$timescale "); - printStr(doubleToTimescale(m_timeRes).c_str()); + const string& timeResStr = doubleToTimescale(m_timeRes); + printStr(timeResStr.c_str()); printStr(" $end\n"); makeNameMap(); @@ -370,10 +371,11 @@ void VerilatedVcd::dumpHeader () { // Print the signal names const char* lastName = ""; for (NameMap::iterator it=m_namemapp->begin(); it!=m_namemapp->end(); ++it) { - const char* hiername = (*it).first.c_str(); - const char* decl = (*it).second.c_str(); + const string& hiernamestr = it->first; + const string& decl = it->second; // Determine difference between the old and new names + const char* hiername = hiernamestr.c_str(); const char* lp = lastName; const char* np = hiername; lastName = hiername; @@ -408,7 +410,7 @@ void VerilatedVcd::dumpHeader () { } printIndent(0); - printStr(decl); + printStr(decl.c_str()); } while (m_modDepth>1) { diff --git a/include/verilated_vpi.h b/include/verilated_vpi.h index bc5865db4..eb6cae5e6 100644 --- a/include/verilated_vpi.h +++ b/include/verilated_vpi.h @@ -259,10 +259,11 @@ public: virtual const vluint32_t type() { return vpiIterator; } virtual vpiHandle dovpi_scan() { if (VL_LIKELY(m_scopep->varsp())) { - if (VL_UNLIKELY(!m_started)) { m_it = m_scopep->varsp()->begin(); m_started=true; } - else if (VL_UNLIKELY(m_it == m_scopep->varsp()->end())) return 0; + VerilatedVarNameMap* varsp = m_scopep->varsp(); + if (VL_UNLIKELY(!m_started)) { m_it = varsp->begin(); m_started=true; } + else if (VL_UNLIKELY(m_it == varsp->end())) return 0; else ++m_it; - if (m_it == m_scopep->varsp()->end()) return 0; + if (m_it == varsp->end()) return 0; return ((new VerilatedVpioVar(&(m_it->second), m_scopep)) ->castVpiHandle()); } else { @@ -430,15 +431,10 @@ class VerilatedVpiError { t_vpi_error_info m_errorInfo; bool m_flag; char m_buff[VL_VPI_LINE_SIZE]; - void setError(PLI_BYTE8 *message, PLI_BYTE8 *file, PLI_INT32 line) { + void setError(PLI_BYTE8 *message, PLI_BYTE8 *code, PLI_BYTE8 *file, PLI_INT32 line) { m_errorInfo.message = message; m_errorInfo.file = file; m_errorInfo.line = line; - m_errorInfo.code = NULL; - do_callbacks(); - } - void setError(PLI_BYTE8 *message, PLI_BYTE8 *code, PLI_BYTE8 *file, PLI_INT32 line) { - setError( message, file, line); m_errorInfo.code = code; do_callbacks(); } @@ -464,14 +460,11 @@ public: return this; } void setMessage(string file, PLI_INT32 line, string message, ...) { + static VL_THREAD string filehold; _VL_VPI_ERROR_SET; m_errorInfo.state = vpiPLI; - setError((PLI_BYTE8*)m_buff, (PLI_BYTE8*)file.c_str(), line); - } - void setMessage(PLI_BYTE8 *code, PLI_BYTE8 *file, PLI_INT32 line, string message, ...) { - _VL_VPI_ERROR_SET; - m_errorInfo.state = vpiPLI; - setError((PLI_BYTE8*)message.c_str(), code, file, line); + filehold = file; + setError((PLI_BYTE8*)m_buff, NULL, (PLI_BYTE8*)filehold.c_str(), line); } p_vpi_error_info getError() { if (m_flag) return &m_errorInfo; diff --git a/src/V3Ast.cpp b/src/V3Ast.cpp index 78804e7ea..b3ba3f865 100644 --- a/src/V3Ast.cpp +++ b/src/V3Ast.cpp @@ -915,8 +915,8 @@ ostream& operator<<(ostream& os, V3Hash rhs) { V3Hash::V3Hash(const string& name) { uint32_t val = 0; - for (const char* c=name.c_str(); *c; c++) { - val = val*31 + *c; + for (string::const_iterator it = name.begin(); it!=name.end(); ++it) { + val = val*31 + *it; } setBoth(1,val); } diff --git a/src/V3Const.cpp b/src/V3Const.cpp index 73d5aaeef..9f9f18cb6 100644 --- a/src/V3Const.cpp +++ b/src/V3Const.cpp @@ -1696,8 +1696,9 @@ private: string fmt = ""; bool inPct = false; AstNode* argp = nodep->exprsp(); - for (const char* inp = nodep->text().c_str(); *inp; inp++) { - char ch = *inp; // Breaks with iterators... + string text = nodep->text(); + for (string::const_iterator it = text.begin(); it!=text.end(); ++it) { + char ch = *it; if (!inPct && ch=='%') { inPct = true; fmt = ch; diff --git a/src/V3EmitC.cpp b/src/V3EmitC.cpp index 3c0e2e9a2..8cfc030f7 100644 --- a/src/V3EmitC.cpp +++ b/src/V3EmitC.cpp @@ -246,12 +246,14 @@ public: char format = '?'; bool pct=false; int got=0; - for (const char* cp = nodep->text().c_str(); *cp; cp++) { + string txt = nodep->text(); + for (string::const_iterator it=txt.begin(); it!=txt.end(); ++it) { + char ch = *it; if (pct) { pct = false; - switch (tolower(*cp)) { + switch (tolower(ch)) { case '%': - prefix += *cp; + prefix += ch; break; case 'd': // FALLTHRU case 'o': // FALLTHRU @@ -259,22 +261,22 @@ public: case 'x': // FALLTHRU case 'b': // FALLTHRU case 's': - got++; format = tolower(*cp); + got++; format = tolower(ch); break; case 'e': // FALLTHRU case 'f': // FALLTHRU case 'g': - got++; format = tolower(*cp); - nodep->v3error("Unsupported $value$plusargs format qualifier: '"<<*cp<<"'"<v3error("Unsupported $value$plusargs format qualifier: '"<v3error("Illegal $value$plusargs format qualifier: '"<<*cp<<"'"<v3error("Illegal $value$plusargs format qualifier: '"<v3error("Missing or extra $value$plusargs format qualifier: '"<text()<<"'"<attrFileDescr() // Zero it out, so we don't core dump if never call $fopen || (varp->basicp() && varp->basicp()->isZeroInit()) - || (varp->name().c_str()[0]=='_' && v3Global.opt.underlineZero())); + || (varp->name().size()>=1 && varp->name()[0]=='_' && v3Global.opt.underlineZero())); if (varp->isWide()) { // DOCUMENT: We randomize everything. If the user wants a _var to be zero, // there should be a initial statement. (Different from verilator2.) diff --git a/src/V3EmitCSyms.cpp b/src/V3EmitCSyms.cpp index 156fcd38d..991cbcadd 100644 --- a/src/V3EmitCSyms.cpp +++ b/src/V3EmitCSyms.cpp @@ -383,7 +383,8 @@ void EmitCSyms::emitSymImp() { AstScope* scopep = it->first; AstNodeModule* modp = it->second; if (modp->isTop()) { } else { - ofp()->printf("\t%c %-30s ", comma, scopep->nameDotless().c_str()); + string nameDl = scopep->nameDotless(); + ofp()->printf("\t%c %-30s ", comma, nameDl.c_str()); puts("(Verilated::catName(topp->name(),"); // The "." is added by catName putsQuoted(scopep->prettyName()); diff --git a/src/V3EmitMk.cpp b/src/V3EmitMk.cpp index 20afad121..272b00757 100644 --- a/src/V3EmitMk.cpp +++ b/src/V3EmitMk.cpp @@ -164,16 +164,16 @@ public: of.puts("# User CFLAGS (from -CFLAGS on Verilator command line)\n"); of.puts("VM_USER_CFLAGS = \\\n"); - for (V3StringSet::const_iterator it = v3Global.opt.cFlags().begin(); - it != v3Global.opt.cFlags().end(); ++it) { + const V3StringSet& cFlags = v3Global.opt.cFlags(); + for (V3StringSet::const_iterator it = cFlags.begin(); it != cFlags.end(); ++it) { of.puts("\t"+*it+" \\\n"); } of.puts("\n"); of.puts("# User LDLIBS (from -LDFLAGS on Verilator command line)\n"); of.puts("VM_USER_LDLIBS = \\\n"); - for (V3StringSet::const_iterator it = v3Global.opt.ldLibs().begin(); - it != v3Global.opt.ldLibs().end(); ++it) { + const V3StringSet& ldLibs = v3Global.opt.ldLibs(); + for (V3StringSet::const_iterator it = ldLibs.begin(); it != ldLibs.end(); ++it) { of.puts("\t"+*it+" \\\n"); } of.puts("\n"); @@ -181,8 +181,8 @@ public: V3StringSet dirs; of.puts("# User .cpp files (from .cpp's on Verilator command line)\n"); of.puts("VM_USER_CLASSES = \\\n"); - for (V3StringSet::const_iterator it = v3Global.opt.cppFiles().begin(); - it != v3Global.opt.cppFiles().end(); ++it) { + const V3StringSet& cppFiles = v3Global.opt.cppFiles(); + for (V3StringSet::const_iterator it = cppFiles.begin(); it != cppFiles.end(); ++it) { string cppfile = *it; of.puts("\t"+V3Options::filenameNonExt(cppfile)+" \\\n"); string dir = V3Options::filenameDir(cppfile); @@ -207,8 +207,7 @@ public: of.puts("\n### Executable rules... (from --exe)\n"); of.puts("VPATH += $(VM_USER_DIR)\n"); of.puts("\n"); - for (V3StringSet::const_iterator it = v3Global.opt.cppFiles().begin(); - it != v3Global.opt.cppFiles().end(); ++it) { + for (V3StringSet::const_iterator it = cppFiles.begin(); it != cppFiles.end(); ++it) { string cppfile = *it; string basename = V3Options::filenameNonExt(cppfile); of.puts(basename+".o: "+cppfile+"\n"); diff --git a/src/V3File.cpp b/src/V3File.cpp index 100e187c4..8cba41fd0 100644 --- a/src/V3File.cpp +++ b/src/V3File.cpp @@ -71,7 +71,8 @@ class V3FileDependImp { time_t mtime() const { return m_stat.st_mtime; } void loadStats() { if (!m_stat.st_mtime) { - int err = stat(filename().c_str(), &m_stat); + string fn = filename(); + int err = stat(fn.c_str(), &m_stat); if (err!=0) { m_stat.st_mtime = 1; // Not a error... This can occur due to `line directives in the .vpp files @@ -258,15 +259,19 @@ bool V3File::checkTimes(const string& filename, const string& cmdline) { return dependImp.checkTimes(filename, cmdline); } +void V3File::createDir(const string& dirname) { +#ifndef _WIN32 + mkdir(dirname.c_str(), 0777); +#else + mkdir(dirname.c_str()); +#endif +} + void V3File::createMakeDir() { static bool created = false; if (!created) { created = true; -#ifndef _WIN32 - mkdir(v3Global.opt.makeDir().c_str(), 0777); -#else - mkdir(v3Global.opt.makeDir().c_str()); -#endif + createDir(v3Global.opt.makeDir()); } } diff --git a/src/V3File.h b/src/V3File.h index b41364cfa..c64db803d 100644 --- a/src/V3File.h +++ b/src/V3File.h @@ -67,6 +67,7 @@ public: static bool checkTimes(const string& filename, const string& cmdline); // Directory utilities + static void createDir(const string& dirname); static void createMakeDir(); }; @@ -188,8 +189,8 @@ public: } virtual ~V3OutCFile() {} virtual void putsCellDecl(const string& classname, const string& cellname) { - this->printf("%-19s\t%s;\n", - (classname + "*").c_str(),cellname.c_str()); + string classStar = classname + "*"; + this->printf("%-19s\t%s;\n", classStar.c_str(), cellname.c_str()); } virtual void putsHeader() { puts("// Verilated -*- C++ -*-\n"); } virtual void putsIntTopInclude() { } diff --git a/src/V3Gate.cpp b/src/V3Gate.cpp index f7429f108..9096158f6 100644 --- a/src/V3Gate.cpp +++ b/src/V3Gate.cpp @@ -258,8 +258,8 @@ public: if (!m_substTreep) { clearSimple("No assignment found\n"); } - for (GateVarRefList::const_iterator it = rhsVarRefs().begin(); - it != rhsVarRefs().end(); ++it) { + for (GateVarRefList::const_iterator it = m_rhsVarRefs.begin(); + it != m_rhsVarRefs.end(); ++it) { if (m_lhsVarRef && m_lhsVarRef->varScopep() == (*it)->varScopep()) { clearSimple("Circular logic\n"); // Oh my, we'll get a UNOPTFLAT much later. } @@ -593,8 +593,9 @@ void GateVisitor::optimizeSignals(bool allowMultiIn) { optimizeElimVar(vvertexp->varScp(), substp, consumerp); // If the new replacement referred to a signal, // Correct the graph to point to this new generating variable - for (GateVarRefList::const_iterator it = okVisitor.rhsVarRefs().begin(); - it != okVisitor.rhsVarRefs().end(); ++it) { + const GateVarRefList& rhsVarRefs = okVisitor.rhsVarRefs(); + for (GateVarRefList::const_iterator it = rhsVarRefs.begin(); + it != rhsVarRefs.end(); ++it) { AstVarScope* newvarscp = (*it)->varScopep(); UINFO(9," Point-to-new vertex "<=1) m_prefix = string("V")+filenameNonExt(*(vFilesList.begin())); if (modPrefix()=="") m_modPrefix = prefix(); // Find files in makedir diff --git a/src/V3Order.cpp b/src/V3Order.cpp index e48f8f46d..3e2998c68 100644 --- a/src/V3Order.cpp +++ b/src/V3Order.cpp @@ -1191,14 +1191,14 @@ void OrderVisitor::processMove() { while (!m_pomReadyDomScope.empty()) { // Start with top node on ready list's domain & scope OrderMoveDomScope* domScopep = m_pomReadyDomScope.begin(); - OrderMoveVertex* topVertexp = domScopep->readyVertices().begin(); + OrderMoveVertex* topVertexp = domScopep->readyVertices().begin(); // lintok-begin-on-ref UASSERT(topVertexp, "domScope on ready list without any nodes ready under it"); // Work on all scopes ready inside this domain while (domScopep) { UINFO(6," MoveDomain l="<domainp()<readyVertices().begin()) { + while (OrderMoveVertex* vertexp = domScopep->readyVertices().begin()) { // lintok-begin-on-ref processMoveOne(vertexp, domScopep, 1); } // Done with scope/domain pair, pick new scope under same domain, or NULL if none left diff --git a/src/V3PreLex.l b/src/V3PreLex.l index d22cbeca9..b58b67132 100644 --- a/src/V3PreLex.l +++ b/src/V3PreLex.l @@ -107,7 +107,7 @@ psl [p]sl /* Optional directives we recognize */ "`__FILE__" { static string rtnfile; - rtnfile = '"'; rtnfile += LEXP->curFilelinep()->filename().c_str(); + rtnfile = '"'; rtnfile += LEXP->curFilelinep()->filename(); rtnfile += '"'; yytext=(char*)rtnfile.c_str(); yyleng = rtnfile.length(); return (VP_STRING); } "`__LINE__" { static char buf[10]; diff --git a/src/V3PreProc.cpp b/src/V3PreProc.cpp index 49c55c588..e5b7b1663 100644 --- a/src/V3PreProc.cpp +++ b/src/V3PreProc.cpp @@ -566,7 +566,8 @@ string V3PreProcImp::defineSubst(V3DefineRef* refp) { bool quote = false; bool haveDefault = false; // Note there's a leading ( and trailing ), so parens==1 is the base parsing level - const char* cp=refp->params().c_str(); + string params = refp->params(); // Must keep in scope + const char* cp=params.c_str(); if (*cp == '(') cp++; for (; *cp; cp++) { //UINFO(4," Parse Paren="<m_tokFilelinep->lineno(), - tokenName(tok), V3PreLex::cleanDbgStrg(buf).c_str()); + if (0 && debug()>=5) { + string bufcln = V3PreLex::cleanDbgStrg(buf); + fprintf (stderr,"%d: FIN: %-10s: %s\n", + m_lexp->m_tokFilelinep->lineno(), tokenName(tok), bufcln.c_str()); + } // Track `line const char* bufp = buf.c_str(); while (*bufp == '\n') bufp++; @@ -1400,7 +1403,7 @@ int V3PreProcImp::getFinalToken(string& buf) { } } // Track newlines in prep for next token - for (const char* cp = buf.c_str(); *cp; cp++) { + for (string::iterator cp=buf.begin(); cp!=buf.end(); ++cp) { if (*cp == '\n') { m_finAtBol = true; m_finFilelinep->linenoIncInPlace(); // Increment in place to avoid new/delete calls. It's private data. @@ -1422,8 +1425,9 @@ string V3PreProcImp::getline() { string buf; int tok = getFinalToken(buf/*ref*/); if (debug()>=5) { + string bufcln = V3PreLex::cleanDbgStrg(buf); fprintf (stderr,"%d: GETFETC: %-10s: %s\n", - m_lexp->m_tokFilelinep->lineno(), tokenName(tok), V3PreLex::cleanDbgStrg(buf).c_str()); + m_lexp->m_tokFilelinep->lineno(), tokenName(tok), bufcln.c_str()); } if (tok==VP_EOF) { // Add a final newline, if the user forgot the final \n. @@ -1444,8 +1448,10 @@ string V3PreProcImp::getline() { int len = rtnp-m_lineChars.c_str()+1; string theLine(m_lineChars, 0, len); m_lineChars = m_lineChars.erase(0,len); // Remove returned characters - if (debug()>=4) fprintf (stderr,"%d: GETLINE: %s\n", - m_lexp->m_tokFilelinep->lineno(), - V3PreLex::cleanDbgStrg(theLine).c_str()); + if (debug()>=4) { + string lncln = V3PreLex::cleanDbgStrg(theLine); + fprintf (stderr,"%d: GETLINE: %s\n", + m_lexp->m_tokFilelinep->lineno(), lncln.c_str()); + } return theLine; } diff --git a/src/V3TraceDecl.cpp b/src/V3TraceDecl.cpp index a6b36d527..e4183903e 100644 --- a/src/V3TraceDecl.cpp +++ b/src/V3TraceDecl.cpp @@ -73,7 +73,7 @@ private: return "Verilator trace_off"; } else if (!v3Global.opt.traceUnderscore()) { - if (prettyName.c_str()[0] == '_') + if (prettyName.size()>=1 && prettyName[0] == '_') return "Leading underscore"; if (prettyName.find("._") != string::npos) return "Inlined leading underscore"; diff --git a/src/V3Undriven.cpp b/src/V3Undriven.cpp index 06636dfa8..94435f547 100644 --- a/src/V3Undriven.cpp +++ b/src/V3Undriven.cpp @@ -145,9 +145,10 @@ public: return isUsedNotDrivenBit(0, m_flags.size()/FLAGS_PER_BIT); } bool unusedMatch(AstVar* nodep) { - const char* regexpp = v3Global.opt.unusedRegexp().c_str(); - if (!regexpp || !*regexpp) return false; - return VString::wildmatch(nodep->prettyName().c_str(), regexpp); + string regexp = v3Global.opt.unusedRegexp(); + if (regexp == "") return false; + string prettyName = nodep->prettyName(); + return VString::wildmatch(prettyName.c_str(), regexp.c_str()); } void reportViolations() { // Combine bits into overall state diff --git a/src/V3Width.cpp b/src/V3Width.cpp index 700d140a7..ff95810e8 100644 --- a/src/V3Width.cpp +++ b/src/V3Width.cpp @@ -1678,8 +1678,9 @@ private: string dispout = ""; bool inPct = false; AstNode* argp = nodep->exprsp(); - for (const char* inp = nodep->text().c_str(); *inp; inp++) { - char ch = *inp; // Breaks with iterators... + string txt = nodep->text(); + for (string::const_iterator it = txt.begin(); it!=txt.end(); ++it) { + char ch = *it; if (!inPct && ch=='%') { inPct = true; } else if (inPct && isdigit(ch)) { diff --git a/src/Verilator.cpp b/src/Verilator.cpp index d8db2e500..33625e6d7 100644 --- a/src/Verilator.cpp +++ b/src/Verilator.cpp @@ -116,8 +116,8 @@ void V3Global::readFiles() { V3Parse parser (v3Global.rootp(), &filter, &parseSyms); // Read top module - for (V3StringList::const_iterator it = v3Global.opt.vFiles().begin(); - it != v3Global.opt.vFiles().end(); ++it) { + const V3StringList& vFiles = v3Global.opt.vFiles(); + for (V3StringList::const_iterator it = vFiles.begin(); it != vFiles.end(); ++it) { string filename = *it; parser.parseFile(new FileLine("COMMAND_LINE",0), filename, false, "Cannot find file containing module: "); @@ -126,8 +126,8 @@ void V3Global::readFiles() { // Read libraries // To be compatible with other simulators, // this needs to be done after the top file is read - for (V3StringSet::const_iterator it = v3Global.opt.libraryFiles().begin(); - it != v3Global.opt.libraryFiles().end(); ++it) { + const V3StringSet& libraryFiles = v3Global.opt.libraryFiles(); + for (V3StringSet::const_iterator it = libraryFiles.begin(); it != libraryFiles.end(); ++it) { string filename = *it; parser.parseFile(new FileLine("COMMAND_LINE",0), filename, true, "Cannot find file containing library module: "); diff --git a/test_regress/t/t_dist_portability.pl b/test_regress/t/t_dist_portability.pl index 99123d6e1..96913a4d9 100755 --- a/test_regress/t/t_dist_portability.pl +++ b/test_regress/t/t_dist_portability.pl @@ -17,6 +17,7 @@ if (!-r "$root/.git") { } else { uint(); printfll(); + cstr(); } ok(1); @@ -67,4 +68,22 @@ sub printfll { } } +sub cstr { + my $files = "src/*.c* src/*.h include/*.c* include/*.h test_c/*.c* test_regress/t/*.c* test_regress/t/*.h"; + my $cmd = "cd $root && grep -n -P 'c_str|begin|end' $files | sort"; + print "C $cmd\n"; + my $grep = `$cmd`; + my %names; + foreach my $line (split /\n/, $grep) { + if ($line =~ /^([^:]+).*\(\)[a-z0-9_().->]*[.->]+(c_str|r?begin|r?end)\(\)/) { + next if $line =~ /lintok-begin-on-ref/; + print "$line\n"; + $names{$1} = 1; + } + } + if (keys %names) { + $Self->error("Files with potential c_str() lifetime issue: ",join(' ',sort keys %names)); + } +} + 1;