Fixed #2467 (false positive: possible nullptr dereference)
This commit is contained in:
parent
065e2e277e
commit
b5020468f6
|
@ -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
|
* @brief parse a function call and extract information about variable usage
|
||||||
|
@ -526,6 +536,17 @@ void CheckNullPointer::nullPointerByCheckAndDeRef()
|
||||||
// - if there are logical operators
|
// - if there are logical operators
|
||||||
// - if (x) { } else { ... }
|
// - 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
|
// vartok : token for the variable
|
||||||
const Token *vartok = 0;
|
const Token *vartok = 0;
|
||||||
if (Token::Match(tok, "if ( ! %var% ) {"))
|
if (Token::Match(tok, "if ( ! %var% ) {"))
|
||||||
|
|
|
@ -60,6 +60,9 @@ public:
|
||||||
checkNullPointer.executionPaths();
|
checkNullPointer.executionPaths();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Is string uppercase? */
|
||||||
|
static bool isUpper(const std::string &str);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief parse a function call and extract information about variable usage
|
* @brief parse a function call and extract information about variable usage
|
||||||
* @param tok first token
|
* @param tok first token
|
||||||
|
|
|
@ -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
|
/// @addtogroup Checks
|
||||||
/// @{
|
/// @{
|
||||||
|
|
||||||
|
@ -679,7 +667,7 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
// ticket #2367 : unexpanded macro that uses sizeof|typeof?
|
// 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();
|
tok2 = tok2->next()->link();
|
||||||
if (!tok2)
|
if (!tok2)
|
||||||
|
@ -703,7 +691,7 @@ private:
|
||||||
functionCall = functionCall ? functionCall->previous() : 0;
|
functionCall = functionCall ? functionCall->previous() : 0;
|
||||||
if (functionCall)
|
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());
|
ExecutionPath::bailOutVar(checks, tok2->varId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -859,6 +859,15 @@ private:
|
||||||
" *p = 0;\n"
|
" *p = 0;\n"
|
||||||
"}\n");
|
"}\n");
|
||||||
ASSERT_EQUALS("[test.cpp:5]: (error) Possible null pointer dereference: p\n", errout.str());
|
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
|
// Test CheckNullPointer::nullConstantDereference
|
||||||
|
|
Loading…
Reference in New Issue