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

Function valueFlowForLoop

lib/valueflow.cpp:5360–5440  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

5358}
5359
5360static void valueFlowForLoop(const TokenList &tokenlist, const SymbolDatabase& symboldatabase, ErrorLogger &errorLogger, const Settings &settings)
5361{
5362 for (const Scope &scope : symboldatabase.scopeList) {
5363 if (scope.type != ScopeType::eFor)
5364 continue;
5365
5366 auto* tok = const_cast<Token*>(scope.classDef);
5367 auto* const bodyStart = const_cast<Token*>(scope.bodyStart);
5368
5369 if (!Token::simpleMatch(tok->next()->astOperand2(), ";") ||
5370 !Token::simpleMatch(tok->next()->astOperand2()->astOperand2(), ";"))
5371 continue;
5372
5373 nonneg int varid;
5374 bool knownInitValue, partialCond;
5375 MathLib::bigint initValue, stepValue, lastValue;
5376
5377 if (extractForLoopValues(tok, varid, knownInitValue, initValue, partialCond, stepValue, lastValue)) {
5378 const bool executeBody = !knownInitValue || initValue <= lastValue;
5379 const Token* vartok = Token::findmatch(tok, "%varid%", bodyStart, varid);
5380 if (executeBody && vartok) {
5381 std::list<ValueFlow::Value> initValues;
5382 initValues.emplace_back(initValue, ValueFlow::Value::Bound::Lower);
5383 initValues.push_back(ValueFlow::asImpossible(initValues.back()));
5384 Analyzer::Result result = valueFlowForward(bodyStart, bodyStart->link(), vartok, std::move(initValues), tokenlist, errorLogger, settings);
5385
5386 if (!result.action.isModified()) {
5387 std::list<ValueFlow::Value> lastValues;
5388 lastValues.emplace_back(lastValue, ValueFlow::Value::Bound::Upper);
5389 lastValues.back().conditional = true;
5390 lastValues.push_back(ValueFlow::asImpossible(lastValues.back()));
5391 if (stepValue != 1)
5392 lastValues.pop_front();
5393 valueFlowForward(bodyStart, bodyStart->link(), vartok, std::move(lastValues), tokenlist, errorLogger, settings);
5394 }
5395 }
5396 const MathLib::bigint afterValue = executeBody ? lastValue + stepValue : initValue;
5397 valueFlowForLoopSimplifyAfter(tok, varid, afterValue, tokenlist, errorLogger, settings);
5398 } else {
5399 ProgramMemory mem1, mem2, memAfter;
5400 if (valueFlowForLoop2(tok, mem1, mem2, memAfter, settings)) {
5401 if (mem1 == memAfter) { // #8192 check if loop never runs
5402 Token* condTok = getCondTok(tok);
5403 if (condTok && !condTok->hasKnownIntValue()) {
5404 ValueFlow::Value v(0);
5405 v.setKnown();
5406 ValueFlow::setTokenValue(condTok, std::move(v), settings);
5407 }
5408 } else {
5409 for (const auto& p : mem1) {
5410 if (!p.second.isIntValue())
5411 continue;
5412 if (p.second.isImpossible())
5413 continue;
5414 if (p.first.tok->varId() == 0)
5415 continue;
5416 valueFlowForLoopSimplify(bodyStart, p.first.tok, false, p.second.intvalue, tokenlist, errorLogger, settings);
5417 }

Callers 1

setValuesMethod · 0.85

Calls 15

extractForLoopValuesFunction · 0.85
valueFlowForwardFunction · 0.85
valueFlowForLoop2Function · 0.85
getCondTokFunction · 0.85
setTokenValueFunction · 0.85
valueFlowForLoopSimplifyFunction · 0.85
astOperand2Method · 0.80
nextMethod · 0.80
isImpossibleMethod · 0.80
getExpressionIdMethod · 0.80
simpleMatchFunction · 0.70

Tested by

no test coverage detected