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

Function fillProgramMemoryFromAssignments

lib/programmemory.cpp:426–495  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

424}
425
426static void fillProgramMemoryFromAssignments(ProgramMemory& pm, const Token* tok, const Settings& settings, const ProgramMemory& state, const ProgramMemory::Map& vars)
427{
428 int indentlevel = 0;
429 for (const Token *tok2 = tok; tok2; tok2 = tok2->previous()) {
430 if ((Token::simpleMatch(tok2, "=") || Token::Match(tok2->previous(), "%var% (|{")) && tok2->astOperand1() &&
431 tok2->astOperand2()) {
432 bool setvar = false;
433 const Token* vartok = tok2->astOperand1();
434 for (const auto& p:vars) {
435 if (p.first.getExpressionId() != vartok->exprId())
436 continue;
437 if (vartok == tok)
438 continue;
439 pm.setValue(vartok, p.second);
440 setvar = true;
441 }
442 if (!setvar) {
443 if (!pm.hasValue(vartok->exprId())) {
444 const Token* valuetok = tok2->astOperand2();
445 ProgramMemory local = state;
446 pm.setValue(vartok, execute(valuetok, local, settings));
447 }
448 }
449 } else if (Token::simpleMatch(tok2, ")") && tok2->link() &&
450 Token::Match(tok2->link()->previous(), "assert|ASSERT ( !!)")) {
451 const Token* cond = tok2->link()->astOperand2();
452 if (!conditionIsTrue(cond, state, settings)) {
453 // TODO: change to assert when we can propagate the assert, for now just bail
454 if (conditionIsFalse(cond, state, settings))
455 return;
456 programMemoryParseCondition(pm, cond, nullptr, settings, true);
457 }
458 tok2 = tok2->link()->previous();
459 } else if (tok2->exprId() > 0 && Token::Match(tok2, ".|(|[|*|%var%") && !pm.hasValue(tok2->exprId()) &&
460 isVariableChanged(tok2, 0, settings)) {
461 pm.setUnknown(tok2);
462 }
463
464 if (tok2->str() == "{") {
465 if (indentlevel <= 0) {
466 const Token* cond = getCondTokFromEnd(tok2->link());
467 // Keep progressing with anonymous/do scopes and always true branches
468 if (!Token::Match(tok2->previous(), "do|; {") && !conditionIsTrue(cond, state, settings) &&
469 (cond || !isBasicForLoop(tok2)))
470 break;
471 } else
472 --indentlevel;
473 if (Token::simpleMatch(tok2->previous(), "else {"))
474 tok2 = tok2->linkAt(-2)->previous();
475 }
476 if (tok2->str() == "}" && !Token::Match(tok2->link()->previous(), "%var% {")) {
477 const Token *cond = getCondTokFromEnd(tok2);
478 const bool inElse = Token::simpleMatch(tok2->link()->previous(), "else {");
479 if (cond) {
480 if (conditionIsFalse(cond, state, settings)) {
481 if (inElse) {
482 ++indentlevel;
483 continue;

Callers 3

getInitialProgramStateFunction · 0.85
addStateMethod · 0.85
getProgramMemoryFunction · 0.85

Calls 15

executeFunction · 0.85
conditionIsTrueFunction · 0.85
conditionIsFalseFunction · 0.85
isVariableChangedFunction · 0.85
getCondTokFromEndFunction · 0.85
isBasicForLoopFunction · 0.85
astOperand1Method · 0.80
astOperand2Method · 0.80
getExpressionIdMethod · 0.80
setUnknownMethod · 0.80
linkAtMethod · 0.80

Tested by

no test coverage detected