From 8643936e0c2490030d8255052cdb7d8107393f30 Mon Sep 17 00:00:00 2001 From: Slava Semushin Date: Sat, 25 Jul 2009 18:11:29 +0700 Subject: [PATCH] Fixed ticket #500 (Tokenizer: simplify the "(p != NULL)" conditions) Also teach simplifyIfNot() to handle variables like Foo::var. https://sourceforge.net/apps/trac/cppcheck/ticket/500 --- src/checkmemoryleak.cpp | 4 +-- src/checkother.cpp | 16 ----------- src/tokenize.cpp | 50 +++++++++++++++++++++++++++++++- src/tokenize.h | 8 ++++++ test/testtokenize.cpp | 64 +++++++++++++++++++++++++++++++++++++++++ 5 files changed, 122 insertions(+), 20 deletions(-) diff --git a/src/checkmemoryleak.cpp b/src/checkmemoryleak.cpp index 3095a93f5..f3df3bc2f 100644 --- a/src/checkmemoryleak.cpp +++ b/src/checkmemoryleak.cpp @@ -728,9 +728,7 @@ Token *CheckMemoryLeakInFunction::getcode(const Token *tok, std::liststr() == "if") { - if (Token::simpleMatch(tok, std::string("if ( " + varnameStr + " )").c_str()) || - Token::simpleMatch(tok, std::string("if ( " + varnameStr + " != 0 )").c_str()) || - Token::simpleMatch(tok, std::string("if ( 0 != " + varnameStr + " )").c_str())) + if (Token::simpleMatch(tok, std::string("if ( " + varnameStr + " )").c_str())) { addtoken("if(var)"); diff --git a/src/checkother.cpp b/src/checkother.cpp index 9613a35dc..d2bdfd830 100644 --- a/src/checkother.cpp +++ b/src/checkother.cpp @@ -86,23 +86,12 @@ void CheckOther::warningRedundantCode() /* * Possible if-constructions: * - * if (0 != var) - * if (0 != this->var) - * if (0 != Foo::var) * if (var) * if (this->var) * if (Foo::var) - * if (var != 0) - * if (this->var != 0) - * if (Foo::var != 0) * **/ - if (Token::simpleMatch(tok2, "0 !=")) - { - tok2 = tok2->tokAt(2); - } - if (Token::simpleMatch(tok2, "this .") || Token::Match(tok2, "%var% ::")) { @@ -115,11 +104,6 @@ void CheckOther::warningRedundantCode() tok2 = tok2->next(); } - if (Token::simpleMatch(tok2, "!= 0")) - { - tok2 = tok2->tokAt(2); - } - if (tok2->str() == ")") { tok2 = tok2->next(); diff --git a/src/tokenize.cpp b/src/tokenize.cpp index 79805ab1a..63d0eab61 100644 --- a/src/tokenize.cpp +++ b/src/tokenize.cpp @@ -1478,6 +1478,7 @@ void Tokenizer::simplifyTokenList() elseif(); simplifyIfNot(); + simplifyIfNotNull(); simplifyNot(); simplifyIfAssign(); @@ -2514,7 +2515,7 @@ bool Tokenizer::simplifyIfNot() ret = true; } - else if (Token::Match(tok, "%var% . %var% == 0")) + else if (Token::Match(tok, "%var% .|:: %var% == 0")) { tok = tok->previous(); tok->insertToken("!"); @@ -2538,6 +2539,53 @@ bool Tokenizer::simplifyIfNot() } +bool Tokenizer::simplifyIfNotNull() +{ + // Make sure we have working links + createLinks(); + bool ret = false; + for (Token *tok = _tokens; tok; tok = tok->next()) + { + Token *deleteFrom = NULL; + + if (tok->str() == "(" || tok->str() == "||" || tok->str() == "&&") + { + tok = tok->next(); + + if (Token::simpleMatch(tok, "0 != (") || + Token::Match(tok, "0 != %var%")) + { + deleteFrom = tok->previous(); + } + + else if (Token::Match(tok, "%var% != 0")) + { + deleteFrom = tok; + } + + else if (Token::Match(tok, "%var% .|:: %var% != 0")) + { + tok = tok->tokAt(2); + deleteFrom = tok; + } + } + + else if (tok->link() && Token::simpleMatch(tok, ") != 0")) + { + deleteFrom = tok; + } + + if (deleteFrom) { + deleteFrom->deleteNext(); + deleteFrom->deleteNext(); + ret = true; + } + + } + return ret; +} + + bool Tokenizer::simplifyNot() { // "if (not p)" => "if (!p)" diff --git a/src/tokenize.h b/src/tokenize.h index e536961d0..892e77f35 100644 --- a/src/tokenize.h +++ b/src/tokenize.h @@ -148,6 +148,14 @@ public: */ bool simplifyIfNot(); + /** + * simplify if-not NULL.. + * Example: "if(0!=x);" => "if(x);" + * @return true if something is modified + * false if nothing is done. + */ + bool simplifyIfNotNull(); + /** * simplify the "not" keyword to "!" * Example: "if (not p)" => "if (!p)" diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index 8063ba8c6..6e9ac96a6 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -85,6 +85,7 @@ private: TEST_CASE(whileAddBraces); TEST_CASE(numeric_true_condition); + TEST_CASE(pointers_condition); TEST_CASE(simplifyKnownVariables1); TEST_CASE(simplifyKnownVariables2); @@ -357,6 +358,69 @@ private: "}", tokenizeAndStringify(code, true)); } + void pointers_condition() + { + const char code[] = "void f()\n" + "{\n" + " if (p != NULL);\n" + " if (NULL != p);\n" + " if (this->p != NULL);\n" + " if (NULL != this->p);\n" + " if (Foo::p != NULL);\n" + " if (NULL != Foo::p);\n" + " while (p != NULL);\n" + " while (NULL != p);\n" + " while (this->p != NULL);\n" + " while (NULL != this->p);\n" + " while (Foo::p != NULL);\n" + " while (NULL != Foo::p);\n" + " if (p == NULL);\n" + " if (NULL == p);\n" + " if (this->p == NULL);\n" + " if (NULL == this->p);\n" + " if (Foo::p == NULL);\n" + " if (NULL == Foo::p);\n" + " while (p == NULL);\n" + " while (NULL == p);\n" + " while (this->p == NULL);\n" + " while (NULL == this->p);\n" + " while (Foo::p == NULL);\n" + " while (NULL == Foo::p);\n" + " if (p1 != NULL || p2 == NULL) { ; }\n" + " if (p1 != NULL && p2 == NULL) { ; }\n" + "}\n"; + + ASSERT_EQUALS("void f ( )\n" + "{\n" + "if ( p ) { ; }\n" + "if ( p ) { ; }\n" + "if ( this . p ) { ; }\n" + "if ( this . p ) { ; }\n" + "if ( Foo :: p ) { ; }\n" + "if ( Foo :: p ) { ; }\n" + "while ( p ) { ; }\n" + "while ( p ) { ; }\n" + "while ( this . p ) { ; }\n" + "while ( this . p ) { ; }\n" + "while ( Foo :: p ) { ; }\n" + "while ( Foo :: p ) { ; }\n" + "if ( ! p ) { ; }\n" + "if ( ! p ) { ; }\n" + "if ( ! this . p ) { ; }\n" + "if ( ! this . p ) { ; }\n" + "if ( ! Foo :: p ) { ; }\n" + "if ( ! Foo :: p ) { ; }\n" + "while ( ! p ) { ; }\n" + "while ( ! p ) { ; }\n" + "while ( ! this . p ) { ; }\n" + "while ( ! this . p ) { ; }\n" + "while ( ! Foo :: p ) { ; }\n" + "while ( ! Foo :: p ) { ; }\n" + "if ( p1 || ! p2 ) { ; }\n" + "if ( p1 && ! p2 ) { ; }\n" + "}", tokenizeAndStringify(code, true)); + } + void ifAddBraces1() { const char code[] = "void f()\n"