Skip to content

Commit 84f0028

Browse files
authored
Fix #12462 (False positive: uninitialized data passed by const address, not used in subfunction) (#6115)
1 parent 7134e9e commit 84f0028

2 files changed

Lines changed: 44 additions & 4 deletions

File tree

lib/astutils.cpp

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3282,10 +3282,19 @@ static ExprUsage getFunctionUsage(const Token* tok, int indirect, const Settings
32823282
for (const Variable* arg : args) {
32833283
if (!arg)
32843284
continue;
3285-
if (arg->isReference())
3286-
return ExprUsage::PassedByReference;
3287-
if (arg->isPointer() && indirect == 1)
3288-
return ExprUsage::PassedByReference;
3285+
if (arg->isReference() || (arg->isPointer() && indirect == 1)) {
3286+
if (!ftok->function()->hasBody())
3287+
return ExprUsage::PassedByReference;
3288+
for (const Token* bodytok = ftok->function()->functionScope->bodyStart; bodytok != ftok->function()->functionScope->bodyEnd; bodytok = bodytok->next()) {
3289+
if (bodytok->variable() == arg) {
3290+
if (arg->isReference())
3291+
return ExprUsage::PassedByReference;
3292+
if (Token::Match(bodytok->astParent(), "%comp%|!"))
3293+
return ExprUsage::NotUsed;
3294+
return ExprUsage::PassedByReference;
3295+
}
3296+
}
3297+
}
32893298
}
32903299
if (!args.empty() && indirect == 0 && !addressOf)
32913300
return ExprUsage::Used;

test/testuninitvar.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ class TestUninitVar : public TestFixture {
6464
TEST_CASE(uninitvar2_value); // value flow
6565
TEST_CASE(valueFlowUninit2_value);
6666
TEST_CASE(valueFlowUninit_uninitvar2);
67+
TEST_CASE(valueFlowUninit_functioncall);
6768
TEST_CASE(uninitStructMember); // struct members
6869
TEST_CASE(uninitvar2_while);
6970
TEST_CASE(uninitvar2_4494); // #4494
@@ -4319,6 +4320,36 @@ class TestUninitVar : public TestFixture {
43194320
ASSERT_EQUALS("", errout.str());
43204321
}
43214322

4323+
void valueFlowUninit_functioncall() {
4324+
4325+
// #12462 - pointer data is not read
4326+
valueFlowUninit("struct myst { int a; };\n"
4327+
"void bar(const void* p) {}\n"
4328+
"void foo() {\n"
4329+
" struct myst item;\n"
4330+
" bar(&item);\n"
4331+
"}", "test.c");
4332+
ASSERT_EQUALS("", errout.str());
4333+
4334+
valueFlowUninit("struct myst { int a; };\n"
4335+
"void bar(const void* p) { a = (p != 0); }\n"
4336+
"void foo() {\n"
4337+
" struct myst item;\n"
4338+
" bar(&item);\n"
4339+
" a = item.a;\n" // <- item.a is not initialized
4340+
"}", "test.c");
4341+
ASSERT_EQUALS("[test.c:6]: (error) Uninitialized variable: item.a\n", errout.str());
4342+
4343+
valueFlowUninit("struct myst { int a; };\n"
4344+
"void bar(struct myst* p) { p->a = 0; }\n"
4345+
"void foo() {\n"
4346+
" struct myst item;\n"
4347+
" bar(&item);\n"
4348+
" a = item.a;\n"
4349+
"}", "test.c");
4350+
ASSERT_EQUALS("", errout.str());
4351+
}
4352+
43224353
void uninitStructMember() { // struct members
43234354
checkUninitVar("struct AB { int a; int b; };\n"
43244355
"void f(void) {\n"

0 commit comments

Comments
 (0)