forked from github/verilator
Fix string corruption, bug780.
This commit is contained in:
parent
69468708e2
commit
6cf50e6579
2
Changes
2
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
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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<<"'"<<endl);
|
||||
got++; format = tolower(ch);
|
||||
nodep->v3error("Unsupported $value$plusargs format qualifier: '"<<ch<<"'"<<endl);
|
||||
break;
|
||||
default:
|
||||
got++;
|
||||
nodep->v3error("Illegal $value$plusargs format qualifier: '"<<*cp<<"'"<<endl);
|
||||
nodep->v3error("Illegal $value$plusargs format qualifier: '"<<ch<<"'"<<endl);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (*cp == '%') pct = true;
|
||||
else prefix += *cp;
|
||||
else if (ch == '%') pct = true;
|
||||
else prefix += ch;
|
||||
}
|
||||
if (got!=1) nodep->v3error("Missing or extra $value$plusargs format qualifier: '"<<nodep->text()<<"'"<<endl);
|
||||
puts("VL_VALUEPLUSARGS_I");
|
||||
@ -1382,7 +1384,7 @@ void EmitCImp::emitVarResets(AstNodeModule* modp) {
|
||||
}
|
||||
bool zeroit = (varp->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.)
|
||||
|
@ -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());
|
||||
|
@ -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");
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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() { }
|
||||
|
@ -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 "<<newvarscp<<endl);
|
||||
GateVarVertex* varvertexp = makeVarVertex(newvarscp);
|
||||
|
@ -250,8 +250,8 @@ private:
|
||||
void expectFormat(AstNode* nodep, const string& format, AstNode* argp, bool isScan) {
|
||||
// Check display arguments
|
||||
bool inPct = false;
|
||||
for (const char* inp = format.c_str(); *inp; inp++) {
|
||||
char ch = tolower(*inp); // Breaks with iterators...
|
||||
for (string::const_iterator it = format.begin(); it != format.end(); ++it) {
|
||||
char ch = tolower(*it);
|
||||
if (!inPct && ch=='%') {
|
||||
inPct = true;
|
||||
} else if (inPct) {
|
||||
|
@ -622,13 +622,14 @@ void V3Options::parseOpts (FileLine* fl, int argc, char** argv) {
|
||||
|
||||
// Default certain options and error check
|
||||
// Detailed error, since this is what we often get when run with minimal arguments
|
||||
if (vFiles().empty()) {
|
||||
const V3StringList& vFilesList = vFiles();
|
||||
if (vFilesList.empty()) {
|
||||
v3fatal("verilator: No Input Verilog file specified on command line, see verilator --help for more information\n");
|
||||
}
|
||||
|
||||
// Default prefix to the filename
|
||||
if (prefix()=="" && topModule()!="") m_prefix = string("V")+topModule();
|
||||
if (prefix()=="") m_prefix = string("V")+filenameNonExt(*(vFiles().begin()));
|
||||
if (prefix()=="" && vFilesList.size()>=1) m_prefix = string("V")+filenameNonExt(*(vFilesList.begin()));
|
||||
if (modPrefix()=="") m_modPrefix = prefix();
|
||||
|
||||
// Find files in makedir
|
||||
|
@ -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="<<domScopep->domainp()<<endl);
|
||||
// Process all nodes ready under same domain & scope
|
||||
m_pomNewFuncp = NULL;
|
||||
while (OrderMoveVertex* vertexp = domScopep->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
|
||||
|
@ -107,7 +107,7 @@ psl [p]sl
|
||||
|
||||
/* Optional directives we recognize */
|
||||
<INITIAL>"`__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); }
|
||||
<INITIAL>"`__LINE__" { static char buf[10];
|
||||
|
@ -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="<<paren<<" Arg="<<numArgs<<" token='"<<token<<"' Parse="<<cp<<endl);
|
||||
@ -1367,9 +1368,11 @@ int V3PreProcImp::getFinalToken(string& buf) {
|
||||
}
|
||||
int tok = m_finToken;
|
||||
buf = m_finBuf;
|
||||
if (0 && debug()>=5) fprintf (stderr,"%d: FIN: %-10s: %s\n",
|
||||
m_lexp->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;
|
||||
}
|
||||
|
@ -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";
|
||||
|
@ -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
|
||||
|
@ -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)) {
|
||||
|
@ -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: ");
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user