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

Method checkInnerScope

lib/checkother.cpp:1338–1447  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1336}
1337
1338bool CheckOtherImpl::checkInnerScope(const Token *tok, const Variable* var, bool& used) const
1339{
1340 const Scope* scope = tok->next()->scope();
1341 bool loopVariable = scope->isLoopScope();
1342 bool noContinue = true;
1343 const Token* forHeadEnd = nullptr;
1344 const Token* end = tok->link();
1345 if (scope->type == ScopeType::eUnconditional && (tok->strAt(-1) == ")" || tok->previous()->isName())) // Might be an unknown macro like BOOST_FOREACH
1346 loopVariable = true;
1347
1348 if (scope->type == ScopeType::eDo) {
1349 end = end->linkAt(2);
1350 } else if (loopVariable && tok->strAt(-1) == ")") {
1351 tok = tok->linkAt(-1); // Jump to opening ( of for/while statement
1352 } else if (scope->type == ScopeType::eSwitch) {
1353 for (const Scope* innerScope : scope->nestedList) {
1354 if (used) {
1355 bool used2 = false;
1356 if (!checkInnerScope(innerScope->bodyStart, var, used2) || used2) {
1357 return false;
1358 }
1359 } else if (!checkInnerScope(innerScope->bodyStart, var, used)) {
1360 return false;
1361 }
1362 }
1363 }
1364
1365 bool bFirstAssignment=false;
1366 for (; tok && tok != end; tok = tok->next()) {
1367 if (tok->str() == "goto")
1368 return false;
1369 if (tok->str() == "continue")
1370 noContinue = false;
1371
1372 if (Token::simpleMatch(tok, "for ("))
1373 forHeadEnd = tok->linkAt(1);
1374 if (tok == forHeadEnd)
1375 forHeadEnd = nullptr;
1376
1377 if (loopVariable && noContinue && !forHeadEnd && scope->type != ScopeType::eSwitch && Token::Match(tok, "%varid% =", var->declarationId()) &&
1378 isOnlyUsedInCurrentScope(var, tok, scope)) { // Assigned in outer scope.
1379 loopVariable = false;
1380 std::pair<const Token*, const Token*> range = tok->next()->findExpressionStartEndTokens();
1381 if (range.first)
1382 range.first = range.first->next();
1383 const Token* exprTok = findExpression(var->nameToken()->exprId(), range.first, range.second, [&](const Token* tok2) {
1384 return tok2->varId() == var->declarationId();
1385 });
1386 if (exprTok) {
1387 tok = exprTok;
1388 loopVariable = true;
1389 }
1390 }
1391
1392 if (loopVariable && Token::Match(tok, "%varid% !!=", var->declarationId())) // Variable used in loop
1393 return false;
1394
1395 if (Token::Match(tok, "& %varid%", var->declarationId())) // Taking address of variable

Callers

nothing calls this directly

Calls 15

isOnlyUsedInCurrentScopeFunction · 0.85
findExpressionFunction · 0.85
findsimplematchFunction · 0.85
getTokenArgumentFunctionFunction · 0.85
mayDependOnFunction · 0.85
astContainerYieldFunction · 0.85
scopeMethod · 0.80
nextMethod · 0.80
linkAtMethod · 0.80
isArrayMethod · 0.80
isArrayOrPointerMethod · 0.80

Tested by

no test coverage detected