Improved CheckNullPointer::isPointerDeRef():

- Fixed #4240
- Added support for wstring/wchar_t
This commit is contained in:
PKEuS 2012-11-10 19:53:20 +01:00
parent 3e03838025
commit 4ee955fc8c
2 changed files with 13 additions and 3 deletions

View File

@ -347,18 +347,18 @@ bool CheckNullPointer::isPointerDeRef(const Token *tok, bool &unknown, const Sym
return true; return true;
// std::string dereferences nullpointers // 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; return true;
if (Token::Match(tok->tokAt(-2), "%var% ( %var% )")) { if (Token::Match(tok->tokAt(-2), "%var% ( %var% )")) {
const Variable* var = symbolDatabase->getVariableFromVarId(tok->tokAt(-2)->varId()); 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; return true;
} }
// streams dereference nullpointers // streams dereference nullpointers
if (Token::Match(tok->previous(), "<<|>> %var%")) { if (Token::Match(tok->previous(), "<<|>> %var%")) {
const Variable* var = symbolDatabase->getVariableFromVarId(tok->varId()); 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 const Token* tok2 = tok->previous(); // Find start of statement
for (; tok2; tok2 = tok2->previous()) { for (; tok2; tok2 = tok2->previous()) {
if (Token::Match(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% ;")) if (Token::Match(tok->previous(), "[{;}] %var% ;"))
return false; 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 if it's a dereference
unknown = true; unknown = true;
} }

View File

@ -2043,6 +2043,12 @@ private:
" return ret;\n" " return ret;\n"
"}", true); "}", true);
ASSERT_EQUALS("", errout.str()); 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 void functioncall() { // #3443 - function calls