Skip to content

Commit 4e0a568

Browse files
Fix #14369: Move boolean literal evaluation to valueFlowSetConstantValue (#8468)
Previously, boolean literals were processed in a separate loop after valueFlowSetConstantValue. This triggered nullPointer FP with code such as: int f() { const int* p = true ? new int() : nullptr; return *p; // nullPointer FP } Because the condition token had no known value, both branches of the ternary operator were treated as possible, leaking a spurious null value. --------- Signed-off-by: Francois Berder <fberder@outlook.fr>
1 parent bafada0 commit 4e0a568

3 files changed

Lines changed: 16 additions & 6 deletions

File tree

lib/valueflow.cpp

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -430,12 +430,7 @@ static void valueFlowNumber(TokenList &tokenlist, const Settings& settings)
430430

431431
if (tokenlist.isCPP() || settings.standards.c >= Standards::C23) {
432432
for (Token *tok = tokenlist.front(); tok; tok = tok->next()) {
433-
if (tok->isName() && !tok->varId() && Token::Match(tok, "%bool%")) {
434-
ValueFlow::Value value(tok->str() == "true");
435-
if (!tok->isTemplateArg())
436-
value.setKnown();
437-
setTokenValue(tok, std::move(value), settings);
438-
} else if (Token::Match(tok, "[(,] NULL [,)]")) {
433+
if (Token::Match(tok, "[(,] NULL [,)]")) {
439434
// NULL function parameters are not simplified in the
440435
// normal tokenlist
441436
ValueFlow::Value value(0);

lib/vf_common.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,11 @@ namespace ValueFlow
154154
if (!tok->isTemplateArg())
155155
value.setKnown();
156156
setTokenValue(tok, std::move(value), settings);
157+
} else if ((tok->isCpp() || settings.standards.c >= Standards::C23) && (tok->isName() && tok->varId() == 0 && Token::Match(tok, "%bool%"))) {
158+
Value value(tok->str() == "true");
159+
if (!tok->isTemplateArg())
160+
value.setKnown();
161+
setTokenValue(tok, std::move(value), settings);
157162
} else if (Token::simpleMatch(tok, "sizeof (")) {
158163
if (tok->next()->astOperand2() && !tok->next()->astOperand2()->isLiteral() && tok->next()->astOperand2()->valueType() &&
159164
(tok->next()->astOperand2()->valueType()->pointer == 0 || // <- TODO this is a bailout, abort when there are array->pointer conversions

test/testvalueflow.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1207,6 +1207,16 @@ class TestValueFlow : public TestFixture {
12071207
ASSERT_EQUALS(1U, values.size());
12081208
ASSERT_EQUALS(123, values.empty() ? 0 : values.front().intvalue);
12091209

1210+
code = "x = true ? 2 : 3;\n"; // #14369
1211+
values = tokenValues(code, "?");
1212+
ASSERT_EQUALS(1U, values.size());
1213+
ASSERT_EQUALS(2, values.empty() ? 0 : values.front().intvalue);
1214+
1215+
code = "x = false ? 2 : 3;\n"; // #14369
1216+
values = tokenValues(code, "?");
1217+
ASSERT_EQUALS(1U, values.size());
1218+
ASSERT_EQUALS(3, values.empty() ? 0 : values.front().intvalue);
1219+
12101220
code = "int f() {\n"
12111221
" const int i = 1;\n"
12121222
" int x = i < 0 ? 0 : 1;\n"

0 commit comments

Comments
 (0)