Fixed #2467 (false positive: possible nullptr dereference)

This commit is contained in:
Daniel Marjamäki 2011-01-17 19:23:00 +01:00
parent 065e2e277e
commit b5020468f6
4 changed files with 35 additions and 14 deletions

View File

@ -32,6 +32,16 @@ CheckNullPointer instance;
//---------------------------------------------------------------------------
/** Is string uppercase? */
bool CheckNullPointer::isUpper(const std::string &str)
{
for (unsigned int i = 0; i < str.length(); ++i)
{
if (str[i] >= 'a' && str[i] <= 'z')
return false;
}
return true;
}
/**
* @brief parse a function call and extract information about variable usage
@ -526,6 +536,17 @@ void CheckNullPointer::nullPointerByCheckAndDeRef()
// - if there are logical operators
// - if (x) { } else { ... }
// If the if-body ends with a unknown macro then bailout
{
// goto the end paranthesis
const Token *endpar = tok->next()->link();
const Token *endbody = endpar ? endpar->next()->link() : 0;
if (endbody &&
Token::Match(endbody->tokAt(-3), "[;{}] %var% ;") &&
isUpper(endbody->tokAt(-2)->str()))
continue;
}
// vartok : token for the variable
const Token *vartok = 0;
if (Token::Match(tok, "if ( ! %var% ) {"))

View File

@ -60,6 +60,9 @@ public:
checkNullPointer.executionPaths();
}
/** Is string uppercase? */
static bool isUpper(const std::string &str);
/**
* @brief parse a function call and extract information about variable usage
* @param tok first token

View File

@ -33,18 +33,6 @@ CheckUninitVar instance;
//---------------------------------------------------------------------------
/** Is string uppercase? */
static bool isUpper(const std::string &str)
{
for (unsigned int i = 0; i < str.length(); ++i)
{
if (str[i] >= 'a' && str[i] <= 'z')
return false;
}
return true;
}
/// @addtogroup Checks
/// @{
@ -679,7 +667,7 @@ private:
}
// ticket #2367 : unexpanded macro that uses sizeof|typeof?
else if (Token::Match(tok2, "%type% (") && isUpper(tok2->str()))
else if (Token::Match(tok2, "%type% (") && CheckNullPointer::isUpper(tok2->str()))
{
tok2 = tok2->next()->link();
if (!tok2)
@ -703,7 +691,7 @@ private:
functionCall = functionCall ? functionCall->previous() : 0;
if (functionCall)
{
if (functionCall->isName() && !isUpper(functionCall->str()) && use_dead_pointer(checks, tok2))
if (functionCall->isName() && !CheckNullPointer::isUpper(functionCall->str()) && use_dead_pointer(checks, tok2))
ExecutionPath::bailOutVar(checks, tok2->varId());
}
}

View File

@ -859,6 +859,15 @@ private:
" *p = 0;\n"
"}\n");
ASSERT_EQUALS("[test.cpp:5]: (error) Possible null pointer dereference: p\n", errout.str());
// #2467 - unknown macro may terminate the application
check("void f(Fred *fred) {\n"
" if (fred == NULL) {\n"
" MACRO;\n"
" }\n"
" fred->a();\n"
"}");
ASSERT_EQUALS("", errout.str());
}
// Test CheckNullPointer::nullConstantDereference