diff --git a/lib/checkother.cpp b/lib/checkother.cpp index b9ff731b0ce..f7e6f2f956b 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -4446,7 +4446,7 @@ void CheckOtherImpl::checkKnownPointerToBool() for (const Token* tok = functionScope->bodyStart; tok != functionScope->bodyEnd; tok = tok->next()) { if (!tok->hasKnownIntValue()) continue; - if (!astIsPointer(tok)) + if (!astIsPointer(tok) && !tok->function()) continue; if (Token::Match(tok->astParent(), "?|!|&&|%oror%|%comp%")) continue; diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index aa0b2c91c29..f61b9efff0b 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -1178,6 +1178,10 @@ static void valueFlowImpossibleValues(TokenList& tokenList, const Settings& sett ValueFlow::Value value{0}; value.setImpossible(); setTokenValue(tok, std::move(value), settings); + } else if (tok->function() && tok->scope()->isExecutable()) { + ValueFlow::Value value{0}; + value.setImpossible(); + setTokenValue(tok, std::move(value), settings); } } } @@ -5162,7 +5166,8 @@ 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))) { + (astIsPointer(tok) && isUsedAsBool(tok, settings)) || + tok->function()) { std::vector result = infer(makeIntegralInferModel(), "!=", tok->values(), 0); if (result.size() != 1) continue; diff --git a/test/testcondition.cpp b/test/testcondition.cpp index c7f39584939..2389d5a994f 100644 --- a/test/testcondition.cpp +++ b/test/testcondition.cpp @@ -5503,6 +5503,19 @@ class TestCondition : public TestFixture { " std::size_t x;\n" "};\n"); ASSERT_EQUALS("", errout_str()); + + check("int g();\n" // #13441 + "void f() {\n" + " int (*p)() = g;\n" + " if (p == nullptr) {}\n" + " if (g == nullptr) {}\n" + " 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()); } void alwaysTrueContainer() { diff --git a/test/testother.cpp b/test/testother.cpp index d115acc2163..acc2f1ec01a 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -14055,6 +14055,12 @@ class TestOther : public TestFixture { " g(b);\n" "}\n"); ASSERT_EQUALS("", errout_str()); + + check("void g(bool);\n" // #14303 + "void f() {\n" + " g(g);\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:3:7]: (style) Pointer expression 'g' converted to bool is always true. [knownPointerToBool]\n", errout_str()); } void iterateByValue() {