Skip to content

Commit 1c19709

Browse files
Fix #7091 FN variableScope for variables used in inner loop (#8245)
Co-authored-by: chrchr-github <noreply@github.com>
1 parent 0580f2b commit 1c19709

2 files changed

Lines changed: 55 additions & 1 deletion

File tree

lib/checkother.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1331,6 +1331,15 @@ static bool mayDependOn(const ValueType *other, const ValueType *original)
13311331
return otherPtr > originalPtr;
13321332
}
13331333

1334+
static bool isOnlyUsedInCurrentScope(const Variable* var, const Token *tok, const Scope* scope)
1335+
{
1336+
if (tok->scope() == scope)
1337+
return true;
1338+
if (tok->scope()->type == ScopeType::eSwitch)
1339+
return false;
1340+
return !Token::findmatch(tok->scope()->bodyEnd, "%varid%", scope->bodyEnd, var->declarationId());
1341+
}
1342+
13341343
bool CheckOther::checkInnerScope(const Token *tok, const Variable* var, bool& used) const
13351344
{
13361345
const Scope* scope = tok->next()->scope();
@@ -1370,7 +1379,8 @@ bool CheckOther::checkInnerScope(const Token *tok, const Variable* var, bool& us
13701379
if (tok == forHeadEnd)
13711380
forHeadEnd = nullptr;
13721381

1373-
if (loopVariable && noContinue && tok->scope() == scope && !forHeadEnd && scope->type != ScopeType::eSwitch && Token::Match(tok, "%varid% =", var->declarationId())) { // Assigned in outer scope.
1382+
if (loopVariable && noContinue && !forHeadEnd && scope->type != ScopeType::eSwitch && Token::Match(tok, "%varid% =", var->declarationId()) &&
1383+
isOnlyUsedInCurrentScope(var, tok, scope)) { // Assigned in outer scope.
13741384
loopVariable = false;
13751385
std::pair<const Token*, const Token*> range = tok->next()->findExpressionStartEndTokens();
13761386
if (range.first)

test/testother.cpp

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ class TestOther : public TestFixture {
123123
TEST_CASE(varScope43);
124124
TEST_CASE(varScope44);
125125
TEST_CASE(varScope45);
126+
TEST_CASE(varScope46);
126127

127128
TEST_CASE(oldStylePointerCast);
128129
TEST_CASE(intToPointerCast);
@@ -1984,6 +1985,49 @@ class TestOther : public TestFixture {
19841985
ASSERT_EQUALS("[test.cpp:2:16]: (style) The scope of the variable 'b' can be reduced. [variableScope]\n", errout_str());
19851986
}
19861987

1988+
void varScope46() {
1989+
check("void f() {\n" // #7091
1990+
" int y1;\n"
1991+
" for (int i = 0; i < 3; ++i) {\n"
1992+
" for(int j = 0; j < 3; ++j) {\n"
1993+
" y1 = 2 * 1;\n"
1994+
" y1 += 1;\n"
1995+
" }\n"
1996+
" }\n"
1997+
"}\n");
1998+
ASSERT_EQUALS("[test.cpp:2:9]: (style) The scope of the variable 'y1' can be reduced. [variableScope]\n",
1999+
errout_str());
2000+
2001+
check("bool f() {\n"
2002+
"bool b = false;\n"
2003+
"do {\n"
2004+
" switch (g()) {\n"
2005+
" case 0:\n"
2006+
" b = true;\n"
2007+
" break;\n"
2008+
" case 1:\n"
2009+
" return b;\n"
2010+
" break;\n"
2011+
" default:\n"
2012+
" break;\n"
2013+
" }\n"
2014+
"}\n"
2015+
"while (true);\n"
2016+
"}\n");
2017+
ASSERT_EQUALS("", errout_str());
2018+
2019+
check("void f() {\n"
2020+
" int y1 = 0;\n"
2021+
" for (int i = 0; i < 3; ++i) {\n"
2022+
" for(int j = 0; j < 3; ++j) {\n"
2023+
" y1 = y1 + 1;\n"
2024+
" dostuff(y1);\n"
2025+
" }\n"
2026+
" }\n"
2027+
"}\n");
2028+
ASSERT_EQUALS("", errout_str());
2029+
}
2030+
19872031
#define checkOldStylePointerCast(...) checkOldStylePointerCast_(__FILE__, __LINE__, __VA_ARGS__)
19882032
template<size_t size>
19892033
void checkOldStylePointerCast_(const char* file, int line, const char (&code)[size], Standards::cppstd_t std = Standards::CPPLatest) {

0 commit comments

Comments
 (0)