CTU: Reuse CheckNullPointer::isPointerDeRef in the nullpointer isUnsafeUsage
This commit is contained in:
parent
03ed4afc70
commit
d18f5d8709
|
@ -672,7 +672,7 @@ const Token * CheckLeakAutoVar::checkTokenInsideExpression(const Token * const t
|
||||||
const std::map<unsigned int, VarInfo::AllocInfo>::const_iterator var = varInfo->alloctype.find(tok->varId());
|
const std::map<unsigned int, VarInfo::AllocInfo>::const_iterator var = varInfo->alloctype.find(tok->varId());
|
||||||
if (var != varInfo->alloctype.end()) {
|
if (var != varInfo->alloctype.end()) {
|
||||||
bool unknown = false;
|
bool unknown = false;
|
||||||
if (var->second.status == VarInfo::DEALLOC && CheckNullPointer::isPointerDeRef(tok, unknown) && !unknown) {
|
if (var->second.status == VarInfo::DEALLOC && CheckNullPointer::isPointerDeRef(tok, unknown, mSettings) && !unknown) {
|
||||||
deallocUseError(tok, tok->str());
|
deallocUseError(tok, tok->str());
|
||||||
} else if (Token::simpleMatch(tok->tokAt(-2), "= &")) {
|
} else if (Token::simpleMatch(tok->tokAt(-2), "= &")) {
|
||||||
varInfo->erase(tok->varId());
|
varInfo->erase(tok->varId());
|
||||||
|
|
|
@ -161,15 +161,37 @@ namespace {
|
||||||
* @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)
|
bool CheckNullPointer::isPointerDeRef(const Token *tok, bool &unknown) const
|
||||||
|
{
|
||||||
|
return isPointerDeRef(tok, unknown, mSettings);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CheckNullPointer::isPointerDeRef(const Token *tok, bool &unknown, const Settings *settings)
|
||||||
{
|
{
|
||||||
unknown = false;
|
unknown = false;
|
||||||
|
|
||||||
|
// Is pointer used as function parameter?
|
||||||
|
if (Token::Match(tok->previous(), "[(,] %name% [,)]") && settings) {
|
||||||
|
const Token *ftok = tok->previous();
|
||||||
|
while (ftok && ftok->str() != "(") {
|
||||||
|
if (ftok->str() == ")")
|
||||||
|
ftok = ftok->link();
|
||||||
|
ftok = ftok->previous();
|
||||||
|
}
|
||||||
|
if (ftok && ftok->previous()) {
|
||||||
|
std::list<const Token *> varlist;
|
||||||
|
parseFunctionCall(*ftok->previous(), varlist, &settings->library);
|
||||||
|
if (std::find(varlist.begin(), varlist.end(), tok) != varlist.end()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const Token* parent = tok->astParent();
|
const Token* parent = tok->astParent();
|
||||||
if (!parent)
|
if (!parent)
|
||||||
return false;
|
return false;
|
||||||
if (parent->str() == "." && parent->astOperand2() == tok)
|
if (parent->str() == "." && parent->astOperand2() == tok)
|
||||||
return isPointerDeRef(parent, unknown);
|
return isPointerDeRef(parent, unknown, settings);
|
||||||
const bool firstOperand = parent->astOperand1() == tok;
|
const bool firstOperand = parent->astOperand1() == tok;
|
||||||
while (parent->str() == "(" && (parent->astOperand2() == nullptr && parent->strAt(1) != ")")) { // Skip over casts
|
while (parent->str() == "(" && (parent->astOperand2() == nullptr && parent->strAt(1) != ")")) { // Skip over casts
|
||||||
parent = parent->astParent();
|
parent = parent->astParent();
|
||||||
|
@ -339,24 +361,6 @@ void CheckNullPointer::nullPointerByDeRefAndChec()
|
||||||
if (!printInconclusive && value->isInconclusive())
|
if (!printInconclusive && value->isInconclusive())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Is pointer used as function parameter?
|
|
||||||
if (Token::Match(tok->previous(), "[(,] %name% [,)]")) {
|
|
||||||
const Token *ftok = tok->previous();
|
|
||||||
while (ftok && ftok->str() != "(") {
|
|
||||||
if (ftok->str() == ")")
|
|
||||||
ftok = ftok->link();
|
|
||||||
ftok = ftok->previous();
|
|
||||||
}
|
|
||||||
if (!ftok || !ftok->previous())
|
|
||||||
continue;
|
|
||||||
std::list<const Token *> varlist;
|
|
||||||
parseFunctionCall(*ftok->previous(), varlist, &mSettings->library);
|
|
||||||
if (std::find(varlist.begin(), varlist.end(), tok) != varlist.end()) {
|
|
||||||
nullPointerError(tok, tok->str(), value, value->isInconclusive());
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Pointer dereference.
|
// Pointer dereference.
|
||||||
bool unknown = false;
|
bool unknown = false;
|
||||||
if (!isPointerDeRef(tok,unknown)) {
|
if (!isPointerDeRef(tok,unknown)) {
|
||||||
|
@ -598,13 +602,15 @@ std::string CheckNullPointer::MyFileInfo::toString() const
|
||||||
|
|
||||||
static bool isUnsafeUsage(const Check *check, const Token *vartok)
|
static bool isUnsafeUsage(const Check *check, const Token *vartok)
|
||||||
{
|
{
|
||||||
(void)check;
|
const CheckNullPointer *checkNullPointer = dynamic_cast<const CheckNullPointer *>(check);
|
||||||
return Token::Match(vartok->astParent(), "*|[");
|
bool unknown = false;
|
||||||
|
return checkNullPointer && checkNullPointer->isPointerDeRef(vartok, unknown);
|
||||||
}
|
}
|
||||||
|
|
||||||
Check::FileInfo *CheckNullPointer::getFileInfo(const Tokenizer *tokenizer, const Settings *settings) const
|
Check::FileInfo *CheckNullPointer::getFileInfo(const Tokenizer *tokenizer, const Settings *settings) const
|
||||||
{
|
{
|
||||||
const std::list<CTU::FileInfo::UnsafeUsage> &unsafeUsage = CTU::getUnsafeUsage(tokenizer, settings, nullptr, ::isUnsafeUsage);
|
CheckNullPointer check(tokenizer, settings, nullptr);
|
||||||
|
const std::list<CTU::FileInfo::UnsafeUsage> &unsafeUsage = CTU::getUnsafeUsage(tokenizer, settings, &check, ::isUnsafeUsage);
|
||||||
if (unsafeUsage.empty())
|
if (unsafeUsage.empty())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
|
|
|
@ -86,7 +86,9 @@ public:
|
||||||
* @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
|
||||||
*/
|
*/
|
||||||
static bool isPointerDeRef(const Token *tok, bool &unknown);
|
bool isPointerDeRef(const Token *tok, bool &unknown) const;
|
||||||
|
|
||||||
|
static bool isPointerDeRef(const Token *tok, bool &unknown, const Settings *settings);
|
||||||
|
|
||||||
/** @brief possible null pointer dereference */
|
/** @brief possible null pointer dereference */
|
||||||
void nullPointer();
|
void nullPointer();
|
||||||
|
|
|
@ -962,7 +962,7 @@ void CheckStl::pushback()
|
||||||
// Using invalid pointer..
|
// Using invalid pointer..
|
||||||
if (invalidPointer && tok2->varId() == pointerId) {
|
if (invalidPointer && tok2->varId() == pointerId) {
|
||||||
bool unknown = false;
|
bool unknown = false;
|
||||||
if (CheckNullPointer::isPointerDeRef(tok2, unknown))
|
if (CheckNullPointer::isPointerDeRef(tok2, unknown, mSettings))
|
||||||
invalidPointerError(tok2, function->str(), tok2->str());
|
invalidPointerError(tok2, function->str(), tok2->str());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -985,7 +985,7 @@ bool CheckUninitVar::isVariableUsage(const Token *vartok, bool pointer, Alloc al
|
||||||
}
|
}
|
||||||
|
|
||||||
bool unknown = false;
|
bool unknown = false;
|
||||||
if (pointer && alloc == NO_ALLOC && CheckNullPointer::isPointerDeRef(vartok, unknown)) {
|
if (pointer && alloc == NO_ALLOC && CheckNullPointer::isPointerDeRef(vartok, unknown, mSettings)) {
|
||||||
// function parameter?
|
// function parameter?
|
||||||
bool functionParameter = false;
|
bool functionParameter = false;
|
||||||
if (Token::Match(vartok->tokAt(-2), "%name% (") || vartok->previous()->str() == ",")
|
if (Token::Match(vartok->tokAt(-2), "%name% (") || vartok->previous()->str() == ",")
|
||||||
|
|
|
@ -2073,12 +2073,12 @@ private:
|
||||||
"}", true);
|
"}", true);
|
||||||
ASSERT_EQUALS("[test.cpp:9]: (error) Null pointer dereference: p\n"
|
ASSERT_EQUALS("[test.cpp:9]: (error) Null pointer dereference: p\n"
|
||||||
"[test.cpp:10]: (error) Null pointer dereference: p\n"
|
"[test.cpp:10]: (error) Null pointer dereference: p\n"
|
||||||
|
"[test.cpp:11]: (error) Null pointer dereference: p\n"
|
||||||
|
"[test.cpp:12]: (warning, inconclusive) Possible null pointer dereference: p\n"
|
||||||
"[test.cpp:3]: (error) Null pointer dereference\n"
|
"[test.cpp:3]: (error) Null pointer dereference\n"
|
||||||
"[test.cpp:5]: (error) Null pointer dereference\n"
|
"[test.cpp:5]: (error) Null pointer dereference\n"
|
||||||
"[test.cpp:7]: (error) Null pointer dereference\n"
|
"[test.cpp:7]: (error) Null pointer dereference\n"
|
||||||
"[test.cpp:8]: (error) Null pointer dereference\n"
|
"[test.cpp:8]: (error) Null pointer dereference\n"
|
||||||
/*"[test.cpp:11]: (error) Possible null pointer dereference: p\n"
|
|
||||||
"[test.cpp:12]: (error) Possible null pointer dereference: p\n"*/
|
|
||||||
, errout.str());
|
, errout.str());
|
||||||
|
|
||||||
check("void f(std::string s1) {\n"
|
check("void f(std::string s1) {\n"
|
||||||
|
|
Loading…
Reference in New Issue