Skip to content

Commit

Permalink
Fix #11353 FP uninitvar for struct member set via pointer
Browse files Browse the repository at this point in the history
  • Loading branch information
chrchr-github committed Aug 11, 2023
1 parent 23deadb commit b452d70
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 7 deletions.
12 changes: 10 additions & 2 deletions lib/valueflow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3295,6 +3295,12 @@ struct MemberExpressionAnalyzer : SubExpressionAnalyzer {
: SubExpressionAnalyzer(e, std::move(val), t, s), varname(std::move(varname))
{}

bool match(const Token* tok) const override
{
return SubExpressionAnalyzer::match(tok) ||
(Token::simpleMatch(tok->astParent(), ".") && SubExpressionAnalyzer::match(tok->astParent()));
}

bool submatch(const Token* tok, bool exact) const override
{
if (!Token::Match(tok, ". %var%"))
Expand Down Expand Up @@ -7965,6 +7971,7 @@ static void valueFlowUninit(TokenList& tokenlist, const Settings* settings)
Token* start = findStartToken(var, tok->next(), &settings->library);

std::map<Token*, ValueFlow::Value> partialReads;
Analyzer::Result result;
if (const Scope* scope = var->typeScope()) {
if (Token::findsimplematch(scope->bodyStart, "union", scope->bodyEnd))
continue;
Expand All @@ -7979,7 +7986,7 @@ static void valueFlowUninit(TokenList& tokenlist, const Settings* settings)
continue;
}
MemberExpressionAnalyzer analyzer(memVar.nameToken()->str(), tok, uninitValue, tokenlist, settings);
valueFlowGenericForward(start, tok->scope()->bodyEnd, analyzer, *settings);
result = valueFlowGenericForward(start, tok->scope()->bodyEnd, analyzer, *settings);

for (auto&& p : *analyzer.partialReads) {
Token* tok2 = p.first;
Expand Down Expand Up @@ -8009,7 +8016,8 @@ static void valueFlowUninit(TokenList& tokenlist, const Settings* settings)
if (partial)
continue;

valueFlowForward(start, tok->scope()->bodyEnd, var->nameToken(), uninitValue, tokenlist, settings);
if (result.terminate != Analyzer::Terminate::Modified)
valueFlowForward(start, tok->scope()->bodyEnd, var->nameToken(), uninitValue, tokenlist, settings);
}
}

Expand Down
19 changes: 14 additions & 5 deletions test/testuninitvar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6139,7 +6139,7 @@ class TestUninitVar : public TestFixture {
" memcpy(wcsin, x, sizeof(wcsstruct));\n" // <- warning
" x->wcsprm = NULL;\n" // <- no warning
"}");
ASSERT_EQUALS("[test.cpp:7]: (error) Uninitialized variable: x\n", errout.str());
ASSERT_EQUALS("[test.cpp:7]: (error) Uninitialized variable: x.wcsprm\n", errout.str());

valueFlowUninit("struct wcsstruct {\n"
" int *wcsprm;\n"
Expand Down Expand Up @@ -6222,7 +6222,7 @@ class TestUninitVar : public TestFixture {
" int * x = &s1.x;\n"
" struct S s2 = {*x, 0};\n"
"}");
ASSERT_EQUALS("[test.cpp:8] -> [test.cpp:9]: (error) Uninitialized variable: *x\n", errout.str());
ASSERT_EQUALS("[test.cpp:9]: (error) Uninitialized variable: *x\n", errout.str());

valueFlowUninit("struct S {\n"
" int x;\n"
Expand Down Expand Up @@ -6855,7 +6855,7 @@ class TestUninitVar : public TestFixture {
" int a = ab.a;\n"
" int b = ab.b;\n"
"}");
TODO_ASSERT_EQUALS("[test.cpp:5]: (error) Uninitialized variable: ab.b\n", "", errout.str());
ASSERT_EQUALS("[test.cpp:5]: (error) Uninitialized variable: ab.b\n", errout.str());

// STL class member
valueFlowUninit("struct A {\n"
Expand Down Expand Up @@ -6967,7 +6967,7 @@ class TestUninitVar : public TestFixture {
" memcpy(in, s, sizeof(S));\n"
" s->p = NULL;\n"
"}\n");
ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: s\n",
ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: s.p\n",
errout.str());

valueFlowUninit("struct S {\n" // #11321
Expand Down Expand Up @@ -7228,7 +7228,7 @@ class TestUninitVar : public TestFixture {
" A::B b;\n"
" x.push_back(b);\n"
"}\n");
ASSERT_EQUALS("[test.cpp:9]: (error) Uninitialized variable: b\n", errout.str());
ASSERT_EQUALS("[test.cpp:9]: (error) Uninitialized variable: b.i\n", errout.str());

valueFlowUninit("struct A {\n"
" struct B {\n"
Expand Down Expand Up @@ -7272,6 +7272,15 @@ class TestUninitVar : public TestFixture {
" int y = x < (1, s.i);\n"
"}\n");
ASSERT_EQUALS("[test.cpp:5]: (error) Uninitialized variable: s.i\n", errout.str());

valueFlowUninit("struct S { int x; };\n" // #11353
"struct S f() {\n"
" struct S s;\n"
" int* p = &s.x;\n"
" *p = 0;\n"
" return s;\n"
"}\n");
ASSERT_EQUALS("", errout.str());
}

void ctu_(const char* file, int line, const char code[]) {
Expand Down

0 comments on commit b452d70

Please sign in to comment.