Fixed #3567 (False positives in boolean expressions)
This commit is contained in:
parent
680883a6a7
commit
e0bee0e037
|
@ -1152,6 +1152,13 @@ private:
|
||||||
for (it = checks.begin(); it != checks.end(); ++it) {
|
for (it = checks.begin(); it != checks.end(); ++it) {
|
||||||
Nullpointer *c = dynamic_cast<Nullpointer *>(*it);
|
Nullpointer *c = dynamic_cast<Nullpointer *>(*it);
|
||||||
if (c && c->varId == varid && c->null) {
|
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);
|
CheckNullPointer *checkNullPointer = dynamic_cast<CheckNullPointer *>(c->owner);
|
||||||
if (checkNullPointer) {
|
if (checkNullPointer) {
|
||||||
checkNullPointer->nullPointerError(tok, c->varname);
|
checkNullPointer->nullPointerError(tok, c->varname);
|
||||||
|
|
|
@ -784,7 +784,36 @@ bool TemplateSimplifier::simplifyCalculations(Token *_tokens)
|
||||||
tok->deleteThis();
|
tok->deleteThis();
|
||||||
ret = true;
|
ret = true;
|
||||||
} else if (Token::Match(tok->previous(), "[=[(,] 0 * %any% ,|]|)|;|=|%op%") ||
|
} 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();
|
tok->deleteNext();
|
||||||
if (tok->next()->str() == "(")
|
if (tok->next()->str() == "(")
|
||||||
Token::eraseTokens(tok, tok->next()->link());
|
Token::eraseTokens(tok, tok->next()->link());
|
||||||
|
|
|
@ -50,6 +50,7 @@ private:
|
||||||
TEST_CASE(nullpointer14);
|
TEST_CASE(nullpointer14);
|
||||||
TEST_CASE(nullpointer15); // #3560 (fp: return p ? f(*p) : f(0))
|
TEST_CASE(nullpointer15); // #3560 (fp: return p ? f(*p) : f(0))
|
||||||
TEST_CASE(nullpointer16); // #3591
|
TEST_CASE(nullpointer16); // #3591
|
||||||
|
TEST_CASE(nullpointer17); // #3567
|
||||||
TEST_CASE(pointerCheckAndDeRef); // check if pointer is null and then dereference it
|
TEST_CASE(pointerCheckAndDeRef); // check if pointer is null and then dereference it
|
||||||
TEST_CASE(nullConstantDereference); // Dereference NULL constant
|
TEST_CASE(nullConstantDereference); // Dereference NULL constant
|
||||||
TEST_CASE(gcc_statement_expression); // Don't crash
|
TEST_CASE(gcc_statement_expression); // Don't crash
|
||||||
|
@ -1210,6 +1211,20 @@ private:
|
||||||
ASSERT_EQUALS("", errout.str());
|
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
|
// Check if pointer is null and the dereference it
|
||||||
void pointerCheckAndDeRef() {
|
void pointerCheckAndDeRef() {
|
||||||
check("void foo(char *p) {\n"
|
check("void foo(char *p) {\n"
|
||||||
|
|
|
@ -6045,6 +6045,13 @@ private:
|
||||||
tokenizeAndStringify("bool f(int i) { switch (i) { case 10 + 5: return true; } }", true));
|
tokenizeAndStringify("bool f(int i) { switch (i) { case 10 + 5: return true; } }", true));
|
||||||
// ticket #3512 - Don't crash on garbage code
|
// ticket #3512 - Don't crash on garbage code
|
||||||
ASSERT_EQUALS("p = const", tokenizeAndStringify("1 *p = const", true));
|
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() {
|
void simplifyCompoundAssignment() {
|
||||||
|
|
Loading…
Reference in New Issue