Skip to content

Commit

Permalink
Fix #13670 FP legacyUninitvar for variables declared in for loop (dan…
Browse files Browse the repository at this point in the history
  • Loading branch information
chrchr-github authored Mar 3, 2025
1 parent 68c129d commit 7b8e8fe
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 4 deletions.
7 changes: 6 additions & 1 deletion lib/symboldatabase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5001,8 +5001,13 @@ const Token *Scope::checkVariable(const Token *tok, AccessControl varaccess, con
tok2 = tok2->link();
continue;
}
if (Token::Match(tok2, ", %name%"))
if (Token::Match(tok2, ", %name%")) {
if (tok2->next()->varId() == 0) {
check->debugMessage(tok2->next(), "varid0", "Scope::checkVariable found variable \'" + tok2->strAt(1) + "\' with varid 0.");
return tok;
}
addVariable(tok2->next(), typestart, vartok->previous(), varaccess, vType, this, settings);
}
}
}
}
Expand Down
6 changes: 3 additions & 3 deletions lib/tokenize.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4727,7 +4727,7 @@ void Tokenizer::setVarIdPass1()
const Token* prev2 = tok2->previous();
if (Token::Match(prev2, "%type% [;[=,)]") && tok2->strAt(-1) != "const")
;
else if (Token::Match(prev2, "%type% :") && tok->strAt(-1) == "for")
else if (Token::Match(prev2, "%type% [:({]") && tok->strAt(-1) == "for")
;
else if (Token::Match(prev2, "%type% ( !!)") && Token::simpleMatch(tok2->link(), ") ;")) {
// In C++ , a variable can't be called operator+ or something like that.
Expand Down Expand Up @@ -4780,11 +4780,11 @@ void Tokenizer::setVarIdPass1()
syntaxErrorC(prev2, prev2->strAt(-2) + prev2->strAt(-1) + " " + prev2->str());
variableMap.addVariable(prev2->str(), scopeStack.size() <= 1);

if (Token::simpleMatch(tok->previous(), "for (") && Token::Match(prev2, "%name% [=,]")) {
if (Token::simpleMatch(tok->previous(), "for (") && Token::Match(prev2, "%name% [=[({,]")) {
for (const Token *tok3 = prev2->next(); tok3 && tok3->str() != ";"; tok3 = tok3->next()) {
if (Token::Match(tok3, "[([]"))
tok3 = tok3->link();
if (Token::Match(tok3, ", %name% [,=;]"))
if (Token::Match(tok3, ", %name% [=[({,;]"))
variableMap.addVariable(tok3->strAt(1), false);
}
}
Expand Down
23 changes: 23 additions & 0 deletions test/testvarid.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ class TestVarID : public TestFixture {
TEST_CASE(varid71); // #12676 - wrong varid in uninstantiated templated constructor
TEST_CASE(varid_for_1);
TEST_CASE(varid_for_2);
TEST_CASE(varid_for_3);
TEST_CASE(varid_cpp_keywords_in_c_code);
TEST_CASE(varid_cpp_keywords_in_c_code2); // #5373: varid=0 for argument called "delete"
TEST_CASE(varid_cpp_keywords_in_c_code3);
Expand Down Expand Up @@ -1418,6 +1419,28 @@ class TestVarID : public TestFixture {
ASSERT_EQUALS(expected, tokenize(code));
}

void varid_for_3() {
const char code[] = "void f(int w, int h) {\n" // #13670
" for (int a[2] = { 2, w / 2 }, b = 2; a[1] && a[0] <= h; a[1] /= 2, a[0] *= 2) {}\n"
"}\n";
const char expected[] = "1: void f ( int w@1 , int h@2 ) {\n"
"2: for ( int a@3 [ 2 ] = { 2 , w@1 / 2 } , b@4 = 2 ; a@3 [ 1 ] && a@3 [ 0 ] <= h@2 ; a@3 [ 1 ] /= 2 , a@3 [ 0 ] *= 2 ) { }\n"
"3: }\n";
ASSERT_EQUALS(expected, tokenize(code));

const char code2[] = "void f() {\n"
" for (int a(1), b{ 2 }, c = 3; a < b + c; ++a) {}\n"
" for (int a{ 1 }, b(2), c = 3; a < b + c; ++a) {}\n"
" for (int a = 1, b{ 2 }, c(3); a < b + c; ++a) {}\n"
"}\n";
const char expected2[] = "1: void f ( ) {\n"
"2: for ( int a@1 ( 1 ) , b@2 { 2 } , c@3 = 3 ; a@1 < b@2 + c@3 ; ++ a@1 ) { }\n"
"3: for ( int a@4 { 1 } , b@5 ( 2 ) , c@6 = 3 ; a@4 < b@5 + c@6 ; ++ a@4 ) { }\n"
"4: for ( int a@7 = 1 , b@8 { 2 } , c@9 ( 3 ) ; a@7 < b@8 + c@9 ; ++ a@7 ) { }\n"
"5: }\n";
ASSERT_EQUALS(expected2, tokenize(code2));
}

void varid_cpp_keywords_in_c_code() {
const char code[] = "void f() {\n"
" delete d;\n"
Expand Down

0 comments on commit 7b8e8fe

Please sign in to comment.