-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix #11311 Do not search for null pointer in dead code #6442
Changes from 2 commits
d2f546c
9e7c76d
d56945f
1b5cbc7
f0eb67b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -24,6 +24,7 @@ | |
#include "ctu.h" | ||
#include "errorlogger.h" | ||
#include "errortypes.h" | ||
#include "findtoken.h" | ||
#include "library.h" | ||
#include "mathlib.h" | ||
#include "settings.h" | ||
|
@@ -279,47 +280,72 @@ static bool isNullablePointer(const Token* tok) | |
return false; | ||
} | ||
|
||
void CheckNullPointer::nullPointerByDeRefAndChec() | ||
static bool isPointerUnevaluated(const Token *tok) | ||
{ | ||
if (isUnevaluated(tok)) | ||
return true; | ||
|
||
while (tok) { | ||
if (isUnevaluated(tok->previous())) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. could you clarify what will There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I want to make sure that the following code does not trigger a warning.
I need to check whether the variable |
||
return true; | ||
|
||
tok = tok->astParent(); | ||
} | ||
return false; | ||
} | ||
|
||
|
||
void CheckNullPointer::nullPointerByDeRefAndCheck() | ||
{ | ||
const bool printInconclusive = (mSettings->certainty.isEnabled(Certainty::inconclusive)); | ||
|
||
for (const Token *tok = mTokenizer->tokens(); tok; tok = tok->next()) { | ||
if (isUnevaluated(tok)) { | ||
tok = tok->linkAt(1); | ||
continue; | ||
} | ||
const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); | ||
for (const Scope * scope : symbolDatabase->functionScopes) { | ||
auto pred = [printInconclusive](const Token* tok) -> bool { | ||
if (!tok) | ||
return false; | ||
|
||
if (Token::Match(tok, "%num%|%char%|%str%")) | ||
continue; | ||
if (Token::Match(tok, "%num%|%char%|%str%")) | ||
return false; | ||
|
||
if (!isNullablePointer(tok) || | ||
(tok->str() == "." && isNullablePointer(tok->astOperand2()) && tok->astOperand2()->getValue(0))) // avoid duplicate warning | ||
continue; | ||
if (!isNullablePointer(tok) || | ||
(tok->str() == "." && isNullablePointer(tok->astOperand2()) && tok->astOperand2()->getValue(0))) // avoid duplicate warning | ||
return false; | ||
|
||
// Can pointer be NULL? | ||
const ValueFlow::Value *value = tok->getValue(0); | ||
if (!value) | ||
continue; | ||
// Can pointer be NULL? | ||
const ValueFlow::Value *value = tok->getValue(0); | ||
if (!value) | ||
return false; | ||
|
||
if (!printInconclusive && value->isInconclusive()) | ||
continue; | ||
if (!printInconclusive && value->isInconclusive()) | ||
return false; | ||
|
||
// Pointer dereference. | ||
bool unknown = false; | ||
if (!isPointerDeRef(tok,unknown)) { | ||
if (unknown) | ||
nullPointerError(tok, tok->expressionString(), value, true); | ||
continue; | ||
} | ||
return true; | ||
}; | ||
std::vector<const Token *> tokens = findTokensSkipDeadCode(mSettings->library, scope->bodyStart, scope->bodyEnd, pred); | ||
for (const Token *tok : tokens) { | ||
if (isPointerUnevaluated(tok)) | ||
continue; | ||
|
||
nullPointerError(tok, tok->expressionString(), value, value->isInconclusive()); | ||
const ValueFlow::Value *value = tok->getValue(0); | ||
|
||
// Pointer dereference. | ||
bool unknown = false; | ||
if (!isPointerDeRef(tok, unknown)) { | ||
if (unknown) | ||
nullPointerError(tok, tok->expressionString(), value, true); | ||
continue; | ||
} | ||
|
||
nullPointerError(tok, tok->expressionString(), value, value->isInconclusive()); | ||
} | ||
} | ||
} | ||
|
||
void CheckNullPointer::nullPointer() | ||
{ | ||
logChecker("CheckNullPointer::nullPointer"); | ||
nullPointerByDeRefAndChec(); | ||
nullPointerByDeRefAndCheck(); | ||
} | ||
|
||
namespace { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be checked in
findTokensSkipDeadCodeImpl
function.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@danmar @pfultz2 I updated my PR to move this in
findTokensSkipDeadAndUnevaluatedCode
function because I was not very happy with the way I detected unevaluated pointers.