diff --git a/lib/checkother.cpp b/lib/checkother.cpp index cf5ecb65b91..16d42f6fff7 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -1331,6 +1331,15 @@ static bool mayDependOn(const ValueType *other, const ValueType *original) return otherPtr > originalPtr; } +static bool isOnlyUsedInCurrentScope(const Variable* var, const Token *tok, const Scope* scope) +{ + if (tok->scope() == scope) + return true; + if (tok->scope()->type == ScopeType::eSwitch) + return false; + return !Token::findmatch(tok->scope()->bodyEnd, "%varid%", scope->bodyEnd, var->declarationId()); +} + bool CheckOther::checkInnerScope(const Token *tok, const Variable* var, bool& used) const { const Scope* scope = tok->next()->scope(); @@ -1370,7 +1379,8 @@ bool CheckOther::checkInnerScope(const Token *tok, const Variable* var, bool& us if (tok == forHeadEnd) forHeadEnd = nullptr; - if (loopVariable && noContinue && tok->scope() == scope && !forHeadEnd && scope->type != ScopeType::eSwitch && Token::Match(tok, "%varid% =", var->declarationId())) { // Assigned in outer scope. + if (loopVariable && noContinue && !forHeadEnd && scope->type != ScopeType::eSwitch && Token::Match(tok, "%varid% =", var->declarationId()) && + isOnlyUsedInCurrentScope(var, tok, scope)) { // Assigned in outer scope. loopVariable = false; std::pair range = tok->next()->findExpressionStartEndTokens(); if (range.first) @@ -1869,6 +1879,8 @@ void CheckOther::checkConstPointer() continue; if (!var->isLocal() && !var->isArgument()) continue; + if (var->isArgument() && var->scope() && var->scope()->type == ScopeType::eLambda) + continue; const Token* const nameTok = var->nameToken(); if (tok == nameTok && var->isLocal() && !astIsRangeBasedForDecl(nameTok)) { if (var->isReference() && var->isPointer()) { diff --git a/test/testother.cpp b/test/testother.cpp index 21a640a3c7d..cc1124963ba 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -123,6 +123,7 @@ class TestOther : public TestFixture { TEST_CASE(varScope43); TEST_CASE(varScope44); TEST_CASE(varScope45); + TEST_CASE(varScope46); TEST_CASE(oldStylePointerCast); TEST_CASE(intToPointerCast); @@ -1984,6 +1985,38 @@ class TestOther : public TestFixture { ASSERT_EQUALS("[test.cpp:2:16]: (style) The scope of the variable 'b' can be reduced. [variableScope]\n", errout_str()); } + void varScope46() { + check("void f() {\n" // #7091 + " int y1;\n" + " for (int i = 0; i < 3; ++i) {\n" + " for(int j = 0; j < 3; ++j) {\n" + " y1 = 2 * 1;\n" + " y1 += 1;\n" + " }\n" + " }\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:2:9]: (style) The scope of the variable 'y1' can be reduced. [variableScope]\n", + errout_str()); + + check("bool f() {\n" + "bool b = false;\n" + "do {\n" + " switch (g()) {\n" + " case 0:\n" + " b = true;\n" + " break;\n" + " case 1:\n" + " return b;\n" + " break;\n" + " default:\n" + " break;\n" + " }\n" + "}\n" + "while (true);\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); + } + #define checkOldStylePointerCast(...) checkOldStylePointerCast_(__FILE__, __LINE__, __VA_ARGS__) template void checkOldStylePointerCast_(const char* file, int line, const char (&code)[size], Standards::cppstd_t std = Standards::CPPLatest) {