diff --git a/src/V3Active.cpp b/src/V3Active.cpp index 3497ede5e..513a05234 100644 --- a/src/V3Active.cpp +++ b/src/V3Active.cpp @@ -97,6 +97,7 @@ protected: result = vertexp->user(); break; case LatchDetectGraphVertex::VT_BLOCK: // (OR of potentially many siblings) + // cppcheck-suppress constVariableReference for (V3GraphEdge& edge : vertexp->outEdges()) { if (latchCheckInternal(castVertexp(edge.top()))) { result = true; @@ -128,6 +129,7 @@ public: } // Clear out userp field of referenced outputs on destruction // (occurs at the end of each combinational always block) + // cppcheck-suppress duplInheritedMember void clear() { m_outputs.clear(); // Calling base class clear will unlink & delete all edges & vertices diff --git a/src/V3AssertPre.cpp b/src/V3AssertPre.cpp index bcaf91c1e..7b6a21bc0 100644 --- a/src/V3AssertPre.cpp +++ b/src/V3AssertPre.cpp @@ -114,6 +114,7 @@ private: const V3TaskConnects tconnects = V3Task::taskConnects(funcrefp, propp->stmtsp()); for (const auto& tconnect : tconnects) { const AstVar* const portp = tconnect.first; + // cppcheck-suppress constVariablePointer // 'exprp' unlinked below AstArg* const argp = tconnect.second; AstNode* const pinp = argp->exprp()->unlinkFrBack(); replaceVarRefsWithExprRecurse(propExprp, portp, pinp); diff --git a/src/V3AstNodes.cpp b/src/V3AstNodes.cpp index 2cea4e39b..014b1f155 100644 --- a/src/V3AstNodes.cpp +++ b/src/V3AstNodes.cpp @@ -87,6 +87,7 @@ bool AstNodeFTaskRef::isPure() { } bool AstNodeFTaskRef::getPurityRecurse() const { + // cppcheck-suppress shadowFunction AstNodeFTask* const taskp = this->taskp(); // Unlinked yet, so treat as impure if (!taskp) return false; @@ -1098,6 +1099,7 @@ std::pair AstNodeDType::dimensions(bool includeBasic) const int AstNodeDType::widthPow2() const { // I.e. width 30 returns 32, width 32 returns 32. + // cppcheck-suppress shadowFunction const uint32_t width = this->width(); for (int p2 = 30; p2 >= 0; p2--) { if (width > (1UL << p2)) return (1UL << (p2 + 1)); @@ -1374,6 +1376,7 @@ AstBasicDType* AstTypeTable::findLogicBitDType(FileLine* fl, VBasicDTypeKwd kwd, return newp; } +// cppcheck-suppress duplInheritedMember AstBasicDType* AstTypeTable::findInsertSameDType(AstBasicDType* nodep) { const VBasicTypeKey key{nodep->width(), nodep->widthMin(), nodep->numeric(), nodep->keyword(), nodep->nrange()}; @@ -1462,7 +1465,7 @@ AstVarScope* AstConstPool::findTable(AstInitArray* initp) { UASSERT_OBJ(VN_IS(valuep, Const), valuep, "Const pool table entry must be Const"); } // Try to find an existing table with the same content - // cppcheck-has-bug-suppress unreadVariable + // cppcheck-suppress unreadVariable const V3Hash hash = V3Hasher::uncachedHash(initp); const auto& er = m_tables.equal_range(hash.value()); for (auto it = er.first; it != er.second; ++it) { @@ -1492,7 +1495,7 @@ static bool sameInit(const AstConst* ap, const AstConst* bp) { AstVarScope* AstConstPool::findConst(AstConst* initp, bool mergeDType) { // Try to find an existing constant with the same value - // cppcheck-has-bug-suppress unreadVariable + // cppcheck-suppress unreadVariable const V3Hash hash = initp->num().toHash(); const auto& er = m_consts.equal_range(hash.value()); for (auto it = er.first; it != er.second; ++it) { diff --git a/src/V3Cast.cpp b/src/V3Cast.cpp index 4839b8d04..c18d17fc0 100644 --- a/src/V3Cast.cpp +++ b/src/V3Cast.cpp @@ -85,6 +85,7 @@ class CastVisitor final : public VNVisitor { if (!nodep->isNull()) insertCast(nodep, castSize(nodep->backp())); } } + // cppcheck-suppress constParameterPointer // lhsp might be changed void ensureLower32Cast(AstCCast* nodep) { // If we have uint64 = CAST(uint64(x)) then the upcasting // really needs to be CAST(uint64(CAST(uint32(x))). diff --git a/src/V3Combine.cpp b/src/V3Combine.cpp index 6fea6c4c9..8c7bce596 100644 --- a/src/V3Combine.cpp +++ b/src/V3Combine.cpp @@ -150,6 +150,7 @@ class CombineVisitor final : VNVisitor { return replaced; } + // cppcheck-suppress constParameterPointer void process(AstNetlist* netlistp) { // First, remove empty functions. We need to do this separately, because removing // calls can change the hashes of the callers. diff --git a/src/V3Const.cpp b/src/V3Const.cpp index b2afb50c5..8c851fae5 100644 --- a/src/V3Const.cpp +++ b/src/V3Const.cpp @@ -1058,7 +1058,7 @@ class ConstVisitor final : public VNVisitor { // Someday we'll sort the biops completely and this can be simplified // This often results from our simplified clock generation: // if (rst) ... else if (enable)... -> OR(rst,AND(!rst,enable)) - AstNodeExpr* ap; + const AstNodeExpr* ap; AstNodeBiop* andp; if (VN_IS(nodep->lhsp(), And)) { andp = VN_AS(nodep->lhsp(), And); @@ -1080,7 +1080,7 @@ class ConstVisitor final : public VNVisitor { } else { return false; } - AstNodeExpr* const bp = notp->lhsp(); + const AstNodeExpr* const bp = notp->lhsp(); if (!operandsSame(ap, bp)) return false; // Do it cp->unlinkFrBack(); @@ -1099,6 +1099,7 @@ class ConstVisitor final : public VNVisitor { // (otherwise we'd be trading one operation for two operations) // V3Clean often makes this pattern, as it postpones the AND until // as high as possible, which is usually the right choice, except for this. + // cppcheck-suppress constVariablePointer // children unlinked below AstCond* const condp = VN_CAST(nodep->rhsp(), Cond); if (!condp) return false; if (!VN_IS(condp->thenp(), Const) && !VN_IS(condp->elsep(), Const)) return false; @@ -1322,6 +1323,7 @@ class ConstVisitor final : public VNVisitor { // A pattern created by []'s after offsets have been removed // SEL(EXTEND(any,width,...),(width-1),0) -> ... // Since select's return unsigned, this is always an extend + // cppcheck-suppress constVariablePointer // children unlinked below AstExtend* const extendp = VN_CAST(nodep->fromp(), Extend); if (!(m_doV && extendp && VN_IS(nodep->lsbp(), Const) && nodep->lsbConst() == 0 && static_cast(nodep->widthConst()) == extendp->lhsp()->width())) @@ -1347,7 +1349,7 @@ class ConstVisitor final : public VNVisitor { // AND({a}, SHIFTR({b}, {c})) is often shorthand in C for Verilog {b}[{c} :+ {a}] // becomes thought other optimizations // SEL(SHIFTR({a},{b}),{lsb},{width}) -> SEL({a},{lsb+b},{width}) - AstShiftR* const shiftp = VN_CAST(nodep->fromp(), ShiftR); + const AstShiftR* const shiftp = VN_CAST(nodep->fromp(), ShiftR); if (!(m_doV && shiftp && VN_IS(shiftp->rhsp(), Const) && VN_IS(nodep->lsbp(), Const))) { return false; } @@ -2005,21 +2007,22 @@ class ConstVisitor final : public VNVisitor { // Skip if we're not const'ing an entire module (IE doing only one assign, etc) if (!m_modp) return false; + // cppcheck-suppress constVariablePointer // children unlinked below AstSel* const sel1p = VN_CAST(nodep->lhsp(), Sel); if (!sel1p) return false; AstNodeAssign* const nextp = VN_CAST(nodep->nextp(), NodeAssign); if (!nextp) return false; if (nodep->type() != nextp->type()) return false; - AstSel* const sel2p = VN_CAST(nextp->lhsp(), Sel); + const AstSel* const sel2p = VN_CAST(nextp->lhsp(), Sel); if (!sel2p) return false; AstVarRef* const varref1p = VN_CAST(sel1p->fromp(), VarRef); if (!varref1p) return false; - AstVarRef* const varref2p = VN_CAST(sel2p->fromp(), VarRef); + const AstVarRef* const varref2p = VN_CAST(sel2p->fromp(), VarRef); if (!varref2p) return false; if (!varref1p->sameGateTree(varref2p)) return false; - AstConst* const con1p = VN_CAST(sel1p->lsbp(), Const); + const AstConst* const con1p = VN_CAST(sel1p->lsbp(), Const); if (!con1p) return false; - AstConst* const con2p = VN_CAST(sel2p->lsbp(), Const); + const AstConst* const con2p = VN_CAST(sel2p->lsbp(), Const); if (!con2p) return false; // We need to make sure there's no self-references involved in either // assignment. For speed, we only look 3 deep, then give up. @@ -2600,6 +2603,7 @@ class ConstVisitor final : public VNVisitor { void replaceSelSel(AstSel* nodep) { // SEL(SEL({x},a,b),c,d) => SEL({x},a+c,d) + // cppcheck-suppress constVariablePointer // children unlinked below AstSel* const belowp = VN_AS(nodep->fromp(), Sel); AstNodeExpr* const fromp = belowp->fromp()->unlinkFrBack(); AstNodeExpr* const lsb1p = nodep->lsbp()->unlinkFrBack(); @@ -2667,9 +2671,10 @@ class ConstVisitor final : public VNVisitor { bool operandSelReplicate(AstSel* nodep) { // SEL(REPLICATE(from,rep),lsb,width) => SEL(from,0,width) as long // as SEL's width <= b's width + // cppcheck-suppress constVariablePointer // children unlinked below AstReplicate* const repp = VN_AS(nodep->fromp(), Replicate); AstNodeExpr* const fromp = repp->srcp(); - AstConst* const lsbp = VN_CAST(nodep->lsbp(), Const); + const AstConst* const lsbp = VN_CAST(nodep->lsbp(), Const); if (!lsbp) return false; UASSERT_OBJ(fromp->width(), nodep, "Not widthed"); if ((lsbp->toUInt() / fromp->width()) @@ -2687,6 +2692,7 @@ class ConstVisitor final : public VNVisitor { } bool operandRepRep(AstReplicate* nodep) { // REPLICATE(REPLICATE2(from2,cnt2),cnt1) => REPLICATE(from2,(cnt1+cnt2)) + // cppcheck-suppress constVariablePointer // children unlinked below AstReplicate* const rep2p = VN_AS(nodep->srcp(), Replicate); AstNodeExpr* const from2p = rep2p->srcp(); AstConst* const cnt1p = VN_CAST(nodep->countp(), Const); @@ -2713,13 +2719,13 @@ class ConstVisitor final : public VNVisitor { AstNodeExpr* from2p = nodep->rhsp(); uint32_t cnt2 = 1; if (VN_IS(from1p, Replicate)) { - AstConst* const cnt1p = VN_CAST(VN_CAST(from1p, Replicate)->countp(), Const); + const AstConst* const cnt1p = VN_CAST(VN_CAST(from1p, Replicate)->countp(), Const); if (!cnt1p) return false; from1p = VN_AS(from1p, Replicate)->srcp(); cnt1 = cnt1p->toUInt(); } if (VN_IS(from2p, Replicate)) { - AstConst* const cnt2p = VN_CAST(VN_CAST(from2p, Replicate)->countp(), Const); + const AstConst* const cnt2p = VN_CAST(VN_CAST(from2p, Replicate)->countp(), Const); if (!cnt2p) return false; from2p = VN_AS(from2p, Replicate)->srcp(); cnt2 = cnt2p->toUInt(); @@ -2826,9 +2832,9 @@ class ConstVisitor final : public VNVisitor { VL_DO_DANGLING(replaceNum(nodep, num), nodep); did = true; } else if (m_selp && VN_IS(valuep, InitArray)) { - AstInitArray* const initarp = VN_AS(valuep, InitArray); + const AstInitArray* const initarp = VN_AS(valuep, InitArray); const uint32_t bit = m_selp->bitConst(); - AstNode* const itemp = initarp->getIndexDefaultedValuep(bit); + const AstNode* const itemp = initarp->getIndexDefaultedValuep(bit); if (VN_IS(itemp, Const)) { const V3Number& num = VN_AS(itemp, Const)->num(); // UINFO(2, "constVisit " << cvtToHex(valuep) << " " << num); @@ -3060,8 +3066,8 @@ class ConstVisitor final : public VNVisitor { if (!nextp) break; AstSenItem* const lItemp = senp; AstSenItem* const rItemp = nextp; - AstNodeExpr* const lSenp = lItemp->sensp(); - AstNodeExpr* const rSenp = rItemp->sensp(); + const AstNodeExpr* const lSenp = lItemp->sensp(); + const AstNodeExpr* const rSenp = rItemp->sensp(); if (!lSenp || !rSenp) continue; if (lSenp->sameGateTree(rSenp)) { @@ -3085,8 +3091,8 @@ class ConstVisitor final : public VNVisitor { // Not identical terms, check if they can be combined if (lSenp->width() != rSenp->width()) continue; - if (AstAnd* const lAndp = VN_CAST(lSenp, And)) { - if (AstAnd* const rAndp = VN_CAST(rSenp, And)) { + if (const AstAnd* const lAndp = VN_CAST(lSenp, And)) { + if (const AstAnd* const rAndp = VN_CAST(rSenp, And)) { if (AstConst* const lConstp = VN_CAST(lAndp->lhsp(), Const)) { if (AstConst* const rConstp = VN_CAST(rAndp->lhsp(), Const)) { if (lAndp->rhsp()->sameTree(rAndp->rhsp())) { @@ -3204,6 +3210,7 @@ class ConstVisitor final : public VNVisitor { } } void visit(AstRelease* nodep) override { + // cppcheck-suppress constVariablePointer // children unlinked below if (AstConcat* const concatp = VN_CAST(nodep->lhsp(), Concat)) { FileLine* const flp = nodep->fileline(); AstRelease* const newLp = new AstRelease{flp, concatp->lhsp()->unlinkFrBack()}; @@ -3282,6 +3289,7 @@ class ConstVisitor final : public VNVisitor { UINFO(4, "IF({a}) ASSIGN({b},{c}) else ASSIGN({b},{d}) => ASSIGN({b}, {a}?{c}:{d})"); AstNodeAssign* const thensp = VN_AS(nodep->thensp(), NodeAssign); + // cppcheck-suppress constVariablePointer // children unlinked below AstNodeAssign* const elsesp = VN_AS(nodep->elsesp(), NodeAssign); thensp->unlinkFrBack(); AstNodeExpr* const condp = nodep->condp()->unlinkFrBack(); @@ -3330,6 +3338,7 @@ class ConstVisitor final : public VNVisitor { if (!prevp->fmtp() || prevp->fmtp()->nextp() || !nodep->fmtp() || nodep->fmtp()->nextp()) return false; AstSFormatF* const pformatp = prevp->fmtp(); + // cppcheck-suppress constVariablePointer // children unlinked below AstSFormatF* const nformatp = nodep->fmtp(); // 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 @@ -3979,6 +3988,7 @@ void V3Const::constifyParamsEdit(AstNode* nodep) { // Make sure we've sized everything first nodep = V3Width::widthParamsEdit(nodep); ConstVisitor visitor{ConstVisitor::PROC_PARAMS, /* globalPass: */ false}; + // cppcheck-suppress constVariablePointer // edited below if (AstVar* const varp = VN_CAST(nodep, Var)) { // If a var wants to be constified, it's really a param, and // we want the value to be constant. We aren't passed just the @@ -4000,6 +4010,7 @@ void V3Const::constifyParamsNoWarnEdit(AstNode* nodep) { // Make sure we've sized everything first nodep = V3Width::widthParamsEdit(nodep); ConstVisitor visitor{ConstVisitor::PROC_PARAMS_NOWARN, /* globalPass: */ false}; + // cppcheck-suppress constVariablePointer // edited below if (AstVar* const varp = VN_CAST(nodep, Var)) { // If a var wants to be constified, it's really a param, and // we want the value to be constant. We aren't passed just the @@ -4029,6 +4040,7 @@ AstNode* V3Const::constifyGenerateParamsEdit(AstNode* nodep) { // Make sure we've sized everything first nodep = V3Width::widthGenerateParamsEdit(nodep); ConstVisitor visitor{ConstVisitor::PROC_GENERATE, /* globalPass: */ false}; + // cppcheck-suppress constVariablePointer // edited below if (AstVar* const varp = VN_CAST(nodep, Var)) { // If a var wants to be constified, it's really a param, and // we want the value to be constant. We aren't passed just the diff --git a/src/V3Dead.cpp b/src/V3Dead.cpp index b36758ed2..469c2e578 100644 --- a/src/V3Dead.cpp +++ b/src/V3Dead.cpp @@ -85,6 +85,7 @@ class DeadVisitor final : public VNVisitor { VL_DO_DANGLING(pushDeletep(nodep->unlinkFrBack()), nodep); } + // cppcheck-suppress constParameterPointer void checkAll(AstNode* nodep) { if (AstNode* const subnodep = nodep->dtypep()) { if (nodep != subnodep // Not NodeDTypes reference themselves @@ -473,7 +474,9 @@ class DeadVisitor final : public VNVisitor { } } + // cppcheck-suppress constParameterPointer void preserveTopIfaces(AstNetlist* rootp) { + // cppcheck-suppress constVariablePointer for (AstNodeModule* modp = rootp->modulesp(); modp && modp->level() <= 2; modp = VN_AS(modp->nextp(), NodeModule)) { for (AstNode* subnodep = modp->stmtsp(); subnodep; subnodep = subnodep->nextp()) { diff --git a/src/V3Delayed.cpp b/src/V3Delayed.cpp index 072e73f29..964a80593 100644 --- a/src/V3Delayed.cpp +++ b/src/V3Delayed.cpp @@ -220,6 +220,7 @@ class DelayedVisitor final : public VNVisitor { // Remove duplicates V3Const::constifyExpensiveEdit(m_senTreep); } + // cppcheck-suppress constParameterPointer void addSensitivity(AstSenTree* nodep) { addSensitivity(nodep->sensesp()); } }; @@ -1126,7 +1127,7 @@ class DelayedVisitor final : public VNVisitor { // First gather all senItems AstSenItem* senItemp = nullptr; - for (AstSenTree* const domainp : m_timingDomains) { + for (const AstSenTree* const domainp : m_timingDomains) { if (domainp->sensesp()) senItemp = AstNode::addNext(senItemp, domainp->sensesp()->cloneTree(true)); } @@ -1216,6 +1217,7 @@ class DelayedVisitor final : public VNVisitor { VL_RESTORER(m_currNbaLhsRefp); UASSERT_OBJ(!m_currNbaLhsRefp, nodep, "NBAs should not nest"); nodep->lhsp()->foreach([&](AstNode* currp) { + // cppcheck-suppress constVariablePointer if (AstExprStmt* const exprp = VN_CAST(currp, ExprStmt)) { // Move statements before the NBA nodep->addHereThisAsNext(exprp->stmtsp()->unlinkFrBackWithNext()); diff --git a/src/V3Dfg.cpp b/src/V3Dfg.cpp index 3311c3f81..b36b27a65 100644 --- a/src/V3Dfg.cpp +++ b/src/V3Dfg.cpp @@ -134,7 +134,7 @@ std::unique_ptr DfgGraph::clone() const { // Hook up inputs of cloned variables for (const DfgVertexVar& vtx : m_varVertices) { // All variable vertices are unary - if (DfgVertex* const srcp = vtx.srcp()) { + if (const DfgVertex* const srcp = vtx.srcp()) { vtxp2clonep.at(&vtx)->as()->srcp(vtxp2clonep.at(srcp)); } } @@ -146,7 +146,7 @@ std::unique_ptr DfgGraph::clone() const { const DfgSpliceArray* const vp = vtx.as(); DfgSpliceArray* const cp = vtxp2clonep.at(vp)->as(); vp->forEachSourceEdge([&](const DfgEdge& edge, size_t i) { - if (DfgVertex* const srcp = edge.sourcep()) { + if (const DfgVertex* const srcp = edge.sourcep()) { cp->addDriver(vp->driverFileLine(i), // vp->driverLo(i), // vtxp2clonep.at(srcp)); @@ -158,7 +158,7 @@ std::unique_ptr DfgGraph::clone() const { const DfgSplicePacked* const vp = vtx.as(); DfgSplicePacked* const cp = vtxp2clonep.at(vp)->as(); vp->forEachSourceEdge([&](const DfgEdge& edge, size_t i) { - if (DfgVertex* const srcVp = edge.sourcep()) { + if (const DfgVertex* const srcVp = edge.sourcep()) { DfgVertex* const srcCp = vtxp2clonep.at(srcVp); UASSERT_OBJ(!srcCp->is(), srcCp, "Cannot clone DfgLogic"); if (srcVp == vp->defaultp()) { @@ -183,7 +183,7 @@ std::unique_ptr DfgGraph::clone() const { UASSERT_OBJ(oSourceEdges.second == cSourceEdges.second, &vtx, "Mismatched source count"); for (size_t i = 0; i < oSourceEdges.second; ++i) { - if (DfgVertex* const srcp = oSourceEdges.first[i].sourcep()) { + if (const DfgVertex* const srcp = oSourceEdges.first[i].sourcep()) { cSourceEdges.first[i].relinkSource(vtxp2clonep.at(srcp)); } } @@ -244,11 +244,11 @@ std::string DfgGraph::makeUniqueName(const std::string& prefix, size_t n) { // Construct the tmpNameStub if we have not done so yet if (m_tmpNameStub.empty()) { // Use the hash of the graph name (avoid long names and non-identifiers) - const std::string name = V3Hash{m_name}.toString(); + const std::string hash = V3Hash{m_name}.toString(); // We need to keep every variable globally unique, and graph hashed // names might not be, so keep a static table to track multiplicity static std::unordered_map s_multiplicity; - m_tmpNameStub += '_' + name + '_' + std::to_string(s_multiplicity[name]++) + '_'; + m_tmpNameStub += '_' + hash + '_' + std::to_string(s_multiplicity[hash]++) + '_'; } // Assemble the globally unique name return "__Vdfg" + prefix + m_tmpNameStub + std::to_string(n); @@ -287,12 +287,12 @@ static const std::string toDotId(const DfgVertex& vtx) { return '"' + cvtToHex(& static void dumpDotVertex(std::ostream& os, const DfgVertex& vtx) { if (const DfgVarPacked* const varVtxp = vtx.cast()) { - AstNode* const nodep = varVtxp->nodep(); - AstVar* const varp = varVtxp->varp(); + const AstNode* const nodep = varVtxp->nodep(); + const AstVar* const varp = varVtxp->varp(); os << toDotId(vtx); os << " [label=\"" << nodep->prettyName() << '\n'; os << cvtToHex(varVtxp) << '\n'; - if (AstNode* const tmpForp = varVtxp->tmpForp()) { + if (const AstNode* const tmpForp = varVtxp->tmpForp()) { os << "temporary for: " << tmpForp->prettyName() << "\n"; } varVtxp->dtypep()->dumpSmall(os); @@ -320,12 +320,12 @@ static void dumpDotVertex(std::ostream& os, const DfgVertex& vtx) { } if (const DfgVarArray* const arrVtxp = vtx.cast()) { - AstNode* const nodep = arrVtxp->nodep(); - AstVar* const varp = arrVtxp->varp(); + const AstNode* const nodep = arrVtxp->nodep(); + const AstVar* const varp = arrVtxp->varp(); os << toDotId(vtx); os << " [label=\"" << nodep->prettyName() << '\n'; os << cvtToHex(arrVtxp) << '\n'; - if (AstNode* const tmpForp = arrVtxp->tmpForp()) { + if (const AstNode* const tmpForp = arrVtxp->tmpForp()) { os << "temporary for: " << tmpForp->prettyName() << "\n"; } arrVtxp->dtypep()->dumpSmall(os); @@ -512,11 +512,12 @@ void DfgGraph::dumpDotFilePrefixed(const std::string& label, template static std::unique_ptr> -dfgGraphCollectCone(const std::vector vtxps) { +dfgGraphCollectCone(const std::vector& vtxps) { // Work queue for traversal starting from all the seed vertices std::vector queue = vtxps; // Set of already visited vertices - std::unordered_set* const resp = new std::unordered_set{}; + std::unique_ptr> resp{ + new std::unordered_set{}}; // Depth first traversal while (!queue.empty()) { // Pop next work item @@ -532,16 +533,16 @@ dfgGraphCollectCone(const std::vector vtxps) { } } // Done - return std::unique_ptr>{resp}; + return resp; } std::unique_ptr> -DfgGraph::sourceCone(const std::vector vtxps) const { +DfgGraph::sourceCone(const std::vector& vtxps) const { return dfgGraphCollectCone(vtxps); } std::unique_ptr> -DfgGraph::sinkCone(const std::vector vtxps) const { +DfgGraph::sinkCone(const std::vector& vtxps) const { return dfgGraphCollectCone(vtxps); } @@ -578,12 +579,12 @@ void DfgEdge::unlinkSource() { if (!m_sourcep) return; #ifdef VL_DEBUG { - DfgEdge* sinkp = m_sourcep->m_sinksp; - while (sinkp) { - if (sinkp == this) break; - sinkp = sinkp->m_nextp; + DfgEdge* currp = m_sourcep->m_sinksp; + while (currp) { + if (currp == this) break; + currp = currp->m_nextp; } - UASSERT(sinkp, "'m_sourcep' does not have this edge as sink"); + UASSERT(currp, "'m_sourcep' does not have this edge as sink"); } #endif // Relink pointers of predecessor and successor @@ -677,7 +678,7 @@ V3Hash DfgVertex::hash() { // variables, which we rely on. if (!is()) { hash += m_type; - if (AstUnpackArrayDType* const adtypep = VN_CAST(dtypep(), UnpackArrayDType)) { + if (const AstUnpackArrayDType* const adtypep = VN_CAST(dtypep(), UnpackArrayDType)) { hash += adtypep->elementsConst(); // TODO: maybe include sub-dtype, but not hugely important at the moment } else { @@ -685,9 +686,9 @@ V3Hash DfgVertex::hash() { } const auto pair = sourceEdges(); const DfgEdge* const edgesp = pair.first; - const size_t arity = pair.second; + const size_t nEdges = pair.second; // Sources must always be connected in well-formed graphs - for (size_t i = 0; i < arity; ++i) hash += edgesp[i].m_sourcep->hash(); + for (size_t i = 0; i < nEdges; ++i) hash += edgesp[i].m_sourcep->hash(); } result = hash; } @@ -758,11 +759,15 @@ DfgVertexVar* DfgVertex::getResultVar() { AstScope* DfgVertex::scopep(ScopeCache& cache, bool tryResultVar) VL_MT_DISABLED { // If this is a variable, we are done - if (DfgVertexVar* const varp = this->cast()) return varp->varScopep()->scopep(); + if (const DfgVertexVar* const varp = this->cast()) { + return varp->varScopep()->scopep(); + } // Try the result var first if instructed (usully only in the recursive case) if (tryResultVar) { - if (DfgVertexVar* const varp = this->getResultVar()) return varp->varScopep()->scopep(); + if (const DfgVertexVar* const varp = this->getResultVar()) { + return varp->varScopep()->scopep(); + } } // Note: the recursive invocation can cause a re-hash but that will not invalidate references @@ -775,7 +780,7 @@ AstScope* DfgVertex::scopep(ScopeCache& cache, bool tryResultVar) VL_MT_DISABLED AstScope* foundp = rootp; const auto edges = sourceEdges(); for (size_t i = 0; i < edges.second; ++i) { - DfgEdge& edge = edges.first[i]; + const DfgEdge& edge = edges.first[i]; foundp = edge.sourcep()->scopep(cache, true); if (foundp != rootp) break; } diff --git a/src/V3Dfg.h b/src/V3Dfg.h index 46a9b26b5..0297f975d 100644 --- a/src/V3Dfg.h +++ b/src/V3Dfg.h @@ -705,7 +705,8 @@ public: // Split this graph into individual components (unique sub-graphs with no edges between them). // Also removes any vertices that are not weakly connected to any variable. // Leaves 'this' graph empty. - std::vector> splitIntoComponents(std::string label) VL_MT_DISABLED; + std::vector> + splitIntoComponents(const std::string& label) VL_MT_DISABLED; // Extract cyclic sub-graphs from 'this' graph. Cyclic sub-graphs are those that contain at // least one strongly connected component (SCC) plus any other vertices that feed or sink from @@ -716,7 +717,7 @@ public: // to be a DAG (acyclic). 'this' will not necessarily be a connected graph at the end, even if // it was originally connected. std::vector> - extractCyclicComponents(std::string label) VL_MT_DISABLED; + extractCyclicComponents(const std::string& label) VL_MT_DISABLED; //----------------------------------------------------------------------- // Debug dumping @@ -742,10 +743,10 @@ public: // Returns the set of vertices in the upstream cones of the given vertices std::unique_ptr> - sourceCone(const std::vector) const VL_MT_DISABLED; + sourceCone(const std::vector&) const VL_MT_DISABLED; // Returns the set of vertices in the downstream cones of the given vertices std::unique_ptr> - sinkCone(const std::vector) const VL_MT_DISABLED; + sinkCone(const std::vector&) const VL_MT_DISABLED; //----------------------------------------------------------------------- // Static methods for data types @@ -824,9 +825,7 @@ T& DfgVertex::user() { UDEBUGONLY(UASSERT_OBJ(userCurrent, this, "DfgVertex user data used without reserving");); if (m_userCnt != userCurrent) { m_userCnt = userCurrent; - // cppcheck-has-bug-suppress uninitvar - VL_ATTR_UNUSED T* const resultp = new (storagep) T{}; - UDEBUGONLY(UASSERT_OBJ(resultp == storagep, this, "Something is odd");); + new (storagep) T{}; } return *storagep; } @@ -864,8 +863,8 @@ void DfgVertex::setUser(T value) { void DfgVertex::forEachSource(std::function f) { const auto pair = sourceEdges(); const DfgEdge* const edgesp = pair.first; - const size_t arity = pair.second; - for (size_t i = 0; i < arity; ++i) { + const size_t nEdges = pair.second; + for (size_t i = 0; i < nEdges; ++i) { if (DfgVertex* const sourcep = edgesp[i].m_sourcep) f(*sourcep); } } @@ -873,8 +872,8 @@ void DfgVertex::forEachSource(std::function f) { void DfgVertex::forEachSource(std::function f) const { const auto pair = sourceEdges(); const DfgEdge* const edgesp = pair.first; - const size_t arity = pair.second; - for (size_t i = 0; i < arity; ++i) { + const size_t nEdges = pair.second; + for (size_t i = 0; i < nEdges; ++i) { if (DfgVertex* const sourcep = edgesp[i].m_sourcep) f(*sourcep); } } @@ -893,15 +892,15 @@ void DfgVertex::forEachSink(std::function f) const { void DfgVertex::forEachSourceEdge(std::function f) { const auto pair = sourceEdges(); DfgEdge* const edgesp = pair.first; - const size_t arity = pair.second; - for (size_t i = 0; i < arity; ++i) f(edgesp[i], i); + const size_t nEdges = pair.second; + for (size_t i = 0; i < nEdges; ++i) f(edgesp[i], i); } void DfgVertex::forEachSourceEdge(std::function f) const { const auto pair = sourceEdges(); const DfgEdge* const edgesp = pair.first; - const size_t arity = pair.second; - for (size_t i = 0; i < arity; ++i) f(edgesp[i], i); + const size_t nEdges = pair.second; + for (size_t i = 0; i < nEdges; ++i) f(edgesp[i], i); } void DfgVertex::forEachSinkEdge(std::function f) { @@ -921,8 +920,8 @@ void DfgVertex::forEachSinkEdge(std::function f) const { const DfgEdge* DfgVertex::findSourceEdge(std::function p) const { const auto pair = sourceEdges(); const DfgEdge* const edgesp = pair.first; - const size_t arity = pair.second; - for (size_t i = 0; i < arity; ++i) { + const size_t nEdges = pair.second; + for (size_t i = 0; i < nEdges; ++i) { const DfgEdge& edge = edgesp[i]; if (p(edge, i)) return &edge; } @@ -979,8 +978,8 @@ DfgVertex* DfgVertexSplice::wholep() const { if (driverLo(0) != 0) return nullptr; DfgVertex* const srcp = DfgVertexVariadic::source(1); if (srcp->size() != size()) return nullptr; - if (DfgUnitArray* const uap = srcp->cast()) { - if (DfgVertexSplice* sp = uap->srcp()->cast()) { + if (const DfgUnitArray* const uap = srcp->cast()) { + if (const DfgVertexSplice* sp = uap->srcp()->cast()) { if (!sp->wholep()) return nullptr; } } @@ -1014,6 +1013,7 @@ DfgVertexVar::DfgVertexVar(DfgGraph& dfg, VDfgType type, AstVarScope* vscp) DfgVertexVar::~DfgVertexVar() { // Decrement reference count + // cppcheck-suppress shadowFunction AstNode* const nodep = this->nodep(); nodep->user1(nodep->user1() - 0x10); UASSERT_OBJ((nodep->user1() >> 4) >= 0, nodep, "Reference count underflow"); diff --git a/src/V3DfgBreakCycles.cpp b/src/V3DfgBreakCycles.cpp index 9d0d852d5..aab0f1eab 100644 --- a/src/V3DfgBreakCycles.cpp +++ b/src/V3DfgBreakCycles.cpp @@ -46,7 +46,8 @@ class TraceDriver final : public DfgVisitor { struct Hash final { size_t operator()(const Visited& item) const { - V3Hash hash{reinterpret_cast(item.m_vtxp)}; + // cppcheck-suppress unreadVariable + V3Hash hash{item.m_vtxp}; hash += item.m_lsb; hash += item.m_msb; return hash.value(); @@ -244,7 +245,7 @@ class TraceDriver final : public DfgVisitor { // Somewhat rudimentary but sufficient for current purposes. static bool knownToBeZeroAtAndAbove(const DfgVertex* vtxp, uint32_t idx) { if (const DfgConcat* const catp = vtxp->cast()) { - DfgConst* const lConstp = catp->lhsp()->cast(); + const DfgConst* const lConstp = catp->lhsp()->cast(); return lConstp && idx >= catp->rhsp()->width() && lConstp->isZero(); } if (const DfgExtend* const extp = vtxp->cast()) { @@ -256,7 +257,7 @@ class TraceDriver final : public DfgVisitor { // Like knownToBeZeroAtAndAbove, but checks vtxp[idx:0] static bool knownToBeZeroAtAndBelow(const DfgVertex* vtxp, uint32_t idx) { if (const DfgConcat* const catp = vtxp->cast()) { - DfgConst* const rConstp = catp->rhsp()->cast(); + const DfgConst* const rConstp = catp->rhsp()->cast(); return rConstp && idx < rConstp->width() && rConstp->isZero(); } return false; @@ -381,10 +382,10 @@ class TraceDriver final : public DfgVisitor { void visit(DfgArraySel* vtxp) override { // Only constant select - DfgConst* const idxp = vtxp->bitp()->cast(); + const DfgConst* const idxp = vtxp->bitp()->cast(); if (!idxp) return; // From a variable - DfgVarArray* varp = vtxp->fromp()->cast(); + const DfgVarArray* varp = vtxp->fromp()->cast(); if (!varp) return; // Skip through intermediate variables while (varp->srcp() && varp->srcp()->is()) { @@ -394,10 +395,10 @@ class TraceDriver final : public DfgVisitor { if (!varp->srcp()) return; // Driver might be a splice - if (DfgSpliceArray* const splicep = varp->srcp()->cast()) { - DfgVertex* const driverp = splicep->driverAt(idxp->toSizeT()); + if (const DfgSpliceArray* const splicep = varp->srcp()->cast()) { + const DfgVertex* const driverp = splicep->driverAt(idxp->toSizeT()); if (!driverp) return; - DfgUnitArray* const uap = driverp->cast(); + const DfgUnitArray* const uap = driverp->cast(); if (!uap) return; // Trace the driver SET_RESULT(trace(uap->srcp(), m_msb, m_lsb)); @@ -405,7 +406,7 @@ class TraceDriver final : public DfgVisitor { } // Or a unit array - DfgUnitArray* const uap = varp->srcp()->cast(); + const DfgUnitArray* const uap = varp->srcp()->cast(); if (!uap) return; // Trace the driver UASSERT_OBJ(idxp->toSizeT() == 0, vtxp, "Array Index out of range"); @@ -523,7 +524,7 @@ class TraceDriver final : public DfgVisitor { void visit(DfgShiftR* vtxp) override { DfgVertex* const lhsp = vtxp->lhsp(); - if (DfgConst* const rConstp = vtxp->rhsp()->cast()) { + if (const DfgConst* const rConstp = vtxp->rhsp()->cast()) { const uint32_t shiftAmnt = rConstp->toU32(); // Width of lower half of result const uint32_t lowerWidth = shiftAmnt > vtxp->width() ? 0 : vtxp->width() - shiftAmnt; @@ -558,7 +559,7 @@ class TraceDriver final : public DfgVisitor { void visit(DfgShiftL* vtxp) override { DfgVertex* const lhsp = vtxp->lhsp(); - if (DfgConst* const rConstp = vtxp->rhsp()->cast()) { + if (const DfgConst* const rConstp = vtxp->rhsp()->cast()) { const uint32_t shiftAmnt = rConstp->toU32(); // Width of lower half of result const uint32_t lowerWidth = shiftAmnt > vtxp->width() ? vtxp->width() : shiftAmnt; @@ -642,13 +643,13 @@ public: // partial trace succeded, but an eventual one falied). Because new // vertices should be created depth first, it is enough to do a single // reverse pass over the collectoin - for (DfgVertex* const vtxp : vlstd::reverse_view(traceDriver.m_newVtxps)) { + for (DfgVertex* const newp : vlstd::reverse_view(traceDriver.m_newVtxps)) { // Keep the actual result! - if (vtxp == resultp) continue; + if (newp == resultp) continue; // Keep used ones! - if (vtxp->hasSinks()) continue; + if (newp->hasSinks()) continue; // Delete it - VL_DO_DANGLING(vtxp->unlinkDelete(dfg), vtxp); + VL_DO_DANGLING(newp->unlinkDelete(dfg), newp); } // Return the result return resultp; @@ -733,10 +734,10 @@ class IndependentBits final : public DfgVisitor { void visit(DfgArraySel* vtxp) override { // Only constant select - DfgConst* const idxp = vtxp->bitp()->cast(); + const DfgConst* const idxp = vtxp->bitp()->cast(); if (!idxp) return; // From a variable - DfgVarArray* varp = vtxp->fromp()->cast(); + const DfgVarArray* varp = vtxp->fromp()->cast(); if (!varp) return; // Skip through intermediate variables while (varp->srcp() && varp->srcp()->is()) { @@ -744,11 +745,11 @@ class IndependentBits final : public DfgVisitor { } // Find driver if (!varp->srcp()) return; - DfgSpliceArray* const splicep = varp->srcp()->cast(); + const DfgSpliceArray* const splicep = varp->srcp()->cast(); if (!splicep) return; - DfgVertex* const driverp = splicep->driverAt(idxp->toSizeT()); + const DfgVertex* const driverp = splicep->driverAt(idxp->toSizeT()); if (!driverp) return; - DfgUnitArray* const uap = driverp->cast(); + const DfgUnitArray* const uap = driverp->cast(); if (!uap) return; // Update mask MASK(vtxp) = MASK(uap->srcp()); @@ -1046,7 +1047,7 @@ class FixUpIndependentRanges final { V3Number result{vtxp->fileline(), static_cast(vtxp->width()), 0}; vtxp->forEachSink([&result](DfgVertex& sink) { // If used via a Sel, mark the selected bits used - if (DfgSel* const selp = sink.cast()) { + if (const DfgSel* const selp = sink.cast()) { uint32_t lsb = selp->lsb(); uint32_t msb = lsb + selp->width() - 1; for (uint32_t i = lsb; i <= msb; ++i) result.setBit(i, '1'); @@ -1058,12 +1059,12 @@ class FixUpIndependentRanges final { return result; } - static std::string debugStr(DfgVertex* vtxp) { - if (DfgArraySel* const aselp = vtxp->cast()) { + static std::string debugStr(const DfgVertex* vtxp) { + if (const DfgArraySel* const aselp = vtxp->cast()) { const size_t i = aselp->bitp()->as()->toSizeT(); return debugStr(aselp->fromp()) + "[" + std::to_string(i) + "]"; } - if (DfgVertexVar* const varp = vtxp->cast()) { + if (const DfgVertexVar* const varp = vtxp->cast()) { return varp->nodep()->name(); } vtxp->v3fatalSrc("Unhandled node type"); // LCOV_EXCL_LINE @@ -1165,7 +1166,7 @@ class FixUpIndependentRanges final { // If no imporovement was possible, delete the terms we just created if (!nImprovements) { - for (DfgVertex* const vtxp : termps) VL_DO_DANGLING(vtxp->unlinkDelete(dfg), vtxp); + for (DfgVertex* const termp : termps) VL_DO_DANGLING(termp->unlinkDelete(dfg), termp); termps.clear(); return 0; } diff --git a/src/V3DfgCache.h b/src/V3DfgCache.h index 469130340..44c773fd1 100644 --- a/src/V3DfgCache.h +++ b/src/V3DfgCache.h @@ -282,22 +282,22 @@ inline void cache(CacheTernary& cache, DfgVertexTernary* vtxp) { } // These remove an existing vertex from the cache, if it is the cached vertex -inline void invalidateByValue(CacheSel& cache, DfgSel* vtxp) { +inline void invalidateByValue(CacheSel& cache, const DfgSel* vtxp) { const auto it = find(cache, vtxp->dtypep(), vtxp->fromp(), vtxp->lsb()); if (it != cache.end() && it->second == vtxp) cache.erase(it); } -inline void invalidateByValue(CacheUnary& cache, DfgVertexUnary* vtxp) { +inline void invalidateByValue(CacheUnary& cache, const DfgVertexUnary* vtxp) { const auto it = find(cache, vtxp->dtypep(), vtxp->source<0>()); if (it != cache.end() && it->second == vtxp) cache.erase(it); } -inline void invalidateByValue(CacheBinary& cache, DfgVertexBinary* vtxp) { +inline void invalidateByValue(CacheBinary& cache, const DfgVertexBinary* vtxp) { const auto it = find(cache, vtxp->dtypep(), vtxp->source<0>(), vtxp->source<1>()); if (it != cache.end() && it->second == vtxp) cache.erase(it); } -inline void invalidateByValue(CacheTernary& cache, DfgVertexTernary* vtxp) { +inline void invalidateByValue(CacheTernary& cache, const DfgVertexTernary* vtxp) { const auto it = find(cache, vtxp->dtypep(), vtxp->source<0>(), vtxp->source<1>(), vtxp->source<2>()); if (it != cache.end() && it->second == vtxp) cache.erase(it); diff --git a/src/V3DfgColorSCCs.cpp b/src/V3DfgColorSCCs.cpp index 95da70dbc..c43566f76 100644 --- a/src/V3DfgColorSCCs.cpp +++ b/src/V3DfgColorSCCs.cpp @@ -126,7 +126,7 @@ class ColorStronglyConnectedComponents final { } } - ColorStronglyConnectedComponents(DfgGraph& dfg) + explicit ColorStronglyConnectedComponents(DfgGraph& dfg) : m_dfg{dfg} { UASSERT(dfg.size() < UNASSIGNED, "Graph too big " << dfg.name()); // Yet another implementation of Pearce's algorithm. diff --git a/src/V3DfgContext.h b/src/V3DfgContext.h index 9fad9e2ee..a32daedd0 100644 --- a/src/V3DfgContext.h +++ b/src/V3DfgContext.h @@ -352,8 +352,8 @@ public: , m_prefix{VString::removeWhitespace(label) + "-"} {} ~V3DfgContext() { - const string prefix = "Optimizations, DFG " + label() + " General, "; - V3Stats::addStat(prefix + "modules", m_modules); + const string front = "Optimizations, DFG " + label() + " General, "; + V3Stats::addStat(front + "modules", m_modules); // Print the collected patterns if (v3Global.opt.stats()) { diff --git a/src/V3DfgDecomposition.cpp b/src/V3DfgDecomposition.cpp index 8de979b4b..6f2aa82fb 100644 --- a/src/V3DfgDecomposition.cpp +++ b/src/V3DfgDecomposition.cpp @@ -113,7 +113,7 @@ public: } }; -std::vector> DfgGraph::splitIntoComponents(std::string label) { +std::vector> DfgGraph::splitIntoComponents(const std::string& label) { return SplitIntoComponents::apply(*this, label); } @@ -125,7 +125,7 @@ class ExtractCyclicComponents final { uint64_t& m_userr; public: - VertexState(DfgVertex& vtx) + explicit VertexState(DfgVertex& vtx) : m_userr{vtx.getUser()} {} bool merged() const { return m_userr >> 63; } void setMerged() { m_userr |= 1ULL << 63; } @@ -266,11 +266,11 @@ class ExtractCyclicComponents final { dfg.forEachVertex([&](const DfgVertex& vtx) { vertices.insert(&vtx); }); // Check that each edge connects to a vertex that is within the same graph - dfg.forEachVertex([&](DfgVertex& vtx) { - vtx.forEachSource([&](DfgVertex& src) { + dfg.forEachVertex([&](const DfgVertex& vtx) { + vtx.forEachSource([&](const DfgVertex& src) { UASSERT_OBJ(vertices.count(&src), &vtx, "Source vertex not in graph"); }); - vtx.forEachSink([&](DfgVertex& snk) { + vtx.forEachSink([&](const DfgVertex& snk) { UASSERT_OBJ(vertices.count(&snk), &snk, "Sink vertex not in graph"); }); }); @@ -287,7 +287,7 @@ class ExtractCyclicComponents final { // earlier merging of components ensured crossing in fact only happen at variable // boundaries). Note that fixing up the edges can create clones of variables. Clones do // not need fixing up, so we do not need to iterate them. - DfgVertex* const lastp = m_dfg.varVertices().backp(); + const DfgVertex* const lastp = m_dfg.varVertices().backp(); for (DfgVertexVar& vtx : m_dfg.varVertices()) { // Fix up the edges crossing components fixEdges(vtx); @@ -337,6 +337,7 @@ public: } }; -std::vector> DfgGraph::extractCyclicComponents(std::string label) { +std::vector> +DfgGraph::extractCyclicComponents(const std::string& label) { return ExtractCyclicComponents::apply(*this, label); } diff --git a/src/V3DfgDfgToAst.cpp b/src/V3DfgDfgToAst.cpp index 09df3a63f..3894534b6 100644 --- a/src/V3DfgDfgToAst.cpp +++ b/src/V3DfgDfgToAst.cpp @@ -194,7 +194,7 @@ class DfgToAstVisitor final : DfgVisitor { AstConst* const idxp = new AstConst{dflp, sArrayp->driverLo(i)}; AstArraySel* const nLhsp = new AstArraySel{dflp, lhsp->cloneTreePure(false), idxp}; // Convert source - if (DfgUnitArray* const uap = driverp->cast()) { + if (const DfgUnitArray* const uap = driverp->cast()) { convertDriver(assignments, dflp, nLhsp, uap->srcp()); } else { convertDriver(assignments, dflp, nLhsp, driverp); @@ -205,7 +205,7 @@ class DfgToAstVisitor final : DfgVisitor { return; } - if (DfgUnitArray* const uap = driverp->cast()) { + if (const DfgUnitArray* const uap = driverp->cast()) { // Single element array being assigned a unit array. Needs an ArraySel. AstConst* const idxp = new AstConst{flp, 0}; AstArraySel* const nLhsp = new AstArraySel{flp, lhsp->cloneTreePure(false), idxp}; diff --git a/src/V3DfgOptimizer.cpp b/src/V3DfgOptimizer.cpp index 3a12470fb..b4d0ef642 100644 --- a/src/V3DfgOptimizer.cpp +++ b/src/V3DfgOptimizer.cpp @@ -164,7 +164,9 @@ class DataflowExtractVisitor final : public VNVisitor { void visit(AstAssignW* nodep) override { // Mark LHS variable as combinationally driven - if (AstVarRef* const vrefp = VN_CAST(nodep->lhsp(), VarRef)) vrefp->varp()->user4(true); + if (const AstVarRef* const vrefp = VN_CAST(nodep->lhsp(), VarRef)) { + vrefp->varp()->user4(true); + } // iterateChildrenConst(nodep); } diff --git a/src/V3DfgPasses.cpp b/src/V3DfgPasses.cpp index a2d47394c..005e6e66b 100644 --- a/src/V3DfgPasses.cpp +++ b/src/V3DfgPasses.cpp @@ -312,7 +312,7 @@ void V3DfgPasses::binToOneHot(DfgGraph& dfg, V3DfgBinToOneHotContext& ctx) { v3Global.rootp()->typeTablep()->addTypesp(tabDTypep); // The index variable - DfgVarPacked* const idxVtxp = [&]() { + AstVar* const idxVarp = [&]() { // If there is an existing result variable, use that, otherwise create a new variable DfgVarPacked* varp = nullptr; if (DfgVertexVar* const vp = srcp->getResultVar()) { @@ -324,7 +324,7 @@ void V3DfgPasses::binToOneHot(DfgGraph& dfg, V3DfgBinToOneHotContext& ctx) { varp->srcp(srcp); } varp->setHasModRdRefs(); - return varp; + return varp->varp(); }(); // The previous index variable - we don't need a vertex for this AstVar* const preVarp = [&]() { @@ -381,13 +381,13 @@ void V3DfgPasses::binToOneHot(DfgGraph& dfg, V3DfgBinToOneHotContext& ctx) { logicp->addStmtsp(new AstAssign{ flp, // new AstArraySel{flp, new AstVarRef{flp, tabVtxp->varp(), VAccess::WRITE}, - new AstVarRef{flp, idxVtxp->varp(), VAccess::READ}}, // + new AstVarRef{flp, idxVarp, VAccess::READ}}, // new AstConst{flp, AstConst::BitTrue{}}}); } { // pre = idx logicp->addStmtsp(new AstAssign{flp, // new AstVarRef{flp, preVarp, VAccess::WRITE}, // - new AstVarRef{flp, idxVtxp->varp(), VAccess::READ}}); + new AstVarRef{flp, idxVarp, VAccess::READ}}); } // Replace terms with ArraySels @@ -500,7 +500,7 @@ void V3DfgPasses::eliminateVars(DfgGraph& dfg, V3DfgEliminateVarsContext& ctx) { ++ctx.m_varsRemoved; varp->replaceWith(varp->srcp()); ctx.m_deleteps.push_back(varp->nodep()); // Delete variable at the end - } else if (DfgVarPacked* const driverp = varp->srcp()->cast()) { + } else if (const DfgVarPacked* const driverp = varp->srcp()->cast()) { // If it's driven from another variable, it can be replaced by that. // Mark it for replacement ++ctx.m_varsReplaced; diff --git a/src/V3DfgPeephole.cpp b/src/V3DfgPeephole.cpp index 634009af8..5a1df937f 100644 --- a/src/V3DfgPeephole.cpp +++ b/src/V3DfgPeephole.cpp @@ -232,7 +232,7 @@ class V3DfgPeephole final : public DfgVisitor { // Same as above, but 'flp' and 'dtypep' are taken from the given example vertex template - Vertex* make(DfgVertex* examplep, Operands... operands) { + Vertex* make(const DfgVertex* examplep, Operands... operands) { return make(examplep->fileline(), examplep->dtypep(), operands...); } @@ -408,8 +408,8 @@ class V3DfgPeephole final : public DfgVisitor { // If both sides are variable references, order the side in some defined way. This // allows CSE to later merge 'a op b' with 'b op a'. if (lhsp->is() && rhsp->is()) { - AstNode* const lVarp = lhsp->as()->nodep(); - AstNode* const rVarp = rhsp->as()->nodep(); + const AstNode* const lVarp = lhsp->as()->nodep(); + const AstNode* const rVarp = rhsp->as()->nodep(); if (lVarp->name() > rVarp->name()) { APPLYING(SWAP_VAR_IN_COMMUTATIVE_BINARY) { Vertex* const replacementp = make(vtxp, rhsp, lhsp); diff --git a/src/V3DfgSynthesize.cpp b/src/V3DfgSynthesize.cpp index 4f16a52fe..3819542ec 100644 --- a/src/V3DfgSynthesize.cpp +++ b/src/V3DfgSynthesize.cpp @@ -153,7 +153,7 @@ class AstToDfgConverter final : public VNVisitor { } // Get (or create a new) temporary for this variable - DfgVertexVar* const vtxp = [&]() -> DfgVertexVar* { + const DfgVertexVar* const vtxp = [&]() -> DfgVertexVar* { // The variable being assigned Variable* const tgtp = getTarget(vrefp); @@ -240,7 +240,9 @@ class AstToDfgConverter final : public VNVisitor { // Return the splice driver DfgVertex* driverp = splicep->driverAt(index); - if (DfgUnitArray* const uap = driverp->cast()) driverp = uap->srcp(); + if (const DfgUnitArray* const uap = driverp->cast()) { + driverp = uap->srcp(); + } return {driverp->as(), 0}; } @@ -1319,6 +1321,7 @@ class AstToDfgSynthesize final { const bool missing = m_logicp->findSink([&](const DfgVertex& sink) -> bool { const DfgUnresolved* const unresolvedp = sink.as(); AstNode* const tgtp = unresolvedp->singleSink()->as()->nodep(); + // cppcheck-suppress constVariablePointer Variable* const varp = reinterpret_cast(tgtp); return !oSymTab.count(varp); }); @@ -1331,6 +1334,7 @@ class AstToDfgSynthesize final { m_logicp->forEachSink([&](DfgVertex& sink) { DfgUnresolved* const unresolvedp = sink.as(); AstNode* const tgtp = unresolvedp->singleSink()->as()->nodep(); + // cppcheck-suppress constVariablePointer Variable* const varp = reinterpret_cast(tgtp); DfgVertexVar* const resp = oSymTab.at(varp); UASSERT_OBJ(resp->srcp(), resp, "Undriven result"); @@ -1489,7 +1493,7 @@ class AstToDfgSynthesize final { //------------------------------------------------------------------- UINFO(5, "Step 2: Revert drivers of variables with unsynthesizeable drivers"); // We do this as the variables might be multi-driven, we just can't know at this point - for (DfgVertexVar& var : m_dfg.varVertices()) { + for (const DfgVertexVar& var : m_dfg.varVertices()) { if (!var.srcp()) continue; DfgUnresolved* const unresolvedp = var.srcp()->cast(); if (!unresolvedp) break; // Stop when reached the synthesized temporaries @@ -1509,7 +1513,7 @@ class AstToDfgSynthesize final { // List of multi-driven variables std::vector multidrivenps; // Map from variable to its resolved driver - std::unordered_map resolvedDrivers; + std::unordered_map resolvedDrivers; // Compute resolved drivers of all variablees for (DfgVertexVar& var : m_dfg.varVertices()) { if (!var.srcp()) continue; @@ -1536,7 +1540,7 @@ class AstToDfgSynthesize final { UASSERT_OBJ(newEntry, &var, "Dupliacte driver"); } // Revert and remove drivers of multi-driven variables - for (DfgVertexVar* const vtxp : multidrivenps) { + for (const DfgVertexVar* const vtxp : multidrivenps) { // Mark as multidriven for future DFG runs - here, so we get all warning before vtxp->varp()->setDfgMultidriven(); // Might not have a driver if transitively removed on an earlier iteration @@ -1546,7 +1550,7 @@ class AstToDfgSynthesize final { revertTransivelyAndRemove(unresolvedp, m_ctx.m_synt.revertMultidrive); } // Replace all DfgUnresolved with the resolved drivers - for (DfgVertexVar& var : m_dfg.varVertices()) { + for (const DfgVertexVar& var : m_dfg.varVertices()) { if (!var.srcp()) continue; DfgUnresolved* const srcp = var.srcp()->cast(); if (!srcp) break; // Stop when reached the synthesized temporaries diff --git a/src/V3DfgVertices.h b/src/V3DfgVertices.h index 1bc756bf0..1b0370725 100644 --- a/src/V3DfgVertices.h +++ b/src/V3DfgVertices.h @@ -185,6 +185,7 @@ public: // the actual driver this DfgVertexSplice can be replaced with. inline DfgVertex* wholep() const; + // cppcheck-suppress duplInheritedMember void resetSources() { m_driverData.clear(); // Unlink default driver @@ -375,7 +376,7 @@ class DfgUnresolved final : public DfgVertexVariadic { // Represents a collection of unresolved variable drivers before synthesis public: - DfgUnresolved(DfgGraph& dfg, DfgVertexVar* vtxp) + DfgUnresolved(DfgGraph& dfg, const DfgVertexVar* vtxp) : DfgVertexVariadic{dfg, dfgType(), vtxp->fileline(), vtxp->dtypep(), 1u} {} ASTGEN_MEMBERS_DfgUnresolved; @@ -383,6 +384,7 @@ public: void addDriver(DfgLogic* vtxp) { addSource()->relinkSource(vtxp); } void addDriver(DfgVertexSplice* vtxp) { addSource()->relinkSource(vtxp); } + // cppcheck-suppress duplInheritedMember void clearSources() { DfgVertexVariadic::clearSources(); } DfgVertex* singleSource() const { return arity() == 1 ? source(0) : nullptr; } diff --git a/src/V3Error.h b/src/V3Error.h index aed9db65c..1df93054c 100644 --- a/src/V3Error.h +++ b/src/V3Error.h @@ -649,18 +649,19 @@ void v3errorEndFatal(std::ostringstream& sstr) /// Based on debug level, call UINFO then dumpTree on nodep, using given message prefix /// If uinfo_msg = "", suppress the first UINFO -/// If dt_msg = "", use the uinfo_msg; note any uinfo_msg side effects will happen twice. -#define UINFOTREE(level, nodep, uinfo_msg, dt_msg) \ +/// If dumptree_msg = "", use the uinfo_msg; note any uinfo_msg side effects will happen twice. +#define UINFOTREE(level, nodep, uinfo_msg, dumptree_msg) \ do { \ if (VL_UNCOVERABLE(debug() >= (level))) { \ std::ostringstream us; \ us << uinfo_msg; \ if (!us.str().empty()) UINFO(level, us.str()); \ - std::ostringstream ss; \ - ss << dt_msg; \ - if (ss.str().empty()) ss << uinfo_msg; \ - if (nodep) \ - nodep->dumpTree("- "s + V3Error::lineStr(__FILE__, __LINE__) + ss.str() + " - "); \ + if (nodep) { \ + std::ostringstream ss; \ + ss << dumptree_msg; \ + if (ss.str().empty()) ss << uinfo_msg; \ + nodep->dumpTree("- " + V3Error::lineStr(__FILE__, __LINE__) + ss.str() + " - "); \ + } \ } \ } while (false) @@ -722,6 +723,8 @@ void v3errorEndFatal(std::ostringstream& sstr) // Takes an optional "name" (as __VA_ARGS__) #define VL_DEFINE_DEBUG(...) \ VL_ATTR_UNUSED static int debug##__VA_ARGS__() VL_MT_SAFE { \ + /* Don't complain this function is unused */ \ + (void)&debug##__VA_ARGS__; \ static int level = -1; \ if (VL_UNLIKELY(level < 0)) { \ std::string tag{VL_STRINGIFY(__VA_ARGS__)}; \ @@ -739,6 +742,8 @@ void v3errorEndFatal(std::ostringstream& sstr) // Takes an optional "name" (as __VA_ARGS__) #define VL_DEFINE_DUMP(func, tag) \ VL_ATTR_UNUSED static int dump##func() VL_MT_SAFE { \ + /* Don't complain this function is unused */ \ + (void)&dump##func; \ static int level = -1; \ if (VL_UNLIKELY(level < 0)) { \ const unsigned dumpTag = v3Global.opt.dumpLevel(tag); \ @@ -762,6 +767,7 @@ void v3errorEndFatal(std::ostringstream& sstr) VL_DEFINE_DUMP(TreeJsonLevel, \ "tree-json"); /* Define 'int dumpTreeJsonLevel()' for dumpi-tree-json */ \ VL_ATTR_UNUSED static int dumpTreeEitherLevel() { \ + /* Don't complain this function is unused */ (void)&dumpTreeEitherLevel; \ return dumpTreeJsonLevel() >= dumpTreeLevel() ? dumpTreeJsonLevel() : dumpTreeLevel(); \ } \ static_assert(true, "") diff --git a/src/V3File.h b/src/V3File.h index 009b658e7..746948386 100644 --- a/src/V3File.h +++ b/src/V3File.h @@ -302,7 +302,9 @@ public: puts("\n"); } virtual void putsHeader() {} + // cppcheck-suppress duplInheritedMember void puts(const char* strg) { putsNoTracking(strg); } + // cppcheck-suppress duplInheritedMember void puts(const string& strg) { putsNoTracking(strg); } // METHODS @@ -388,7 +390,9 @@ public: ~V3OutMkFile() override = default; virtual void putsHeader() { puts("# Verilated -*- Makefile -*-\n"); } // No automatic indentation yet. + // cppcheck-suppress duplInheritedMember void puts(const char* strg) { putsNoTracking(strg); } + // cppcheck-suppress duplInheritedMember void puts(const string& strg) { putsNoTracking(strg); } // Put VARIABLE = VALUE void putSet(const string& var, const string& value) { diff --git a/src/V3Hash.h b/src/V3Hash.h index d73fbae6f..3263e2208 100644 --- a/src/V3Hash.h +++ b/src/V3Hash.h @@ -38,14 +38,17 @@ public: : m_value{0} {} explicit V3Hash(uint32_t val) : m_value{val} {} - explicit V3Hash(int32_t val) - : m_value{static_cast(val)} {} explicit V3Hash(uint64_t val) : m_value{combine(static_cast(val), static_cast(val >> 32))} {} - explicit V3Hash(int64_t val) - : m_value{combine(static_cast(val), static_cast(val >> 32))} {} explicit V3Hash(const std::string& val); + explicit V3Hash(int32_t val) + : V3Hash{static_cast(val)} {} + explicit V3Hash(int64_t val) + : V3Hash{static_cast(val)} {} + explicit V3Hash(void* val) + : V3Hash{reinterpret_cast(val)} {} + // METHODS uint32_t value() const VL_MT_SAFE { return m_value; } std::string toString() const VL_MT_SAFE; diff --git a/src/V3PairingHeap.h b/src/V3PairingHeap.h index 98b22b1e6..7956e3766 100644 --- a/src/V3PairingHeap.h +++ b/src/V3PairingHeap.h @@ -93,7 +93,7 @@ public: Link m_next; // Next in list of sibling heaps Link m_kids; // Head of list of child heaps Node** m_ownerpp = nullptr; // Pointer to the Link pointer pointing to this heap - T_Key m_key; // The key in the heap + T_Key m_key{}; // The key in the heap // CONSTRUCTOR explicit Node() = default; diff --git a/src/V3Simulate.h b/src/V3Simulate.h index 3364308d4..65b58cf7b 100644 --- a/src/V3Simulate.h +++ b/src/V3Simulate.h @@ -168,7 +168,7 @@ private: V3Number fieldNum{nump, width}; fieldNum.opSel(*nump, msb, lsb); out << itemp->name() << ": "; - if (AstNodeDType* const childTypep = itemp->subDTypep()) { + if (const AstNodeDType* const childTypep = itemp->subDTypep()) { out << prettyNumber(&fieldNum, childTypep); } else { out << fieldNum; @@ -179,7 +179,7 @@ private: return out.str(); } } else if (const AstPackArrayDType* const arrayp = VN_CAST(dtypep, PackArrayDType)) { - if (AstNodeDType* const childTypep = arrayp->subDTypep()) { + if (const AstNodeDType* const childTypep = arrayp->subDTypep()) { std::ostringstream out; out << "["; const int arrayElements = arrayp->elementsConst(); @@ -226,7 +226,7 @@ public: conIt != tconnects->end(); ++conIt) { const AstVar* const portp = conIt->first; AstNodeExpr* const pinp = conIt->second->exprp(); - AstNodeDType* const dtypep = pinp->dtypep(); + const AstNodeDType* const dtypep = pinp->dtypep(); if (AstConst* const valp = fetchConstNull(pinp)) { stack << "\n " << portp->prettyName() << " = " << prettyNumber(&valp->num(), dtypep); @@ -876,7 +876,7 @@ private: void visit(AstArraySel* nodep) override { checkNodeInfo(nodep); iterateChildrenConst(nodep); - if (AstInitArray* const initp = VN_CAST(fetchValueNull(nodep->fromp()), InitArray)) { + if (const AstInitArray* const initp = VN_CAST(fetchValueNull(nodep->fromp()), InitArray)) { const AstConst* const indexp = fetchConst(nodep->bitp()); const uint32_t offset = indexp->num().toUInt(); AstNodeExpr* const itemp = initp->getIndexDefaultedValuep(offset); diff --git a/src/cppcheck-suppressions.txt b/src/cppcheck-suppressions.txt index e1fad255b..c83e0c03e 100644 --- a/src/cppcheck-suppressions.txt +++ b/src/cppcheck-suppressions.txt @@ -27,7 +27,8 @@ 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 +// These are all inappropriate +constVariablePointer:src/V3DfgPeephole.cpp +constParameterPointer:src/V3DfgPeephole.cpp