Skip to content

Commit 7506b4a

Browse files
Fix #11441 FP variableScope when lambda is used (#4660)
1 parent ad858e9 commit 7506b4a

2 files changed

Lines changed: 21 additions & 14 deletions

File tree

lib/checkother.cpp

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1033,20 +1033,15 @@ bool CheckOther::checkInnerScope(const Token *tok, const Variable* var, bool& us
10331033

10341034
if (loopVariable && noContinue && tok->scope() == scope && !forHeadEnd && scope->type != Scope::eSwitch && Token::Match(tok, "%varid% =", var->declarationId())) { // Assigned in outer scope.
10351035
loopVariable = false;
1036-
int indent = 0;
1037-
for (const Token* tok2 = tok->tokAt(2); tok2; tok2 = tok2->next()) { // Ensure that variable isn't used on right side of =, too
1038-
if (tok2->str() == "(")
1039-
indent++;
1040-
else if (tok2->str() == ")") {
1041-
if (indent == 0)
1042-
break;
1043-
indent--;
1044-
} else if (tok2->str() == ";")
1045-
break;
1046-
else if (tok2->varId() == var->declarationId()) {
1047-
loopVariable = true;
1048-
break;
1049-
}
1036+
std::pair<const Token*, const Token*> range = tok->next()->findExpressionStartEndTokens();
1037+
if (range.first)
1038+
range.first = range.first->next();
1039+
const Token* exprTok = findExpression(var->nameToken()->exprId(), range.first, range.second, [&](const Token* tok2) {
1040+
return tok2->varId() == var->declarationId();
1041+
});
1042+
if (exprTok) {
1043+
tok = exprTok;
1044+
loopVariable = true;
10501045
}
10511046
}
10521047

test/testother.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ class TestOther : public TestFixture {
102102
TEST_CASE(varScope29); // #10888
103103
TEST_CASE(varScope30); // #8541
104104
TEST_CASE(varScope31); // #11099
105+
TEST_CASE(varScope32); // #11441
105106

106107
TEST_CASE(oldStylePointerCast);
107108
TEST_CASE(invalidPointerCast);
@@ -1527,6 +1528,17 @@ class TestOther : public TestFixture {
15271528
errout.str());
15281529
}
15291530

1531+
void varScope32() { // #11441
1532+
check("template <class F>\n"
1533+
"std::vector<int> g(F, const std::vector<int>&);\n"
1534+
"void f(const std::vector<int>&v) {\n"
1535+
" std::vector<int> w;\n"
1536+
" for (auto x : v)\n"
1537+
" w = g([&]() { x; }, w);\n"
1538+
"}\n");
1539+
ASSERT_EQUALS("[test.cpp:6]: (warning) Unused variable value 'x'\n", errout.str());
1540+
}
1541+
15301542
#define checkOldStylePointerCast(code) checkOldStylePointerCast_(code, __FILE__, __LINE__)
15311543
void checkOldStylePointerCast_(const char code[], const char* file, int line) {
15321544
// Clear the error buffer..

0 commit comments

Comments
 (0)