Fixed #3567 (False positives in boolean expressions)

This commit is contained in:
August Sodora 2012-03-07 20:31:23 +01:00 committed by Daniel Marjamäki
parent 680883a6a7
commit e0bee0e037
4 changed files with 59 additions and 1 deletions

View File

@ -1152,6 +1152,13 @@ private:
for (it = checks.begin(); it != checks.end(); ++it) {
Nullpointer *c = dynamic_cast<Nullpointer *>(*it);
if (c && c->varId == varid && c->null) {
if ((Token::Match(tok->tokAt(-4), "[=[(,] %var% && * %var% ,|]|)|;|=|%op%") ||
Token::Match(tok->tokAt(-5), "[=[(,] ! %var% %oror% * %var% ,|]|)|;|=|%op%") ||
Token::Match(tok->tokAt(-4), "return|case %var% && * %var% ,|:|;|=|%op%") ||
Token::Match(tok->tokAt(-5), "return|case ! %var% %oror% * %var% ,|:|;|=|%op%")) &&
tok->tokAt(-3) && (tok->tokAt(-3)->varId() == tok->varId()))
return;
CheckNullPointer *checkNullPointer = dynamic_cast<CheckNullPointer *>(c->owner);
if (checkNullPointer) {
checkNullPointer->nullPointerError(tok, c->varname);

View File

@ -784,7 +784,36 @@ bool TemplateSimplifier::simplifyCalculations(Token *_tokens)
tok->deleteThis();
ret = true;
} else if (Token::Match(tok->previous(), "[=[(,] 0 * %any% ,|]|)|;|=|%op%") ||
Token::Match(tok->previous(), "return|case 0 * %any% ,|:|;|=|%op%")) {
Token::Match(tok->previous(), "[=[(,] 0 && %any% ,|]|)|;|=|%op%") ||
Token::Match(tok->previous(), "return|case 0 * %any% ,|:|;|=|%op%") ||
Token::Match(tok->previous(), "return|case 0 && %any% ,|:|;|=|%op%")) {
tok->deleteNext();
if (tok->next()->str() == "(")
Token::eraseTokens(tok, tok->next()->link());
tok->deleteNext();
ret = true;
} else if (Token::Match(tok->previous(), "[=[(,] 0 && *|& %any% ,|]|)|;|=|%op%") ||
Token::Match(tok->previous(), "return|case 0 && *|& %any% ,|:|;|=|%op%")) {
tok->deleteNext();
tok->deleteNext();
if (tok->next()->str() == "(")
Token::eraseTokens(tok, tok->next()->link());
tok->deleteNext();
ret = true;
}
}
if (tok->str() == "1") {
if (Token::Match(tok->previous(), "[=[(,] 1 %oror% %any% ,|]|)|;|=|%op%") ||
Token::Match(tok->previous(), "return|case 1 %oror% %any% ,|:|;|=|%op%")) {
tok->deleteNext();
if (tok->next()->str() == "(")
Token::eraseTokens(tok, tok->next()->link());
tok->deleteNext();
ret = true;
} else if (Token::Match(tok->previous(), "[=[(,] 1 %oror% *|& %any% ,|]|)|;|=|%op%") ||
Token::Match(tok->previous(), "return|case 1 %oror% *|& %any% ,|:|;|=|%op%")) {
tok->deleteNext();
tok->deleteNext();
if (tok->next()->str() == "(")
Token::eraseTokens(tok, tok->next()->link());

View File

@ -50,6 +50,7 @@ private:
TEST_CASE(nullpointer14);
TEST_CASE(nullpointer15); // #3560 (fp: return p ? f(*p) : f(0))
TEST_CASE(nullpointer16); // #3591
TEST_CASE(nullpointer17); // #3567
TEST_CASE(pointerCheckAndDeRef); // check if pointer is null and then dereference it
TEST_CASE(nullConstantDereference); // Dereference NULL constant
TEST_CASE(gcc_statement_expression); // Don't crash
@ -1210,6 +1211,20 @@ private:
ASSERT_EQUALS("", errout.str());
}
void nullpointer17() { // #3567
check("int foo() {\n"
" int *p = 0;\n"
" return (!p || *p);\n"
"}");
ASSERT_EQUALS("", errout.str());
check("int foo() {\n"
" int *p = 0;\n"
" return p && *p;\n"
"}");
ASSERT_EQUALS("", errout.str());
}
// Check if pointer is null and the dereference it
void pointerCheckAndDeRef() {
check("void foo(char *p) {\n"

View File

@ -6045,6 +6045,13 @@ private:
tokenizeAndStringify("bool f(int i) { switch (i) { case 10 + 5: return true; } }", true));
// ticket #3512 - Don't crash on garbage code
ASSERT_EQUALS("p = const", tokenizeAndStringify("1 *p = const", true));
// ticket #3576 - False positives in boolean expressions
ASSERT_EQUALS("int foo ( ) { return 1 ; }",
tokenizeAndStringify("int foo ( ) { int i; int j; i = 1 || j; return i; }", true));
ASSERT_EQUALS("int foo ( ) { return 0 ; }",
tokenizeAndStringify("int foo ( ) { int i; int j; i = 0 && j; return i; }", true));
}
void simplifyCompoundAssignment() {