From 1556569a078cc1617fdcbfda7ca29c196e2d1738 Mon Sep 17 00:00:00 2001 From: chrchr-github Date: Mon, 5 Oct 2026 18:52:33 +0200 Subject: [PATCH] Fixup #14303: Function pointers are not known to be 1 --- lib/astutils.cpp | 2 +- lib/valueflow.cpp | 3 +-- test/testcondition.cpp | 10 ++++++---- test/testvalueflow.cpp | 10 ++++++++++ 4 files changed, 18 insertions(+), 7 deletions(-) diff --git a/lib/astutils.cpp b/lib/astutils.cpp index 4ebbc8644da..31c8d2e0e2d 100644 --- a/lib/astutils.cpp +++ b/lib/astutils.cpp @@ -1554,7 +1554,7 @@ bool isUsedAsBool(const Token* const tok, const Settings& settings) return true; if (parent->isCast()) return !Token::simpleMatch(parent->astOperand1(), "dynamic_cast") && isUsedAsBool(parent, settings); - if (Token::Match(parent, "==|!=") && tok->valueType() && tok->valueType()->pointer && + if (Token::Match(parent, "==|!=") && ((tok->valueType() && tok->valueType()->pointer) || tok->function()) && tok->astSibling()->hasKnownIntValue() && tok->astSibling()->getKnownIntValue() == 0) return true; if (parent->str() == "(" && astIsRHS(tok) && Token::Match(parent->astOperand1(), "if|while")) diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index baa279803cf..c021d1d296b 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -5166,8 +5166,7 @@ static void valueFlowInferCondition(TokenList& tokenlist, const Settings& settin } } else if (Token::Match(tok->astParent(), "?|&&|!|%oror%") || Token::Match(tok->astParent()->previous(), "if|while (") || - (astIsPointer(tok) && isUsedAsBool(tok, settings)) || - tok->function()) { + ((astIsPointer(tok) || tok->function()) && isUsedAsBool(tok, settings))) { std::vector result = infer(makeIntegralInferModel(), "!=", tok->values(), 0); if (result.size() != 1) continue; diff --git a/test/testcondition.cpp b/test/testcondition.cpp index 4d989804b36..93248837cb3 100644 --- a/test/testcondition.cpp +++ b/test/testcondition.cpp @@ -5518,10 +5518,12 @@ class TestCondition : public TestFixture { " auto q = g;\n" " if (q == nullptr) {}\n" "};\n"); - ASSERT_EQUALS("[test.cpp:4:11]: (style) Condition 'p==nullptr' is always false [knownConditionTrueFalse]\n" - "[test.cpp:5:11]: (style) Condition 'g==nullptr' is always false [knownConditionTrueFalse]\n" - "[test.cpp:7:11]: (style) Condition 'q==nullptr' is always false [knownConditionTrueFalse]\n", - errout_str()); + TODO_ASSERT_EQUALS("[test.cpp:4:11]: (style) Condition 'p==nullptr' is always false [knownConditionTrueFalse]\n" + "[test.cpp:5:11]: (style) Condition 'g==nullptr' is always false [knownConditionTrueFalse]\n" + "[test.cpp:7:11]: (style) Condition 'q==nullptr' is always false [knownConditionTrueFalse]\n", + "[test.cpp:4:11]: (style) Condition 'p==nullptr' is always false [knownConditionTrueFalse]\n" + "[test.cpp:5:11]: (style) Condition 'g==nullptr' is always false [knownConditionTrueFalse]\n", + errout_str()); } void alwaysTrueContainer() { diff --git a/test/testvalueflow.cpp b/test/testvalueflow.cpp index b192a34eb7f..f84f0ea0d89 100644 --- a/test/testvalueflow.cpp +++ b/test/testvalueflow.cpp @@ -3286,6 +3286,16 @@ class TestValueFlow : public TestFixture { " }\n" "};\n"; ASSERT_EQUALS(false, testValueOfXKnown(code, 7U, 0)); + + code = "int g() { return 0; }\n" + "int f() {\n" + " int (*x)() = g;\n" + " return x();\n" + "}\n"; + auto values = tokenValues(code, "x ("); + ASSERT_EQUALS(1U, values.size()); + ASSERT(values.front().isImpossible()); + ASSERT_EQUALS(0, values.front().intvalue); } void valueFlowAfterSwap()