From 1fd9ba0cc48dcdfd7cd9f513dbed3d0dd54e420e Mon Sep 17 00:00:00 2001 From: Frank Zingsheim Date: Sun, 13 Sep 2015 10:53:05 +0200 Subject: [PATCH] Fixed #6988 (incorrect nullPointer error for string) --- lib/checknullpointer.cpp | 19 ++++++++++++------- test/testnullpointer.cpp | 30 ++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 7 deletions(-) diff --git a/lib/checknullpointer.cpp b/lib/checknullpointer.cpp index b95e04782..16e7b51a0 100644 --- a/lib/checknullpointer.cpp +++ b/lib/checknullpointer.cpp @@ -446,14 +446,19 @@ void CheckNullPointer::nullConstantDereference() } const Variable *ovar = nullptr; - if (Token::Match(tok, "0 ==|!=|>|>=|<|<= %var% !!.")) - ovar = tok->tokAt(2)->variable(); - else if (Token::Match(tok, "%var% ==|!=|>|>=|<|<= 0")) + const Token *tokNull = nullptr; + if (Token::Match(tok, "0 ==|!=|>|>=|<|<= %var%")) { + if (!Token::Match(tok->tokAt(3),".|[")) { + ovar = tok->tokAt(2)->variable(); + tokNull = tok; + } + } else if (Token::Match(tok, "%var% ==|!=|>|>=|<|<= 0") || + Token::Match(tok, "%var% =|+ 0 )|]|,|;|+")) { ovar = tok->variable(); - else if (Token::Match(tok, "%var% =|+ 0 )|]|,|;|+")) - ovar = tok->variable(); - if (ovar && !ovar->isPointer() && !ovar->isArray() && ovar->isStlStringType() && tok->tokAt(2)->originalName() != "'\\0'") - nullPointerError(tok); + tokNull = tok->tokAt(2); + } + if (ovar && !ovar->isPointer() && !ovar->isArray() && ovar->isStlStringType() && tokNull && tokNull->originalName() != "'\\0'") + nullPointerError(tokNull); } } } diff --git a/test/testnullpointer.cpp b/test/testnullpointer.cpp index be23cb815..2541ad482 100644 --- a/test/testnullpointer.cpp +++ b/test/testnullpointer.cpp @@ -2030,6 +2030,36 @@ private: "[test.cpp:7]: (error) Possible null pointer dereference: p\n" "[test.cpp:8]: (error) Possible 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" + " if (x) { return; }\n" + " foo(0 == s1.size());\n" + " foo(0 == s2.size());\n" + " foo(0 == s3->size());\n" + " foo(s1.size() == 0);\n" + " foo(s2.size() == 0);\n" + " foo(s3->size() == 0);\n" + "}", true); + ASSERT_EQUALS("", errout.str()); + + check("void f(std::string s1, const std::string& s2) {\n" + " if (x) { return; }\n" + " foo(0 == s1[0]);\n" + " foo(0 == s2[0]);\n" + " foo(s1[0] == 0);\n" + " foo(s2[0] == 0);\n" + "}", true); + ASSERT_EQUALS("", errout.str()); + + check("void f(std::string s1, const std::string& s2) {\n" + " if (x) { return; }\n" + " foo(s1 == '\\0');\n" + " foo(s2 == '\\0');\n" + " foo('\\0' == s1);\n" + " foo('\\0' == s2);\n" + "}", true); + ASSERT_EQUALS("", errout.str()); + check("class Bar {\n" " std::string s;\n" " Bar() : s(0) {}\n"