Skip to content

Commit

Permalink
Fix 12461: False positive: uninitialized buffer, address of and funct…
Browse files Browse the repository at this point in the history
…ion call with nested array
  • Loading branch information
pfultz2 committed Apr 26, 2024
1 parent b7360ce commit cd3d704
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 6 deletions.
17 changes: 11 additions & 6 deletions lib/astutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -632,6 +632,13 @@ static std::vector<const Token*> getParentMembers(const Token* tok)
return result;
}

static const Token* getParentLifetimeObject(const Token* tok)
{
while(Token::simpleMatch(tok, "["))
tok = tok->astOperand1();
return tok;
}

const Token* getParentLifetime(const Token* tok, const Library& library)
{
std::vector<const Token*> members = getParentMembers(tok);
Expand All @@ -650,9 +657,7 @@ const Token* getParentLifetime(const Token* tok, const Library& library)
return tok;
// If any of the submembers are borrowed types then stop
if (std::any_of(it.base() - 1, members.cend() - 1, [&](const Token* tok2) {
const Token* obj = tok2;
if (Token::simpleMatch(obj, "["))
obj = tok2->astOperand1();
const Token* obj = getParentLifetimeObject(tok2);
const Variable* var = obj->variable();
// Check for arrays first since astIsPointer will return true, but an array is not a borrowed type
if (var && var->isArray())
Expand All @@ -679,9 +684,9 @@ const Token* getParentLifetime(const Token* tok, const Library& library)
return var && var->isReference();
}))
return nullptr;
const Token* result = *it;
if (Token::simpleMatch(result, "[") && result->astOperand1())
return getParentLifetime(result->astOperand1());
const Token* result = getParentLifetimeObject(*it);
if (result != *it)
return getParentLifetime(result);
return result;
}

Expand Down
13 changes: 13 additions & 0 deletions test/testuninitvar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7503,6 +7503,19 @@ class TestUninitVar : public TestFixture {
"}\n");
ASSERT_EQUALS("[test.cpp:8]: (error) Uninitialized variable: arr\n", errout_str());

valueFlowUninit("struct S {\n"
" void *out;\n"
"};\n"
"void bar(S* s);\n"
"void foo() {\n"
" S s[1][1];\n"
" char arr[5];\n"
" s[0][0].out = &arr;\n"
" bar(s[0]);\n"
" int len = strlen(arr);\n"
"}\n");
ASSERT_EQUALS("", errout_str());

valueFlowUninit("struct S1 { int x; };\n" // #12401
"struct S2 { struct S1 s1; };\n"
"struct S2 f() {\n"
Expand Down

0 comments on commit cd3d704

Please sign in to comment.