From 7506b4ab52cd155549e55b65081847d603522b4d Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Tue, 20 Dec 2022 14:50:31 +0100 Subject: [PATCH] Fix #11441 FP variableScope when lambda is used (#4660) --- lib/checkother.cpp | 23 +++++++++-------------- test/testother.cpp | 12 ++++++++++++ 2 files changed, 21 insertions(+), 14 deletions(-) diff --git a/lib/checkother.cpp b/lib/checkother.cpp index 727843c53..941e5cd5f 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -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. loopVariable = false; - int indent = 0; - for (const Token* tok2 = tok->tokAt(2); tok2; tok2 = tok2->next()) { // Ensure that variable isn't used on right side of =, too - if (tok2->str() == "(") - indent++; - else if (tok2->str() == ")") { - if (indent == 0) - break; - indent--; - } else if (tok2->str() == ";") - break; - else if (tok2->varId() == var->declarationId()) { - loopVariable = true; - break; - } + std::pair range = tok->next()->findExpressionStartEndTokens(); + if (range.first) + range.first = range.first->next(); + const Token* exprTok = findExpression(var->nameToken()->exprId(), range.first, range.second, [&](const Token* tok2) { + return tok2->varId() == var->declarationId(); + }); + if (exprTok) { + tok = exprTok; + loopVariable = true; } } diff --git a/test/testother.cpp b/test/testother.cpp index fc122b1e5..b19e3b5bc 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -102,6 +102,7 @@ private: TEST_CASE(varScope29); // #10888 TEST_CASE(varScope30); // #8541 TEST_CASE(varScope31); // #11099 + TEST_CASE(varScope32); // #11441 TEST_CASE(oldStylePointerCast); TEST_CASE(invalidPointerCast); @@ -1527,6 +1528,17 @@ private: errout.str()); } + void varScope32() { // #11441 + check("template \n" + "std::vector g(F, const std::vector&);\n" + "void f(const std::vector&v) {\n" + " std::vector 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__) void checkOldStylePointerCast_(const char code[], const char* file, int line) { // Clear the error buffer..