diff --git a/lib/checknullpointer.cpp b/lib/checknullpointer.cpp index 4e77e1a81..e18305d83 100644 --- a/lib/checknullpointer.cpp +++ b/lib/checknullpointer.cpp @@ -347,18 +347,18 @@ bool CheckNullPointer::isPointerDeRef(const Token *tok, bool &unknown, const Sym return true; // std::string dereferences nullpointers - if (Token::Match(tok->tokAt(-4), "std :: string ( %var% )")) + if (Token::Match(tok->tokAt(-4), "std :: string|wstring ( %var% )")) return true; if (Token::Match(tok->tokAt(-2), "%var% ( %var% )")) { const Variable* var = symbolDatabase->getVariableFromVarId(tok->tokAt(-2)->varId()); - if (var && !var->isPointer() && !var->isArray() && Token::Match(var->typeStartToken(), "std :: string !!::")) + if (var && !var->isPointer() && !var->isArray() && Token::Match(var->typeStartToken(), "std :: string|wstring !!::")) return true; } // streams dereference nullpointers if (Token::Match(tok->previous(), "<<|>> %var%")) { const Variable* var = symbolDatabase->getVariableFromVarId(tok->varId()); - if (var && var->isPointer() && var->typeStartToken()->str() == "char") { // Only outputing or reading to char* can cause problems + if (var && var->isPointer() && Token::Match(var->typeStartToken(), "char|wchar_t")) { // Only outputing or reading to char* can cause problems const Token* tok2 = tok->previous(); // Find start of statement for (; tok2; tok2 = tok2->previous()) { if (Token::Match(tok2->previous(), ";|{|}|:")) @@ -421,6 +421,10 @@ bool CheckNullPointer::isPointerDeRef(const Token *tok, bool &unknown, const Sym if (Token::Match(tok->previous(), "[{;}] %var% ;")) return false; + // Shift pointer (e.g. to cout, but its no char* (see above)) + if (Token::Match(tok->previous(), "<<|>> %var%")) + return false; + // unknown if it's a dereference unknown = true; } diff --git a/test/testnullpointer.cpp b/test/testnullpointer.cpp index a9feeece5..3ec32a7f3 100644 --- a/test/testnullpointer.cpp +++ b/test/testnullpointer.cpp @@ -2043,6 +2043,12 @@ private: " return ret;\n" "}", true); ASSERT_EQUALS("", errout.str()); + + check("void f(int* i) {\n" + " if(i) return;\n" + " std::cout << i;\n" // Its no char* (#4240) + "}", true); + ASSERT_EQUALS("", errout.str()); } void functioncall() { // #3443 - function calls