Skip to content

Commit 1af83ad

Browse files
authored
Fix #12091 (False negative: Uninitialized variable read in subfunction (regression)) (#5739)
1 parent f5109df commit 1af83ad

4 files changed

Lines changed: 28 additions & 11 deletions

File tree

lib/valueflow.cpp

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7325,9 +7325,16 @@ struct MultiValueFlowAnalyzer : ValueFlowAnalyzer {
73257325
return false;
73267326
}
73277327

7328-
bool stopOnCondition(const Token* /*condTok*/) const override {
7329-
// TODO fix false negatives
7330-
return true; // isConditional();
7328+
bool stopOnCondition(const Token* condTok) const override {
7329+
if (isConditional())
7330+
return true;
7331+
if (!condTok->hasKnownIntValue() && values.count(condTok->varId()) == 0) {
7332+
const auto& values_ = condTok->values();
7333+
return std::any_of(values_.cbegin(), values_.cend(), [](const ValueFlow::Value& v) {
7334+
return v.isSymbolicValue() && Token::Match(v.tokvalue, "%oror%|&&");
7335+
});
7336+
}
7337+
return false;
73317338
}
73327339

73337340
bool updateScope(const Token* endBlock, bool /*modified*/) const override {

test/teststl.cpp

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2403,12 +2403,11 @@ class TestStl : public TestFixture {
24032403
"void g(const std::vector<int>& w) {\n"
24042404
" f(-1, w);\n"
24052405
"}\n");
2406-
TODO_ASSERT_EQUALS("test.cpp:5:warning:Array index -1 is out of bounds.\n"
2407-
"test.cpp:8:note:Calling function 'f', 1st argument '-1' value is -1\n"
2408-
"test.cpp:3:note:Assuming condition is false\n"
2409-
"test.cpp:5:note:Negative array index\n",
2410-
"",
2411-
errout.str());
2406+
ASSERT_EQUALS("test.cpp:5:warning:Array index -1 is out of bounds.\n"
2407+
"test.cpp:8:note:Calling function 'f', 1st argument '-1' value is -1\n"
2408+
"test.cpp:3:note:Assuming condition is false\n"
2409+
"test.cpp:5:note:Negative array index\n",
2410+
errout.str());
24122411

24132412
settings = oldSettings;
24142413
}

test/testuninitvar.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6587,7 +6587,7 @@ class TestUninitVar : public TestFixture {
65876587
" bool copied_all = true;\n"
65886588
" g(&copied_all, 5, 6, &bytesCopied);\n"
65896589
"}");
6590-
TODO_ASSERT_EQUALS("[test.cpp:7] -> [test.cpp:2]: (warning) Uninitialized variable: *buflen\n", "", errout.str());
6590+
ASSERT_EQUALS("[test.cpp:7] -> [test.cpp:2]: (warning) Uninitialized variable: *buflen\n", errout.str());
65916591

65926592
// # 9953
65936593
valueFlowUninit("uint32_t f(uint8_t *mem) {\n"

test/testvalueflow.cpp

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4511,7 +4511,7 @@ class TestValueFlow : public TestFixture {
45114511
"void f(Object *obj) {\n"
45124512
" if (valid(obj, K0)) {}\n"
45134513
"}\n";
4514-
TODO_ASSERT_EQUALS(true, false, testValueOfX(code, 7U, 0));
4514+
ASSERT_EQUALS(true, testValueOfX(code, 7U, 0));
45154515
ASSERT_EQUALS(false, testValueOfXKnown(code, 7U, 0));
45164516

45174517
code = "int f(int i) {\n"
@@ -5624,6 +5624,17 @@ class TestValueFlow : public TestFixture {
56245624
"}\n";
56255625
values = tokenValues(code, "x <", ValueFlow::Value::ValueType::UNINIT);
56265626
ASSERT_EQUALS(0, values.size());
5627+
5628+
code = "void g(bool *result, size_t *buflen) {\n" // #12091
5629+
" if (*result && *buflen >= 5) {}\n" // <- *buflen might not be initialized
5630+
"}\n"
5631+
"void f() {\n"
5632+
" size_t bytesCopied;\n"
5633+
" bool copied_all = true;\n"
5634+
" g(&copied_all, &bytesCopied);\n"
5635+
"}";
5636+
values = tokenValues(code, "buflen >=", ValueFlow::Value::ValueType::UNINIT);
5637+
ASSERT_EQUALS(1, values.size());
56275638
}
56285639

56295640
void valueFlowConditionExpressions() {

0 commit comments

Comments
 (0)