diff --git a/lib/checkmemoryleak.cpp b/lib/checkmemoryleak.cpp index 355d10571..f46fd78d8 100644 --- a/lib/checkmemoryleak.cpp +++ b/lib/checkmemoryleak.cpp @@ -517,13 +517,30 @@ const char *CheckMemoryLeak::functionArgAlloc(const Function *func, unsigned int } -bool CheckMemoryLeakInFunction::notvar(const Token *tok, unsigned int varid) +static bool notvar(const Token *tok, unsigned int varid) { if (!tok) return false; if (Token::Match(tok, "&&|;")) return notvar(tok->astOperand1(),varid) || notvar(tok->astOperand2(),varid); - return tok->str() == "!" && tok->astOperand1()->varId() == varid; + + if (tok->str() == "!") + tok = tok->astOperand1(); + else if (tok->str() == "==") { + if (Token::simpleMatch(tok->astOperand1(), "0")) + tok = tok->astOperand2(); + else if (Token::simpleMatch(tok->astOperand2(), "0")) + tok = tok->astOperand1(); + else + return false; + } else { + return false; + } + + while (tok && tok->str() == ".") + tok = tok->astOperand2(); + + return tok && tok->varId() == varid; } @@ -1040,15 +1057,10 @@ Token *CheckMemoryLeakInFunction::getcode(const Token *tok, std::listnext()->astOperand2(), varid)) addtoken(&rettail, tok, "if(!var)"); - } else if (tok->next() && - tok->next()->link() && - Token::Match(tok->next()->link()->tokAt(-3), "&& ! %varid%", varid)) { - addtoken(&rettail, tok, "if(!var)"); - } else { + else addtoken(&rettail, tok, (dep ? "ifv" : "if")); - } tok = tok->next()->link(); continue; @@ -2579,7 +2591,8 @@ void CheckMemoryLeakStructMember::checkStructVariable(const Variable * const var } // failed allocation => skip code.. - else if (Token::Match(tok3, "if ( ! %var% . %varid% )", structmemberid)) { + else if (Token::simpleMatch(tok3, "if (") && + notvar(tok3->next()->astOperand2(), structmemberid)) { // Goto the ")" tok3 = tok3->next()->link(); diff --git a/lib/checkmemoryleak.h b/lib/checkmemoryleak.h index e82f7f8c6..4abc05e2d 100644 --- a/lib/checkmemoryleak.h +++ b/lib/checkmemoryleak.h @@ -215,14 +215,6 @@ public: */ void checkReallocUsage(); - /** - * @brief %Check if there is a "!var" match inside a condition - * @param tok first token to match - * @param varid variable id - * @return true if match - */ - static bool notvar(const Token *tok, unsigned int varid); - /** * Inspect a function call. the call_func and getcode are recursive * @param tok token where the function call occurs diff --git a/lib/checkstl.cpp b/lib/checkstl.cpp index 3b234196d..c3a3a0764 100644 --- a/lib/checkstl.cpp +++ b/lib/checkstl.cpp @@ -750,7 +750,7 @@ static bool if_findCompare(const Token * const tokBack) if (!tok) return true; if (tok->isComparisonOp()) - return true; + return (!tok->astOperand1()->isNumber() && !tok->astOperand2()->isNumber()); if (tok->isArithmeticalOp()) // result is used in some calculation return true; // TODO: check if there is a comparison of the result somewhere if (tok->str() == ".") @@ -773,11 +773,7 @@ void CheckStl::if_find() if ((i->type != Scope::eIf && i->type != Scope::eWhile) || !i->classDef) continue; - const Token* tok = i->classDef->next(); - if (tok->str() == "if") - tok = tok->next(); - - for (const Token* const end = tok->link(); tok != end; tok = (tok == end) ? end : tok->next()) { + for (const Token *tok = i->classDef; tok->str() != "{"; tok = tok->next()) { const Token* funcTok = nullptr; const Library::Container* container = nullptr; diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index abe18f775..a385a9864 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -3702,12 +3702,11 @@ bool Tokenizer::simplifyTokenList2() simplifyErrNoInWhile(); simplifyIfAndWhileAssign(); simplifyRedundantParentheses(); - simplifyIfNot(); simplifyIfSameInnerCondition(); simplifyNestedStrcat(); simplifyFuncInWhile(); - simplifyIfAndWhileAssign(); // Could be affected by simplifyIfNot + simplifyIfAndWhileAssign(); // replace strlen(str) for (Token *tok = list.front(); tok; tok = tok->next()) { @@ -5871,7 +5870,9 @@ void Tokenizer::simplifyIfAndWhileAssign() { for (Token *tok = list.front(); tok; tok = tok->next()) { if (!Token::Match(tok->next(), "if|while ( !| (| %name% =") && - !Token::Match(tok->next(), "if|while ( !| (| %name% . %name% =")) + !Token::Match(tok->next(), "if|while ( !| (| %name% . %name% =") && + !Token::Match(tok->next(), "if|while ( 0 == (| %name% =") && + !Token::Match(tok->next(), "if|while ( 0 == (| %name% . %name% =")) continue; // simplifying a "while(cond) { }" condition ? @@ -5885,9 +5886,9 @@ void Tokenizer::simplifyIfAndWhileAssign() tok->deleteNext(); // Remember if there is a "!" or not. And delete it if there are. - const bool isNot(tok->strAt(2) == "!"); + const bool isNot(Token::Match(tok->tokAt(2), "!|0")); if (isNot) - tok->next()->deleteNext(); + tok->next()->deleteNext((tok->strAt(2) == "0") ? 2 : 1); // Delete parentheses.. and remember how many there are with // their links. @@ -6008,66 +6009,6 @@ void Tokenizer::simplifyVariableMultipleAssign() } } - -void Tokenizer::simplifyIfNot() -{ - for (Token *tok = list.front(); tok; tok = tok->next()) { - if (Token::Match(tok, "(|&&|%oror%")) { - tok = tok->next(); - while (tok && tok->str() == "(") - tok = tok->next(); - - if (!tok) - break; - - if (Token::Match(tok, "0|false == %name%|(")) { - tok->deleteNext(); - tok->str("!"); - } - - else if (Token::Match(tok, "%name% == 0|false")) { - tok->deleteNext(2); - tok = tok->previous(); - tok->insertToken("!"); - tok = tok->next(); - } - - else if (Token::Match(tok, "%name% .|:: %name% == 0|false")) { - tok = tok->previous(); - tok->insertToken("!"); - tok = tok->tokAt(4); - tok->deleteNext(2); - } - - else if (Token::Match(tok, "* %name% == 0|false")) { - tok = tok->previous(); - tok->insertToken("!"); - tok = tok->tokAt(3); - tok->deleteNext(2); - } - } - - else if (tok->link() && Token::Match(tok, ") == 0|false")) { - // if( foo(x) == 0 ) - if (Token::Match(tok->link()->tokAt(-2), "( %name%")) { - tok->deleteNext(2); - tok->link()->previous()->insertToken(tok->link()->previous()->str()); - tok->link()->tokAt(-2)->str("!"); - } - - // if( (x) == 0 ) - else if (tok->link()->strAt(-1) == "(") { - tok->deleteNext(2); - tok->link()->insertToken("("); - tok->link()->str("!"); - Token *temp = tok->link(); - Token::createMutualLinks(tok->link()->next(), tok); - temp->link(0); - } - } - } -} - void Tokenizer::simplifyIfSameInnerCondition() { // same inner condition diff --git a/lib/tokenize.h b/lib/tokenize.h index 4e3869314..6f4ad5c3f 100644 --- a/lib/tokenize.h +++ b/lib/tokenize.h @@ -299,12 +299,6 @@ public: */ void simplifyVariableMultipleAssign(); - /** - * simplify if-not - * Example: "if(0==x);" => "if(!x);" - */ - void simplifyIfNot(); - /** @brief simplify if (a) { if (a) */ void simplifyIfSameInnerCondition(); diff --git a/test/testsimplifytokens.cpp b/test/testsimplifytokens.cpp index 2ce40841d..5e4a68b3f 100644 --- a/test/testsimplifytokens.cpp +++ b/test/testsimplifytokens.cpp @@ -97,9 +97,6 @@ private: TEST_CASE(doWhileAssign); // varid TEST_CASE(test_4881); // similar to doWhileAssign (#4911), taken from #4881 with full code - // "if(0==x)" => "if(!x)" - TEST_CASE(simplifyIfNot); - TEST_CASE(combine_wstrings); // Simplify "not" to "!" (#345) @@ -364,7 +361,7 @@ private: void cast() { - ASSERT_EQUALS("if ( ! p ) { ; }", tok("if (p == (char *)0);")); + ASSERT_EQUALS("if ( p == 0 ) { ; }", tok("if (p == (char *)0);")); ASSERT_EQUALS("return str ;", tok("return (char *)str;")); ASSERT_EQUALS("if ( * a )", tok("if ((char)*a)")); @@ -372,7 +369,7 @@ private: ASSERT_EQUALS("if ( * a )", tok("if ((unsigned int)(unsigned char)*a)")); ASSERT_EQUALS("class A { A operator* ( int ) ; } ;", tok("class A { A operator *(int); };")); ASSERT_EQUALS("class A { A operator* ( int ) const ; } ;", tok("class A { A operator *(int) const; };")); - ASSERT_EQUALS("if ( ! p ) { ; }", tok("if (p == (char *)(char *)0);")); + ASSERT_EQUALS("if ( p == 0 ) { ; }", tok("if (p == (char *)(char *)0);")); // no simplification as the cast may be important here. see #2897 for example ASSERT_EQUALS("; * ( ( char * ) p + 1 ) = 0 ;", tok("; *((char *)p + 1) = 0;")); @@ -684,11 +681,11 @@ private: ASSERT_EQUALS("void f ( ) { int p ; if ( -1 == p ) { } }", tok("void f(){int p; if(-1==(p)){}}")); ASSERT_EQUALS("void f ( ) { int p ; if ( p ) { } }", tok("void f(){int p; if((p)){}}")); ASSERT_EQUALS("return p ;", tok("return (p);")); - ASSERT_EQUALS("void f ( ) { int * p ; if ( ! * p ) { } }", tok("void f(){int *p; if (*(p) == 0) {}}")); - ASSERT_EQUALS("void f ( ) { int * p ; if ( ! * p ) { } }", tok("void f(){int *p; if (*p == 0) {}}")); + ASSERT_EQUALS("void f ( ) { int * p ; if ( * p == 0 ) { } }", tok("void f(){int *p; if (*(p) == 0) {}}")); + ASSERT_EQUALS("void f ( ) { int * p ; if ( * p == 0 ) { } }", tok("void f(){int *p; if (*p == 0) {}}")); ASSERT_EQUALS("void f ( int & p ) { p = 1 ; }", tok("void f(int &p) {(p) = 1;}")); ASSERT_EQUALS("void f ( ) { int p [ 10 ] ; p [ 0 ] = 1 ; }", tok("void f(){int p[10]; (p)[0] = 1;}")); - ASSERT_EQUALS("void f ( ) { int p ; if ( ! p ) { } }", tok("void f(){int p; if ((p) == 0) {}}")); + ASSERT_EQUALS("void f ( ) { int p ; if ( p == 0 ) { } }", tok("void f(){int p; if ((p) == 0) {}}")); ASSERT_EQUALS("void f ( ) { int * p ; * p = 1 ; }", tok("void f(){int *p; *(p) = 1;}")); ASSERT_EQUALS("void f ( ) { int p ; if ( p ) { } p = 1 ; }", tok("void f(){int p; if ( p ) { } (p) = 1;}")); ASSERT_EQUALS("void f ( ) { a . b ; }", tok("void f ( ) { ( & a ) -> b ; }")); // Ticket #5776 @@ -824,7 +821,7 @@ private: "else { " "if ( g == 2 ) " "{ " - "if ( ! f ) { coo ( ) ; } " + "if ( f == 0 ) { coo ( ) ; } " "else { " "if ( f == 1 ) " "{ " @@ -1592,7 +1589,7 @@ private: "{ " "FILE * f ; " "f = fopen ( \"foo\" , \"r\" ) ; " - "if ( ! f ) " + "if ( f == 0 ) " "{ " "return -1 ; " "} " @@ -1673,19 +1670,6 @@ private: ASSERT_EQUALS("; do { current = f ( ) ; } while ( ( current ) != 0 ) ;", simplifyIfAndWhileAssign(";do { } while((current=f()) != NULL);")); } - void simplifyIfNot() { - ASSERT_EQUALS("if ( ! x ) { ; }", tok("if(0==x);")); - ASSERT_EQUALS("if ( ! x ) { ; }", tok("if(x==0);")); - ASSERT_EQUALS("if ( ! ( a = b ) ) { ; }", tok("if(0==(a=b));")); - ASSERT_EQUALS("if ( ! a && b ( ) ) { ; }", tok("if( 0 == a && b() );")); - ASSERT_EQUALS("if ( b ( ) && ! a ) { ; }", tok("if( b() && 0 == a );")); - ASSERT_EQUALS("if ( ! ( a = b ) ) { ; }", tok("if((a=b)==0);")); - ASSERT_EQUALS("if ( ! x . y ) { ; }", tok("if(x.y==0);")); - ASSERT_EQUALS("if ( ! x ) { ; }", tok("if((x==0));")); - ASSERT_EQUALS("if ( ( ! x ) && ! y ) { ; }", tok("if((x==0) && y==0);")); - ASSERT_EQUALS("if ( ! ( ! fclose ( fd ) ) ) { ; }", tok("if(!(fclose(fd) == 0));")); - } - void not1() { ASSERT_EQUALS("void f ( ) { if ( ! p ) { ; } }", tok("void f() { if (not p); }", "test.c", false)); ASSERT_EQUALS("void f ( ) { if ( p && ! q ) { ; } }", tok("void f() { if (p && not q); }", "test.c", false)); diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index acc8cbfab..862492f42 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -84,7 +84,6 @@ private: TEST_CASE(removeCast3); TEST_CASE(removeCast4); TEST_CASE(removeCast5); - TEST_CASE(removeCast6); TEST_CASE(removeCast7); TEST_CASE(removeCast8); TEST_CASE(removeCast9); @@ -971,11 +970,6 @@ private: ASSERT_EQUALS("a . data = f ;", tokenizeAndStringify("a->data = reinterpret_cast(static_cast(f));", true)); } - void removeCast6() { - // ticket #2103 - ASSERT_EQUALS("if ( ! x ) { ; }", tokenizeAndStringify("if (x == (char *) ((void *)0)) ;", true)); - } - void removeCast7() { ASSERT_EQUALS("str = malloc ( 3 )", tokenizeAndStringify("str=(char **)malloc(3)", true)); }