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

Method checkLoopBodyRecursive

lib/checkuninitvar.cpp:922–1088  ·  view source on GitHub ↗

recursively check loop, return error token */

Source from the content-addressed store, hash-verified

920
921/** recursively check loop, return error token */
922const Token* CheckUninitVarImpl::checkLoopBodyRecursive(const Token *start, const Variable& var, const Alloc alloc, const std::string &membervar, bool &bailout, bool &alwaysReturns) const
923{
924 assert(start->str() == "{");
925
926 const Token *errorToken = nullptr;
927
928 const Token *const end = start->link();
929 for (const Token *tok = start->next(); tok != end; tok = tok->next()) {
930 // skip sizeof / offsetof
931 if (isUnevaluated(tok)) {
932 tok = tok->linkAt(1);
933 continue;
934 }
935
936 if (Token::Match(tok, "asm ( %str% ) ;")) {
937 bailout = true;
938 return nullptr;
939 }
940
941 // for loop; skip third expression until loop body has been analyzed..
942 if (tok->str() == ";" && Token::simpleMatch(tok->astParent(), ";") && Token::simpleMatch(tok->astParent()->astParent(), "(")) {
943 const Token *top = tok->astParent()->astParent();
944 if (!Token::simpleMatch(top->previous(), "for (") || !Token::simpleMatch(top->link(), ") {"))
945 continue;
946 const Token *bodyStart = top->link()->next();
947 const Token *errorToken1 = checkLoopBodyRecursive(bodyStart, var, alloc, membervar, bailout, alwaysReturns);
948 if (!errorToken)
949 errorToken = errorToken1;
950 bailout |= alwaysReturns;
951 if (bailout)
952 return nullptr;
953 }
954 // for loop; skip loop body if there is third expression
955 if (Token::simpleMatch(tok, ") {") &&
956 Token::simpleMatch(tok->link()->previous(), "for (") &&
957 Token::simpleMatch(tok->link()->astOperand2(), ";") &&
958 Token::simpleMatch(tok->link()->astOperand2()->astOperand2(), ";")) {
959 tok = tok->linkAt(1);
960 }
961
962 if (tok->str() == "{") {
963 // switch => bailout
964 if (tok->scope() && tok->scope()->type == ScopeType::eSwitch) {
965 bailout = true;
966 return nullptr;
967 }
968
969 bool alwaysReturnsUnused = false;
970 const Token *errorToken1 = checkLoopBodyRecursive(tok, var, alloc, membervar, bailout, alwaysReturnsUnused);
971 tok = tok->link();
972 if (Token::simpleMatch(tok, "} else {")) {
973 const Token *elseBody = tok->tokAt(2);
974 const Token *errorToken2 = checkLoopBodyRecursive(elseBody, var, alloc, membervar, bailout, alwaysReturnsUnused);
975 tok = elseBody->link();
976 if (errorToken1 && errorToken2)
977 return errorToken1;
978 if (errorToken2)
979 errorToken = errorToken2;

Callers

nothing calls this directly

Calls 15

isUnevaluatedFunction · 0.85
astIsRHSFunction · 0.85
isVariableUsageFunction · 0.85
visitAstNodesFunction · 0.85
nextMethod · 0.80
linkAtMethod · 0.80
astParentMethod · 0.80
astOperand2Method · 0.80
scopeMethod · 0.80
isVariableMethod · 0.80
variableMethod · 0.80
simpleMatchFunction · 0.70

Tested by

no test coverage detected