From a0edd4e907da8d9fdafdfe999c542fb5b44e7ff0 Mon Sep 17 00:00:00 2001 From: Geza Lore Date: Tue, 19 Aug 2025 22:02:10 +0100 Subject: [PATCH] Internals: Improve cppcheck flow and fix up issues (#6311) Added cppcheck-suppressions.txt in the repo root. You can add new patterns in there instead of having to parse the XML output. Also configure to add the -D__GNUC__ preprocessor macro, which makes it understand UASSERT (it understands the 'noreturn' function attribute). Added some case by case specific suppressions and fixed up other code, especially in V3Ast*h and V3Dfg*.h, including code generated by astgen that had some no-ops that irks cppcheck. One thing it does not seem to like is `const` class members with default initializers in the class. It will assume that's always the value, even if overridden in the constructor. We had few so removed them. With that a lot of files in `src/` are now clean or only have a handful of issues. Therefore, I have also deleted cppcheck_filtered, and made it produce human readable output straight to the terminal. Regarding cleaning up the reported nits, I kind of got bored after V3[A-E] so pausing here. Apologies for the merge conflicts. Tested with cppcheck 2.13.0 --- Makefile.in | 58 +++++----- include/verilatedos.h | 6 +- src/V3Active.cpp | 2 +- src/V3Assert.cpp | 10 +- src/V3AssertPre.cpp | 6 +- src/V3Ast.cpp | 27 +++-- src/V3Ast.h | 21 ++-- src/V3AstInlines.h | 8 +- src/V3AstNodeDType.h | 2 +- src/V3AstNodeExpr.h | 47 +++++--- src/V3AstNodeOther.h | 28 ++--- src/V3AstNodeStmt.h | 1 + src/V3AstNodes.cpp | 63 ++++++----- src/V3Begin.cpp | 2 +- src/V3Branch.cpp | 2 +- src/V3CUse.cpp | 7 +- src/V3Case.cpp | 8 +- src/V3Cast.cpp | 2 +- src/V3CfgLiveVariables.cpp | 2 +- src/V3Class.cpp | 5 +- src/V3Clean.cpp | 6 +- src/V3Const.cpp | 84 +++++++-------- src/V3Control.cpp | 7 +- src/V3Control.h | 5 +- src/V3Coverage.cpp | 24 ++--- src/V3CoverageJoin.cpp | 2 +- src/V3Dead.cpp | 6 +- src/V3Delayed.cpp | 12 +-- src/V3Descope.cpp | 4 +- src/V3Dfg.h | 4 +- src/V3DfgPasses.cpp | 4 +- src/V3DfgVertices.h | 2 + src/V3DiagSarif.cpp | 10 +- src/V3EmitCBase.h | 4 +- src/V3EmitCConstInit.h | 2 +- src/V3EmitCConstPool.cpp | 2 +- src/V3EmitCFunc.h | 14 +-- src/V3EmitCHeaders.cpp | 4 +- src/V3EmitCImp.cpp | 16 +-- src/V3EmitCMake.cpp | 12 ++- src/V3Simulate.h | 26 +++-- src/astgen | 39 ++++--- src/cppcheck-suppressions.txt | 33 ++++++ src/cppcheck_filtered | 196 ---------------------------------- 44 files changed, 357 insertions(+), 468 deletions(-) create mode 100644 src/cppcheck-suppressions.txt delete mode 100755 src/cppcheck_filtered diff --git a/Makefile.in b/Makefile.in index f98a03a49..763b18f94 100644 --- a/Makefile.in +++ b/Makefile.in @@ -409,36 +409,39 @@ CHECK_H = $(wildcard \ CHECK_YL = $(wildcard \ $(srcdir)/src/*.y \ $(srcdir)/src/*.l ) -CPPCHECK = src/cppcheck_filtered cppcheck -CPPCHECK_FLAGS = --enable=all --inline-suppr \ - --suppress=cstyleCast --suppress=ctunullpointer \ - --suppress=derefInvalidIteratorRedundantCheck \ - --suppress=nullPointer --suppress=nullPointerRedundantCheck \ - --suppress=templateRecursion \ - --suppress=unusedFunction --suppress=unusedScopedObject \ - --suppress=useInitializationList --suppress=useStlAlgorithm \ +CPPCHECK = cppcheck +CPPCHECK_CACHE = $(srcdir)/src/obj_dbg/cppcheck-cache +CPPCHECK_FLAGS = --enable=all +CPPCHECK_FLAGS += --inline-suppr +CPPCHECK_FLAGS += --suppressions-list=$(srcdir)/src/cppcheck-suppressions.txt +CPPCHECK_FLAGS += --cppcheck-build-dir=$(CPPCHECK_CACHE) +CPPCHECK_FLAGS += -DVL_DEBUG=1 -DVL_CPPCHECK=1 -D__GNUC__=1 +CPPCHECK_INC = -I$(srcdir)/include +CPPCHECK_INC += -I$(srcdir)/include/gtkwave +CPPCHECK_INC += -I$(srcdir)/include/vltstd +CPPCHECK_INC += -I$(srcdir)/src/obj_dbg +CPPCHECK_INC += -I$(srcdir)/src -CPPCHECK_FLAGS += --xml -CPPCHECK_DEP = $(subst .cpp,.cppcheck,$(CHECK_CPP)) -CPPCHECK_INC = -I$(srcdir)/include -I$(srcdir)/include/gtkwave -I$(srcdir)/include/vltstd -I$(srcdir)/src/obj_dbg -I$(srcdir)/src +$(CPPCHECK_CACHE): + mkdir -p $@ cppcheck: cppcheck-1 cppcheck-2 cppcheck-3 cppcheck-4 cppcheck-5 cppcheck-6 cppcheck-7 cppcheck-8 -cppcheck-1: - $(CPPCHECK) $(CPPCHECK_FLAGS) -DVL_DEBUG=1 -DVL_CPPCHECK=1 $(CPPCHECK_INC) $(CPPCHECK1_CPP) -cppcheck-2: - $(CPPCHECK) $(CPPCHECK_FLAGS) -DVL_DEBUG=1 -DVL_CPPCHECK=1 $(CPPCHECK_INC) $(CPPCHECK2_CPP) -cppcheck-3: - $(CPPCHECK) $(CPPCHECK_FLAGS) -DVL_DEBUG=1 -DVL_CPPCHECK=1 $(CPPCHECK_INC) $(CPPCHECK3_CPP) -cppcheck-4: - $(CPPCHECK) $(CPPCHECK_FLAGS) -DVL_DEBUG=1 -DVL_CPPCHECK=1 $(CPPCHECK_INC) $(CPPCHECK4_CPP) -cppcheck-5: - $(CPPCHECK) $(CPPCHECK_FLAGS) -DVL_DEBUG=1 -DVL_CPPCHECK=1 $(CPPCHECK_INC) $(CPPCHECK5_CPP) -cppcheck-6: - $(CPPCHECK) $(CPPCHECK_FLAGS) -DVL_DEBUG=1 -DVL_CPPCHECK=1 $(CPPCHECK_INC) $(CPPCHECK6_CPP) -cppcheck-7: - $(CPPCHECK) $(CPPCHECK_FLAGS) -DVL_DEBUG=1 -DVL_CPPCHECK=1 $(CPPCHECK_INC) $(CPPCHECK7_CPP) -cppcheck-8: - $(CPPCHECK) $(CPPCHECK_FLAGS) -DVL_DEBUG=1 -DVL_CPPCHECK=1 $(CPPCHECK_INC) $(CPPCHECK8_CPP) +cppcheck-1: | $(CPPCHECK_CACHE) + $(CPPCHECK) $(CPPCHECK_FLAGS) $(CPPCHECK_INC) $(CPPCHECK1_CPP) +cppcheck-2: | $(CPPCHECK_CACHE) + $(CPPCHECK) $(CPPCHECK_FLAGS) $(CPPCHECK_INC) $(CPPCHECK2_CPP) +cppcheck-3: | $(CPPCHECK_CACHE) + $(CPPCHECK) $(CPPCHECK_FLAGS) $(CPPCHECK_INC) $(CPPCHECK3_CPP) +cppcheck-4: | $(CPPCHECK_CACHE) + $(CPPCHECK) $(CPPCHECK_FLAGS) $(CPPCHECK_INC) $(CPPCHECK4_CPP) +cppcheck-5: | $(CPPCHECK_CACHE) + $(CPPCHECK) $(CPPCHECK_FLAGS) $(CPPCHECK_INC) $(CPPCHECK5_CPP) +cppcheck-6: | $(CPPCHECK_CACHE) + $(CPPCHECK) $(CPPCHECK_FLAGS) $(CPPCHECK_INC) $(CPPCHECK6_CPP) +cppcheck-7: | $(CPPCHECK_CACHE) + $(CPPCHECK) $(CPPCHECK_FLAGS) $(CPPCHECK_INC) $(CPPCHECK7_CPP) +cppcheck-8: | $(CPPCHECK_CACHE) + $(CPPCHECK) $(CPPCHECK_FLAGS) $(CPPCHECK_INC) $(CPPCHECK8_CPP) CLANGTIDY = clang-tidy CLANGTIDY_FLAGS = -config='' \ @@ -512,7 +515,6 @@ PY_PROGRAMS = \ src/astgen \ src/bisonpre \ src/config_rev \ - src/cppcheck_filtered \ src/flexfix \ src/vlcovgen \ src/.gdbinit.py \ diff --git a/include/verilatedos.h b/include/verilatedos.h index b24b7a58c..a4c03c46d 100644 --- a/include/verilatedos.h +++ b/include/verilatedos.h @@ -52,15 +52,13 @@ // clang and gcc-8.0+ support no_sanitize("string") style attribute # if defined(__clang__) || (__GNUC__ >= 8) # define VL_ATTR_NO_SANITIZE_ALIGN __attribute__((no_sanitize("alignment"))) -#else // The entire undefined sanitizer has to be disabled for older gcc +# else // The entire undefined sanitizer has to be disabled for older gcc # define VL_ATTR_NO_SANITIZE_ALIGN __attribute__((no_sanitize_undefined)) -#endif +# endif # define VL_ATTR_PRINTF(fmtArgNum) __attribute__((format(printf, (fmtArgNum), (fmtArgNum) + 1))) # define VL_ATTR_PURE __attribute__((pure)) # define VL_ATTR_UNUSED __attribute__((unused)) -#ifndef VL_ATTR_WARN_UNUSED_RESULT # define VL_ATTR_WARN_UNUSED_RESULT __attribute__((warn_unused_result)) -#endif # if !defined(_WIN32) && !defined(__MINGW32__) // All VL_ATTR_WEAK symbols must be marked with the macOS -U linker flag in verilated.mk.in # define VL_ATTR_WEAK __attribute__((weak)) diff --git a/src/V3Active.cpp b/src/V3Active.cpp index dc2367144..3497ede5e 100644 --- a/src/V3Active.cpp +++ b/src/V3Active.cpp @@ -166,7 +166,7 @@ public: // paths make an assignment. Detected latches are flagged in the variables AstVar void latchCheck(AstNode* nodep, bool latch_expected) { bool latch_detected = false; - for (const auto& vrp : m_outputs) { + for (const AstVarRef* const vrp : m_outputs) { LatchDetectGraphVertex* const vertp = castVertexp(vrp->varp()->user1p()); vertp->user(true); // Identify the output vertex we are checking paths _to_ if (!latchCheckInternal(castVertexp(vertices().frontp()))) latch_detected = true; diff --git a/src/V3Assert.cpp b/src/V3Assert.cpp index 57ca6092b..72279d547 100644 --- a/src/V3Assert.cpp +++ b/src/V3Assert.cpp @@ -86,7 +86,7 @@ class AssertVisitor final : public VNVisitor { } VL_UNREACHABLE; } - string assertDisplayMessage(AstNode* nodep, const string& prefix, const string& message, + string assertDisplayMessage(const AstNode* nodep, const string& prefix, const string& message, VDisplayType severity) { if (severity == VDisplayType::DT_ERROR || severity == VDisplayType::DT_FATAL) { return ("[%0t] "s + prefix + ": " + nodep->fileline()->filebasename() + ":" @@ -148,7 +148,7 @@ class AssertVisitor final : public VNVisitor { sampledp->dtypeFrom(nodep); return sampledp; } - AstVarRef* newMonitorNumVarRefp(AstNode* nodep, VAccess access) { + AstVarRef* newMonitorNumVarRefp(const AstNode* nodep, VAccess access) { if (!m_monitorNumVarp) { m_monitorNumVarp = new AstVar{nodep->fileline(), VVarType::MODULETEMP, "__VmonitorNum", nodep->findUInt64DType()}; @@ -158,7 +158,7 @@ class AssertVisitor final : public VNVisitor { varrefp->classOrPackagep(v3Global.rootp()->dollarUnitPkgAddp()); return varrefp; } - AstVarRef* newMonitorOffVarRefp(AstNode* nodep, VAccess access) { + AstVarRef* newMonitorOffVarRefp(const AstNode* nodep, VAccess access) { if (!m_monitorOffVarp) { m_monitorOffVarp = new AstVar{nodep->fileline(), VVarType::MODULETEMP, "__VmonitorOff", nodep->findBitDType()}; @@ -181,7 +181,7 @@ class AssertVisitor final : public VNVisitor { return newp; } - AstNodeStmt* newFireAssertUnchecked(AstNodeStmt* nodep, const string& message, + AstNodeStmt* newFireAssertUnchecked(const AstNodeStmt* nodep, const string& message, AstNodeExpr* exprsp = nullptr) { // Like newFireAssert() but omits the asserts-on check AstDisplay* const dispp @@ -194,7 +194,7 @@ class AssertVisitor final : public VNVisitor { return bodysp; } - AstNodeStmt* newFireAssert(AstNodeStmt* nodep, VAssertDirectiveType directiveType, + AstNodeStmt* newFireAssert(const AstNodeStmt* nodep, VAssertDirectiveType directiveType, VAssertType assertType, const string& message, AstNodeExpr* exprsp = nullptr) { AstNodeStmt* bodysp = newFireAssertUnchecked(nodep, message, exprsp); diff --git a/src/V3AssertPre.cpp b/src/V3AssertPre.cpp index 032c2855b..bcaf91c1e 100644 --- a/src/V3AssertPre.cpp +++ b/src/V3AssertPre.cpp @@ -102,7 +102,7 @@ private: } AstPropSpec* substitutePropertyCall(AstPropSpec* nodep) { if (AstFuncRef* const funcrefp = VN_CAST(nodep->propp(), FuncRef)) { - if (AstProperty* const propp = VN_CAST(funcrefp->taskp(), Property)) { + if (const AstProperty* const propp = VN_CAST(funcrefp->taskp(), Property)) { AstPropSpec* propExprp = getPropertyExprp(propp); // Substitute inner property call before copying in order to not doing the same for // each call of outer property call. @@ -183,7 +183,7 @@ private: m_clockingp->addNextHere(varp->unlinkFrBack()); varp->user1p(nodep); if (nodep->direction() == VDirection::OUTPUT) { - exprp->foreach([](AstNodeVarRef* varrefp) { + exprp->foreach([](const AstNodeVarRef* varrefp) { // Prevent confusing BLKANDNBLK warnings on clockvars due to generated assignments varrefp->fileline()->warnOff(V3ErrorCode::BLKANDNBLK, true); }); @@ -318,7 +318,7 @@ private: if (nodep->stmtsp()) nodep->addNextHere(nodep->stmtsp()->unlinkFrBackWithNext()); FileLine* const flp = nodep->fileline(); AstNodeExpr* valuep = V3Const::constifyEdit(nodep->lhsp()->unlinkFrBack()); - AstConst* const constp = VN_CAST(valuep, Const); + const AstConst* const constp = VN_CAST(valuep, Const); if (constp->isZero()) { nodep->v3warn(E_UNSUPPORTED, "Unsupported: ##0 delays"); VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); diff --git a/src/V3Ast.cpp b/src/V3Ast.cpp index b0d8f7cfe..dea6e32f5 100644 --- a/src/V3Ast.cpp +++ b/src/V3Ast.cpp @@ -255,14 +255,13 @@ string AstNode::vpiName(const string& namein) { // This is slightly different from prettyName, in that when we encounter escaped characters, // we change that identifier to an escaped identifier, wrapping it with '\' and ' ' // as specified in LRM 23.6 - string name = namein; - if (0 == namein.substr(0, 7).compare("__SYM__")) name = namein.substr(7); + const size_t offset = VString::startsWith(namein, "__SYM__") ? 7 : 0; string pretty; - pretty.reserve(name.length()); + pretty.reserve(namein.length()); bool inEscapedIdent = false; int lastIdent = 0; - for (const char* pos = name.c_str(); *pos;) { + for (const char* pos = namein.c_str() + offset; *pos;) { char specialChar = 0; if (pos[0] == '-' && pos[1] == '>') { // -> specialChar = '.'; @@ -280,7 +279,7 @@ string AstNode::vpiName(const string& namein) { } else if (0 == std::strncmp(pos, "__PVT__", 7)) { pos += 7; continue; - } else if (pos[0] == '_' && pos[1] == '_' && pos[2] == '0' && std::isxdigit(pos[3]) + } else if (0 == std::strncmp(pos, "__0", 3) && std::isxdigit(pos[3]) && std::isxdigit(pos[4])) { char value = 0; value += 16 @@ -567,6 +566,7 @@ AstNode* AstNode::unlinkFrBackWithNext(VNRelinker* linkerp) { AstNode* const oldp = this; UASSERT_OBJ(oldp->m_backp, oldp, "Node has no back, already unlinked?"); oldp->editCountInc(); + // cppcheck-suppress shadowFunction AstNode* const backp = oldp->m_backp; if (linkerp) { linkerp->m_oldp = oldp; @@ -629,6 +629,7 @@ AstNode* AstNode::unlinkFrBack(VNRelinker* linkerp) { AstNode* const oldp = this; UASSERT_OBJ(oldp->m_backp, oldp, "Node has no back, already unlinked?"); oldp->editCountInc(); + // cppcheck-suppress shadowFunction AstNode* const backp = oldp->m_backp; if (linkerp) { linkerp->m_oldp = oldp; @@ -710,6 +711,7 @@ void AstNode::relink(VNRelinker* linkerp) { cout << endl; } + // cppcheck-suppress shadowFunction AstNode* const backp = linkerp->m_backp; debugTreeChange(this, "-relinkNew: ", __LINE__, true); debugTreeChange(backp, "-relinkTre: ", __LINE__, true); @@ -773,6 +775,7 @@ void AstNode::addHereThisAsNext(AstNode* newp) { UASSERT_OBJ(this->m_backp, this, "'this' node has no back, already unlinked?"); UASSERT_OBJ(newp->m_headtailp, newp, "m_headtailp not set on new node"); // + // cppcheck-suppress shadowFunction AstNode* const backp = this->m_backp; AstNode* const newLastp = newp->m_headtailp; // @@ -1185,6 +1188,7 @@ void AstNode::checkTreeIter(const AstNode* prevBackp) const VL_MT_STABLE { break; case VNTypeInfo::OP_LIST: if (const AstNode* const headp = nodep) { + // cppcheck-suppress shadowFunction const AstNode* backp = this; const AstNode* tailp; const AstNode* opp = headp; @@ -1457,15 +1461,16 @@ string AstNode::instanceStr() const { // in case we have some circular reference bug. constexpr unsigned maxIterations = 10000; unsigned iterCount = 0; - for (const AstNode* backp = this; backp; backp = backp->backp(), ++iterCount) { + // Walk 'backp' chain + for (const AstNode* currp = this; currp; currp = currp->backp(), ++iterCount) { if (VL_UNCOVERABLE(iterCount >= maxIterations)) return ""; // LCOV_EXCL_LINE // Prefer the enclosing scope, if there is one. This is always under the enclosing module, // so just pick it up when encountered - if (const AstScope* const scopep = VN_CAST(backp, Scope)) { + if (const AstScope* const scopep = VN_CAST(currp, Scope)) { return scopep->isTop() ? "" : "... note: In instance " + scopep->prettyNameQ(); } // If scopes don't exist, report an example instance of the enclosing module - if (const AstModule* const modp = VN_CAST(backp, Module)) { + if (const AstModule* const modp = VN_CAST(currp, Module)) { const string instanceName = modp->someInstanceName(); return instanceName.empty() ? "" : "... note: In instance '" + instanceName + "'"; } @@ -1619,8 +1624,8 @@ static VCastable computeCastableImp(const AstNodeDType* toDtp, const AstNodeDTyp } else if (VN_IS(toDtp, ClassRefDType) && VN_IS(fromConstp, Const)) { if (fromConstp->isNull()) return VCastable::COMPATIBLE; } else if (VN_IS(toDtp, ClassRefDType) && VN_IS(fromDtp, ClassRefDType)) { - const auto toClassp = VN_AS(toDtp, ClassRefDType)->classp(); - const auto fromClassp = VN_AS(fromDtp, ClassRefDType)->classp(); + const AstClass* const toClassp = VN_AS(toDtp, ClassRefDType)->classp(); + const AstClass* const fromClassp = VN_AS(fromDtp, ClassRefDType)->classp(); const bool downcast = AstClass::isClassExtendedFrom(toClassp, fromClassp); const bool upcast = AstClass::isClassExtendedFrom(fromClassp, toClassp); if (upcast) { @@ -1664,7 +1669,7 @@ AstNodeDType* AstNode::getCommonClassTypep(AstNode* node1p, AstNode* node2p) { while (classDtypep1) { const VCastable castable = computeCastable(classDtypep1, node2p->dtypep(), node2p); if (castable == VCastable::COMPATIBLE) return classDtypep1; - AstClassExtends* const extendsp = classDtypep1->classp()->extendsp(); + const AstClassExtends* const extendsp = classDtypep1->classp()->extendsp(); classDtypep1 = extendsp ? VN_AS(extendsp->dtypep(), ClassRefDType) : nullptr; } return nullptr; diff --git a/src/V3Ast.h b/src/V3Ast.h index 32b1ceb99..1e5403b96 100644 --- a/src/V3Ast.h +++ b/src/V3Ast.h @@ -116,9 +116,8 @@ public: // Above include has: // enum en {...}; // const char* ascii() const {...}; - enum en m_e; - // cppcheck-suppress uninitVar // responsibility of each subclass - VNType() = default; + const enum en m_e; + VNType() = delete; // cppcheck-suppress noExplicitConstructor constexpr VNType(en _e) VL_MT_SAFE : m_e{_e} {} explicit VNType(int _e) @@ -2138,7 +2137,7 @@ protected: AstNode(VNType t, FileLine* fl); virtual AstNode* clone() = 0; // Generally, cloneTree is what you want instead virtual void cloneRelink() { cloneRelinkGen(); } - virtual void cloneRelinkGen() = 0; // Generated by 'astgen' + virtual void cloneRelinkGen(){}; // Overrides generated by 'astgen' void cloneRelinkTree(); // METHODS @@ -2662,20 +2661,24 @@ public: // For use via privateAs or the VN_DBG_AS macro only template static T* unsafePrivateAs(AstNode* nodep) VL_PURE { - static_assert(!uselessCast(), "Unnecessary VN_AS, node known to have target type."); - static_assert(!impossibleCast(), "Unnecessary VN_AS, node cannot be this type."); + static_assert(!uselessCast(), + "Unnecessary VN_DBG_AS, node known to have target type."); + static_assert(!impossibleCast(), "Unnecessary VN_DBG_AS, node cannot be this type."); return reinterpret_cast(nodep); } template static const T* unsafePrivateAs(const AstNode* nodep) VL_PURE { - static_assert(!uselessCast(), "Unnecessary VN_AS, node known to have target type."); - static_assert(!impossibleCast(), "Unnecessary VN_AS, node cannot be this type."); + static_assert(!uselessCast(), + "Unnecessary VN_DBG_AS, node known to have target type."); + static_assert(!impossibleCast(), "Unnecessary VN_DBG_AS, node cannot be this type."); return reinterpret_cast(nodep); } // For use via the VN_AS macro only template static T* privateAs(AstNode* nodep) VL_PURE { + static_assert(!uselessCast(), "Unnecessary VN_AS, node known to have target type."); + static_assert(!impossibleCast(), "Unnecessary VN_AS, node cannot be this type."); UASSERT_OBJ(!nodep || privateTypeTest(nodep), nodep, "AstNode is not of expected type, but instead has type '" << nodep->typeName() << "'"); @@ -2683,6 +2686,8 @@ public: } template static const T* privateAs(const AstNode* nodep) VL_PURE { + static_assert(!uselessCast(), "Unnecessary VN_AS, node known to have target type."); + static_assert(!impossibleCast(), "Unnecessary VN_AS, node cannot be this type."); UASSERT_OBJ(!nodep || privateTypeTest(nodep), nodep, "AstNode is not of expected type, but instead has type '" << nodep->typeName() << "'"); diff --git a/src/V3AstInlines.h b/src/V3AstInlines.h index 3ec6c1917..d6f3444d7 100644 --- a/src/V3AstInlines.h +++ b/src/V3AstInlines.h @@ -94,11 +94,11 @@ AstRange::AstRange(FileLine* fl, const VNumRange& range) rightp(new AstConst{fl, static_cast(range.right())}); } int AstRange::leftConst() const VL_MT_STABLE { - AstConst* const constp = VN_CAST(leftp(), Const); + const AstConst* const constp = VN_CAST(leftp(), Const); return (constp ? constp->toSInt() : 0); } int AstRange::rightConst() const VL_MT_STABLE { - AstConst* const constp = VN_CAST(rightp(), Const); + const AstConst* const constp = VN_CAST(rightp(), Const); return (constp ? constp->toSInt() : 0); } @@ -129,7 +129,7 @@ AstPackArrayDType::AstPackArrayDType(FileLine* fl, AstNodeDType* dtp, AstRange* } int AstQueueDType::boundConst() const VL_MT_STABLE { - AstConst* const constp = VN_CAST(boundp(), Const); + const AstConst* const constp = VN_CAST(boundp(), Const); return (constp ? constp->toSInt() : 0); } @@ -193,7 +193,7 @@ bool AstVarRef::sameNode(const AstVarRef* samep) const { && (varp() && samep->varp() && varp()->name() == samep->varp()->name())); } } -bool AstVarRef::sameNoLvalue(AstVarRef* samep) const { +bool AstVarRef::sameNoLvalue(const AstVarRef* samep) const { if (varScopep()) { return (varScopep() == samep->varScopep()); } else { diff --git a/src/V3AstNodeDType.h b/src/V3AstNodeDType.h index f16fc7fa2..861a1254d 100644 --- a/src/V3AstNodeDType.h +++ b/src/V3AstNodeDType.h @@ -792,7 +792,7 @@ public: private: string m_name; // Name from upper typedef, if any - const int m_uniqueNum = 0; + const int m_uniqueNum; TableMap m_tableMap; // Created table for V3Width only to remove duplicates public: diff --git a/src/V3AstNodeExpr.h b/src/V3AstNodeExpr.h index 71a97d67a..ce7241113 100644 --- a/src/V3AstNodeExpr.h +++ b/src/V3AstNodeExpr.h @@ -656,6 +656,7 @@ public: childDTypep(dtp); dtypeFrom(dtp); } + // cppcheck-suppress constParameterPointer AstCast(FileLine* fl, AstNodeExpr* fromp, AstNodeDType* dtp) : ASTGEN_SUPER_Cast(fl) { this->fromp(fromp); @@ -791,14 +792,17 @@ class AstConsDynArray final : public AstNodeExpr { // Construct a queue and return object, '{}. '{lhs}, '{lhs. rhs} // @astgen op1 := lhsp : Optional[AstNode] // @astgen op2 := rhsp : Optional[AstNode] - const bool m_lhsIsValue = false; // LHS constructs value inside the queue, not concat - const bool m_rhsIsValue = false; // RHS constructs value inside the queue, not concat + const bool m_lhsIsValue; // LHS constructs value inside the queue, not concat + const bool m_rhsIsValue; // RHS constructs value inside the queue, not concat public: explicit AstConsDynArray(FileLine* fl) - : ASTGEN_SUPER_ConsDynArray(fl) {} + : ASTGEN_SUPER_ConsDynArray(fl) + , m_lhsIsValue{false} + , m_rhsIsValue{false} {} explicit AstConsDynArray(FileLine* fl, bool lhsIsValue, AstNode* lhsp) : ASTGEN_SUPER_ConsDynArray(fl) - , m_lhsIsValue{lhsIsValue} { + , m_lhsIsValue{lhsIsValue} + , m_rhsIsValue{false} { this->lhsp(lhsp); } explicit AstConsDynArray(FileLine* fl, bool lhsIsValue, AstNode* lhsp, bool rhsIsValue, @@ -873,14 +877,17 @@ class AstConsQueue final : public AstNodeExpr { // Construct a queue and return object, '{}. '{lhs}, '{lhs. rhs} // @astgen op1 := lhsp : Optional[AstNode] // @astgen op2 := rhsp : Optional[AstNode] - const bool m_lhsIsValue = false; // LHS constructs value inside the queue, not concat - const bool m_rhsIsValue = false; // RHS constructs value inside the queue, not concat + const bool m_lhsIsValue; // LHS constructs value inside the queue, not concat + const bool m_rhsIsValue; // RHS constructs value inside the queue, not concat public: explicit AstConsQueue(FileLine* fl) - : ASTGEN_SUPER_ConsQueue(fl) {} + : ASTGEN_SUPER_ConsQueue(fl) + , m_lhsIsValue{false} + , m_rhsIsValue{false} {} explicit AstConsQueue(FileLine* fl, bool lhsIsValue, AstNode* lhsp) : ASTGEN_SUPER_ConsQueue(fl) - , m_lhsIsValue{lhsIsValue} { + , m_lhsIsValue{lhsIsValue} + , m_rhsIsValue{false} { this->lhsp(lhsp); } explicit AstConsQueue(FileLine* fl, bool lhsIsValue, AstNode* lhsp, bool rhsIsValue, @@ -1116,6 +1123,8 @@ private: const int m_srcElementBits; // num bits in rhs (ex 8 if from byte-queue, 1 if from bit-queue) public: + // cppcheck-suppress constParameterPointer + // cppcheck-suppress constParameterCallback AstCvtArrayToArray(FileLine* fl, AstNodeExpr* fromp, AstNodeDType* dtp, bool reverse, int blockSize, int dstElementBits, int srcElementBits) : ASTGEN_SUPER_CvtArrayToArray(fl) @@ -1141,6 +1150,8 @@ class AstCvtArrayToPacked final : public AstNodeExpr { // Cast from dynamic queue data type to packed array // @astgen op1 := fromp : AstNodeExpr public: + // cppcheck-suppress constParameterPointer + // cppcheck-suppress constParameterCallback AstCvtArrayToPacked(FileLine* fl, AstNodeExpr* fromp, AstNodeDType* dtp) : ASTGEN_SUPER_CvtArrayToPacked(fl) { this->fromp(fromp); @@ -1155,6 +1166,8 @@ class AstCvtPackedToArray final : public AstNodeExpr { // Cast from packed array to dynamic/unpacked queue data type // @astgen op1 := fromp : AstNodeExpr public: + // cppcheck-suppress constParameterPointer + // cppcheck-suppress constParameterCallback AstCvtPackedToArray(FileLine* fl, AstNodeExpr* fromp, AstNodeDType* dtp) : ASTGEN_SUPER_CvtPackedToArray(fl) { this->fromp(fromp); @@ -1169,6 +1182,8 @@ class AstCvtUnpackedToQueue final : public AstNodeExpr { // Cast from unpacked array to dynamic/unpacked queue data type // @astgen op1 := fromp : AstNodeExpr public: + // cppcheck-suppress constParameterPointer + // cppcheck-suppress constParameterCallback AstCvtUnpackedToQueue(FileLine* fl, AstNodeExpr* fromp, AstNodeDType* dtp) : ASTGEN_SUPER_CvtUnpackedToQueue(fl) { this->fromp(fromp); @@ -1604,7 +1619,6 @@ class AstLambdaArgRef final : public AstNodeExpr { // Lambda argument usage // These are not AstVarRefs because we need to be able to delete/clone lambdas during // optimizations and AstVar's are painful to remove. - ASTGEN_MEMBERS_AstLambdaArgRef; private: string m_name; // Name of variable @@ -1615,6 +1629,7 @@ public: : ASTGEN_SUPER_LambdaArgRef(fl) , m_name{name} , m_index{index} {} + ASTGEN_MEMBERS_AstLambdaArgRef; bool sameNode(const AstNode* /*samep*/) const override { return true; } string emitVerilog() override { return name(); } string emitC() override { V3ERROR_NA_RETURN(""); } @@ -1812,7 +1827,7 @@ class AstRand final : public AstNodeExpr { // $random/$random(seed) or $urandom/$urandom(seed) // Return a random number, based upon width() // @astgen op1 := seedp : Optional[AstNode] - const bool m_urandom = false; // $urandom vs $random + const bool m_urandom; // $urandom vs $random public: class Reset {}; AstRand(FileLine* fl, AstNode* seedp, bool urandom) @@ -1994,7 +2009,7 @@ class AstScopeName final : public AstNodeExpr { // @astgen op1 := scopeAttrp : List[AstText] // @astgen op2 := scopeEntrp : List[AstText] bool m_dpiExport = false; // Is for dpiExport - const bool m_forFormat = false; // Is for a format %m + const bool m_forFormat; // Is for a format %m string scopeNameFormatter(AstText* scopeTextp) const; string scopePrettyNameFormatter(AstText* scopeTextp) const; @@ -4211,7 +4226,7 @@ public: // === AstNodeSel === class AstArraySel final : public AstNodeSel { - void init(AstNode* fromp) { + void init(const AstNode* fromp) { if (fromp && VN_IS(fromp->dtypep()->skipRefp(), NodeArrayDType)) { // Strip off array to find what array references dtypeFrom(VN_AS(fromp->dtypep()->skipRefp(), NodeArrayDType)->subDTypep()); @@ -4251,7 +4266,7 @@ public: static AstNode* baseFromp(AstNode* nodep, bool overMembers); }; class AstAssocSel final : public AstNodeSel { - void init(AstNode* fromp) { + void init(const AstNode* fromp) { if (fromp && VN_IS(fromp->dtypep()->skipRefp(), AssocArrayDType)) { // Strip off array to find what array references dtypeFrom(VN_AS(fromp->dtypep()->skipRefp(), AssocArrayDType)->subDTypep()); @@ -4285,7 +4300,7 @@ public: int instrCount() const override { return widthInstrs(); } }; class AstWildcardSel final : public AstNodeSel { - void init(AstNode* fromp) { + void init(const AstNode* fromp) { if (fromp && VN_IS(fromp->dtypep()->skipRefp(), WildcardArrayDType)) { // Strip off array to find what array references dtypeFrom(VN_AS(fromp->dtypep()->skipRefp(), WildcardArrayDType)->subDTypep()); @@ -4976,6 +4991,8 @@ public: dtypeSetLogicUnsized(setwidth, minwidth, VSigning::UNSIGNED); } } + // cppcheck-suppress constParameterPointer + // cppcheck-suppress constParameterCallback AstCCast(FileLine* fl, AstNodeExpr* lhsp, AstNode* typeFromp) : ASTGEN_SUPER_CCast(fl, lhsp) { dtypeFrom(typeFromp); @@ -5768,7 +5785,7 @@ public: const char* broken() const override; bool sameNode(const AstNode* samep) const override; inline bool sameNode(const AstVarRef* samep) const; - inline bool sameNoLvalue(AstVarRef* samep) const; + inline bool sameNoLvalue(const AstVarRef* samep) const; int instrCount() const override; string emitVerilog() override { V3ERROR_NA_RETURN(""); } string emitC() override { V3ERROR_NA_RETURN(""); } diff --git a/src/V3AstNodeOther.h b/src/V3AstNodeOther.h index bf18a7049..aaaf9698f 100644 --- a/src/V3AstNodeOther.h +++ b/src/V3AstNodeOther.h @@ -784,7 +784,7 @@ class AstClassExtends final : public AstNode { // @astgen op1 := childDTypep : Optional[AstNodeDType] // @astgen op2 := classOrPkgsp : Optional[AstNode] // @astgen op3 := argsp : List[AstNodeExpr] - const bool m_isImplements = false; // class implements + const bool m_isImplements; // class implements bool m_parameterized = false; // has parameters in its statement public: @@ -812,8 +812,8 @@ class AstClocking final : public AstNode { // @astgen op2 := itemsp : List[AstClockingItem] // @astgen op3 := eventp : Optional[AstVar] std::string m_name; // Clocking block name - const bool m_isDefault = false; // True if default clocking - const bool m_isGlobal = false; // True if global clocking + const bool m_isDefault; // True if default clocking + const bool m_isGlobal; // True if global clocking public: AstClocking(FileLine* fl, const std::string& name, AstSenItem* sensesp, @@ -1531,7 +1531,7 @@ public: // Create new MODULETEMP variable under this scope AstVarScope* createTemp(const string& name, unsigned width); AstVarScope* createTemp(const string& name, AstNodeDType* dtypep); - AstVarScope* createTempLike(const string& name, AstVarScope* vscp); + AstVarScope* createTempLike(const string& name, const AstVarScope* vscp); }; class AstSenItem final : public AstNode { // Parents: SENTREE @@ -1961,7 +1961,7 @@ public: combineType(type); dtypeSetBitSized(wantwidth, VSigning::UNSIGNED); } - AstVar(FileLine* fl, VVarType type, const string& name, AstVar* examplep) + AstVar(FileLine* fl, VVarType type, const string& name, const AstVar* examplep) : ASTGEN_SUPER_Var(fl) , m_name{name} , m_origName{name} { @@ -2133,7 +2133,7 @@ public: bool isGParam() const { return varType() == VVarType::GPARAM; } bool isGenVar() const { return varType() == VVarType::GENVAR; } bool isBitLogic() const { - AstBasicDType* bdtypep = basicp(); + const AstBasicDType* const bdtypep = basicp(); return bdtypep && bdtypep->isBitLogic(); } bool isUsedClock() const VL_MT_SAFE { return m_usedClock; } @@ -2486,7 +2486,7 @@ public: && std::is_base_of::value, "T_Callable 'f' must have a signature compatible with 'void(AstClass*, T_Node*)', " "with 'T_Node' being a subtype of 'AstNode'"); - if (AstClassExtends* const cextendsp = this->extendsp()) { + if (const AstClassExtends* const cextendsp = this->extendsp()) { cextendsp->classp()->foreachMember(f); } for (AstNode* stmtp = stmtsp(); stmtp; stmtp = stmtp->nextp()) { @@ -2502,7 +2502,7 @@ public: && std::is_base_of::value, "Predicate 'p' must have a signature compatible with 'bool(const AstClass*, " "const T_Node*)', with 'T_Node' being a subtype of 'AstNode'"); - if (AstClassExtends* const cextendsp = this->extendsp()) { + if (const AstClassExtends* const cextendsp = this->extendsp()) { if (cextendsp->classp()->existsMember(p)) return true; } for (AstNode* stmtp = stmtsp(); stmtp; stmtp = stmtp->nextp()) { @@ -2540,18 +2540,22 @@ public: }; class AstModule final : public AstNodeModule { // A module declaration - const bool m_isChecker = false; // Module represents a checker - const bool m_isProgram = false; // Module represents a program + const bool m_isChecker; // Module represents a checker + const bool m_isProgram; // Module represents a program public: class Checker {}; // for constructor type-overload selection class Program {}; // for constructor type-overload selection AstModule(FileLine* fl, const string& name, const string& libname) - : ASTGEN_SUPER_Module(fl, name, libname) {} + : ASTGEN_SUPER_Module(fl, name, libname) + , m_isChecker{false} + , m_isProgram{false} {} AstModule(FileLine* fl, const string& name, const string& libname, Checker) : ASTGEN_SUPER_Module(fl, name, libname) - , m_isChecker{true} {} + , m_isChecker{true} + , m_isProgram{false} {} AstModule(FileLine* fl, const string& name, const string& libname, Program) : ASTGEN_SUPER_Module(fl, name, libname) + , m_isChecker{false} , m_isProgram{true} {} ASTGEN_MEMBERS_AstModule; string verilogKwd() const override { diff --git a/src/V3AstNodeStmt.h b/src/V3AstNodeStmt.h index 7d47b230c..447441684 100644 --- a/src/V3AstNodeStmt.h +++ b/src/V3AstNodeStmt.h @@ -845,6 +845,7 @@ public: this->exprp(exprp); } ASTGEN_MEMBERS_AstStmtExpr; + // cppcheck-suppress uselessOverride bool isPure() override { return exprp()->isPure(); } }; class AstStop final : public AstNodeStmt { diff --git a/src/V3AstNodes.cpp b/src/V3AstNodes.cpp index 60a87ef90..2cea4e39b 100644 --- a/src/V3AstNodes.cpp +++ b/src/V3AstNodes.cpp @@ -542,18 +542,16 @@ string AstVar::vlArgType(bool named, bool forReturn, bool forFunc, const string& string ostatic; if (isStatic() && namespc.empty()) ostatic = "static "; - const bool isRef = isDpiOpenArray() - || (forFunc && (isWritable() || this->isRef() || this->isConstRef())) - || asRef; + asRef = asRef || isDpiOpenArray() || (forFunc && (isWritable() || isRef() || isConstRef())); - if (forFunc && isReadOnly() && isRef) ostatic = ostatic + "const "; + if (forFunc && isReadOnly() && asRef) ostatic = ostatic + "const "; string oname; if (named) { if (!namespc.empty()) oname += namespc + "::"; oname += VIdProtect::protectIf(name(), protect()); } - return ostatic + dtypep()->cType(oname, forFunc, isRef); + return ostatic + dtypep()->cType(oname, forFunc, asRef); } string AstVar::vlEnumType() const { @@ -687,7 +685,7 @@ string AstVar::cPubArgType(bool named, bool forReturn) const { if (forReturn) named = false; string arg; if (isWide() && isReadOnly()) arg += "const "; - const bool isRef = !forReturn && (isWritable() || this->isRef() || this->isConstRef()); + const bool asRef = !forReturn && (isWritable() || this->isRef() || this->isConstRef()); if (VN_IS(dtypeSkipRefp(), BasicDType) && !dtypeSkipRefp()->isDouble() && !dtypeSkipRefp()->isString()) { // Backward compatible type declaration @@ -708,12 +706,12 @@ string AstVar::cPubArgType(bool named, bool forReturn) const { arg += " (& " + name(); arg += ")[" + cvtToStr(widthWords()) + "]"; } else { - if (isRef) arg += "&"; + if (asRef) arg += "&"; if (named) arg += " " + name(); } } else { // Newer internal-compatible types - arg += dtypep()->cType((named ? name() : std::string{}), true, isRef); + arg += dtypep()->cType((named ? name() : std::string{}), true, asRef); } return arg; } @@ -775,7 +773,7 @@ string AstVar::dpiTmpVarType(const string& varName) const { class converter final : public dpiTypesToStringConverter { const string m_name; string arraySuffix(const AstVar* varp, size_t n) const { - if (AstUnpackArrayDType* const unpackp + if (const AstUnpackArrayDType* const unpackp = VN_CAST(varp->dtypep()->skipRefp(), UnpackArrayDType)) { // Convert multi dimensional unpacked array to 1D array if (n == 0) n = 1; @@ -849,13 +847,13 @@ AstVar* AstVar::scVarRecurse(AstNode* nodep) { } else { return nullptr; } - } else if (AstVarRef* const vrefp = VN_CAST(nodep, VarRef)) { + } else if (const AstVarRef* const vrefp = VN_CAST(nodep, VarRef)) { if (vrefp->varp()->isSc()) { return vrefp->varp(); } else { return nullptr; } - } else if (AstArraySel* const arraySelp = VN_CAST(nodep, ArraySel)) { + } else if (const AstArraySel* const arraySelp = VN_CAST(nodep, ArraySel)) { if (AstVar* const p = scVarRecurse(arraySelp->fromp())) return p; } return nullptr; @@ -1194,7 +1192,7 @@ AstVarScope* AstScope::createTemp(const string& name, AstNodeDType* dtypep) { return vscp; } -AstVarScope* AstScope::createTempLike(const string& name, AstVarScope* vscp) { +AstVarScope* AstScope::createTempLike(const string& name, const AstVarScope* vscp) { return createTemp(name, vscp->dtypep()); } @@ -1568,7 +1566,7 @@ void AstNode::dump(std::ostream& str) const { } else { str << " @dt=" << nodeAddr(dtypep()) << "@"; } - if (AstNodeDType* const dtp = dtypep()) dtp->dumpSmall(str); + if (const AstNodeDType* const dtp = dtypep()) dtp->dumpSmall(str); } else { // V3Broken will throw an error if (dtypep()) str << " %Error-dtype-exp=null,got=" << nodeAddr(dtypep()); } @@ -2217,10 +2215,10 @@ void AstRefDType::dump(std::ostream& str) const { if (!s_recursing) { // Prevent infinite dump if circular typedefs s_recursing = true; str << " -> "; - if (const auto subp = subDTypep()) { + if (const AstNodeDType* const subp = subDTypep()) { if (typedefp()) str << "typedef=" << static_cast(typedefp()) << " -> "; subp->dump(str); - } else if (const auto subp = typedefp()) { + } else if (const AstTypedef* const subp = typedefp()) { subp->dump(str); } s_recursing = false; @@ -2264,7 +2262,7 @@ string AstNodeUOrStructDType::prettyDTypeName(bool full) const { void AstNodeDType::dump(std::ostream& str) const { this->AstNode::dump(str); if (generic()) str << " [GENERIC]"; - if (AstNodeDType* const dtp = virtRefDTypep()) { + if (const AstNodeDType* const dtp = virtRefDTypep()) { str << " refdt=" << nodeAddr(dtp); dtp->dumpSmall(str); } @@ -2476,7 +2474,7 @@ void AstMTaskBody::dumpJson(std::ostream& str) const { void AstTypeTable::dump(std::ostream& str) const { this->AstNode::dump(str); for (int i = 0; i < static_cast(VBasicDTypeKwd::_ENUM_MAX); ++i) { - if (AstBasicDType* const subnodep = m_basicps[i]) { + if (const AstBasicDType* const subnodep = m_basicps[i]) { str << '\n'; // Newline from caller, so newline first str << "\t\t" << std::setw(8) << VBasicDTypeKwd{i}.ascii(); str << " -> "; @@ -2486,7 +2484,7 @@ void AstTypeTable::dump(std::ostream& str) const { { const DetailedMap& mapr = m_detailedMap; for (const auto& itr : mapr) { - AstBasicDType* const dtypep = itr.second; + const AstBasicDType* const dtypep = itr.second; str << '\n'; // Newline from caller, so newline first str << "\t\tdetailed -> "; dtypep->dump(str); @@ -2591,15 +2589,21 @@ void AstNodeVarRef::dumpJson(std::ostream& str) const { AstNodeVarRef* AstNodeVarRef::varRefLValueRecurse(AstNode* nodep) { // Given a (possible) lvalue expression, recurse to find the being-set NodeVarRef, else nullptr if (AstNodeVarRef* const anodep = VN_CAST(nodep, NodeVarRef)) return anodep; - if (AstNodeSel* const anodep = VN_CAST(nodep, NodeSel)) + if (const AstNodeSel* const anodep = VN_CAST(nodep, NodeSel)) { return varRefLValueRecurse(anodep->fromp()); - if (AstSel* const anodep = VN_CAST(nodep, Sel)) return varRefLValueRecurse(anodep->fromp()); - if (AstArraySel* const anodep = VN_CAST(nodep, ArraySel)) + } + if (const AstSel* const anodep = VN_CAST(nodep, Sel)) { return varRefLValueRecurse(anodep->fromp()); - if (AstMemberSel* const anodep = VN_CAST(nodep, MemberSel)) + } + if (const AstArraySel* const anodep = VN_CAST(nodep, ArraySel)) { return varRefLValueRecurse(anodep->fromp()); - if (AstStructSel* const anodep = VN_CAST(nodep, StructSel)) + } + if (const AstMemberSel* const anodep = VN_CAST(nodep, MemberSel)) { return varRefLValueRecurse(anodep->fromp()); + } + if (const AstStructSel* const anodep = VN_CAST(nodep, StructSel)) { + return varRefLValueRecurse(anodep->fromp()); + } return nullptr; } @@ -2796,9 +2800,12 @@ AstNodeModule* AstClassOrPackageRef::classOrPackageSkipp() const { if (AstNodeDType* const anodep = VN_CAST(foundp, NodeDType)) { foundp = anodep->skipRefOrNullp(); } - if (AstTypedef* const anodep = VN_CAST(foundp, Typedef)) foundp = anodep->subDTypep(); - if (AstClassRefDType* const anodep = VN_CAST(foundp, ClassRefDType)) + if (const AstTypedef* const anodep = VN_CAST(foundp, Typedef)) { + foundp = anodep->subDTypep(); + } + if (const AstClassRefDType* const anodep = VN_CAST(foundp, ClassRefDType)) { foundp = anodep->classp(); + } } return VN_CAST(foundp, NodeModule); } @@ -3076,7 +3083,7 @@ void AstCAwait::dump(std::ostream& str) const { } void AstCAwait::dumpJson(std::ostream& str) const { dumpJsonGen(str); } int AstCMethodHard::instrCount() const { - if (AstBasicDType* const basicp = fromp()->dtypep()->basicp()) { + if (const AstBasicDType* const basicp = fromp()->dtypep()->basicp()) { // TODO: add a more structured description of library methods, rather than using string // matching. See issue #3715. if (basicp->isTriggerVec() && m_name == "word") { @@ -3165,8 +3172,8 @@ void AstCMethodHard::setPurity() { if (name() == "atWriteAppend" || name() == "atWriteAppendBack") { m_pure = false; // Treat atWriteAppend as pure if the argument is a loop iterator - if (AstNodeExpr* const argp = pinsp()) { - if (AstVarRef* const varrefp = VN_CAST(argp, VarRef)) { + if (const AstNodeExpr* const argp = pinsp()) { + if (const AstVarRef* const varrefp = VN_CAST(argp, VarRef)) { if (varrefp->varp()->isUsedLoopIdx()) m_pure = true; } } diff --git a/src/V3Begin.cpp b/src/V3Begin.cpp index cd6cd7fe9..d90ac3aa0 100644 --- a/src/V3Begin.cpp +++ b/src/V3Begin.cpp @@ -455,7 +455,7 @@ AstNode* V3Begin::convertToWhile(AstForeach* nodep) { lastp->unlinkFrBack(&handle); if (const AstNodeArrayDType* const adtypep = VN_CAST(fromDtp, NodeArrayDType)) { loopp = createForeachLoopRanged(nodep, bodyPointp, varp, adtypep->declRange()); - } else if (AstBasicDType* const adtypep = VN_CAST(fromDtp, BasicDType)) { + } else if (const AstBasicDType* const adtypep = VN_CAST(fromDtp, BasicDType)) { if (adtypep->isString()) { AstConst* const leftp = new AstConst{fl, 0}; AstNodeExpr* const rightp = new AstLenN{fl, fromp->cloneTreePure(false)}; diff --git a/src/V3Branch.cpp b/src/V3Branch.cpp index 72203bd8e..f4defb43c 100644 --- a/src/V3Branch.cpp +++ b/src/V3Branch.cpp @@ -51,7 +51,7 @@ class BranchVisitor final : public VNVisitorConst { m_likely = false; m_unlikely = false; } - void checkUnlikely(AstNode* nodep) { + void checkUnlikely(const AstNode* nodep) { if (nodep->isUnlikely()) { UINFO(4, " UNLIKELY: " << nodep); m_unlikely++; diff --git a/src/V3CUse.cpp b/src/V3CUse.cpp index e51507c39..19687d603 100644 --- a/src/V3CUse.cpp +++ b/src/V3CUse.cpp @@ -43,7 +43,7 @@ class CUseVisitor final : public VNVisitorConst { std::map> m_didUse; // What we already used // METHODS - void addNewUse(AstNode* nodep, VUseType useType, const string& name) { + void addNewUse(const AstNode* nodep, VUseType useType, const string& name) { auto e = m_didUse.emplace(name, std::make_pair(nodep->fileline(), useType)); if (e.second || ((e.first->second.second & useType) != useType)) { e.first->second.second = e.first->second.second | useType; @@ -73,7 +73,8 @@ class CUseVisitor final : public VNVisitorConst { if (stypep && stypep->classOrPackagep()) { addNewUse(nodep, VUseType::INT_INCLUDE, stypep->classOrPackagep()->name()); iterateChildrenConst(stypep); - } else if (AstClassRefDType* const classp = VN_CAST(nodep->skipRefp(), ClassRefDType)) { + } else if (const AstClassRefDType* const classp + = VN_CAST(nodep->skipRefp(), ClassRefDType)) { addNewUse(nodep, VUseType::INT_FWD_CLASS, classp->name()); } } @@ -95,7 +96,7 @@ public: : m_modp{modp} { iterateConst(modp); - for (auto& used : m_didUse) { + for (const auto& used : m_didUse) { AstCUse* const newp = new AstCUse{used.second.first, used.second.second, used.first}; m_modp->addStmtsp(newp); UINFO(8, "Insert " << newp); diff --git a/src/V3Case.cpp b/src/V3Case.cpp index 1c13b744a..7af727731 100644 --- a/src/V3Case.cpp +++ b/src/V3Case.cpp @@ -216,7 +216,7 @@ class CaseVisitor final : public VNVisitor { const uint32_t val = numval.toUInt(); uint32_t firstOverlap = 0; - AstNode* overlappedCondp = nullptr; + const AstNode* overlappedCondp = nullptr; bool foundHit = false; for (uint32_t i = 0; i < numCases; ++i) { if ((i & mask) == val) { @@ -307,7 +307,7 @@ class CaseVisitor final : public VNVisitor { // Not done earlier, as we may now have a nullptr because it's just a ";" NOP branch for (uint32_t i = 0; i < numCases; ++i) { if (AstNode* const condp = m_valueItem[i]) { - AstCaseItem* caseItemp = caseItemMap[condp]; + const AstCaseItem* const caseItemp = caseItemMap[condp]; UASSERT(caseItemp, "caseItemp should exist"); m_valueItem[i] = caseItemp->stmtsp(); } @@ -325,7 +325,7 @@ class CaseVisitor final : public VNVisitor { } else { // Make left and right subtrees // cexpr[msb:lsb] == 1 - AstNode* tree0p = replaceCaseFastRecurse(cexprp, msb - 1, upperValue | 0); + AstNode* tree0p = replaceCaseFastRecurse(cexprp, msb - 1, upperValue); AstNode* tree1p = replaceCaseFastRecurse( cexprp, msb - 1, upperValue | (1UL << static_cast(msb))); @@ -548,7 +548,7 @@ class CaseVisitor final : public VNVisitor { } } - bool neverItem(AstCase* casep, AstConst* itemp) { + bool neverItem(const AstCase* casep, const AstConst* itemp) { // Xs in case or casez are impossible due to two state simulations if (casep->casex()) { } else if (casep->casez() || casep->caseInside()) { diff --git a/src/V3Cast.cpp b/src/V3Cast.cpp index 24e20d3e1..4839b8d04 100644 --- a/src/V3Cast.cpp +++ b/src/V3Cast.cpp @@ -69,7 +69,7 @@ class CastVisitor final : public VNVisitor { ensureLower32Cast(castp); nodep->user1(1); // Now must be of known size } - static int castSize(AstNode* nodep) { + static int castSize(const AstNode* nodep) { if (nodep->isQuad()) { return VL_QUADSIZE; } else if (nodep->width() <= 8) { diff --git a/src/V3CfgLiveVariables.cpp b/src/V3CfgLiveVariables.cpp index 790ee7fee..b0db3aa76 100644 --- a/src/V3CfgLiveVariables.cpp +++ b/src/V3CfgLiveVariables.cpp @@ -83,7 +83,7 @@ class CfgLiveVariables final : VNVisitorConst { // Check and return if variable is incompatible bool incompatible(Variable* varp) { if (!isSupportedPackedDType(varp->dtypep())) return true; - AstVar* astVarp = nullptr; + const AstVar* astVarp = nullptr; // TODO: remove the useless reinterpret_casts when C++17 'if constexpr' actually works if VL_CONSTEXPR_CXX17 (T_Scoped) { astVarp = reinterpret_cast(varp)->varp(); diff --git a/src/V3Class.cpp b/src/V3Class.cpp index 6cd5d9b1e..fbf384d6a 100644 --- a/src/V3Class.cpp +++ b/src/V3Class.cpp @@ -257,7 +257,7 @@ public: modp->addStmtsp(nodep); } // BFS to mark public typedefs. - std::set pubStrDtypeps; + std::set pubStrDtypeps; while (!m_pubStrDtypeps.empty()) { AstNodeUOrStructDType* const dtypep = m_pubStrDtypeps.front(); m_pubStrDtypeps.pop(); @@ -270,7 +270,8 @@ public: } } for (AstTypedef* typedefp : m_typedefps) { - AstNodeUOrStructDType* const sdtypep = VN_AS(typedefp->dtypep(), NodeUOrStructDType); + const AstNodeUOrStructDType* const sdtypep + = VN_AS(typedefp->dtypep(), NodeUOrStructDType); if (pubStrDtypeps.count(sdtypep)) typedefp->attrPublic(true); } // Clear package pointer of non-public packed struct / union type, which will never be diff --git a/src/V3Clean.cpp b/src/V3Clean.cpp index 0fe863e4d..ed8134b9a 100644 --- a/src/V3Clean.cpp +++ b/src/V3Clean.cpp @@ -51,7 +51,7 @@ class CleanVisitor final : public VNVisitor { // METHODS // Width resetting - int cppWidth(AstNode* nodep) { + int cppWidth(const AstNode* nodep) { if (nodep->width() <= VL_IDATASIZE) { return VL_IDATASIZE; } else if (nodep->width() <= VL_QUADSIZE) { @@ -101,7 +101,9 @@ class CleanVisitor final : public VNVisitor { // Store the clean state in the userp on each node void setCleanState(AstNode* nodep, CleanState clean) { nodep->user1(clean); } - CleanState getCleanState(AstNode* nodep) { return static_cast(nodep->user1()); } + CleanState getCleanState(const AstNode* nodep) { + return static_cast(nodep->user1()); + } bool isClean(AstNode* nodep) { const CleanState clstate = getCleanState(nodep); if (clstate == CS_CLEAN) return true; diff --git a/src/V3Const.cpp b/src/V3Const.cpp index 0846a3126..b2afb50c5 100644 --- a/src/V3Const.cpp +++ b/src/V3Const.cpp @@ -170,8 +170,8 @@ class ConstBitOpTreeVisitor final : public VNVisitorConst { struct BitPolarityEntry final { // Found bit polarity during iterate() LeafInfo m_info; - bool m_polarity; - int m_bit; + bool m_polarity = false; + int m_bit = 0; BitPolarityEntry(const LeafInfo& info, bool pol, int bit) : m_info{info} , m_polarity{pol} @@ -392,7 +392,7 @@ class ConstBitOpTreeVisitor final : public VNVisitorConst { #define CONST_BITOP_SET_FAILED(reason, nodep) setFailed(true, reason, nodep, __LINE__) - bool setFailed(bool fail, const char* reason, AstNode* nodep, int line) { + bool setFailed(bool fail, const char* reason, const AstNode* nodep, int line) { if (fail && !m_failed) { UINFO(9, "cannot optimize " << m_rootp << " reason:" << reason << " called from line:" << line << " when checking:" << nodep); @@ -460,7 +460,7 @@ class ConstBitOpTreeVisitor final : public VNVisitorConst { } void visit(AstShiftR* nodep) override { CONST_BITOP_RETURN_IF(!m_leafp, nodep); - AstConst* const constp = VN_CAST(nodep->rhsp(), Const); + const AstConst* const constp = VN_CAST(nodep->rhsp(), Const); CONST_BITOP_RETURN_IF(!constp, nodep->rhsp()); m_lsb += constp->toUInt(); incrOps(nodep, __LINE__); @@ -484,7 +484,7 @@ class ConstBitOpTreeVisitor final : public VNVisitorConst { } void visit(AstWordSel* nodep) override { CONST_BITOP_RETURN_IF(!m_leafp, nodep); - AstConst* const constp = VN_CAST(nodep->bitp(), Const); + const AstConst* const constp = VN_CAST(nodep->bitp(), Const); CONST_BITOP_RETURN_IF(!constp, nodep->bitp()); UASSERT_OBJ(m_leafp->wordIdx() == -1, nodep, "Unexpected nested WordSel"); m_leafp->wordIdx(constp->toSInt()); @@ -796,7 +796,7 @@ public: if (debug() >= 9) { // LCOV_EXCL_START cout << "- Bitop tree considered:\n"; - for (AstNodeExpr* const termp : termps) termp->dumpTree("- Reduced term: "); + for (const AstNodeExpr* const termp : termps) termp->dumpTree("- Reduced term: "); for (const std::pair& termp : visitor.m_frozenNodes) { termp.first->dumpTree("- Frozen term with lsb " + std::to_string(termp.second.m_lsb) + " polarity " @@ -916,7 +916,6 @@ class ConstVisitor final : public VNVisitor { // AstEnum::user4 -> bool. Recursing. // STATE - static constexpr bool m_doShort = true; // Remove expressions that short circuit bool m_params = false; // If true, propagate parameterized and true numbers only bool m_required = false; // If true, must become a constant bool m_wremove = true; // Inside scope, no assignw removal @@ -949,12 +948,12 @@ class ConstVisitor final : public VNVisitor { const V3Number& numc = VN_AS(nodep, Const)->num(); return !numc.isNumber() ? numc : V3Number{nodep, nodep->widthMinV(), numc}; } - V3Number toNumC(AstNode* nodep, V3Number& numv) { + V3Number toNumC(AstNode* nodep, const V3Number& numv) { // Extend V width back to C width for given node return !numv.isNumber() ? numv : V3Number{nodep, nodep->width(), numv}; } - bool operandConst(AstNode* nodep) { return VN_IS(nodep, Const); } + bool operandConst(const AstNode* nodep) { return VN_IS(nodep, Const); } bool operandAsvConst(const AstNode* nodep) { // BIASV(CONST, BIASV(CONST,...)) -> BIASV( BIASV_CONSTED(a,b), ...) const AstNodeBiComAsv* const bnodep = VN_CAST(nodep, NodeBiComAsv); @@ -1022,8 +1021,9 @@ class ConstVisitor final : public VNVisitor { UASSERT_OBJ(constp && constp->isOne(), andp->lhsp(), "TRREEOPC must meet this condition"); AstNodeExpr* const rhsp = andp->rhsp(); AstCCast* ccastp = nullptr; - const auto isEqOrNeq - = [](AstNode* nodep) -> bool { return VN_IS(nodep, Eq) || VN_IS(nodep, Neq); }; + const auto isEqOrNeq = [](const AstNode* nodep) -> bool { // + return VN_IS(nodep, Eq) || VN_IS(nodep, Neq); + }; if (isEqOrNeq(rhsp)) { ccastp = new AstCCast{andp->fileline(), rhsp->unlinkFrBack(), andp}; } else if (AstCCast* const tmpp = VN_CAST(rhsp, CCast)) { @@ -1352,8 +1352,8 @@ class ConstVisitor final : public VNVisitor { return false; } AstNodeExpr* const ap = shiftp->lhsp(); - AstConst* const bp = VN_AS(shiftp->rhsp(), Const); - AstConst* const lp = VN_AS(nodep->lsbp(), Const); + const AstConst* const bp = VN_AS(shiftp->rhsp(), Const); + const AstConst* const lp = VN_AS(nodep->lsbp(), Const); if (bp->isWide() || bp->num().isFourState() || bp->num().isNegative() || lp->isWide() || lp->num().isFourState() || lp->num().isNegative()) { return false; @@ -1402,7 +1402,7 @@ class ConstVisitor final : public VNVisitor { // Avoids compiler warning const AstExtend* const extendp = VN_CAST(nodep->rhsp(), Extend); if (!extendp) return false; - AstNode* const smallerp = extendp->lhsp(); + const AstNode* const smallerp = extendp->lhsp(); const int subsize = smallerp->width(); const AstConst* const constp = VN_CAST(nodep->lhsp(), Const); if (!constp) return false; @@ -1459,7 +1459,7 @@ class ConstVisitor final : public VNVisitor { return false; // Not a transform, so NOP } - static bool operandsSame(AstNode* node1p, AstNode* node2p) { + static bool operandsSame(const AstNode* node1p, const AstNode* node2p) { // For now we just detect constants & simple vars, though it could be more generic if (VN_IS(node1p, Const) && VN_IS(node2p, Const)) return node1p->sameGateTree(node2p); if (VN_IS(node1p, VarRef) && VN_IS(node2p, VarRef)) { @@ -1469,8 +1469,8 @@ class ConstVisitor final : public VNVisitor { return node1p->isSame(node2p); } // Pattern created by coverage-line; avoid compiler tautological-compare warning - if (AstAnd* const and1p = VN_CAST(node1p, And)) { - if (AstAnd* const and2p = VN_CAST(node2p, And)) { + if (const AstAnd* const and1p = VN_CAST(node1p, And)) { + if (const AstAnd* const and2p = VN_CAST(node2p, And)) { if (VN_IS(and1p->lhsp(), Const) && VN_IS(and1p->rhsp(), NodeVarRef) && VN_IS(and2p->lhsp(), Const) && VN_IS(and2p->rhsp(), NodeVarRef)) return node1p->sameGateTree(node2p); @@ -1535,11 +1535,11 @@ class ConstVisitor final : public VNVisitor { if (!lselp || !rselp) return false; // a[a:b] a[b-1:c] are adjacent - AstNode* const lfromp = lselp->fromp(); - AstNode* const rfromp = rselp->fromp(); + const AstNode* const lfromp = lselp->fromp(); + const AstNode* const rfromp = rselp->fromp(); if (!lfromp || !rfromp || !lfromp->sameGateTree(rfromp)) return false; - AstConst* const lstart = VN_CAST(lselp->lsbp(), Const); - AstConst* const rstart = VN_CAST(rselp->lsbp(), Const); + const AstConst* const lstart = VN_CAST(lselp->lsbp(), Const); + const AstConst* const rstart = VN_CAST(rselp->lsbp(), Const); if (!lstart || !rstart) return false; // too complicated const int rend = (rstart->toSInt() + rselp->widthConst()); // a[i:j] a[j-1:k] @@ -2209,11 +2209,11 @@ class ConstVisitor final : public VNVisitor { if (VN_IS(srcDTypep, QueueDType) || VN_IS(srcDTypep, DynArrayDType)) { if (VN_IS(dstDTypep, QueueDType) || VN_IS(dstDTypep, DynArrayDType)) { int srcElementBits = 0; - if (AstNodeDType* const elemDtp = srcDTypep->subDTypep()) { + if (const AstNodeDType* const elemDtp = srcDTypep->subDTypep()) { srcElementBits = elemDtp->width(); } int dstElementBits = 0; - if (AstNodeDType* const elemDtp = dstDTypep->subDTypep()) { + if (const AstNodeDType* const elemDtp = dstDTypep->subDTypep()) { dstElementBits = elemDtp->width(); } srcp = new AstCvtArrayToArray{ @@ -2243,7 +2243,7 @@ class ConstVisitor final : public VNVisitor { AstNodeExpr* const dstp = VN_AS(streamp, StreamL)->lhsp()->unlinkFrBack(); AstNodeDType* const dstDTypep = dstp->dtypep()->skipRefp(); AstNodeExpr* const srcp = nodep->rhsp()->unlinkFrBack(); - AstNodeDType* const srcDTypep = srcp->dtypep()->skipRefp(); + const AstNodeDType* const srcDTypep = srcp->dtypep()->skipRefp(); const int sWidth = srcp->width(); const int dWidth = dstp->width(); // Connect the rhs to the stream operator and update its width @@ -2306,7 +2306,7 @@ class ConstVisitor final : public VNVisitor { } else if (m_doV && VN_IS(nodep->rhsp(), StreamL)) { AstStreamL* streamp = VN_AS(nodep->rhsp(), StreamL); AstNodeExpr* srcp = streamp->lhsp(); - AstNodeDType* const srcDTypep = srcp->dtypep()->skipRefp(); + const AstNodeDType* const srcDTypep = srcp->dtypep()->skipRefp(); AstNodeDType* const dstDTypep = nodep->lhsp()->dtypep()->skipRefp(); if ((VN_IS(srcDTypep, QueueDType) || VN_IS(srcDTypep, DynArrayDType) || VN_IS(srcDTypep, UnpackArrayDType))) { @@ -2330,11 +2330,11 @@ class ConstVisitor final : public VNVisitor { // streamp->rhsp()->prettyTypeName() << ")"); // } int srcElementBits = 0; - if (AstNodeDType* const elemDtp = srcDTypep->subDTypep()) { + if (const AstNodeDType* const elemDtp = srcDTypep->subDTypep()) { srcElementBits = elemDtp->width(); } int dstElementBits = 0; - if (AstNodeDType* const elemDtp = dstDTypep->subDTypep()) { + if (const AstNodeDType* const elemDtp = dstDTypep->subDTypep()) { dstElementBits = elemDtp->width(); } streamp->unlinkFrBack(); @@ -2500,7 +2500,7 @@ class ConstVisitor final : public VNVisitor { bool matchConcatRand(AstConcat* nodep) { // CONCAT(RAND, RAND) - created by Chisel code AstRand* const aRandp = VN_CAST(nodep->lhsp(), Rand); - AstRand* const bRandp = VN_CAST(nodep->rhsp(), Rand); + const AstRand* const bRandp = VN_CAST(nodep->rhsp(), Rand); if (!aRandp || !bRandp) return false; if (!aRandp->combinable(bRandp)) return false; UINFO(4, "Concat(Rand,Rand) => Rand: " << nodep); @@ -2518,15 +2518,15 @@ class ConstVisitor final : public VNVisitor { VL_DO_DANGLING(pushDeletep(nodep), nodep); return true; } - int operandConcatMove(AstConcat* nodep) { + int operandConcatMove(const AstConcat* nodep) { // CONCAT under concat (See moveConcat) // Return value: true indicates to do it; 2 means move to LHS const AstConcat* const abConcp = VN_CAST(nodep->lhsp(), Concat); const AstConcat* const bcConcp = VN_CAST(nodep->rhsp(), Concat); if (!abConcp && !bcConcp) return 0; if (bcConcp) { - AstNodeExpr* const ap = nodep->lhsp(); - AstNodeExpr* const bp = bcConcp->lhsp(); + const AstNodeExpr* const ap = nodep->lhsp(); + const AstNodeExpr* const bp = bcConcp->lhsp(); // If a+b == 32,64,96 etc, then we want to have a+b together on LHS if (VL_BITBIT_I(ap->width() + bp->width()) == 0) return 2; // Transform 2: to abConc } else { // abConcp @@ -2617,7 +2617,7 @@ class ConstVisitor final : public VNVisitor { // potentially smaller lsb1p's width, but don't insert a redundant AstExtend. // Note that due to some sloppiness in earlier passes, lsb1p might actually be wider, // so extend to the wider type. - AstNodeExpr* const widep = lsb1p->width() > lsb2p->width() ? lsb1p : lsb2p; + const AstNodeExpr* const widep = lsb1p->width() > lsb2p->width() ? lsb1p : lsb2p; AstNodeExpr* const lhsp = widep->width() > lsb2p->width() ? new AstExtend{lsb2p->fileline(), lsb2p} : lsb2p; @@ -2895,7 +2895,7 @@ class ConstVisitor final : public VNVisitor { // Not constant propagated (for today) because AstNodeExpr::isOpaque is set // Someday if lower is constant, convert to quoted "string". - bool onlySenItemInSenTree(AstSenItem* nodep) { + bool onlySenItemInSenTree(const AstSenItem* nodep) { // Only one if it's not in a list return (!nodep->nextp() && nodep->backp()->nextp() != nodep); } @@ -2981,8 +2981,8 @@ class ConstVisitor final : public VNVisitor { if (aCallp->name() < bCallp->name()) return -1; if (aCallp->name() > bCallp->name()) return 1; if (const int c = cmp(aCallp->fromp(), bCallp->fromp())) return c; - AstNodeExpr* aPinsp = aCallp->pinsp(); - AstNodeExpr* bPinsp = bCallp->pinsp(); + const AstNodeExpr* aPinsp = aCallp->pinsp(); + const AstNodeExpr* bPinsp = bCallp->pinsp(); while (aPinsp && bPinsp) { if (const int c = cmp(aPinsp, bPinsp)) return c; aPinsp = VN_AS(aPinsp->nextp(), NodeExpr); @@ -2996,8 +2996,8 @@ class ConstVisitor final : public VNVisitor { public: bool operator()(const AstSenItem* lhsp, const AstSenItem* rhsp) const { - AstNodeExpr* const lSensp = lhsp->sensp(); - AstNodeExpr* const rSensp = rhsp->sensp(); + const AstNodeExpr* const lSensp = lhsp->sensp(); + const AstNodeExpr* const rSensp = rhsp->sensp(); if (lSensp && rSensp) { // If both terms have sensitivity expressions, recursively compare them if (const int c = cmp(lSensp, rSensp)) return c < 0; @@ -3163,11 +3163,11 @@ class ConstVisitor final : public VNVisitor { } if (streamp) { AstNodeExpr* srcp = streamp->lhsp(); - AstNodeDType* const srcDTypep = srcp->dtypep()->skipRefp(); + const AstNodeDType* const srcDTypep = srcp->dtypep()->skipRefp(); AstNodeDType* const dstDTypep = nodep->dtypep()->skipRefp(); if (VN_IS(srcDTypep, QueueDType) && VN_IS(dstDTypep, QueueDType)) { int blockSize = 1; - if (AstConst* const constp = VN_CAST(streamp->rhsp(), Const)) { + if (const AstConst* const constp = VN_CAST(streamp->rhsp(), Const)) { blockSize = constp->toSInt(); if (VL_UNLIKELY(blockSize <= 0)) { // Not reachable due to higher level checks when parsing stream @@ -3184,11 +3184,11 @@ class ConstVisitor final : public VNVisitor { // streamp->rhsp()->prettyTypeName() << ")"); // } int srcElementBits = 0; - if (AstNodeDType* const elemDtp = srcDTypep->subDTypep()) { + if (const AstNodeDType* const elemDtp = srcDTypep->subDTypep()) { srcElementBits = elemDtp->width(); } int dstElementBits = 0; - if (AstNodeDType* const elemDtp = dstDTypep->subDTypep()) { + if (const AstNodeDType* const elemDtp = dstDTypep->subDTypep()) { dstElementBits = elemDtp->width(); } streamp->unlinkFrBack(); @@ -3330,9 +3330,7 @@ class ConstVisitor final : public VNVisitor { if (!prevp->fmtp() || prevp->fmtp()->nextp() || !nodep->fmtp() || nodep->fmtp()->nextp()) return false; AstSFormatF* const pformatp = prevp->fmtp(); - if (!pformatp) return false; AstSFormatF* const nformatp = nodep->fmtp(); - if (!nformatp) return false; // We don't merge scopeNames as can have only one and might be different scopes (late in // process) Also rare for real code to print %m multiple times in same message if (nformatp->scopeNamep() && pformatp->scopeNamep()) return false; diff --git a/src/V3Control.cpp b/src/V3Control.cpp index 36402417b..9e745a1fb 100644 --- a/src/V3Control.cpp +++ b/src/V3Control.cpp @@ -441,7 +441,7 @@ using V3ControlFileResolver = V3ControlWildcardResolver; class V3ControlScopeTraceEntry final { public: const string m_scope; // Scope or regexp to match - const bool m_on = false; // True to enable message + const bool m_on; // True to enable message int m_levels = 0; // # levels, 0 = all, 1 = only this, ... // CONSTRUCTORS V3ControlScopeTraceEntry(const string& scope, bool on, int levels) @@ -757,7 +757,8 @@ void V3Control::applyFTask(AstNodeModule* modulep, AstNodeFTask* ftaskp) { if (ftp) ftp->apply(ftaskp); } -void V3Control::applyVarAttr(AstNodeModule* modulep, AstNodeFTask* ftaskp, AstVar* varp) { +void V3Control::applyVarAttr(const AstNodeModule* modulep, const AstNodeFTask* ftaskp, + AstVar* varp) { V3ControlVar* vp; V3ControlModule* const modp = V3ControlResolver::s().modules().resolve(modulep->prettyOrigOrName()); @@ -797,7 +798,7 @@ bool V3Control::containsMTaskProfileData() { return V3ControlResolver::s().containsMTaskProfileData(); } -bool V3Control::waive(FileLine* filelinep, V3ErrorCode code, const string& message) { +bool V3Control::waive(const FileLine* filelinep, V3ErrorCode code, const string& message) { V3ControlFile* const filep = V3ControlResolver::s().files().resolve(filelinep->filename()); if (!filep) return false; return filep->waive(code, message); diff --git a/src/V3Control.h b/src/V3Control.h index ff26e5ab6..3b3142158 100644 --- a/src/V3Control.h +++ b/src/V3Control.h @@ -51,7 +51,8 @@ public: static void applyFTask(AstNodeModule* modulep, AstNodeFTask* ftaskp); static void applyIgnores(FileLine* filelinep); static void applyModule(AstNodeModule* modulep); - static void applyVarAttr(AstNodeModule* modulep, AstNodeFTask* ftaskp, AstVar* varp); + static void applyVarAttr(const AstNodeModule* modulep, const AstNodeFTask* ftaskp, + AstVar* varp); static int getHierWorkers(const string& model); static FileLine* getHierWorkersFileLine(const string& model); @@ -64,7 +65,7 @@ public: static bool containsMTaskProfileData(); - static bool waive(FileLine* filelinep, V3ErrorCode code, const string& message); + static bool waive(const FileLine* filelinep, V3ErrorCode code, const string& message); }; #endif // Guard diff --git a/src/V3Coverage.cpp b/src/V3Coverage.cpp index 2c142ac0a..718a0a0d2 100644 --- a/src/V3Coverage.cpp +++ b/src/V3Coverage.cpp @@ -35,30 +35,30 @@ VL_DEFINE_DEBUG_FUNCTIONS; -class ExprCoverageEligibleVisitor final : public VNVisitor { +class ExprCoverageEligibleVisitor final : public VNVisitorConst { // STATE bool m_eligible = true; static bool elemDTypeEligible(const AstNodeDType* dtypep) { dtypep = dtypep->skipRefp(); - if (AstNodeDType* const dtp = dtypep->virtRefDTypep()) { + if (const AstNodeDType* const dtp = dtypep->virtRefDTypep()) { if (!elemDTypeEligible(dtp)) return false; } - if (AstNodeDType* const dtp = dtypep->virtRefDType2p()) { + if (const AstNodeDType* const dtp = dtypep->virtRefDType2p()) { if (!elemDTypeEligible(dtp)) return false; } return !VN_IS(dtypep, ClassRefDType); } void visit(AstNodeVarRef* nodep) override { - AstNodeDType* dtypep = nodep->varp()->dtypep(); + const AstNodeDType* const dtypep = nodep->varp()->dtypep(); // Class objects and references not supported for expression coverage // because the object may not persist until the point at which // coverage data is gathered // This could be resolved in the future by protecting against dereferrencing // null pointers when cloning the expression for expression coverage if (dtypep && elemDTypeEligible(dtypep)) { - iterateChildren(nodep); + iterateChildrenConst(nodep); } else { m_eligible = false; } @@ -68,13 +68,13 @@ class ExprCoverageEligibleVisitor final : public VNVisitor { if (!nodep->isExprCoverageEligible()) { m_eligible = false; } else { - iterateChildren(nodep); + iterateChildrenConst(nodep); } } public: // CONSTRUCTORS - explicit ExprCoverageEligibleVisitor(AstNode* nodep) { iterateChildren(nodep); } + explicit ExprCoverageEligibleVisitor(AstNode* nodep) { iterateChildrenConst(nodep); } ~ExprCoverageEligibleVisitor() override = default; bool eligible() { return m_eligible; } @@ -162,7 +162,7 @@ class CoverageVisitor final : public VNVisitor { // METHODS - const char* varIgnoreToggle(AstVar* nodep) { + const char* varIgnoreToggle(const AstVar* nodep) { // Return true if this shouldn't be traced // See also similar rule in V3TraceDecl::varIgnoreTrace if (!nodep->isToggleCoverable()) return "Not relevant signal type"; @@ -203,7 +203,7 @@ class CoverageVisitor final : public VNVisitor { } return incp; } - string traceNameForLine(AstNode* nodep, const string& type) { + string traceNameForLine(const AstNode* nodep, const string& type) { string name = "vlCoverageLineTrace_" + nodep->fileline()->filebasenameNoExt() + "__" + cvtToStr(nodep->fileline()->lineno()) + "_" + type; if (const uint32_t suffix = m_varnames[name]++) name += "_" + cvtToStr(suffix); @@ -438,7 +438,7 @@ class CoverageVisitor final : public VNVisitor { if (adtypep->packed()) { for (AstMemberDType* itemp = adtypep->membersp(); itemp; itemp = VN_AS(itemp->nextp(), MemberDType)) { - AstNodeDType* const subtypep = itemp->subDTypep()->skipRefp(); + const AstNodeDType* const subtypep = itemp->subDTypep()->skipRefp(); const int index_code = itemp->lsb(); ToggleEnt newent{ above.m_comment + "."s + itemp->name(), @@ -855,7 +855,7 @@ class CoverageVisitor final : public VNVisitor { // not be flagged as redundant or impossible, however the results will // still be valid, albeit messier for (CoverTerm& term : l) { - if (AstVarRef* const refp = VN_CAST(term.m_exprp, VarRef)) { + if (const AstVarRef* const refp = VN_CAST(term.m_exprp, VarRef)) { varps[term.m_objective].insert(refp->varp()); } else { strs[term.m_objective].insert(term.m_emitV); @@ -865,7 +865,7 @@ class CoverageVisitor final : public VNVisitor { bool impossible = false; for (CoverTerm& term : r) { bool redundant = false; - if (AstNodeVarRef* const refp = VN_CAST(term.m_exprp, NodeVarRef)) { + if (const AstNodeVarRef* const refp = VN_CAST(term.m_exprp, NodeVarRef)) { if (varps[term.m_objective].find(refp->varp()) != varps[term.m_objective].end()) redundant = true; diff --git a/src/V3CoverageJoin.cpp b/src/V3CoverageJoin.cpp index 39d73bd10..9b2c8f25a 100644 --- a/src/V3CoverageJoin.cpp +++ b/src/V3CoverageJoin.cpp @@ -48,7 +48,7 @@ class CoverageJoinVisitor final : public VNVisitor { // Note uses user4 V3DupFinder dupFinder; // Duplicate code detection // Hash all of the original signals we toggle cover - for (AstCoverToggle* nodep : m_toggleps) dupFinder.insert(nodep->origp()); + for (const AstCoverToggle* const nodep : m_toggleps) dupFinder.insert(nodep->origp()); if (dumpLevel() || debug() >= 9) dupFinder.dumpFile(v3Global.debugFilename("coveragejoin") + ".hash", false); // Find if there are any duplicates diff --git a/src/V3Dead.cpp b/src/V3Dead.cpp index 8cbf22db3..b36758ed2 100644 --- a/src/V3Dead.cpp +++ b/src/V3Dead.cpp @@ -334,8 +334,8 @@ class DeadVisitor final : public VNVisitor { checkAll(typedefp); } } - bool shouldDeleteTypedef(AstTypedef* typedefp) { - if (auto* const structp = VN_CAST(typedefp->subDTypep(), NodeUOrStructDType)) { + bool shouldDeleteTypedef(const AstTypedef* typedefp) { + if (const auto* const structp = VN_CAST(typedefp->subDTypep(), NodeUOrStructDType)) { if (structp->user1() && !structp->packed()) return false; } return m_elimCells && !typedefp->attrPublic(); @@ -367,7 +367,7 @@ class DeadVisitor final : public VNVisitor { } } } - bool mightElimVar(AstVar* nodep) const { + bool mightElimVar(const AstVar* nodep) const { if (nodep->isSigPublic()) return false; // Can't elim publics! if (nodep->isIO() || nodep->isClassMember() || nodep->sensIfacep()) return false; if (nodep->isTemp() && !nodep->isTrace()) return true; diff --git a/src/V3Delayed.cpp b/src/V3Delayed.cpp index a11d01410..072e73f29 100644 --- a/src/V3Delayed.cpp +++ b/src/V3Delayed.cpp @@ -540,7 +540,7 @@ class DelayedVisitor final : public VNVisitor { } // Create a unique temporary variable name - std::string uniqueTmpName(AstScope* scopep, AstVarScope* vscp, VarScopeInfo& vscpInfo) { + std::string uniqueTmpName(AstScope* scopep, const AstVarScope* vscp, VarScopeInfo& vscpInfo) { std::stringstream ss; ss << "__" << vscp->varp()->shortName() + "__v"; // If the assignment is in the same scope as the variable, just @@ -900,7 +900,7 @@ class DelayedVisitor final : public VNVisitor { return dtypep; }(); - if (AstSel* const lSelp = VN_CAST(lhsNodep, Sel)) { + if (const AstSel* const lSelp = VN_CAST(lhsNodep, Sel)) { // This is a partial assignment. // Need to create a mask and widen the value to element size. lhsNodep = lSelp->fromp(); @@ -910,7 +910,7 @@ class DelayedVisitor final : public VNVisitor { // Create mask value maskp = [&]() -> AstNodeExpr* { // Constant mask we can compute here - if (AstConst* const cLsbp = VN_CAST(sLsbp, Const)) { + if (const AstConst* const cLsbp = VN_CAST(sLsbp, Const)) { AstConst* const cp = new AstConst{flp, AstConst::DTyped{}, eDTypep}; cp->num().setMask(sWidth, cLsbp->toSInt()); return cp; @@ -927,7 +927,7 @@ class DelayedVisitor final : public VNVisitor { valuep = [&]() -> AstNodeExpr* { // Constant value with constant select we can compute here if (AstConst* const cValuep = VN_CAST(valuep, Const)) { - if (AstConst* const cLsbp = VN_CAST(sLsbp, Const)) { + if (const AstConst* const cLsbp = VN_CAST(sLsbp, Const)) { AstConst* const cp = new AstConst{flp, AstConst::DTyped{}, eDTypep}; cp->num().setAllBits0(); cp->num().opSelInto(cValuep->num(), cLsbp->toSInt(), sWidth); @@ -1097,7 +1097,7 @@ class DelayedVisitor final : public VNVisitor { VL_RESTORER(m_ignoreBlkAndNBlk); VL_RESTORER(m_inNonCombLogic); m_activep = nodep; - AstSenTree* const senTreep = nodep->sentreep(); + const AstSenTree* const senTreep = nodep->sentreep(); m_ignoreBlkAndNBlk = senTreep->hasStatic() || senTreep->hasInitial(); m_inNonCombLogic = senTreep->hasClocked(); iterateChildren(nodep); @@ -1160,7 +1160,7 @@ class DelayedVisitor final : public VNVisitor { AstNode* newp = new AstCStmt{flp, blockp}; if (nodep->isDelayed()) { - AstVarRef* const vrefp = VN_AS(eventp, VarRef); + const AstVarRef* const vrefp = VN_AS(eventp, VarRef); const std::string newvarname = "__Vdly__" + vrefp->varp()->shortName(); AstVarScope* const dlyvscp = createTemp(flp, vrefp->varScopep()->scopep(), newvarname, 1); diff --git a/src/V3Descope.cpp b/src/V3Descope.cpp index 9a9fa9e5b..03ecabf2f 100644 --- a/src/V3Descope.cpp +++ b/src/V3Descope.cpp @@ -55,11 +55,11 @@ class DescopeVisitor final : public VNVisitor { // METHODS - static bool modIsSingleton(AstNodeModule* modp) { + static bool modIsSingleton(const AstNodeModule* modp) { // True iff there's exactly one instance of this module in the design (including top). if (modp->isTop()) return true; int instances = 0; - for (AstNode* stmtp = modp->stmtsp(); stmtp; stmtp = stmtp->nextp()) { + for (const AstNode* stmtp = modp->stmtsp(); stmtp; stmtp = stmtp->nextp()) { if (VN_IS(stmtp, Scope)) { if (++instances > 1) return false; } diff --git a/src/V3Dfg.h b/src/V3Dfg.h index 2936dffa8..46a9b26b5 100644 --- a/src/V3Dfg.h +++ b/src/V3Dfg.h @@ -79,8 +79,8 @@ struct std::hash> final { class VDfgType final { public: #include "V3Dfg__gen_type_enum.h" // From ./astgen - enum en m_e; - VDfgType() = default; + const enum en m_e; + VDfgType() = delete; // cppcheck-suppress noExplicitConstructor constexpr VDfgType(en _e) : m_e{_e} {} diff --git a/src/V3DfgPasses.cpp b/src/V3DfgPasses.cpp index 0ea612634..a2d47394c 100644 --- a/src/V3DfgPasses.cpp +++ b/src/V3DfgPasses.cpp @@ -181,8 +181,8 @@ void V3DfgPasses::binToOneHot(DfgGraph& dfg, V3DfgBinToOneHotContext& ctx) { // Structure to keep track of comparison details struct Term final { - DfgVertex* m_vtxp; // Vertex to replace - bool m_inv; // '!=', instead of '==' + DfgVertex* m_vtxp = nullptr; // Vertex to replace + bool m_inv = false; // '!=', instead of '==' Term() = default; Term(DfgVertex* vtxp, bool inv) : m_vtxp{vtxp} diff --git a/src/V3DfgVertices.h b/src/V3DfgVertices.h index f3ef92c65..1bc756bf0 100644 --- a/src/V3DfgVertices.h +++ b/src/V3DfgVertices.h @@ -234,7 +234,9 @@ public: uint32_t toU32() const { return static_cast(num().toUInt()); } + // cppcheck-suppress duplInheritedMember bool isZero() const { return num().isEqZero(); } + // cppcheck-suppress duplInheritedMember bool isOnes() const { return num().isEqAllOnes(width()); } // Does this DfgConst have the given value? Note this is not easy to answer if wider than 32. diff --git a/src/V3DiagSarif.cpp b/src/V3DiagSarif.cpp index e8008725d..1a3881c99 100644 --- a/src/V3DiagSarif.cpp +++ b/src/V3DiagSarif.cpp @@ -33,14 +33,14 @@ class V3DiagSarifImp final { // METHODS void calculate() { - for (auto& msgr : m_messages) + for (const VErrorMessage& msgr : m_messages) if (msgr.code().isNamed()) m_codes.emplace(msgr.code()); int i = 0; - for (const auto& code : m_codes) m_codeIndex[code] = i++; + for (const V3ErrorCode& code : m_codes) m_codeIndex[code] = i++; } void putRules(V3OutJsonFile& of) const { - for (const auto& code : m_codes) { + for (const V3ErrorCode& code : m_codes) { of.begin().put("id", code.ascii()).put("helpUri", code.url()).end(); } } @@ -97,7 +97,7 @@ class V3DiagSarifImp final { of.begin("message"); putText(of, first_clean, first_fmt); of.end(); - if (auto fl = msg.fileline()) { + if (const FileLine* const fl = msg.fileline()) { of.begin("locations", '[').begin(); putLocation(of, fl); of.end(); @@ -175,7 +175,7 @@ public: .end(); of.begin("results", '['); - for (auto& msgr : m_messages) putResult(of, msgr); + for (const VErrorMessage& msgr : m_messages) putResult(of, msgr); of.end(); of.end(); // runs ] diff --git a/src/V3EmitCBase.h b/src/V3EmitCBase.h index c6dce2755..82fef00fa 100644 --- a/src/V3EmitCBase.h +++ b/src/V3EmitCBase.h @@ -148,8 +148,8 @@ public: void emitVarAccessors(const AstVar* nodep); template static void forModCUse(const AstNodeModule* modp, VUseType useType, T_Callable action) { - for (AstNode* itemp = modp->stmtsp(); itemp; itemp = itemp->nextp()) { - if (AstCUse* const usep = VN_CAST(itemp, CUse)) { + for (const AstNode* itemp = modp->stmtsp(); itemp; itemp = itemp->nextp()) { + if (const AstCUse* const usep = VN_CAST(itemp, CUse)) { if (usep->useType().containsAny(useType)) { if (usep->useType().containsAny(VUseType::INT_INCLUDE)) { action("#include \"" + prefixNameProtect(usep) + ".h\"\n"); diff --git a/src/V3EmitCConstInit.h b/src/V3EmitCConstInit.h index c80154ddb..051b75fb4 100644 --- a/src/V3EmitCConstInit.h +++ b/src/V3EmitCConstInit.h @@ -33,7 +33,7 @@ class EmitCConstInit VL_NOT_FINAL : public EmitCBaseVisitorConst { // METHODS - uint32_t tabModulus(AstNodeDType* dtypep) { + uint32_t tabModulus(const AstNodeDType* dtypep) { const uint32_t elemBytes = dtypep->widthTotalBytes(); return dtypep->isString() ? 1 // String : elemBytes <= 2 ? 8 // CData, SData diff --git a/src/V3EmitCConstPool.cpp b/src/V3EmitCConstPool.cpp index e43d511ef..3f9565d0a 100644 --- a/src/V3EmitCConstPool.cpp +++ b/src/V3EmitCConstPool.cpp @@ -110,7 +110,7 @@ class EmitCConstPool final : public EmitCConstInit { } public: - explicit EmitCConstPool(AstConstPool* poolp) { + explicit EmitCConstPool(const AstConstPool* poolp) { emitVars(poolp); V3Stats::addStatSum("ConstPool, Tables emitted", m_tablesEmitted); V3Stats::addStatSum("ConstPool, Constants emitted", m_constsEmitted); diff --git a/src/V3EmitCFunc.h b/src/V3EmitCFunc.h index 2c1c92d1c..c367bee6a 100644 --- a/src/V3EmitCFunc.h +++ b/src/V3EmitCFunc.h @@ -175,7 +175,7 @@ public: // ACCESSORS void splitSizeInc(int count) { m_splitSize += count; } - void splitSizeInc(AstNode* nodep) { splitSizeInc(nodep->nodeCount()); } + void splitSizeInc(const AstNode* nodep) { splitSizeInc(nodep->nodeCount()); } void splitSizeReset() { m_splitSize = 0; } bool splitNeeded() const { return v3Global.opt.outputSplit() && m_splitSize >= v3Global.opt.outputSplit(); @@ -189,13 +189,13 @@ public: char fmtLetter); bool emitSimpleOk(AstNodeExpr* nodep); - void emitIQW(AstNode* nodep) { + void emitIQW(const AstNode* nodep) { // See "Type letters" in verilated.h // Other abbrevs: "C"har, "S"hort, "F"loat, "D"ouble, stri"N"g, "R"=queue, "U"npacked puts(nodep->dtypep()->skipRefp()->charIQWN()); } - void emitRU(AstNode* nodep) { - AstNodeDType* dtp = nodep->dtypep()->skipRefp(); + void emitRU(const AstNode* nodep) { + const AstNodeDType* dtp = nodep->dtypep()->skipRefp(); // See "Type letters" in verilated.h if (VN_IS(dtp, UnpackArrayDType)) puts("U"); @@ -210,7 +210,7 @@ public: : nodep->isDouble() ? "SD" : (nodep->isScQuad() ? "SQ" : "SI")); } - void emitDatap(AstNode* nodep) { + void emitDatap(const AstNode* nodep) { // When passing to a function with va_args the compiler doesn't // know need a pointer so when wide, need to look inside VlWide if (nodep->isWide()) puts(".data()"); @@ -319,7 +319,7 @@ public: // VISITORS using EmitCConstInit::visit; - void visit(AstCFunc* nodep) override { + void visit(AstCFunc* const nodep) override { if (nodep->emptyBody() && !nodep->isLoose()) return; VL_RESTORER(m_useSelfForThis); VL_RESTORER(m_cfuncp); @@ -339,7 +339,7 @@ public: if (nodep->isConstructor()) { const AstClass* const classp = VN_CAST(nodep->scopep()->modp(), Class); - if (nodep->isConstructor() && classp && classp->extendsp()) { + if (classp && classp->extendsp()) { puts("\n : "); putConstructorSubinit(classp, nodep); } diff --git a/src/V3EmitCHeaders.cpp b/src/V3EmitCHeaders.cpp index ce420095f..c7a5824f1 100644 --- a/src/V3EmitCHeaders.cpp +++ b/src/V3EmitCHeaders.cpp @@ -259,7 +259,7 @@ class EmitCHeader final : public EmitCConstInit { case AttributeType::Width: { if (isArrayType) { // For arrays, get innermost element width - AstNodeDType* dtype = itemp->dtypep(); + const AstNodeDType* dtype = itemp->dtypep(); while (dtype->subDTypep()) dtype = dtype->subDTypep(); return dtype->width(); } @@ -461,7 +461,7 @@ class EmitCHeader final : public EmitCConstInit { AstMemberDType* itemp; AstMemberDType* lastItemp; - AstMemberDType* witemp = nullptr; + const AstMemberDType* witemp = nullptr; // LSB is first field in C, so loop backwards for (lastItemp = sdtypep->membersp(); lastItemp && lastItemp->nextp(); lastItemp = VN_AS(lastItemp->nextp(), MemberDType)) { diff --git a/src/V3EmitCImp.cpp b/src/V3EmitCImp.cpp index e2b9e0196..e1945a393 100644 --- a/src/V3EmitCImp.cpp +++ b/src/V3EmitCImp.cpp @@ -724,28 +724,28 @@ class EmitCTrace final : EmitCFunc { && m_typeSplitSize >= v3Global.opt.outputSplitCTrace(); } - bool emitTraceIsScBv(AstTraceInc* nodep) { + bool emitTraceIsScBv(const AstTraceInc* nodep) { const AstVarRef* const varrefp = VN_CAST(nodep->declp()->valuep(), VarRef); if (!varrefp) return false; - AstVar* const varp = varrefp->varp(); + const AstVar* const varp = varrefp->varp(); return varp->isSc() && varp->isScBv(); } - bool emitTraceIsScBigUint(AstTraceInc* nodep) { + bool emitTraceIsScBigUint(const AstTraceInc* nodep) { const AstVarRef* const varrefp = VN_CAST(nodep->declp()->valuep(), VarRef); if (!varrefp) return false; - AstVar* const varp = varrefp->varp(); + const AstVar* const varp = varrefp->varp(); return varp->isSc() && varp->isScBigUint(); } - bool emitTraceIsScUint(AstTraceInc* nodep) { + bool emitTraceIsScUint(const AstTraceInc* nodep) { const AstVarRef* const varrefp = VN_CAST(nodep->declp()->valuep(), VarRef); if (!varrefp) return false; - AstVar* const varp = varrefp->varp(); + const AstVar* const varp = varrefp->varp(); return varp->isSc() && (varp->isScUint() || varp->isScUintBool()); } - void emitTraceInitOne(AstTraceDecl* nodep, int enumNum) { + void emitTraceInitOne(const AstTraceDecl* nodep, int enumNum) { if (nodep->dtypep()->basicp()->isDouble()) { puts("tracep->declDouble("); } else if (nodep->isWide()) { @@ -906,7 +906,7 @@ class EmitCTrace final : EmitCFunc { void emitTraceValue(AstTraceInc* nodep, int arrayindex) { if (AstVarRef* const varrefp = VN_CAST(nodep->valuep(), VarRef)) { - AstVar* const varp = varrefp->varp(); + const AstVar* const varp = varrefp->varp(); if (varp->isEvent()) puts("&"); puts("("); if (emitTraceIsScBigUint(nodep)) { diff --git a/src/V3EmitCMake.cpp b/src/V3EmitCMake.cpp index 0949ce3fa..02926abfc 100644 --- a/src/V3EmitCMake.cpp +++ b/src/V3EmitCMake.cpp @@ -39,7 +39,7 @@ class CMakeEmitter final { template static string cmake_list(const T_List& strs) { string s; - for (auto& itr : strs) { + for (const std::string& itr : strs) { if (!s.empty()) s += ' '; s += '"'; s += V3OutFormatter::quoteNameControls(itr); @@ -49,7 +49,7 @@ class CMakeEmitter final { } static string cmake_list(const VFileLibList& strs) { string s; - for (auto& itr : strs) { + for (const VFileLibName& itr : strs) { if (!s.empty()) s += ' '; s += '"'; s += V3OutFormatter::quoteNameControls(itr.filename()); @@ -191,14 +191,16 @@ class CMakeEmitter final { *of << "target_link_libraries(${TOP_TARGET_NAME} PRIVATE " << prefix << ")\n"; if (!children.empty()) { *of << "target_link_libraries(" << prefix << " INTERFACE"; - for (const auto& childr : children) *of << " " << (childr)->hierPrefix(); + for (const V3HierBlock* const childp : children) { + *of << " " << childp->hierPrefix(); + } *of << ")\n"; } *of << "verilate(" << prefix << " PREFIX " << prefix << " TOP_MODULE " << hblockp->modp()->name() << " DIRECTORY " << v3Global.opt.makeDir() + "/" + prefix << " SOURCES "; - for (const auto& childr : children) { - *of << " " << v3Global.opt.makeDir() + "/" + childr->hierWrapperFilename(true); + for (const V3HierBlock* const childp : children) { + *of << " " << v3Global.opt.makeDir() + "/" + childp->hierWrapperFilename(true); } *of << " "; const string vFile = hblockp->vFileIfNecessary(); diff --git a/src/V3Simulate.h b/src/V3Simulate.h index dc09fef88..3364308d4 100644 --- a/src/V3Simulate.h +++ b/src/V3Simulate.h @@ -152,11 +152,11 @@ private: VL_DEFINE_DEBUG_FUNCTIONS; // Potentially very slow, intended for debugging - string prettyNumber(const V3Number* nump, AstNodeDType* dtypep) { - if (AstRefDType* const refdtypep = VN_CAST(dtypep, RefDType)) { // + string prettyNumber(const V3Number* nump, const AstNodeDType* dtypep) { + if (const AstRefDType* const refdtypep = VN_CAST(dtypep, RefDType)) { // dtypep = refdtypep->skipRefp(); } - if (AstNodeUOrStructDType* const stp = VN_CAST(dtypep, NodeUOrStructDType)) { + if (const AstNodeUOrStructDType* const stp = VN_CAST(dtypep, NodeUOrStructDType)) { if (stp->packed()) { std::ostringstream out; out << "'{"; @@ -218,13 +218,13 @@ public: m_whyNotOptimizable = why; std::ostringstream stack; for (const auto& callstack : vlstd::reverse_view(m_callStack)) { - AstFuncRef* const funcp = callstack->m_funcp; + const AstFuncRef* const funcp = callstack->m_funcp; stack << "\n " << funcp->fileline() << "... Called from '" << funcp->prettyName() << "()' with parameters:"; V3TaskConnects* tconnects = callstack->m_tconnects; for (V3TaskConnects::iterator conIt = tconnects->begin(); conIt != tconnects->end(); ++conIt) { - AstVar* const portp = conIt->first; + const AstVar* const portp = conIt->first; AstNodeExpr* const pinp = conIt->second->exprp(); AstNodeDType* const dtypep = pinp->dtypep(); if (AstConst* const valp = fetchConstNull(pinp)) { @@ -400,7 +400,7 @@ private: // True if current node might be jumped over - all visitors must call this up front bool jumpingOver() const { return m_jumpp; } - void assignOutValue(AstNodeAssign* nodep, AstNode* vscp, const AstNodeExpr* valuep) { + void assignOutValue(const AstNodeAssign* nodep, AstNode* vscp, const AstNodeExpr* valuep) { if (VN_IS(nodep, AssignDly)) { // Don't do setValue, as value isn't yet visible to following statements newOutValue(vscp, valuep); @@ -458,7 +458,7 @@ private: m_varAux(vscp).usage |= VU_RV; const bool varIsConst = (nodep->varp()->isConst() || nodep->varp()->isParam()) && nodep->varp()->valuep(); - AstNodeExpr* const valuep + const AstNodeExpr* const valuep = varIsConst ? fetchValueNull(nodep->varp()->valuep()) : nullptr; // Propagate PARAM constants for constant function analysis if (varIsConst && valuep) { @@ -800,9 +800,7 @@ private: handleAssignArray(nodep, selp, valueFromp); } else if (AstConcat* const selp = VN_CAST(lhsp, Concat)) { checkNodeInfo(selp); - AstBasicDType* const rhsBasicp - = VN_CAST(selp->rhsp()->dtypep()->skipRefp(), BasicDType); - if (!rhsBasicp) { + if (!VN_IS(selp->rhsp()->dtypep()->skipRefp(), BasicDType)) { clearOptimizable(lhsp, "Assign LHS concat of non-basic type"); return; } @@ -879,7 +877,7 @@ private: checkNodeInfo(nodep); iterateChildrenConst(nodep); if (AstInitArray* const initp = VN_CAST(fetchValueNull(nodep->fromp()), InitArray)) { - AstConst* const indexp = fetchConst(nodep->bitp()); + const AstConst* const indexp = fetchConst(nodep->bitp()); const uint32_t offset = indexp->num().toUInt(); AstNodeExpr* const itemp = initp->getIndexDefaultedValuep(offset); if (!itemp) { @@ -904,7 +902,7 @@ private: iterateChildrenConst(nodep); if (m_checkOnly || !optimizable()) return; // Fetch the base constant array - if (AstInitArray* const initp = VN_CAST(fetchValueNull(nodep->fromp()), InitArray)) { + if (const AstInitArray* const initp = VN_CAST(fetchValueNull(nodep->fromp()), InitArray)) { const VNumRange& sliceRange = nodep->declRange(); const uint32_t sliceElements = sliceRange.elements(); const int sliceLo = sliceRange.lo(); @@ -962,7 +960,7 @@ private: for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp = VN_AS(itemp->nextp(), CaseItem)) { if (hit) break; - if (!hit && itemp->isDefault()) { + if (itemp->isDefault()) { iterateAndNextConstNull(itemp->stmtsp()); hit = true; } @@ -1250,7 +1248,7 @@ private: checkNodeInfo(nodep, /*display:*/ true); iterateChildrenConst(nodep); if (m_params) { - AstConst* const textp = fetchConst(nodep->fmtp()); + const AstConst* const textp = fetchConst(nodep->fmtp()); switch (nodep->displayType()) { case VDisplayType::DT_DISPLAY: // FALLTHRU case VDisplayType::DT_INFO: v3warn(USERINFO, textp->name()); break; diff --git a/src/astgen b/src/astgen index f59e84865..d36d6fd59 100755 --- a/src/astgen +++ b/src/astgen @@ -938,10 +938,11 @@ def write_ast_impl(filename): emitBlock(" BROKEN_RTN(!m_{name});\n" + " BROKEN_RTN(!m_{name}->brokeExists());\n", name=ptr['name']) - if ptr['legals'] != '': + legals = ptr['legals'].split('|') + if legals and legals != ["Node"]: emitBlock(" BROKEN_RTN(m_{name} && !(", name=ptr['name']) eor = "" - for legal in ptr['legals'].split('|'): + for legal in legals: # We use privateTypeTest, as VN_IS would assert that we know # the type is correct, but we want to check regardless, # to find errors after raw node edits/replacements @@ -956,10 +957,11 @@ def write_ast_impl(filename): if op is None: continue name, _, _, legals = op - if legals != '': + legals = legals.split('|') + if legals and legals != ["Node"]: emitBlock(" BROKEN_RTN({name}() && !(", name=name) eor = "" - for legal in legals.split('|'): + for legal in legals: emitBlock("{eor}privateTypeTest({name}())", eor=eor, name=name, @@ -978,12 +980,13 @@ def write_ast_impl(filename): if op is None: continue name, _, _, legals = op - if legals != '': + legals = legals.split('|') + if legals and legals != ["Node"]: # 'this' is a parent, where oldp replacing newp as op1p, must follow op1p's rules # Could also be on a list, we don't check for speed reasons and as V3Broken doesn't emitBlock(" if (oldp == op{i}p() && !(", i=i) eor = "" - for legal in legals.split('|'): + for legal in legals: emitBlock("{eor}privateTypeTest(newp)", eor=eor, name=name, @@ -994,16 +997,17 @@ def write_ast_impl(filename): emitBlock(" return false;\n") emitBlock("}}\n") - emitBlock("void Ast{t}::cloneRelinkGen() {{\n", t=node.name) - if node.superClass.name != 'Node': - emitBlock(" Ast{base}::cloneRelinkGen();\n", base=node.superClass.name) - for ptr in node.ptrs: - emitBlock( - " if (m_{name} && m_{name}->clonep()) m_{name} = m_{name}->clonep();\n", - name=ptr['name'], - kind=ptr['kind']) + if node.ptrs: + emitBlock("void Ast{t}::cloneRelinkGen() {{\n", t=node.name) + if node.superClass.name != 'Node': + emitBlock(" Ast{base}::cloneRelinkGen();\n", base=node.superClass.name) + for ptr in node.ptrs: + emitBlock( + " if (m_{name} && m_{name}->clonep()) m_{name} = m_{name}->clonep();\n", + name=ptr['name'], + kind=ptr['kind']) - emitBlock("}}\n") + emitBlock("}}\n") emitBlock("void Ast{t}::dumpJsonGen(std::ostream& str) const {{\n", t=node.name) if node.superClass.name != 'Node': @@ -1067,11 +1071,14 @@ def write_ast_macros(filename): Ast{t}* addNext(Ast{t}* nodep) {{ return static_cast(AstNode::addNext(this, nodep)); }} const char* brokenGen() const override; bool wouldBreakGen(const AstNode* const oldp, const AstNode* const newp) const override; - void cloneRelinkGen() override; void dumpTreeJsonOpGen(std::ostream& str, const string& indent) const override; void dumpJsonGen(std::ostream& str) const; ''', t=node.name) + if node.ptrs: + emitBlock('''\ + void cloneRelinkGen() override; + ''') if node.isLeaf: emitBlock('''\ diff --git a/src/cppcheck-suppressions.txt b/src/cppcheck-suppressions.txt new file mode 100644 index 000000000..e1fad255b --- /dev/null +++ b/src/cppcheck-suppressions.txt @@ -0,0 +1,33 @@ +// Copyright 2003-2025 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. +// SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 + +cstyleCast +ctunullpointer +derefInvalidIteratorRedundantCheck +nullPointer +nullPointerRedundantCheck +templateRecursion +unusedFunction +unusedScopedObject +useInitializationList +useStlAlgorithm + +// Seems useless +missingIncludeSystem +// Tedious +unmatchedSuppression +// Not our code +*:include/gtkwave/* +*:include/vltstd/* +// We intentionally redefine AstNode methods to improve type safety +duplInheritedMember:src/V3AstNode*.h +duplInheritedMember:src/obj_*/V3Ast__gen_impl.h +// We intentionally redefine DfgVertex methods to match Ast +duplInheritedMember:src/obj_*/V3Dfg__gen_auto_classes.h +// TODO: fix - maybe? +duplInheritedMember:src/V3File*.h +// They are used after astgen expansion +unusedPrivateFunction:src/V3Const.cpp diff --git a/src/cppcheck_filtered b/src/cppcheck_filtered deleted file mode 100755 index ccf633938..000000000 --- a/src/cppcheck_filtered +++ /dev/null @@ -1,196 +0,0 @@ -#!/usr/bin/env python3 -# pylint: disable=C0103,C0114,C0115,C0116,C0209,R0911,R0912,R0915,W0621 -###################################################################### - -import argparse -import os -import re -import sys - -SuppressMap = { - # New cpp check error Can suppress with old error - 'nullPointerRedundantCheck': 'nullPointer' -} - -###################################################################### - - -def process(cppcheck_args): - cmd = " ".join(cppcheck_args) + " 2>&1" - if Args.debug: - print("\t" + cmd) - fh = os.popen(cmd) - errs = False - last_error = "" - for line in fh: - line = line.rstrip() - if Args.debug: - print(">>>" + line) - line = re.sub(r'^\s+', '', line) - # Sometimes tacked at end-of-line - line = re.sub(r'Checking usage of global functions\.+', '', line) - line = re.sub(r' file0="[^"]+"', r'', line) - - if re.search(r'^<\?xml version', line): - continue - if re.search(r'^', line): - continue - if re.search(r'^', line): - continue - if re.search(r'^', line): - continue - if re.search(r'^', line): - continue - # An earlier id line is more specific - if re.search(r'Cppcheck cannot find all the include files', line): - continue - if re.search(r'^Checking ', line): - continue - if re.search(r'^make.*Entering directory ', line): - continue - if re.search(r'^make.*Leaving directory ', line): - continue - if re.search(r'^\s+$', line): - continue - - # Output - if re.search(r'^cppcheck --', line): - if Args.debug: - print(line) - continue - if re.search(r'^\d+/\d+ files checked', line): - print(line) - continue - - suppress = False - # --xml-format=2 - if re.search(r'