From e0bee0e037211aec0a6e4b301f475c2c1716675f Mon Sep 17 00:00:00 2001 From: August Sodora Date: Wed, 7 Mar 2012 20:31:23 +0100 Subject: [PATCH] Fixed #3567 (False positives in boolean expressions) --- lib/checknullpointer.cpp | 7 +++++++ lib/templatesimplifier.cpp | 31 ++++++++++++++++++++++++++++++- test/testnullpointer.cpp | 15 +++++++++++++++ test/testtokenize.cpp | 7 +++++++ 4 files changed, 59 insertions(+), 1 deletion(-) diff --git a/lib/checknullpointer.cpp b/lib/checknullpointer.cpp index 90711282b..613957ca1 100644 --- a/lib/checknullpointer.cpp +++ b/lib/checknullpointer.cpp @@ -1152,6 +1152,13 @@ private: for (it = checks.begin(); it != checks.end(); ++it) { Nullpointer *c = dynamic_cast(*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(c->owner); if (checkNullPointer) { checkNullPointer->nullPointerError(tok, c->varname); diff --git a/lib/templatesimplifier.cpp b/lib/templatesimplifier.cpp index 4cb919ce4..8afd2af88 100644 --- a/lib/templatesimplifier.cpp +++ b/lib/templatesimplifier.cpp @@ -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()); diff --git a/test/testnullpointer.cpp b/test/testnullpointer.cpp index 50452334f..08bb23009 100644 --- a/test/testnullpointer.cpp +++ b/test/testnullpointer.cpp @@ -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" diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index b915b5f49..24f89aa91 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -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() {