diff --git a/include/verilated.cpp b/include/verilated.cpp index d6196159c..1a34b7117 100644 --- a/include/verilated.cpp +++ b/include/verilated.cpp @@ -495,7 +495,7 @@ void _vl_vsformat(string& output, const char* formatp, va_list ap) { case 'u': // Packed 2-state output.reserve(output.size() + 4*VL_WORDS_I(lbits)); for (int i=0; i> 0) & 0xff); + output += (char)((lwp[i] ) & 0xff); output += (char)((lwp[i] >> 8) & 0xff); output += (char)((lwp[i] >> 16) & 0xff); output += (char)((lwp[i] >> 24) & 0xff); @@ -504,7 +504,7 @@ void _vl_vsformat(string& output, const char* formatp, va_list ap) { case 'z': // Packed 4-state output.reserve(output.size() + 8*VL_WORDS_I(lbits)); for (int i=0; i> 0) & 0xff); + output += (char)((lwp[i] ) & 0xff); output += (char)((lwp[i] >> 8) & 0xff); output += (char)((lwp[i] >> 16) & 0xff); output += (char)((lwp[i] >> 24) & 0xff); @@ -654,7 +654,7 @@ IData _vl_vsscanf(FILE* fp, // If a fscanf // Deal with all read-and-scan somethings // Note LSBs are preserved if there's an overflow const int obits = va_arg(ap, int); - WData qowp[2]; + WData qowp[2] = {0, 0}; WDataOutP owp = qowp; if (obits > VL_QUADSIZE) { owp = va_arg(ap,WDataOutP); @@ -1095,7 +1095,7 @@ void VL_READMEM_N(bool hex, int width, int depth, int array_lsb, int fnwords, } lastc = c; } - if (needinc) { addr++; needinc=false; } + if (needinc) { addr++; } // Final checks fclose(fp); @@ -1250,7 +1250,7 @@ const char* Verilated::catName(const char* n1, const char* n2) { static char* strp = NULL; static size_t len = 0; size_t newlen = strlen(n1)+strlen(n2)+2; - if (newlen > len) { + if (!strp || newlen > len) { if (strp) delete [] strp; strp = new char[newlen]; len = newlen; diff --git a/include/verilated_cov.cpp b/include/verilated_cov.cpp index b6fa82e59..8e0d2f936 100644 --- a/include/verilated_cov.cpp +++ b/include/verilated_cov.cpp @@ -72,6 +72,7 @@ private: T* m_countp; ///< Count value public: // METHODS + // cppcheck-suppress truncLongCastReturn virtual vluint64_t count() const { return *m_countp; } virtual void zero() const { *m_countp = 0; } // CONSTRUCTORS diff --git a/include/verilated_vcd_c.cpp b/include/verilated_vcd_c.cpp index fd45389dd..2115d43d3 100644 --- a/include/verilated_vcd_c.cpp +++ b/include/verilated_vcd_c.cpp @@ -570,6 +570,7 @@ void VerilatedVcd::declDouble (vluint32_t code, const char* name, int arraynum //============================================================================= void VerilatedVcd::fullDouble (vluint32_t code, const double newval) { + // cppcheck-suppress invalidPointerCast (*((double*)&m_sigs_oldvalp[code])) = newval; // Buffer can't overflow before sprintf; we sized during declaration sprintf(m_writep, "r%.16g", newval); @@ -578,6 +579,7 @@ void VerilatedVcd::fullDouble (vluint32_t code, const double newval) { bufferCheck(); } void VerilatedVcd::fullFloat (vluint32_t code, const float newval) { + // cppcheck-suppress invalidPointerCast (*((float*)&m_sigs_oldvalp[code])) = newval; // Buffer can't overflow before sprintf; we sized during declaration sprintf(m_writep, "r%.16g", (double)newval); diff --git a/include/verilated_vcd_c.h b/include/verilated_vcd_c.h index 5f925e7d2..f61b969c6 100644 --- a/include/verilated_vcd_c.h +++ b/include/verilated_vcd_c.h @@ -382,11 +382,13 @@ public: } } inline void chgDouble (vluint32_t code, const double newval) { + // cppcheck-suppress invalidPointerCast if (VL_UNLIKELY((*((double*)&m_sigs_oldvalp[code])) != newval)) { fullDouble (code, newval); } } inline void chgFloat (vluint32_t code, const float newval) { + // cppcheck-suppress invalidPointerCast if (VL_UNLIKELY((*((float*)&m_sigs_oldvalp[code])) != newval)) { fullFloat (code, newval); } diff --git a/include/verilatedos.h b/include/verilatedos.h index 1122f76ad..f18772da5 100644 --- a/include/verilatedos.h +++ b/include/verilatedos.h @@ -95,7 +95,7 @@ // This is not necessarily the same as #UL, depending on what the IData typedef is. #define VL_UL(c) ((IData)(c##UL)) ///< Add appropriate suffix to 32-bit constant -#ifdef VL_CPPCHECK +#if defined(VL_CPPCHECK) || defined(__clang_analyzer__) # define VL_DANGLING(v) #else # define VL_DANGLING(v) do { (v) = NULL; } while(0) ///< After e.g. delete, set variable to NULL to indicate must not use later diff --git a/src/V3Active.cpp b/src/V3Active.cpp index f0db05e28..9f44684dd 100644 --- a/src/V3Active.cpp +++ b/src/V3Active.cpp @@ -323,7 +323,7 @@ private: // Read sensitivitues m_itemCombo = false; m_itemSequent = false; - oldsensesp->iterateAndNext(*this); + if (oldsensesp) oldsensesp->iterateAndNext(*this); bool combo = m_itemCombo; bool sequent = m_itemSequent; diff --git a/src/V3Assert.cpp b/src/V3Assert.cpp index 308034079..762b88ff3 100644 --- a/src/V3Assert.cpp +++ b/src/V3Assert.cpp @@ -119,7 +119,7 @@ private: } else { nodep->v3fatalSrc("Unknown node type"); } - if (stmtsp) bodysp = bodysp->addNext(stmtsp); + if (bodysp && stmtsp) bodysp = bodysp->addNext(stmtsp); AstIf* ifp = new AstIf (nodep->fileline(), propp, bodysp, NULL); bodysp = ifp; if (nodep->castVAssert()) ifp->branchPred(AstBranchPred::BP_UNLIKELY); diff --git a/src/V3Ast.cpp b/src/V3Ast.cpp index 63dcae5b5..600a1f675 100644 --- a/src/V3Ast.cpp +++ b/src/V3Ast.cpp @@ -902,7 +902,7 @@ bool AstNode::sameTreeIter(AstNode* node1p, AstNode* node2p, bool ignNext, bool //====================================================================== // Static utilities -ostream& operator<<(ostream& os, V3Hash rhs) { +ostream& operator<<(ostream& os, const V3Hash& rhs) { return os<(this)) { // No known cases cause this, but better than a core dump diff --git a/src/V3Ast.h b/src/V3Ast.h index e20919a53..4ee7a174e 100644 --- a/src/V3Ast.h +++ b/src/V3Ast.h @@ -61,7 +61,7 @@ public: inline bool operator== (AstType lhs, AstType rhs) { return (lhs.m_e == rhs.m_e); } inline bool operator== (AstType lhs, AstType::en rhs) { return (lhs.m_e == rhs); } inline bool operator== (AstType::en lhs, AstType rhs) { return (lhs == rhs.m_e); } - inline ostream& operator<<(ostream& os, AstType rhs) { return os<=1 && !m_littleEndian)); } void dump(ostream& str) const { if (ranged()) str<<"["< rhs return false; } VBasicTypeKey(int width, int widthMin, AstNumeric numeric, AstBasicDTypeKwd kwd, - VNumRange nrange) + const VNumRange& nrange) : m_width(width), m_widthMin(widthMin), m_numeric(numeric), m_keyword(kwd), m_nrange(nrange) {} ~VBasicTypeKey() {} @@ -733,8 +733,9 @@ class VNUser { } m_u; public: VNUser() {} + // non-explicit: VNUser(int i) { m_u.up = 0; m_u.ui = i; } - VNUser(void* p) { m_u.up = p; } + explicit VNUser(void* p) { m_u.up = p; } ~VNUser() {} // Casters WidthVP* c() { return ((WidthVP*)m_u.up); } @@ -891,7 +892,7 @@ public: AstNode* oldp() const { return m_oldp; } void dump(ostream& str=cout) const; }; -inline ostream& operator<<(ostream& os, AstNRelinker& rhs) { rhs.dump(os); return os;} +inline ostream& operator<<(ostream& os, const AstNRelinker& rhs) { rhs.dump(os); return os;} //###################################################################### // V3Hash -- Node hashing for V3Combine @@ -941,7 +942,7 @@ public: V3Hash(V3Hash h1, V3Hash h2, V3Hash h3, V3Hash h4) { setBoth(1,((h1.hshval()*31+h2.hshval())*31+h3.hshval())*31+h4.hshval()); } }; -ostream& operator<<(ostream& os, V3Hash rhs); +ostream& operator<<(ostream& os, const V3Hash& rhs); //###################################################################### // AstNode -- Base type of all Ast types @@ -1231,6 +1232,7 @@ public: // METHODS - dump and error void v3errorEnd(ostringstream& str) const; + void v3errorEndFatal(ostringstream& str) const VL_ATTR_NORETURN; string warnMore() const; virtual void dump(ostream& str=cout); void dumpGdb(); // For GDB only diff --git a/src/V3AstNodes.h b/src/V3AstNodes.h index e00308168..5587c71d5 100644 --- a/src/V3AstNodes.h +++ b/src/V3AstNodes.h @@ -121,7 +121,7 @@ public: m_littleEndian = false; setOp2p(new AstConst(fl,msb)); setOp3p(new AstConst(fl,lsb)); } - AstRange(FileLine* fl, VNumRange range) + AstRange(FileLine* fl, const VNumRange& range) :AstNode(fl) { m_littleEndian = range.littleEndian(); setOp2p(new AstConst(fl,range.hi())); setOp3p(new AstConst(fl,range.lo())); @@ -743,7 +743,7 @@ class AstParseTypeDType : public AstNodeDType { // During parsing, this indicates the type of a parameter is a "parameter type" // e.g. the data type is a container of any data type public: - AstParseTypeDType(FileLine* fl) + explicit AstParseTypeDType(FileLine* fl) : AstNodeDType(fl) {} ASTNODE_NODE_FUNCS(ParseTypeDType) AstNodeDType* dtypep() const { return NULL; } @@ -1655,7 +1655,7 @@ private: string m_name; // Cell name public: AstCellRef(FileLine* fl, - string name, AstNode* cellp, AstNode* exprp) + const string& name, AstNode* cellp, AstNode* exprp) : AstNode(fl) , m_name(name) { addNOp1p(cellp); addNOp2p(exprp); } @@ -1672,7 +1672,7 @@ private: string m_name; // Array name public: AstCellArrayRef(FileLine* fl, - string name, AstNode* selectExprp) + const string& name, AstNode* selectExprp) : AstNode(fl) , m_name(name) { addNOp1p(selectExprp); } @@ -1688,7 +1688,7 @@ private: string m_name; // Var name public: AstUnlinkedRef(FileLine* fl, - AstNode* refp, string name, AstNode* crp) + AstNode* refp, const string& name, AstNode* crp) : AstNode(fl) , m_name(name) { addNOp1p(refp); addNOp2p(crp); } diff --git a/src/V3CCtors.cpp b/src/V3CCtors.cpp index 92cac3471..2c961ec56 100644 --- a/src/V3CCtors.cpp +++ b/src/V3CCtors.cpp @@ -94,6 +94,7 @@ public: m_funcp = m_tlFuncp; m_modp->addStmtp(m_tlFuncp); } + ~V3CCtorsVisitor() {} }; //###################################################################### diff --git a/src/V3Case.cpp b/src/V3Case.cpp index c8b29f918..69510df45 100644 --- a/src/V3Case.cpp +++ b/src/V3Case.cpp @@ -423,7 +423,7 @@ private: // Handle any assertions replaceCaseParallel(nodep, false); // Replace the CASE... with IF... - if (debug()>=9) grouprootp->dumpTree(cout," _new: "); + if (debug()>=9 && grouprootp) grouprootp->dumpTree(cout," _new: "); if (grouprootp) nodep->replaceWith(grouprootp); else nodep->unlinkFrBack(); nodep->deleteTree(); VL_DANGLING(nodep); diff --git a/src/V3ClkGater.cpp b/src/V3ClkGater.cpp index 5bf3bcbc7..e119df88d 100644 --- a/src/V3ClkGater.cpp +++ b/src/V3ClkGater.cpp @@ -611,7 +611,8 @@ class GaterVisitor : public GaterBaseVisitor { // Edges from IFs represent a real IF branch in the equation tree //UINFO(9," ifver "<<(void*)(edgep)<<" cc"<dotColor()<nodep()->condp()->cloneTree(true); - if (eqnp && cedgep->ifelseFalse()) { + if (!eqnp) cVxp->nodep()->v3fatalSrc("null condition"); + if (cedgep->ifelseFalse()) { eqnp = new AstNot(eqnp->fileline(),eqnp); } // We need to AND this term onto whatever was found below it diff --git a/src/V3Config.cpp b/src/V3Config.cpp index 238f2f7ed..44514f389 100644 --- a/src/V3Config.cpp +++ b/src/V3Config.cpp @@ -104,7 +104,7 @@ class V3ConfigIgnores { public: inline static V3ConfigIgnores& singleton() { return s_singleton; } - void addIgnore(V3ErrorCode code, string wildname, int lineno, bool on) { + void addIgnore(V3ErrorCode code, const string& wildname, int lineno, bool on) { // Insert IgnLines* linesp = findWilds(wildname); UINFO(9,"config addIgnore "<lhsp()->unlinkFrBack(); AstConst* lsbp = nodep->lsbp()->castConst(); AstNode* widthp = nodep->widthp()->unlinkFrBack(); + if (!fromp->width()) nodep->v3fatalSrc("Not widthed"); AstSel* newp = new AstSel(nodep->fileline(), fromp, new AstConst(lsbp->fileline(), lsbp->toUInt() % fromp->width()), diff --git a/src/V3Descope.cpp b/src/V3Descope.cpp index 8b2af8618..519bf544d 100644 --- a/src/V3Descope.cpp +++ b/src/V3Descope.cpp @@ -138,8 +138,9 @@ private: for (AstNode* stmtp = newfuncp->argsp(); stmtp; stmtp=stmtp->nextp()) { if (AstVar* portp = stmtp->castVar()) { if (portp->isIO() && !portp->isFuncReturn()) { - argsp = argsp->addNextNull(new AstVarRef(portp->fileline(), portp, - portp->isOutput())); + AstNode* newp = new AstVarRef(portp->fileline(), portp, portp->isOutput()); + if (argsp) argsp = argsp->addNextNull(newp); + else argsp = newp; } } } diff --git a/src/V3EmitC.cpp b/src/V3EmitC.cpp index 56f2d441b..405b76513 100644 --- a/src/V3EmitC.cpp +++ b/src/V3EmitC.cpp @@ -69,7 +69,7 @@ public: const string& vformat, AstNode* exprsp, bool isScan); void displayEmit(AstNode* nodep, bool isScan); void displayArg(AstNode* dispp, AstNode** elistp, bool isScan, - string vfmt, char fmtLetter); + const string& vfmt, char fmtLetter); void emitVarDecl(AstVar* nodep, const string& prefixIfImp); typedef enum {EVL_IO, EVL_SIG, EVL_TEMP, EVL_PAR, EVL_ALL} EisWhich; @@ -1237,7 +1237,6 @@ void EmitCStmts::displayEmit(AstNode* nodep, bool isScan) { if (dispp) {} puts("VL_SFORMATF_NX("); } else { - isStmt = true; nodep->v3fatalSrc("Unknown displayEmit node type"); } ofp()->putsQuoted(emitDispState.m_format); @@ -1269,7 +1268,7 @@ void EmitCStmts::displayEmit(AstNode* nodep, bool isScan) { } void EmitCStmts::displayArg(AstNode* dispp, AstNode** elistp, bool isScan, - string vfmt, char fmtLetter) { + const string& vfmt, char fmtLetter) { // Print display argument, edits elistp AstNode* argp = *elistp; if (!argp) { diff --git a/src/V3EmitMk.cpp b/src/V3EmitMk.cpp index 01cf1d87b..faf243885 100644 --- a/src/V3EmitMk.cpp +++ b/src/V3EmitMk.cpp @@ -106,7 +106,7 @@ public: } else { for (AstCFile* nodep = v3Global.rootp()->filesp(); nodep; nodep=nodep->nextp()->castCFile()) { - if (nodep->source() && nodep->slow()==slow && nodep->support()==support) { + if (nodep->source() && nodep->slow()==(slow!=0) && nodep->support()==(support!=0)) { putMakeClassEntry(of, nodep->name()); } } diff --git a/src/V3Error.h b/src/V3Error.h index 3093d9976..e0c95df7d 100644 --- a/src/V3Error.h +++ b/src/V3Error.h @@ -29,6 +29,7 @@ #include #include #include +#include //###################################################################### @@ -253,18 +254,21 @@ class V3Error { // Global versions, so that if the class doesn't define a operator, we get the functions anyways. inline int debug() { return V3Error::debugDefault(); } inline void v3errorEnd(ostringstream& sstr) { V3Error::v3errorEnd(sstr); } +inline void v3errorEndFatal(ostringstream& sstr) VL_ATTR_NORETURN; +inline void v3errorEndFatal(ostringstream& sstr) { V3Error::v3errorEnd(sstr); assert(0); } // Theses allow errors using << operators: v3error("foo"<<"bar"); // Careful, you can't put () around msg, as you would in most macro definitions // Note the commas are the comma operator, not separating arguments. These are needed to insure // evaluation order as otherwise we couldn't insure v3errorPrep is called first. #define v3warnCode(code,msg) v3errorEnd((V3Error::v3errorPrep(code), (V3Error::v3errorStr()<=(level))) { cout<<"- "<=(level))) { cout<valuep()) valuep = new AstAdd(nodep->fileline(), nodep->valuep()->cloneTree(true), new AstConst(nodep->fileline(), AstConst::Unsized32(), offset_from_init)); - addp = addp->addNextNull(new AstEnumItem(nodep->fileline(), name, NULL, valuep)); + AstNode* newp = new AstEnumItem(nodep->fileline(), name, NULL, valuep); + if (addp) addp = addp->addNextNull(newp); + else addp = newp; } nodep->replaceWith(addp); nodep->deleteTree(); diff --git a/src/V3Number.cpp b/src/V3Number.cpp index a1fc5ee6c..8ec864a85 100644 --- a/src/V3Number.cpp +++ b/src/V3Number.cpp @@ -71,7 +71,7 @@ V3Number::V3Number (FileLine* fileline, const char* sourcep) { if (*cp != '_') *wp++ = *cp; } *wp++ = '\0'; - while (*cp && *cp == '_') cp++; + while (*cp == '_') cp++; if (*cp && tolower(*cp)=='s') { cp++; isSigned(true); } diff --git a/src/V3Number.h b/src/V3Number.h index 88d7b7097..7b72a9ba0 100644 --- a/src/V3Number.h +++ b/src/V3Number.h @@ -327,6 +327,6 @@ public: V3Number& opLtN (const V3Number& lhs, const V3Number& rhs); V3Number& opLteN (const V3Number& lhs, const V3Number& rhs); }; -inline ostream& operator<<(ostream& os, V3Number rhs) { return os< #include "V3Number.h" -void test(string lhss, string op, string rhss, string exps) { +void test(const string& lhss, const string& op, const string& rhss, const string& exps) { char* l1 = strdup(lhss.c_str()); char* r1 = strdup(rhss.c_str()); char* e1 = strdup(exps.c_str()); diff --git a/src/V3Options.cpp b/src/V3Options.cpp index 26af3594c..4e5ea7dfe 100644 --- a/src/V3Options.cpp +++ b/src/V3Options.cpp @@ -559,8 +559,9 @@ string V3Options::version() { } void V3Options::throwSigsegv() { - // cppcheck-suppress nullPointer +#if !(defined(VL_CPPCHECK) || defined(__clang_analyzer__)) char* zp=NULL; *zp=0; // Intentional core dump, ignore warnings here +#endif } //###################################################################### diff --git a/src/V3PreProc.h b/src/V3PreProc.h index 211a33cc8..df5b2493d 100644 --- a/src/V3PreProc.h +++ b/src/V3PreProc.h @@ -90,8 +90,8 @@ public: virtual string removeDefines(const string& text)=0; // Remove defines in a text string // UTILITIES - void error(string msg) { fileline()->v3error(msg); } ///< Report a error - void fatal(string msg) { fileline()->v3fatalSrc(msg); } ///< Report a fatal error + void error(const string& msg) { fileline()->v3error(msg); } ///< Report a error + void fatal(const string& msg) { fileline()->v3fatalSrc(msg); } ///< Report a fatal error protected: // CONSTUCTORS diff --git a/src/V3Split.cpp b/src/V3Split.cpp index ff88efbca..194f838fd 100644 --- a/src/V3Split.cpp +++ b/src/V3Split.cpp @@ -411,7 +411,8 @@ private: UINFO(6, " Color="<unlinkFrBack(&replaceHandle); else nextp->unlinkFrBack(); - newListp = newListp->addNext(nextp); + if (newListp) newListp = newListp->addNext(nextp); + else newListp = nextp; } if (splitAlwaysp) { ++m_statSplits; diff --git a/src/V3Task.cpp b/src/V3Task.cpp index b75f87a0e..2edf928b0 100644 --- a/src/V3Task.cpp +++ b/src/V3Task.cpp @@ -357,7 +357,7 @@ private: return newvscp; } - AstNode* createInlinedFTask(AstNodeFTaskRef* refp, string namePrefix, AstVarScope* outvscp) { + AstNode* createInlinedFTask(AstNodeFTaskRef* refp, const string& namePrefix, AstVarScope* outvscp) { // outvscp is the variable for functions only, if NULL, it's a task if (!refp->taskp()) refp->v3fatalSrc("Unlinked?"); AstNode* newbodysp = refp->taskp()->stmtsp()->cloneTree(true); // Maybe NULL @@ -463,7 +463,7 @@ private: return beginp; } - AstNode* createNonInlinedFTask(AstNodeFTaskRef* refp, string namePrefix, AstVarScope* outvscp) { + AstNode* createNonInlinedFTask(AstNodeFTaskRef* refp, const string& namePrefix, AstVarScope* outvscp) { // outvscp is the variable for functions only, if NULL, it's a task if (!refp->taskp()) refp->v3fatalSrc("Unlinked?"); AstCFunc* cfuncp = m_statep->ftaskCFuncp(refp->taskp()); diff --git a/src/V3WidthSel.cpp b/src/V3WidthSel.cpp index c6bb5fd29..1bb86acf0 100644 --- a/src/V3WidthSel.cpp +++ b/src/V3WidthSel.cpp @@ -154,7 +154,7 @@ private: return newp; } - AstNode* newSubLsbOf(AstNode* underp, VNumRange fromRange) { + AstNode* newSubLsbOf(AstNode* underp, const VNumRange& fromRange) { // Account for a variable's LSB in bit selections // Will likely become SUB(underp, lsb_of_signal) // Don't report WIDTH warnings etc here, as may be inside a generate branch that will be deleted diff --git a/src/cppcheck_filtered b/src/cppcheck_filtered index dd18e141f..9b1ca043e 100755 --- a/src/cppcheck_filtered +++ b/src/cppcheck_filtered @@ -52,14 +52,19 @@ sub process { $fh or die "%Error: '$cmd' failed: $!\n"; my %uniq; my %errs; + my $last_error = ""; while (defined(my $line = $fh->getline())) { $line =~ s/^\s+//; $line =~ s/Checking usage of global functions\.+//; # Sometimes tacked at end-of-line # General gunk next if $uniq{$line}++; next if $line =~ m!^<\?xml version!; - next if $line =~ m!^!; + next if $line =~ m!^!; + next if $line =~ m!^!; + next if $line =~ m!^!; next if $line =~ m!^