MCPcopy Create free account
hub / github.com/cppcheck-opensource/cppcheck / useStlAlgorithm

Method useStlAlgorithm

lib/checkstl.cpp:3003–3237  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

3001} // namespace
3002
3003void CheckStlImpl::useStlAlgorithm()
3004{
3005 if (!mSettings.severity.isEnabled(Severity::style) && !mSettings.isPremiumEnabled("useStlAlgorithm"))
3006 return;
3007
3008 logChecker("CheckStl::useStlAlgorithm"); // style
3009
3010 auto checkAssignee = [](const Token* tok) {
3011 if (astIsBool(tok)) // std::accumulate is not a good fit for bool values, std::all/any/none_of return early
3012 return false;
3013 return !astIsContainer(tok); // don't warn for containers, where overloaded operators can be costly
3014 };
3015
3016 enum class ConditionOpType : std::uint8_t { OTHER, MIN, MAX };
3017 auto isConditionWithoutSideEffects = [this](const Token* tok, ConditionOpType& type) -> bool {
3018 if (!Token::simpleMatch(tok, "{") || !Token::simpleMatch(tok->previous(), ")"))
3019 return false;
3020 const Token* condTok = tok->linkAt(-1)->astOperand2();
3021 if (isConstExpression(condTok, mSettings.library)) {
3022 if (condTok->str() == "<")
3023 type = ConditionOpType::MIN;
3024 else if (condTok->str() == ">")
3025 type = ConditionOpType::MAX;
3026 else
3027 type = ConditionOpType::OTHER;
3028 return true;
3029 }
3030 return false;
3031 };
3032
3033 auto isAccumulation = [](const Token* tok, int varId) {
3034 if (tok->str() != "=")
3035 return true;
3036 const Token* end = Token::findmatch(tok, "%varid%|;", varId); // TODO: lambdas?
3037 return end && end->varId() != 0;
3038 };
3039
3040 for (const Scope *function : mTokenizer->getSymbolDatabase()->functionScopes) {
3041 for (const Token *tok = function->bodyStart; tok != function->bodyEnd; tok = tok->next()) {
3042 // Parse range-based for loop
3043 if (!Token::simpleMatch(tok, "for ("))
3044 continue;
3045 if (!Token::simpleMatch(tok->linkAt(1), ") {"))
3046 continue;
3047 LoopAnalyzer a{tok, &mSettings};
3048 std::string algoName = a.findAlgo();
3049 if (!algoName.empty()) {
3050 useStlAlgorithmError(tok, algoName);
3051 continue;
3052 }
3053
3054 const Token *bodyTok = tok->linkAt(1)->next();
3055 const Token *splitTok = tok->next()->astOperand2();
3056 const Token* loopVar{};
3057 LoopType loopType{};
3058 if (Token::simpleMatch(splitTok, ":")) {
3059 loopVar = splitTok->previous();
3060 if (loopVar->varId() == 0)

Callers 1

runChecksMethod · 0.80

Calls 15

astIsBoolFunction · 0.85
astIsContainerFunction · 0.85
isConstExpressionFunction · 0.85
getInitTokFunction · 0.85
getCondTokFunction · 0.85
getStepTokFunction · 0.85
singleAssignInScopeFunction · 0.85
addByOneFunction · 0.85
accumulateBoolFunction · 0.85
isTernaryAssignmentFunction · 0.85
singleMemberCallInScopeFunction · 0.85
singleIncrementInScopeFunction · 0.85

Tested by

no test coverage detected