diff --git a/lib/checknullpointer.cpp b/lib/checknullpointer.cpp index 5c2e64e9a6c..2251d50e1e7 100644 --- a/lib/checknullpointer.cpp +++ b/lib/checknullpointer.cpp @@ -454,7 +454,7 @@ void CheckNullPointerImpl::nullPointerError(const Token *tok, const std::string } else if (value->defaultArg) { reportError(std::move(errorPath), Severity::warning, "nullPointerDefaultArg", errmsgdefarg, CWE_NULL_POINTER_DEREFERENCE, inconclusive || value->isInconclusive() ? Certainty::inconclusive : Certainty::normal); } else { - std::string errmsg = std::string(value->isKnown() ? "Null" : "Possible null") + " pointer dereference"; + std::string errmsg = std::string(value->isKnown() && !value->conditional ? "Null" : "Possible null") + " pointer dereference"; std::string id = "nullPointer"; if (value->unknownFunctionReturn == ValueFlow::Value::UnknownFunctionReturn::outOfMemory) { @@ -470,7 +470,7 @@ void CheckNullPointerImpl::nullPointerError(const Token *tok, const std::string errmsg = "$symbol:" + varname + '\n' + errmsg + ": $symbol"; reportError(std::move(errorPath), - value->isKnown() ? Severity::error : Severity::warning, + value->isKnown() && !value->conditional ? Severity::error : Severity::warning, id.c_str(), errmsg, CWE_NULL_POINTER_DEREFERENCE, inconclusive || value->isInconclusive() ? Certainty::inconclusive : Certainty::normal); diff --git a/test/testnullpointer.cpp b/test/testnullpointer.cpp index ca5c183c911..741f54ba76a 100644 --- a/test/testnullpointer.cpp +++ b/test/testnullpointer.cpp @@ -173,6 +173,7 @@ class TestNullPointer : public TestFixture { TEST_CASE(nullpointerSmartPointer); TEST_CASE(nullpointerOutOfMemory); TEST_CASE(nullpointerOutOfResources); + TEST_CASE(nullpointerErrorPath); TEST_CASE(functioncall); TEST_CASE(functioncalllibrary); // use Library to parse function call TEST_CASE(functioncallDefaultArguments); @@ -2488,7 +2489,7 @@ class TestNullPointer : public TestFixture { " *p = 0;\n" " }\n" "}\n"); - ASSERT_EQUALS("[test.cpp:4:10]: (error) Null pointer dereference: p [nullPointer]\n", errout_str()); + ASSERT_EQUALS("[test.cpp:4:10]: (warning) Possible null pointer dereference: p [nullPointer]\n", errout_str()); } void nullpointer78() // #7802 @@ -4100,10 +4101,10 @@ class TestNullPointer : public TestFixture { " foo(p == s2);\n" " foo(p == s3);\n" "}\n", dinit(CheckOptions, $.inconclusive = true)); - ASSERT_EQUALS("[test.cpp:4:15]: (error) Null pointer dereference: p [nullPointer]\n" - "[test.cpp:5:15]: (error) Null pointer dereference: p [nullPointer]\n" - "[test.cpp:7:9]: (error) Null pointer dereference: p [nullPointer]\n" - "[test.cpp:8:9]: (error) Null pointer dereference: p [nullPointer]\n", errout_str()); + ASSERT_EQUALS("[test.cpp:4:15]: (warning) Possible null pointer dereference: p [nullPointer]\n" + "[test.cpp:5:15]: (warning) Possible null pointer dereference: p [nullPointer]\n" + "[test.cpp:7:9]: (warning) Possible null pointer dereference: p [nullPointer]\n" + "[test.cpp:8:9]: (warning) Possible null pointer dereference: p [nullPointer]\n", errout_str()); check("void f(std::string s1, const std::string& s2, const std::string* s3) {\n" " void* p = 0;\n" @@ -4586,6 +4587,23 @@ class TestNullPointer : public TestFixture { errout_str()); } + void nullpointerErrorPath() { + setMultiline(); + + check("int f(bool b) {\n" + " int* p = nullptr;\n" + " if (b)\n" + " return 0;\n" + " return *p;\n" + "}\n"); + ASSERT_EQUALS( + "[test.cpp:5:13]: warning: Possible null pointer dereference: p [nullPointer]\n" + "[test.cpp:2:14]: note: Assignment 'p=nullptr', assigned value is 0\n" + "[test.cpp:3:9]: note: Assuming condition is false\n" + "[test.cpp:5:13]: note: Null pointer dereference\n", + errout_str()); + } + void functioncalllibrary() { SimpleTokenizer tokenizer(settingsDefault,*this,false); const char code[] = "void f() { int a,b,c; x(a,b,c); }\n";