| 1336 | } |
| 1337 | |
| 1338 | bool 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 |
nothing calls this directly
no test coverage detected