CheckNullPointer::isPointerDeRef: Refactoring - use tok->variable(). Ticket: #4535

This commit is contained in:
Daniel Marjamäki 2013-02-01 19:10:14 +01:00
parent 1a58ae4994
commit a04f7b1a94
3 changed files with 20 additions and 24 deletions

View File

@ -317,7 +317,7 @@ void CheckNullPointer::parseFunctionCall(const Token &tok, std::list<const Token
* @param unknown it is not known if there is a pointer dereference (could be reported as a debug message) * @param unknown it is not known if there is a pointer dereference (could be reported as a debug message)
* @return true => there is a dereference * @return true => there is a dereference
*/ */
bool CheckNullPointer::isPointerDeRef(const Token *tok, bool &unknown, const SymbolDatabase* symbolDatabase) bool CheckNullPointer::isPointerDeRef(const Token *tok, bool &unknown)
{ {
const bool inconclusive = unknown; const bool inconclusive = unknown;
@ -350,14 +350,14 @@ bool CheckNullPointer::isPointerDeRef(const Token *tok, bool &unknown, const Sym
if (Token::Match(tok->tokAt(-4), "std :: string|wstring ( %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 = tok->tokAt(-2)->variable();
if (var && !var->isPointer() && !var->isArray() && Token::Match(var->typeStartToken(), "std :: string|wstring !!::")) 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 = tok->variable();
if (var && var->isPointer() && Token::Match(var->typeStartToken(), "char|wchar_t")) { // Only outputting or reading to char* can cause problems if (var && var->isPointer() && Token::Match(var->typeStartToken(), "char|wchar_t")) { // Only outputting 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()) {
@ -367,25 +367,22 @@ bool CheckNullPointer::isPointerDeRef(const Token *tok, bool &unknown, const Sym
if (Token::Match(tok2, "std :: cout|cin|cerr")) if (Token::Match(tok2, "std :: cout|cin|cerr"))
return true; return true;
if (tok2 && tok2->varId() != 0) { if (tok2 && tok2->varId() != 0) {
const Variable* var2 = symbolDatabase->getVariableFromVarId(tok2->varId()); const Variable* var2 = tok2->variable();
if (var2 && Token::Match(var2->typeStartToken(), "std :: istream|ifstream|istringstream|wistringstream|ostream|ofstream|ostringstream|wostringstream|stringstream|wstringstream|fstream|iostream")) if (var2 && Token::Match(var2->typeStartToken(), "std :: istream|ifstream|istringstream|wistringstream|ostream|ofstream|ostringstream|wostringstream|stringstream|wstringstream|fstream|iostream"))
return true; return true;
} }
} }
} }
unsigned int ovarid = 0; const Variable *ovar = NULL;
if (Token::Match(tok, "%var% ==|!= %var%")) if (Token::Match(tok, "%var% ==|!= %var%"))
ovarid = tok->tokAt(2)->varId(); ovar = tok->tokAt(2)->variable();
else if (Token::Match(tok->tokAt(-2), "%var% ==|!= %var%")) else if (Token::Match(tok->tokAt(-2), "%var% ==|!= %var%"))
ovarid = tok->tokAt(-2)->varId(); ovar = tok->tokAt(-2)->variable();
else if (Token::Match(tok->tokAt(-2), "%var% =|+ %var% )|]|,|;|+")) else if (Token::Match(tok->tokAt(-2), "%var% =|+ %var% )|]|,|;|+"))
ovarid = tok->tokAt(-2)->varId(); ovar = tok->tokAt(-2)->variable();
if (ovarid) { if (ovar && !ovar->isPointer() && !ovar->isArray() && Token::Match(ovar->typeStartToken(), "std :: string|wstring !!::"))
const Variable* var = symbolDatabase->getVariableFromVarId(ovarid); return true;
if (var && !var->isPointer() && !var->isArray() && Token::Match(var->typeStartToken(), "std :: string|wstring !!::"))
return true;
}
// Check if it's NOT a pointer dereference. // Check if it's NOT a pointer dereference.
// This is most useful in inconclusive checking // This is most useful in inconclusive checking
@ -875,7 +872,7 @@ void CheckNullPointer::nullPointerByDeRefAndChec()
break; break;
} else if (Token::Match(tok1->tokAt(-2), "&&|%oror% !")) { } else if (Token::Match(tok1->tokAt(-2), "&&|%oror% !")) {
break; break;
} else if (CheckNullPointer::isPointerDeRef(tok1, unknown, symbolDatabase)) { } else if (CheckNullPointer::isPointerDeRef(tok1, unknown)) {
nullPointerError(tok1, varname, tok, inconclusive); nullPointerError(tok1, varname, tok, inconclusive);
break; break;
} else if (tok1->strAt(-1) == "&") { } else if (tok1->strAt(-1) == "&") {
@ -963,7 +960,7 @@ void CheckNullPointer::nullPointerByCheckAndDeRef()
// Pointer is used // Pointer is used
bool unknown = _settings->inconclusive; bool unknown = _settings->inconclusive;
if (tok2->varId() == varid && (isPointerDeRef(tok2, unknown, symbolDatabase) || unknown)) { if (tok2->varId() == varid && (isPointerDeRef(tok2, unknown) || unknown)) {
nullPointerError(tok2, pointerName, vartok, unknown); nullPointerError(tok2, pointerName, vartok, unknown);
break; break;
} }
@ -1020,7 +1017,7 @@ void CheckNullPointer::nullPointerByCheckAndDeRef()
bool unknown = _settings->inconclusive; bool unknown = _settings->inconclusive;
for (; tok2 && tok2->str() != ";"; tok2 = tok2->next()) { for (; tok2 && tok2->str() != ";"; tok2 = tok2->next()) {
if (tok2->varId() == varid) { if (tok2->varId() == varid) {
if (CheckNullPointer::isPointerDeRef(tok2, unknown, symbolDatabase)) if (CheckNullPointer::isPointerDeRef(tok2, unknown))
nullPointerError(tok2, pointerName, vartok, inconclusive); nullPointerError(tok2, pointerName, vartok, inconclusive);
else if (unknown) else if (unknown)
nullPointerError(tok2, pointerName, vartok, true); nullPointerError(tok2, pointerName, vartok, true);
@ -1090,7 +1087,7 @@ void CheckNullPointer::nullPointerByCheckAndDeRef()
if (Token::Match(tok2->previous(), "[;{}=] %var% = 0 ;")) if (Token::Match(tok2->previous(), "[;{}=] %var% = 0 ;"))
; ;
else if (CheckNullPointer::isPointerDeRef(tok2, unknown, symbolDatabase)) else if (CheckNullPointer::isPointerDeRef(tok2, unknown))
nullPointerError(tok2, pointerName, vartok, inconclusive); nullPointerError(tok2, pointerName, vartok, inconclusive);
else if (unknown && _settings->inconclusive) else if (unknown && _settings->inconclusive)
@ -1251,7 +1248,7 @@ void CheckNullPointer::nullPointerDefaultArgument()
if (Token::Match(tok, "%var% =")) if (Token::Match(tok, "%var% ="))
pointerArgs.erase(tok->varId()); pointerArgs.erase(tok->varId());
if (isPointerDeRef(tok, unknown, symbolDatabase)) if (isPointerDeRef(tok, unknown))
nullPointerDefaultArgError(tok, tok->str()); nullPointerDefaultArgError(tok, tok->str());
} }
} }
@ -1380,7 +1377,7 @@ private:
// unknown: if isPointerDeRef fails to determine if there // unknown: if isPointerDeRef fails to determine if there
// is a dereference this will be set to true. // is a dereference this will be set to true.
bool unknown = owner->inconclusiveFlag(); bool unknown = owner->inconclusiveFlag();
bool deref = CheckNullPointer::isPointerDeRef(&tok, unknown, symbolDatabase); bool deref = CheckNullPointer::isPointerDeRef(&tok, unknown);
if (deref) if (deref)
dereference(checks, &tok); dereference(checks, &tok);
@ -1407,7 +1404,7 @@ private:
const Token* tok2 = &tok; const Token* tok2 = &tok;
for (; tok2 && tok2->str() != ";"; tok2 = tok2->next()) { for (; tok2 && tok2->str() != ";"; tok2 = tok2->next()) {
if (tok2->varId()) { if (tok2->varId()) {
if (CheckNullPointer::isPointerDeRef(tok2, unknown, symbolDatabase) || unknown) if (CheckNullPointer::isPointerDeRef(tok2, unknown) || unknown)
dereference(checks, tok2); dereference(checks, tok2);
} }
@ -1430,7 +1427,7 @@ private:
if (tok2->str() == "(" || tok2->str() == ")" || tok2->str() == "&&" || tok2->str() == "||" || tok2->str() == "?") if (tok2->str() == "(" || tok2->str() == ")" || tok2->str() == "&&" || tok2->str() == "||" || tok2->str() == "?")
break; break;
bool unknown = owner->inconclusiveFlag(); bool unknown = owner->inconclusiveFlag();
if (tok2->varId() && (CheckNullPointer::isPointerDeRef(tok2, unknown, symbolDatabase) || unknown)) if (tok2->varId() && (CheckNullPointer::isPointerDeRef(tok2, unknown) || unknown))
dereference(checks, tok2); dereference(checks, tok2);
} }

View File

@ -77,10 +77,9 @@ public:
* is returned. * is returned.
* @param tok token for the pointer * @param tok token for the pointer
* @param unknown it is not known if there is a pointer dereference (could be reported as a debug message) * @param unknown it is not known if there is a pointer dereference (could be reported as a debug message)
* @param symbolDatabase symbol database
* @return true => there is a dereference * @return true => there is a dereference
*/ */
static bool isPointerDeRef(const Token *tok, bool &unknown, const SymbolDatabase* symbolDatabase); static bool isPointerDeRef(const Token *tok, bool &unknown);
/** @brief possible null pointer dereference */ /** @brief possible null pointer dereference */
void nullPointer(); void nullPointer();

View File

@ -1544,7 +1544,7 @@ bool CheckUninitVar::isVariableUsage(const Token *vartok, bool pointer) const
} }
bool unknown = false; bool unknown = false;
if (pointer && CheckNullPointer::isPointerDeRef(vartok, unknown, _tokenizer->getSymbolDatabase())) { if (pointer && CheckNullPointer::isPointerDeRef(vartok, unknown)) {
// function parameter? // function parameter?
bool functionParameter = false; bool functionParameter = false;
if (Token::Match(vartok->tokAt(-2), "%var% (") || vartok->previous()->str() == ",") if (Token::Match(vartok->tokAt(-2), "%var% (") || vartok->previous()->str() == ",")