From 385afffb14e9c49152c95e7cf45d479822c963f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Mon, 26 Dec 2011 07:13:10 +0100 Subject: [PATCH] Null pointers: show inconclusive errors if functions are called. Assume they won't assign the pointer. Ticket: #3443 --- lib/checknullpointer.cpp | 19 +++++++++++++------ lib/tokenize.h | 4 ++-- test/testnullpointer.cpp | 16 ++++++++++++++++ 3 files changed, 31 insertions(+), 8 deletions(-) diff --git a/lib/checknullpointer.cpp b/lib/checknullpointer.cpp index bd617f7c4..556a7eccb 100644 --- a/lib/checknullpointer.cpp +++ b/lib/checknullpointer.cpp @@ -623,8 +623,11 @@ void CheckNullPointer::nullPointerStructByDeRefAndChec() break; // function call.. - else if (Token::Match(tok2, "[;{}] %var% (") && CanFunctionAssignPointer(tok2->next(), varid1)) - break; + else if (Token::Match(tok2, "[;{}] %var% (") && CanFunctionAssignPointer(tok2->next(), varid1)) { + if (!_settings->inconclusive) + break; + inconclusive = true; + } // Reassignment of the struct else if (tok2->varId() == varid1) { @@ -698,6 +701,7 @@ void CheckNullPointer::nullPointerByDeRefAndChec() continue; const Token * const decltok = var->nameToken(); + bool inconclusive = false; for (const Token *tok1 = tok->previous(); tok1 && tok1 != decltok; tok1 = tok1->previous()) { if (tok1->str() == ")" && Token::Match(tok1->link()->previous(), "%var% (")) { @@ -727,15 +731,18 @@ void CheckNullPointer::nullPointerByDeRefAndChec() std::list varlist; parseFunctionCall(*(tok2->next()), varlist, 0); if (!varlist.empty() && varlist.front() == tok2->tokAt(3)) { - nullPointerError(tok2->tokAt(3), varname, tok->linenr()); + nullPointerError(tok2->tokAt(3), varname, tok->linenr(), inconclusive); break; } } // Passing pointer as parameter.. if (Token::Match(tok2, "[;{}] %type% (")) { - if (CanFunctionAssignPointer(tok2->next(), varid)) - break; + if (CanFunctionAssignPointer(tok2->next(), varid)) { + if (!_settings->inconclusive) + break; + inconclusive = true; + } } // calling unknown function => it might initialize the pointer @@ -780,7 +787,7 @@ void CheckNullPointer::nullPointerByDeRefAndChec() } else if (Token::Match(tok1->tokAt(-2), "&&|%oror% !")) { break; } else if (CheckNullPointer::isPointerDeRef(tok1, unknown)) { - nullPointerError(tok1, varname, tok->linenr()); + nullPointerError(tok1, varname, tok->linenr(), inconclusive); break; } else if (Token::simpleMatch(tok1->previous(), "&")) { break; diff --git a/lib/tokenize.h b/lib/tokenize.h index 817689b8e..88ce385a4 100644 --- a/lib/tokenize.h +++ b/lib/tokenize.h @@ -504,8 +504,8 @@ public: * @param expandedtemplates all templates that has been expanded so far. The full names are stored. */ void simplifyTemplateInstantions(const Token *tok, - std::list &templateInstantiations, - std::set &expandedtemplates); + std::list &templateInstantiations, + std::set &expandedtemplates); void simplifyTemplatesExpandTemplate(const Token *tok, const std::string &name, diff --git a/test/testnullpointer.cpp b/test/testnullpointer.cpp index 0fe8e2911..3a1df84f2 100644 --- a/test/testnullpointer.cpp +++ b/test/testnullpointer.cpp @@ -1749,6 +1749,14 @@ private: " if (p) { }\n" "}"); TODO_ASSERT_EQUALS("[test.cpp:4]: (error) Possible null pointer dereference: p - otherwise it is redundant to check if p is null at line 6\n", "", errout.str()); + + // inconclusive + check("void f(int *p) {\n" + " *p = 0;\n" + " foo(p);\n" + " if (p) { }\n" + "}", true); + ASSERT_EQUALS("[test.cpp:2]: (error) Possible null pointer dereference: p - otherwise it is redundant to check if p is null at line 4\n", errout.str()); } // dereference struct pointer and then check if it's null @@ -1780,6 +1788,14 @@ private: " if (abc) { }\n" "}"); TODO_ASSERT_EQUALS("[test.cpp:4]: (error) Possible null pointer dereference: abc - otherwise it is redundant to check if abc is null at line 6\n", "", errout.str()); + + // inconclusive + check("void f(struct ABC *abc) {\n" + " abc->a = 0;\n" + " foo(abc);\n" + " if (abc) { }\n" + "}", true); + ASSERT_EQUALS("[test.cpp:2]: (error) Possible null pointer dereference: abc - otherwise it is redundant to check if abc is null at line 4\n", errout.str()); } } };