Fixed #10293 (Uninitialized variables; False positive for array in union)

This commit is contained in:
Daniel Marjamäki 2021-05-23 12:06:23 +02:00
parent 85723f8605
commit 8828619855
2 changed files with 16 additions and 7 deletions

View File

@ -1497,10 +1497,8 @@ void CheckUninitVar::valueFlowUninit()
const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase();
// check every executable scope // check every executable scope
for (const Scope &scope : symbolDatabase->scopeList) { for (const Scope *scope : symbolDatabase->functionScopes) {
if (!scope.isExecutable()) for (const Token* tok = scope->bodyStart; tok != scope->bodyEnd; tok = tok->next()) {
continue;
for (const Token* tok = scope.bodyStart; tok != scope.bodyEnd; tok = tok->next()) {
if (isSizeOfEtc(tok)) { if (isSizeOfEtc(tok)) {
tok = tok->linkAt(1); tok = tok->linkAt(1);
continue; continue;
@ -1528,9 +1526,11 @@ void CheckUninitVar::valueFlowUninit()
bool unknown; bool unknown;
const bool isarray = !tok->variable() || tok->variable()->isArray(); const bool isarray = !tok->variable() || tok->variable()->isArray();
const bool ispointer = astIsPointer(tok) && !isarray; const bool ispointer = astIsPointer(tok) && !isarray;
const bool deref = ispointer && CheckNullPointer::isPointerDeRef(tok, unknown, mSettings); const bool deref = CheckNullPointer::isPointerDeRef(tok, unknown, mSettings);
if (v->indirect == 1 && !deref) if (ispointer && v->indirect == 1 && !deref)
continue; continue;
if (isarray && !deref)
continue;
uninitderef = deref && v->indirect == 0; uninitderef = deref && v->indirect == 0;
const bool isleaf = isLeafDot(tok) || uninitderef; const bool isleaf = isLeafDot(tok) || uninitderef;
if (Token::Match(tok->astParent(), ". %var%") && !isleaf) if (Token::Match(tok->astParent(), ". %var%") && !isleaf)
@ -1541,7 +1541,7 @@ void CheckUninitVar::valueFlowUninit()
continue; continue;
uninitvarError(tok, tok->expressionString(), v->errorPath); uninitvarError(tok, tok->expressionString(), v->errorPath);
const Token* nextTok = nextAfterAstRightmostLeaf(parent); const Token* nextTok = nextAfterAstRightmostLeaf(parent);
if (nextTok == scope.bodyEnd) if (nextTok == scope->bodyEnd)
break; break;
tok = nextTok ? nextTok : tok; tok = nextTok ? nextTok : tok;
} }

View File

@ -4769,6 +4769,15 @@ private:
"}"); "}");
ASSERT_EQUALS("[test.cpp:7]: (error) Uninitialized variable: flags\n", errout.str()); ASSERT_EQUALS("[test.cpp:7]: (error) Uninitialized variable: flags\n", errout.str());
valueFlowUninit("void foo() {\n" // #10293
" union {\n"
" struct hdr cm;\n"
" char control[123];\n"
" } u;\n"
" char *x = u.control;\n" // <- no error
"}");
ASSERT_EQUALS("", errout.str());
valueFlowUninit("struct pc_data {\n" valueFlowUninit("struct pc_data {\n"
" struct {\n" " struct {\n"
" char * strefa;\n" " char * strefa;\n"