Fix #11441 FP variableScope when lambda is used (#4660)

This commit is contained in:
chrchr-github 2022-12-20 14:50:31 +01:00 committed by GitHub
parent ad858e92dc
commit 7506b4ab52
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 21 additions and 14 deletions

View File

@ -1033,20 +1033,15 @@ bool CheckOther::checkInnerScope(const Token *tok, const Variable* var, bool& us
if (loopVariable && noContinue && tok->scope() == scope && !forHeadEnd && scope->type != Scope::eSwitch && Token::Match(tok, "%varid% =", var->declarationId())) { // Assigned in outer scope. if (loopVariable && noContinue && tok->scope() == scope && !forHeadEnd && scope->type != Scope::eSwitch && Token::Match(tok, "%varid% =", var->declarationId())) { // Assigned in outer scope.
loopVariable = false; loopVariable = false;
int indent = 0; std::pair<const Token*, const Token*> range = tok->next()->findExpressionStartEndTokens();
for (const Token* tok2 = tok->tokAt(2); tok2; tok2 = tok2->next()) { // Ensure that variable isn't used on right side of =, too if (range.first)
if (tok2->str() == "(") range.first = range.first->next();
indent++; const Token* exprTok = findExpression(var->nameToken()->exprId(), range.first, range.second, [&](const Token* tok2) {
else if (tok2->str() == ")") { return tok2->varId() == var->declarationId();
if (indent == 0) });
break; if (exprTok) {
indent--; tok = exprTok;
} else if (tok2->str() == ";") loopVariable = true;
break;
else if (tok2->varId() == var->declarationId()) {
loopVariable = true;
break;
}
} }
} }

View File

@ -102,6 +102,7 @@ private:
TEST_CASE(varScope29); // #10888 TEST_CASE(varScope29); // #10888
TEST_CASE(varScope30); // #8541 TEST_CASE(varScope30); // #8541
TEST_CASE(varScope31); // #11099 TEST_CASE(varScope31); // #11099
TEST_CASE(varScope32); // #11441
TEST_CASE(oldStylePointerCast); TEST_CASE(oldStylePointerCast);
TEST_CASE(invalidPointerCast); TEST_CASE(invalidPointerCast);
@ -1527,6 +1528,17 @@ private:
errout.str()); errout.str());
} }
void varScope32() { // #11441
check("template <class F>\n"
"std::vector<int> g(F, const std::vector<int>&);\n"
"void f(const std::vector<int>&v) {\n"
" std::vector<int> w;\n"
" for (auto x : v)\n"
" w = g([&]() { x; }, w);\n"
"}\n");
ASSERT_EQUALS("[test.cpp:6]: (warning) Unused variable value 'x'\n", errout.str());
}
#define checkOldStylePointerCast(code) checkOldStylePointerCast_(code, __FILE__, __LINE__) #define checkOldStylePointerCast(code) checkOldStylePointerCast_(code, __FILE__, __LINE__)
void checkOldStylePointerCast_(const char code[], const char* file, int line) { void checkOldStylePointerCast_(const char code[], const char* file, int line) {
// Clear the error buffer.. // Clear the error buffer..