Skip to content

Commit c2d3611

Browse files
committed
Fix #13685 FP uinitvar with nested compound statement scopes
PR #6714 introduced a regression in which variables initialized in nested compound statements are incorrectly flagged as uninitialized by uninitvar. Such scopes could be present due to usage of GNU compound statements.
1 parent 2dac535 commit c2d3611

2 files changed

Lines changed: 21 additions & 5 deletions

File tree

lib/symboldatabase.cpp

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@ void SymbolDatabase::createSymbolDatabaseFindAllScopes()
160160
};
161161

162162
std::stack<const Token*> inIfCondition;
163+
std::stack<Scope*> pendingIfScopes;
163164

164165
auto addLambda = [this, &scope](const Token* tok, const Token* lambdaEndToken) -> const Token* {
165166
const Token* lambdaStartToken = lambdaEndToken->link();
@@ -766,13 +767,14 @@ void SymbolDatabase::createSymbolDatabaseFindAllScopes()
766767
scopeList.emplace_back(*this, tok, scope, ScopeType::eSwitch, scopeStartTok);
767768

768769
scope->nestedList.push_back(&scopeList.back());
769-
scope = &scopeList.back();
770-
if (scope->type == ScopeType::eFor)
771-
scope->checkVariable(tok->tokAt(2), AccessControl::Local); // check for variable declaration and add it to new scope if found
772-
else if (scope->type == ScopeType::eCatch)
773-
scope->checkVariable(tok->tokAt(2), AccessControl::Throw); // check for variable declaration and add it to new scope if found
770+
Scope* newScope = &scopeList.back();
771+
if (newScope->type == ScopeType::eFor)
772+
newScope->checkVariable(tok->tokAt(2), AccessControl::Local); // check for variable declaration and add it to new scope if found
773+
else if (newScope->type == ScopeType::eCatch)
774+
newScope->checkVariable(tok->tokAt(2), AccessControl::Throw); // check for variable declaration and add it to new scope if found
774775
tok = tok->next();
775776
inIfCondition.push(scopeStartTok);
777+
pendingIfScopes.push(newScope);
776778
} else if (Token::Match(tok, "%var% {")) {
777779
endInitList.emplace(tok->linkAt(1), scope);
778780
tok = tok->next();
@@ -783,6 +785,8 @@ void SymbolDatabase::createSymbolDatabaseFindAllScopes()
783785
endInitList.emplace(tok->link(), scope);
784786
} else if (!inIfCondition.empty() && tok == inIfCondition.top()) {
785787
inIfCondition.pop();
788+
scope = pendingIfScopes.top();
789+
pendingIfScopes.pop();
786790
} else if (isExecutableScope(tok)) {
787791
scopeList.emplace_back(*this, tok, scope, ScopeType::eUnconditional, tok);
788792
scope->nestedList.push_back(&scopeList.back());

test/testuninitvar.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ class TestUninitVar : public TestFixture {
7676
TEST_CASE(uninitvar12); // #10218 - stream read
7777
TEST_CASE(uninitvar13); // #9772
7878
TEST_CASE(uninitvar14);
79+
TEST_CASE(uninitvar15); // #13685
7980
TEST_CASE(uninitvar_unconditionalTry);
8081
TEST_CASE(uninitvar_funcptr); // #6404
8182
TEST_CASE(uninitvar_operator); // #6680
@@ -3647,6 +3648,17 @@ class TestUninitVar : public TestFixture {
36473648
(checkuninitvar.valueFlowUninit)();
36483649
}
36493650

3651+
void uninitvar15() { // #13685
3652+
const char code[] = "int f() {\n"
3653+
" int x;\n"
3654+
" if (!({ int *p = &x; *p = 1; 1; }))\n"
3655+
" return 0;\n"
3656+
" return x;\n"
3657+
"}";
3658+
valueFlowUninit(code, false);
3659+
ASSERT_EQUALS("", errout_str());
3660+
}
3661+
36503662
void valueFlowUninit2_value()
36513663
{
36523664
valueFlowUninit("void f() {\n"

0 commit comments

Comments
 (0)