From 923f7f843d745a91a3d4b883d6166f5db844d9c3 Mon Sep 17 00:00:00 2001 From: PKEuS Date: Sat, 30 Jan 2016 20:43:21 +0100 Subject: [PATCH] Better distinguishing between possible and known null pointer dereferenciations (#7157) --- lib/checknullpointer.cpp | 15 ++++++---- lib/checknullpointer.h | 8 ++--- test/testnullpointer.cpp | 63 ++++++++++++++++++---------------------- 3 files changed, 42 insertions(+), 44 deletions(-) diff --git a/lib/checknullpointer.cpp b/lib/checknullpointer.cpp index b375c402d..7f6b7590d 100644 --- a/lib/checknullpointer.cpp +++ b/lib/checknullpointer.cpp @@ -291,7 +291,7 @@ void CheckNullPointer::nullPointerLinkedList() // for statement. for (const Token *tok4 = scope->classStart; tok4; tok4 = tok4->next()) { if (tok4 == i->classEnd) { - nullPointerError(tok1, var->name(), scope->classDef); + nullPointerError(tok1, var->name(), scope->classDef, false); break; } @@ -345,7 +345,7 @@ void CheckNullPointer::nullPointerByDeRefAndChec() parseFunctionCall(*ftok->previous(), varlist, &_settings->library, 0); if (std::find(varlist.begin(), varlist.end(), tok) != varlist.end()) { if (value->condition == nullptr) - nullPointerError(tok, tok->str(), false, value->defaultArg); + nullPointerError(tok, tok->str(), false, value->defaultArg, !value->isKnown()); else if (printWarnings) nullPointerError(tok, tok->str(), value->condition, value->inconclusive); } @@ -357,7 +357,7 @@ void CheckNullPointer::nullPointerByDeRefAndChec() if (!isPointerDeRef(tok,unknown)) { if (printInconclusive && unknown) { if (value->condition == nullptr) - nullPointerError(tok, tok->str(), true, value->defaultArg); + nullPointerError(tok, tok->str(), true, value->defaultArg, !value->isKnown()); else nullPointerError(tok, tok->str(), value->condition, true); } @@ -365,7 +365,7 @@ void CheckNullPointer::nullPointerByDeRefAndChec() } if (value->condition == nullptr) - nullPointerError(tok, tok->str(), value->inconclusive, value->defaultArg); + nullPointerError(tok, tok->str(), value->inconclusive, value->defaultArg, !value->isKnown()); else if (printWarnings) nullPointerError(tok, tok->str(), value->condition, value->inconclusive); } @@ -471,13 +471,16 @@ void CheckNullPointer::nullPointerError(const Token *tok) reportError(tok, Severity::error, "nullPointer", "Null pointer dereference", CWE476, false); } -void CheckNullPointer::nullPointerError(const Token *tok, const std::string &varname, bool inconclusive, bool defaultArg) +void CheckNullPointer::nullPointerError(const Token *tok, const std::string &varname, bool inconclusive, bool defaultArg, bool possible) { if (defaultArg) { if (_settings->isEnabled("warning")) reportError(tok, Severity::warning, "nullPointerDefaultArg", "Possible null pointer dereference if the default parameter value is used: " + varname, CWE(0U), inconclusive); + } else if (possible) { + if (_settings->isEnabled("warning")) + reportError(tok, Severity::warning, "nullPointer", "Possible null pointer dereference: " + varname, CWE476, inconclusive); } else - reportError(tok, Severity::error, "nullPointer", "Possible null pointer dereference: " + varname, CWE476, inconclusive); + reportError(tok, Severity::error, "nullPointer", "Null pointer dereference: " + varname, CWE476, inconclusive); } void CheckNullPointer::nullPointerError(const Token *tok, const std::string &varname, const Token* nullCheck, bool inconclusive) diff --git a/lib/checknullpointer.h b/lib/checknullpointer.h index 54e728430..7d545429f 100644 --- a/lib/checknullpointer.h +++ b/lib/checknullpointer.h @@ -86,16 +86,16 @@ public: void nullConstantDereference(); void nullPointerError(const Token *tok); // variable name unknown / doesn't exist - void nullPointerError(const Token *tok, const std::string &varname, bool inconclusive = false, bool defaultArg = false); - void nullPointerError(const Token *tok, const std::string &varname, const Token* nullcheck, bool inconclusive = false); + void nullPointerError(const Token *tok, const std::string &varname, bool inconclusive, bool defaultArg, bool possible); + void nullPointerError(const Token *tok, const std::string &varname, const Token* nullcheck, bool inconclusive); private: /** Get error messages. Used by --errorlist */ void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const { CheckNullPointer c(0, settings, errorLogger); c.nullPointerError(0); - c.nullPointerError(0, "pointer", false, true); - c.nullPointerError(0, "pointer", nullptr); + c.nullPointerError(0, "pointer", false, true, true); + c.nullPointerError(0, "pointer", nullptr, false); } /** Name of check */ diff --git a/test/testnullpointer.cpp b/test/testnullpointer.cpp index 3f4794212..68b775f17 100644 --- a/test/testnullpointer.cpp +++ b/test/testnullpointer.cpp @@ -892,7 +892,7 @@ private: // inconclusive=true => error check(code, true); - ASSERT_EQUALS("[test.cpp:3]: (error, inconclusive) Possible null pointer dereference: abc\n", errout.str()); + ASSERT_EQUALS("[test.cpp:3]: (error, inconclusive) Null pointer dereference: abc\n", errout.str()); } check("static void foo() {\n" @@ -908,7 +908,7 @@ private: " }\n" " c[0] = 0;\n" "}"); - ASSERT_EQUALS("[test.cpp:7]: (error) Possible null pointer dereference: c\n", errout.str()); + ASSERT_EQUALS("[test.cpp:7]: (error) Null pointer dereference: c\n", errout.str()); check("static void foo() {\n" " if (3 > *0);\n" @@ -970,7 +970,7 @@ private: " *Q=1;\n" " return Q;\n" "}"); - ASSERT_EQUALS("[test.cpp:12]: (error) Possible null pointer dereference: Q\n", errout.str()); + ASSERT_EQUALS("[test.cpp:12]: (warning) Possible null pointer dereference: Q\n", errout.str()); // Ticket #2052 (false positive for 'else continue;') check("void f() {\n" @@ -990,7 +990,7 @@ private: " f = 0;\n" " f();\n" "}"); - ASSERT_EQUALS("[test.cpp:5]: (error) Possible null pointer dereference: f\n", errout.str()); + ASSERT_EQUALS("[test.cpp:5]: (error) Null pointer dereference: f\n", errout.str()); // loops.. check("void f() {\n" @@ -999,7 +999,7 @@ private: " int x = *p + 1;\n" " }\n" "}"); - ASSERT_EQUALS("[test.cpp:4]: (error) Possible null pointer dereference: p\n", errout.str()); + ASSERT_EQUALS("[test.cpp:4]: (error) Null pointer dereference: p\n", errout.str()); check("void f(int a) {\n" " const char *p = 0;\n" @@ -1098,7 +1098,7 @@ private: "\n" " *p = 0;\n" "}"); - ASSERT_EQUALS("[test.cpp:11]: (error) Possible null pointer dereference: p\n", errout.str()); + ASSERT_EQUALS("[test.cpp:11]: (warning) Possible null pointer dereference: p\n", errout.str()); } void nullpointer7() { @@ -1116,8 +1116,7 @@ private: " std::string * x = 0;\n" " *x = \"test\";\n" "}"); - ASSERT_EQUALS("[test.cpp:4]: (error) Possible null pointer dereference: x\n" - "[test.cpp:4]: (error) Null pointer dereference\n", errout.str()); + ASSERT_EQUALS("[test.cpp:4]: (error) Null pointer dereference: x\n", errout.str()); } void nullpointer10() { @@ -1126,7 +1125,7 @@ private: " struct my_type* p = 0;\n" " p->x = 0;\n" "}"); - ASSERT_EQUALS("[test.cpp:4]: (error) Possible null pointer dereference: p\n", errout.str()); + ASSERT_EQUALS("[test.cpp:4]: (error) Null pointer dereference: p\n", errout.str()); } void nullpointer11() { // ticket #2812 @@ -1136,7 +1135,7 @@ private: " p = 0;\n" " return p->x;\n" "}"); - ASSERT_EQUALS("[test.cpp:5]: (error) Possible null pointer dereference: p\n", errout.str()); + ASSERT_EQUALS("[test.cpp:5]: (error) Null pointer dereference: p\n", errout.str()); } void nullpointer12() { // ticket #2470, #4035 @@ -1147,8 +1146,7 @@ private: "}\n"; check(code, false, "test.cpp"); // C++ file => nullptr means NULL - ASSERT_EQUALS("[test.cpp:4]: (error) Possible null pointer dereference: i\n" - "[test.cpp:4]: (error) Null pointer dereference\n", errout.str()); + ASSERT_EQUALS("[test.cpp:4]: (error) Null pointer dereference: i\n", errout.str()); check(code, false, "test.c"); // C file => nullptr does not mean NULL ASSERT_EQUALS("", errout.str()); @@ -1198,8 +1196,7 @@ private: " i++;\n" " };\n" "}"); - ASSERT_EQUALS("[test.cpp:5]: (error) Possible null pointer dereference: str\n" - "[test.cpp:5]: (error) Null pointer dereference\n", errout.str()); + ASSERT_EQUALS("[test.cpp:5]: (error) Null pointer dereference: str\n", errout.str()); } void nullpointer19() { // #3811 @@ -1222,7 +1219,7 @@ private: " if (x) p = q;\n" " if (y ? p->x : p->y) { }\n" "}"); - ASSERT_EQUALS("[test.cpp:4]: (error) Possible null pointer dereference: p\n", errout.str()); + ASSERT_EQUALS("[test.cpp:4]: (warning) Possible null pointer dereference: p\n", errout.str()); } void nullpointer21() { // #4038 - fp: if (x) p=q; else return; @@ -1260,7 +1257,7 @@ private: " if (data == 1 && array[i] == 0)\n" " std::cout << \"test\";\n" "}"); - ASSERT_EQUALS("[test.cpp:4]: (error) Possible null pointer dereference: array\n", errout.str()); + ASSERT_EQUALS("[test.cpp:4]: (error) Null pointer dereference: array\n", errout.str()); } void nullpointer26() { // #3589 @@ -1291,8 +1288,7 @@ private: " *pointer_=0;\n" " return *this;\n" "}"); - ASSERT_EQUALS("[test.cpp:8]: (error) Possible null pointer dereference: pointer_\n" - "[test.cpp:8]: (error) Null pointer dereference\n", errout.str()); + ASSERT_EQUALS("[test.cpp:8]: (error) Null pointer dereference: pointer_\n", errout.str()); } void nullpointer28() { // #6491 @@ -1303,7 +1299,7 @@ private: " return i;\n" "}\n" "int main(){f(0);}\n", true); - ASSERT_EQUALS("[test.cpp:4]: (error) Possible null pointer dereference: s\n", errout.str()); + ASSERT_EQUALS("[test.cpp:4]: (warning) Possible null pointer dereference: s\n", errout.str()); } void nullpointer30() { // #6392 @@ -1347,7 +1343,7 @@ private: " }\n" " return p;\n" "}", true); - ASSERT_EQUALS("[test.cpp:7]: (error) Possible null pointer dereference: p\n" + ASSERT_EQUALS("[test.cpp:7]: (warning) Possible null pointer dereference: p\n" "[test.cpp:7]: (error) Null pointer dereference\n", errout.str()); } @@ -1756,8 +1752,7 @@ private: " int* p = 0;\n" " return p[4];\n" "}"); - ASSERT_EQUALS("[test.cpp:3]: (error) Possible null pointer dereference: p\n" - "[test.cpp:3]: (error) Null pointer dereference\n", errout.str()); + ASSERT_EQUALS("[test.cpp:3]: (error) Null pointer dereference: p\n", errout.str()); check("void f() {\n" " typeof(*NULL) y;\n" @@ -1804,7 +1799,7 @@ private: " char* s = 0;\n" " printf(\"%s\", s);\n" "}"); - ASSERT_EQUALS("[test.cpp:3]: (error) Possible null pointer dereference: s\n", errout.str()); + ASSERT_EQUALS("[test.cpp:3]: (error) Null pointer dereference: s\n", errout.str()); check("void f() {\n" " char *s = 0;\n" @@ -1826,7 +1821,7 @@ private: " char* s = 0;\n" " printf(\"%u%s\", 123, s);\n" "}"); - ASSERT_EQUALS("[test.cpp:3]: (error) Possible null pointer dereference: s\n", errout.str()); + ASSERT_EQUALS("[test.cpp:3]: (error) Null pointer dereference: s\n", errout.str()); check("void f() {\n" @@ -1893,7 +1888,7 @@ private: " int* iVal = 0;\n" " sscanf(dummy, \"%d\", iVal);\n" "}"); - ASSERT_EQUALS("[test.cpp:3]: (error) Possible null pointer dereference: iVal\n", errout.str()); + ASSERT_EQUALS("[test.cpp:3]: (error) Null pointer dereference: iVal\n", errout.str()); check("void f(char *dummy) {\n" " int* iVal;\n" @@ -1919,7 +1914,7 @@ private: " if(g()) iVal = g();\n" " return iVal[0];\n" "}"); - ASSERT_EQUALS("[test.cpp:4]: (error) Possible null pointer dereference: iVal\n", errout.str()); + ASSERT_EQUALS("[test.cpp:4]: (warning) Possible null pointer dereference: iVal\n", errout.str()); check("int foo(int* iVal) {\n" " return iVal[0];\n" @@ -2005,8 +2000,8 @@ private: " std::string s5(p);\n" " foo(std::string(p));\n" "}", true); - ASSERT_EQUALS("[test.cpp:9]: (error) Possible null pointer dereference: p\n" - "[test.cpp:10]: (error) Possible null pointer dereference: p\n" + ASSERT_EQUALS("[test.cpp:9]: (error) Null pointer dereference: p\n" + "[test.cpp:10]: (error) Null pointer dereference: p\n" "[test.cpp:3]: (error) Null pointer dereference\n" "[test.cpp:5]: (error) Null pointer dereference\n" "[test.cpp:7]: (error) Null pointer dereference\n" @@ -2025,10 +2020,10 @@ private: " foo(p == s2);\n" " foo(p == s3);\n" "}", true); - ASSERT_EQUALS("[test.cpp:4]: (error) Possible null pointer dereference: p\n" - "[test.cpp:5]: (error) Possible null pointer dereference: p\n" - "[test.cpp:7]: (error) Possible null pointer dereference: p\n" - "[test.cpp:8]: (error) Possible null pointer dereference: p\n", errout.str()); + ASSERT_EQUALS("[test.cpp:4]: (error) Null pointer dereference: p\n" + "[test.cpp:5]: (error) Null pointer dereference: p\n" + "[test.cpp:7]: (error) Null pointer dereference: p\n" + "[test.cpp:8]: (error) Null pointer dereference: p\n", errout.str()); check("void f(std::string s1, const std::string& s2, const std::string* s3) {\n" " void* p = 0;\n" @@ -2098,8 +2093,8 @@ private: " if(q == 0)\n" " oss << foo << q;\n" "}", false); - ASSERT_EQUALS("[test.cpp:3]: (error) Possible null pointer dereference: p\n" - "[test.cpp:4]: (error) Possible null pointer dereference: p\n" + ASSERT_EQUALS("[test.cpp:3]: (error) Null pointer dereference: p\n" + "[test.cpp:4]: (error) Null pointer dereference: p\n" "[test.cpp:6] -> [test.cpp:5]: (warning) Either the condition 'q==0' is redundant or there is possible null pointer dereference: q.\n", errout.str()); check("void f(const char* p) {\n"