From fc8749e952513dc7d542f1cd393cb12e811010ba Mon Sep 17 00:00:00 2001 From: PKEuS Date: Mon, 2 Apr 2012 12:12:02 +0200 Subject: [PATCH] Improved nullpointer check: - Fixed #3673 - Fixed potential issue with constructor calls (like #3697) - Added support for operator+ on std::string --- lib/checknullpointer.cpp | 26 +++++++++++++++----------- test/testnullpointer.cpp | 5 +++++ 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/lib/checknullpointer.cpp b/lib/checknullpointer.cpp index 9d53135bf..4baad6893 100644 --- a/lib/checknullpointer.cpp +++ b/lib/checknullpointer.cpp @@ -276,7 +276,9 @@ bool CheckNullPointer::isPointerDeRef(const Token *tok, bool &unknown, const Sym unsigned int ovarid = 0; if (Token::Match(tok, "%var% ==|!= %var%")) ovarid = tok->tokAt(2)->varId(); - else if (Token::Match(tok->tokAt(-2), "%var% ==|!=|=|+= %var%")) + else if (Token::Match(tok->tokAt(-2), "%var% ==|!= %var%")) + ovarid = tok->tokAt(-2)->varId(); + else if (Token::Match(tok->tokAt(-2), "%var% =|+=|+ %var% )|]|,|;|+")) ovarid = tok->tokAt(-2)->varId(); if (ovarid) { const Variable* var = symbolDatabase->getVariableFromVarId(ovarid); @@ -1071,19 +1073,19 @@ void CheckNullPointer::nullConstantDereference() nullPointerError(tok); else if (Token::Match(tok->previous(), "!!. %var% (") && (tok->previous()->str() != "::" || tok->strAt(-2) == "std")) { - if (Token::simpleMatch(tok->tokAt(2), "0 )")) { + if (Token::simpleMatch(tok->tokAt(2), "0 )") && tok->varId()) { // constructor call const Variable* var = symbolDatabase->getVariableFromVarId(tok->varId()); if (var && !var->isPointer() && !var->isArray() && Token::Match(var->typeStartToken(), "const| std :: string !!::")) nullPointerError(tok); - } + } else { // function call + std::list var; + parseFunctionCall(*tok, var, 0); - std::list var; - parseFunctionCall(*tok, var, 0); - - // is one of the var items a NULL pointer? - for (std::list::const_iterator it = var.begin(); it != var.end(); ++it) { - if (Token::Match(*it, "0 [,)]")) { - nullPointerError(*it); + // is one of the var items a NULL pointer? + for (std::list::const_iterator it = var.begin(); it != var.end(); ++it) { + if (Token::Match(*it, "0 [,)]")) { + nullPointerError(*it); + } } } } else if (Token::simpleMatch(tok, "std :: string ( 0 )")) @@ -1107,7 +1109,9 @@ void CheckNullPointer::nullConstantDereference() unsigned int ovarid = 0; if (Token::Match(tok, "0 ==|!= %var%")) ovarid = tok->tokAt(2)->varId(); - else if (Token::Match(tok, "%var% ==|!=|=|+= 0")) + else if (Token::Match(tok, "%var% ==|!= 0")) + ovarid = tok->varId(); + else if (Token::Match(tok, "%var% =|+=|+ 0 )|]|,|;|+")) ovarid = tok->varId(); if (ovarid) { const Variable* var = symbolDatabase->getVariableFromVarId(ovarid); diff --git a/test/testnullpointer.cpp b/test/testnullpointer.cpp index 7863d9b77..2d1cae0df 100644 --- a/test/testnullpointer.cpp +++ b/test/testnullpointer.cpp @@ -1919,6 +1919,11 @@ private: TODO_ASSERT_EQUALS("[test.cpp:3]: (error) Null pointer dereference\n" "[test.cpp:9]: (error) Null pointer dereference\n", "[test.cpp:3]: (error) Null pointer dereference\n", errout.str()); + + check("void f() {\n" + " std::string s = 0 == x ? \"a\" : \"b\";\n" + "}", true); + ASSERT_EQUALS("", errout.str()); } void nullpointerStdStream() {