diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index ce4a6acbf..865987658 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -5362,37 +5362,17 @@ bool Tokenizer::simplifyTokenList2() // e.g. const static int value = sizeof(X)/sizeof(Y); simplifyCalculations(); - if (Settings::terminated()) - return false; - - simplifyRealloc(); - - // Change initialisation of variable to assignment - simplifyInitVar(); - - // Simplify variable declarations - simplifyVarDecl(false); - - simplifyIfAndWhileAssign(); - simplifyRedundantParentheses(); simplifyNestedStrcat(); simplifyFuncInWhile(); - simplifyIfAndWhileAssign(); - - bool modified = true; while (modified) { if (Settings::terminated()) return false; modified = false; - modified |= simplifyConditions(); - modified |= simplifyFunctionReturn(); modified |= simplifyKnownVariables(); - modified |= removeRedundantConditions(); - modified |= simplifyRedundantParentheses(); modified |= simplifyConstTernaryOp(); modified |= simplifyCalculations(); validate(); @@ -5942,51 +5922,6 @@ void Tokenizer::addSemicolonAfterUnknownMacro() } //--------------------------------------------------------------------------- -void Tokenizer::simplifyRealloc() -{ - for (Token *tok = list.front(); tok; tok = tok->next()) { - if (Token::Match(tok, "(|[") || - (tok->str() == "{" && tok->previous() && tok->previous()->str() == "=")) - tok = tok->link(); - else if (Token::Match(tok, "[;{}] %name% = realloc (")) { - tok = tok->tokAt(3); - if (Token::simpleMatch(tok->next(), "( 0 ,")) { - //no "x = realloc(0,);" - if (!Token::simpleMatch(tok->next()->link(), ") ;") || tok->next()->link()->previous() == tok->tokAt(3)) - continue; - - // delete "0 ," - tok->next()->deleteNext(2); - - // Change function name "realloc" to "malloc" - tok->str("malloc"); - tok = tok->next()->link(); - } else { - Token *tok2 = tok->next()->link()->tokAt(-2); - //no "x = realloc(,0);" - if (!Token::simpleMatch(tok2, ", 0 ) ;") || tok2 == tok->tokAt(2)) - continue; - - //remove ", 0" - tok2 = tok2->previous(); - tok2->deleteNext(2); - //change "realloc" to "free" - tok->str("free"); - //insert "0" after "var =" - tok = tok->previous(); - tok->insertToken("0"); - //move "var = 0" between "free(...)" and ";" - tok2 = tok2->next(); - Token::move(tok->previous(), tok->next(), tok2); - //add missing ";" after "free(...)" - tok2->insertToken(";"); - //goto before last ";" and continue - tok = tok->next(); - } - } - } -} - void Tokenizer::simplifyEmptyNamespaces() { if (isC()) @@ -6102,73 +6037,6 @@ void Tokenizer::simplifyFlowControl() } -bool Tokenizer::removeRedundantConditions() -{ - // Return value for function. Set to true if there are any simplifications - bool ret = false; - - for (Token *tok = list.front(); tok; tok = tok->next()) { - if (!Token::Match(tok, "if ( %bool% ) {")) - continue; - - // Find matching else - Token *elseTag = tok->linkAt(4)->next(); - - const bool boolValue = (tok->strAt(2) == "true"); - - // Handle if with else - if (Token::simpleMatch(elseTag, "else {")) { - // Handle else - if (!boolValue) { - // Convert "if( false ) {aaa;} else {bbb;}" => "{bbb;}" - - //remove '(false)' - tok->deleteNext(3); - //delete dead code inside scope - eraseDeadCode(tok, elseTag); - //remove 'else' - elseTag->deleteThis(); - //remove 'if' - tok->deleteThis(); - } else { - // Convert "if( true ) {aaa;} else {bbb;}" => "{aaa;}" - const Token *end = elseTag->next()->link()->next(); - - // Remove "else { bbb; }" - elseTag = elseTag->previous(); - eraseDeadCode(elseTag, end); - - // Remove "if( true )" - tok->deleteNext(3); - tok->deleteThis(); - } - - ret = true; - } - - // Handle if without else - else { - if (!boolValue) { - //remove '(false)' - tok->deleteNext(3); - //delete dead code inside scope - eraseDeadCode(tok, elseTag); - //remove 'if' - tok->deleteThis(); - } else { - // convert "if( true ) {aaa;}" => "{aaa;}" - tok->deleteNext(3); - tok->deleteThis(); - } - - ret = true; - } - } - - return ret; -} - - void Tokenizer::removeRedundantSemicolons() { for (Token *tok = list.front(); tok; tok = tok->next()) { @@ -6339,165 +6207,6 @@ Token *Tokenizer::simplifyAddBracesPair(Token *tok, bool commandWithCondition) return tokBracesEnd; } -bool Tokenizer::simplifyConditions() -{ - bool ret = false; - - for (Token *tok = list.front(); tok; tok = tok->next()) { - if (Token::Match(tok, "! %bool%|%num%")) { - tok->deleteThis(); - if (Token::Match(tok, "0|false")) - tok->str("true"); - else - tok->str("false"); - - ret = true; - } - - if (Token::simpleMatch(tok, "&& true &&")) { - tok->deleteNext(2); - ret = true; - } - - else if (Token::simpleMatch(tok, "|| false ||")) { - tok->deleteNext(2); - ret = true; - } - - else if (Token::Match(tok, "(|&& true && true &&|)")) { - tok->deleteNext(2); - ret = true; - } - - else if (Token::Match(tok, "%oror%|( false %oror% false %oror%|)")) { - tok->deleteNext(2); - ret = true; - } - - else if (Token::simpleMatch(tok, "( true ||") || - Token::simpleMatch(tok, "( false &&")) { - Token::eraseTokens(tok->next(), tok->link()); - ret = true; - } - - else if (Token::simpleMatch(tok, "|| true )") || - Token::simpleMatch(tok, "&& false )")) { - tok = tok->next(); - Token::eraseTokens(tok->next()->link(), tok); - ret = true; - } - - else if (Token::simpleMatch(tok, "&& false &&") || - Token::simpleMatch(tok, "|| true ||")) { - //goto '(' - Token *tok2 = tok; - while (tok2 && tok2->previous()) { - if (tok2->previous()->str() == ")") - tok2 = tok2->previous()->link(); - else { - tok2 = tok2->previous(); - if (tok2->str() == "(") - break; - } - } - if (!tok2) - continue; - //move tok to 'true|false' position - tok = tok->next(); - //remove everything before 'true|false' - Token::eraseTokens(tok2, tok); - //remove everything after 'true|false' - Token::eraseTokens(tok, tok2->link()); - ret = true; - } - - // Change numeric constant in condition to "true" or "false" - if (Token::Match(tok, "if|while ( %num% )|%oror%|&&")) { - tok->tokAt(2)->str((tok->strAt(2) != "0") ? "true" : "false"); - ret = true; - } - if (Token::Match(tok, "&&|%oror% %num% )|%oror%|&&")) { - tok->next()->str((tok->next()->str() != "0") ? "true" : "false"); - ret = true; - } - - // Reduce "(%num% == %num%)" => "(true)"/"(false)" - if (Token::Match(tok, "&&|%oror%|(") && - (Token::Match(tok->next(), "%num% %any% %num%") || - Token::Match(tok->next(), "%bool% %any% %bool%")) && - Token::Match(tok->tokAt(4), "&&|%oror%|)|?")) { - std::string cmp = tok->strAt(2); - bool result = false; - if (tok->next()->isNumber()) { - // Compare numbers - - if (cmp == "==" || cmp == "!=") { - const std::string& op1(tok->next()->str()); - const std::string& op2(tok->strAt(3)); - - bool eq = false; - if (MathLib::isInt(op1) && MathLib::isInt(op2)) - eq = (MathLib::toLongNumber(op1) == MathLib::toLongNumber(op2)); - else { - eq = (op1 == op2); - - // It is inconclusive whether two unequal float representations are numerically equal - if (!eq && MathLib::isFloat(op1)) - cmp.clear(); - } - - if (cmp == "==") - result = eq; - else - result = !eq; - } else { - const double op1 = MathLib::toDoubleNumber(tok->next()->str()); - const double op2 = MathLib::toDoubleNumber(tok->strAt(3)); - if (cmp == ">=") - result = (op1 >= op2); - else if (cmp == ">") - result = (op1 > op2); - else if (cmp == "<=") - result = (op1 <= op2); - else if (cmp == "<") - result = (op1 < op2); - else - cmp.clear(); - } - } else { - // Compare boolean - const bool op1 = (tok->next()->str() == std::string("true")); - const bool op2 = (tok->strAt(3) == std::string("true")); - - if (cmp == "==") - result = (op1 == op2); - else if (cmp == "!=") - result = (op1 != op2); - else if (cmp == ">=") - result = (op1 || !op2); - else if (cmp == ">") - result = (op1 && !op2); - else if (cmp == "<=") - result = (!op1 || op2); - else if (cmp == "<") - result = (!op1 && op2); - else - cmp.clear(); - } - - if (!cmp.empty()) { - tok = tok->next(); - tok->deleteNext(2); - - tok->str(result ? "true" : "false"); - ret = true; - } - } - } - - return ret; -} - bool Tokenizer::simplifyConstTernaryOp() { bool ret = false; @@ -6996,41 +6705,6 @@ void Tokenizer::simplifyFunctionPointers() } } - -bool Tokenizer::simplifyFunctionReturn() -{ - std::map functions; - - for (const Token *tok = tokens(); tok; tok = tok->next()) { - if (tok->str() == "{") - tok = tok->link(); - - else if (Token::Match(tok, "%name% ( ) { return %bool%|%char%|%num%|%str% ; }") && tok->strAt(-1) != "::") { - const Token* const any = tok->tokAt(5); - functions[tok->str()] = any; - tok = any; - } - } - - if (functions.empty()) - return false; - - bool ret = false; - for (Token *tok = list.front(); tok; tok = tok->next()) { - if (Token::Match(tok, "(|[|=|return|%op% %name% ( ) ;|]|)|%cop%")) { - tok = tok->next(); - auto it = functions.find(tok->str()); - if (it != functions.cend()) { - tok->str(it->second->str()); - tok->deleteNext(2); - ret = true; - } - } - } - - return ret; -} - void Tokenizer::simplifyVarDecl(const bool only_k_r_fpar) { simplifyVarDecl(list.front(), nullptr, only_k_r_fpar); @@ -7455,123 +7129,6 @@ void Tokenizer::simplifyStaticConst() } } -void Tokenizer::simplifyIfAndWhileAssign() -{ - for (Token *tok = list.front(); tok; tok = tok->next()) { - if (!Token::Match(tok->next(), "if|while (")) - continue; - - const Token* tokAt3 = tok->tokAt(3); - if (!Token::Match(tokAt3, "!| (| %name% =") && - !Token::Match(tokAt3, "!| (| %name% . %name% =") && - !Token::Match(tokAt3, "0 == (| %name% =") && - !Token::Match(tokAt3, "0 == (| %name% . %name% =")) - continue; - - // simplifying a "while(cond) { }" condition ? - const bool iswhile(tok->next()->str() == "while"); - - // simplifying a "do { } while(cond);" condition ? - const bool isDoWhile = iswhile && Token::simpleMatch(tok, "}") && Token::simpleMatch(tok->link()->previous(), "do"); - Token* openBraceTok = tok->link(); - - // delete the "if|while" - tok->deleteNext(); - - // Remember if there is a "!" or not. And delete it if there are. - const bool isNot(Token::Match(tok->tokAt(2), "!|0")); - if (isNot) - tok->next()->deleteNext((tok->strAt(2) == "0") ? 2 : 1); - - // Delete parentheses.. and remember how many there are with - // their links. - std::stack braces; - while (tok->next()->str() == "(") { - braces.push(tok->next()->link()); - tok->deleteNext(); - } - - // Skip the "%name% = ..." - Token *tok2; - for (tok2 = tok->next(); tok2; tok2 = tok2->next()) { - if (tok2->str() == "(") - tok2 = tok2->link(); - else if (tok2->str() == ")") - break; - } - - // Insert "; if|while ( .." - tok2 = tok2->previous(); - if (tok->strAt(2) == ".") { - tok2->insertToken(tok->strAt(3)); - tok2->next()->varId(tok->tokAt(3)->varId()); - tok2->insertToken("."); - } - tok2->insertToken(tok->next()->str()); - tok2->next()->varId(tok->next()->varId()); - - while (!braces.empty()) { - tok2->insertToken("("); - Token::createMutualLinks(tok2->next(), braces.top()); - braces.pop(); - } - - if (isNot) - tok2->next()->insertToken("!"); - tok2->insertToken(iswhile ? "while" : "if"); - if (isDoWhile) { - tok2->insertToken("}"); - Token::createMutualLinks(openBraceTok, tok2->next()); - } - - tok2->insertToken(";"); - - // delete the extra "}" - if (isDoWhile) - tok->deleteThis(); - - // If it's a while loop, insert the assignment in the loop - if (iswhile && !isDoWhile) { - int indentlevel = 0; - Token *tok3 = tok2; - - for (; tok3; tok3 = tok3->next()) { - if (tok3->str() == "{") - ++indentlevel; - else if (tok3->str() == "}") { - if (indentlevel <= 1) - break; - --indentlevel; - } - } - - if (tok3 && indentlevel == 1) { - tok3 = tok3->previous(); - std::stack braces2; - - for (tok2 = tok2->next(); tok2 && tok2 != tok; tok2 = tok2->previous()) { - tok3->insertToken(tok2->str()); - Token *newTok = tok3->next(); - - newTok->varId(tok2->varId()); - newTok->fileIndex(tok2->fileIndex()); - newTok->linenr(tok2->linenr()); - - // link() new tokens manually - if (tok2->link()) { - if (Token::Match(newTok, "}|)|]|>")) { - braces2.push(newTok); - } else { - Token::createMutualLinks(newTok, braces2.top()); - braces2.pop(); - } - } - } - } - } - } -} - void Tokenizer::simplifyVariableMultipleAssign() { for (Token *tok = list.front(); tok; tok = tok->next()) { diff --git a/lib/tokenize.h b/lib/tokenize.h index 35895535a..6910bd71b 100644 --- a/lib/tokenize.h +++ b/lib/tokenize.h @@ -230,12 +230,6 @@ public: /** Remove unknown macro in variable declarations: PROGMEM char x; */ void removeMacroInVarDecl(); - /** Simplifies some realloc usage like - * 'x = realloc (0, n);' => 'x = malloc(n);' - * 'x = realloc (y, 0);' => 'x = 0; free(y);' - */ - void simplifyRealloc(); - /** Add parentheses for sizeof: sizeof x => sizeof(x) */ void sizeofAddParentheses(); @@ -276,14 +270,6 @@ public: */ void simplifyStaticConst(); - /** - * Simplify assignments in "if" and "while" conditions - * Example: "if(a=b);" => "a=b;if(a);" - * Example: "while(a=b) { f(a); }" => "a = b; while(a){ f(a); a = b; }" - * Example: "do { f(a); } while(a=b);" => "do { f(a); a = b; } while(a);" - */ - void simplifyIfAndWhileAssign(); - /** * Simplify multiple assignments. * Example: "a = b = c = 0;" => "a = 0; b = 0; c = 0;" @@ -397,30 +383,11 @@ public: /** Simplify C++17/C++20 if/switch/for initialization expression */ void simplifyIfSwitchForInit(); - /** Simplify conditions - * @return true if something is modified - * false if nothing is done. - */ - bool simplifyConditions(); - - /** Remove redundant code, e.g. if( false ) { int a; } should be - * removed, because it is never executed. - * @return true if something is modified - * false if nothing is done. - */ - bool removeRedundantConditions(); - /** * Reduces "; ;" to ";", except in "( ; ; )" */ void removeRedundantSemicolons(); - /** Simplify function calls - constant return value - * @return true if something is modified - * false if nothing is done. - */ - bool simplifyFunctionReturn(); - /** Struct simplification * "struct S { } s;" => "struct S { }; S s;" */ diff --git a/test/testsimplifytokens.cpp b/test/testsimplifytokens.cpp index c020bd0f3..d3334ddee 100644 --- a/test/testsimplifytokens.cpp +++ b/test/testsimplifytokens.cpp @@ -53,7 +53,6 @@ private: settings_windows.checkUnusedTemplates = true; TEST_CASE(cast); - TEST_CASE(iftruefalse); TEST_CASE(combine_strings); TEST_CASE(combine_wstrings); @@ -71,8 +70,6 @@ private: TEST_CASE(declareArray); TEST_CASE(dontRemoveIncrement); - TEST_CASE(removePostIncrement); - TEST_CASE(removePreIncrement); TEST_CASE(elseif1); @@ -100,16 +97,6 @@ private: TEST_CASE(namespaces); - // Assignment in condition.. - TEST_CASE(ifassign1); - TEST_CASE(ifAssignWithCast); - TEST_CASE(whileAssign1); - TEST_CASE(whileAssign2); - TEST_CASE(whileAssign3); // varid - TEST_CASE(whileAssign4); // links - TEST_CASE(doWhileAssign); // varid - TEST_CASE(test_4881); // similar to doWhileAssign (#4911), taken from #4881 with full code - // Simplify "not" to "!" (#345) TEST_CASE(not1); @@ -132,10 +119,6 @@ private: TEST_CASE(comparisons); TEST_CASE(simplifyCalculations); - //remove dead code after flow control statements - TEST_CASE(simplifyFlowControl); - TEST_CASE(flowControl); - // Simplify nested strcat() calls TEST_CASE(strcat1); TEST_CASE(strcat2); @@ -144,16 +127,12 @@ private: TEST_CASE(simplifyOperator2); TEST_CASE(simplifyArrayAccessSyntax); - TEST_CASE(simplify_condition); TEST_CASE(pointeralias1); TEST_CASE(pointeralias2); TEST_CASE(pointeralias3); TEST_CASE(pointeralias4); - // x = realloc(y,0); => free(y);x=0; - TEST_CASE(simplifyRealloc); - // while(fclose(f)); => r = fclose(f); while(r){r=fclose(f);} TEST_CASE(simplifyFuncInWhile); @@ -222,7 +201,6 @@ private: TEST_CASE(simplifyKnownVariables32); // const TEST_CASE(simplifyKnownVariables33); // struct variable TEST_CASE(simplifyKnownVariables34); - TEST_CASE(simplifyKnownVariables35); // ticket #2353 - False positive: Division by zero 'if (x == 0) return 0; return 10 / x;' TEST_CASE(simplifyKnownVariables36); // ticket #2304 - known value for strcpy parameter TEST_CASE(simplifyKnownVariables39); TEST_CASE(simplifyKnownVariables41); // p=&x; if (p) .. @@ -1752,61 +1730,12 @@ private: // no simplification as the cast may be important here. see #2897 for example ASSERT_EQUALS("; * ( ( char * ) p + 1 ) = 0 ;", tok("; *((char *)p + 1) = 0;")); - ASSERT_EQUALS("{ if ( true ) }", tok("{ if ((unsigned char)1) }")); // #4164 + ASSERT_EQUALS("{ if ( 1 ) }", tok("{ if ((unsigned char)1) }")); // #4164 ASSERT_EQUALS("f ( 200 )", tok("f((unsigned char)200)")); ASSERT_EQUALS("f ( ( char ) 1234 )", tok("f((char)1234)")); // don't simplify downcast } - void iftruefalse() { - { - const char code1[] = " void f() { int a; bool use = false; if( use ) { a=0; } else {a=1;} }"; - const char code2[] = " void f() { int a; bool use = false; {a=1;} }"; - ASSERT_EQUALS(tok(code2), tok(code1)); - } - - { - const char code1[] = " void f() { int a; bool use = true; if( use ) { a=0; } else {a=1;} }"; - const char code2[] = " void f() { int a; bool use = true; { a=0; } }"; - ASSERT_EQUALS(tok(code2), tok(code1)); - } - - { - const char code1[] = " void f() { int a; int use = 5; if( use ) { a=0; } else {a=1;} }"; - const char code2[] = " void f() { int a; int use = 5; { a=0; } }"; - ASSERT_EQUALS(tok(code2), tok(code1)); - } - - { - const char code1[] = " void f() { int a; int use = 0; if( use ) { a=0; } else {a=1;} }"; - const char code2[] = " void f() { int a; int use = 0; {a=1;} }"; - ASSERT_EQUALS(tok(code2), tok(code1)); - } - - { - const char code1[] = " void f() { int a; bool use = false; if( use ) a=0; else a=1; int c=1; }"; - const char code2[] = " void f() { int a; bool use = false; { a=1; } int c=1; }"; - ASSERT_EQUALS(tok(code2), tok(code1)); - } - - { - const char code1[] = " void f() { int a; bool use = true; if( use ) a=0; else a=1; int c=1; }"; - const char code2[] = " void f() { int a; bool use = true; { a=0; } int c=1; }"; - ASSERT_EQUALS(tok(code2), tok(code1)); - } - - { - const char code1[] = " void f() { int a; bool use = false; if( use ) a=0; else if( bb ) a=1; int c=1; }"; - const char code2[] = " void f ( ) { int a ; bool use ; use = false ; { if ( bb ) { a = 1 ; } } int c ; c = 1 ; }"; - ASSERT_EQUALS(tok(code2), tok(code1)); - } - - { - const char code1[] = " void f() { int a; bool use = true; if( use ) a=0; else if( bb ) a=1; int c=1; }"; - const char code2[] = " void f() { int a; bool use = true; { a=0;} int c=1; }"; - ASSERT_EQUALS(tok(code2), tok(code1)); - } - } void combine_strings() { const char code1[] = "void foo()\n" @@ -2115,41 +2044,6 @@ private: } } - void removePostIncrement() { - const char code[] = "void f(int &c)\n" - "{\n" - " c = 0;\n" - " c++;\n" - " if (c>0) { c++; }\n" - " c++;\n" - "}\n"; - TODO_ASSERT_EQUALS("void f ( int & c ) { c = 3 ; { ; } ; }", - "void f ( int & c ) { c = 1 ; { c ++ ; } c ++ ; }", tok(code)); - } - - - void removePreIncrement() { - { - const char code[] = "void f(int &c)\n" - "{\n" - " c = 0;\n" - " ++c;\n" - " if (c>0) { ++c; }\n" - " ++c;\n" - "}\n"; - TODO_ASSERT_EQUALS("void f ( int & c ) { c = 3 ; { ; } ; }", - "void f ( int & c ) { c = 1 ; { ++ c ; } ++ c ; }", tok(code)); - } - - { - const char code[] = "void f()\n" - "{\n" - " char a[] = \"p\";\n" - " ++a[0];\n" - "}\n"; - ASSERT_EQUALS("void f ( ) { char a [ 2 ] = \"p\" ; ++ a [ 0 ] ; }", tok(code)); - } - } void elseif1() { const char code[] = "void f(){ if(x) {} else if(ab) { cd } else { ef }gh; }"; @@ -2583,7 +2477,7 @@ private: " sizeof 1;\n" " while (0);\n" "}\n"; - ASSERT_EQUALS("void f ( ) { sizeof ( 1 ) ; while ( false ) { ; } }", tok(code)); + ASSERT_EQUALS("void f ( ) { sizeof ( 1 ) ; while ( 0 ) { ; } }", tok(code)); ASSERT_EQUALS("", errout.str()); } @@ -2881,130 +2775,6 @@ private: } } -#define simplifyIfAndWhileAssign(code) simplifyIfAndWhileAssign_(code, __FILE__, __LINE__) - std::string simplifyIfAndWhileAssign_(const char code[], const char* file, int line) { - // tokenize.. - Tokenizer tokenizer(&settings0, this); - std::istringstream istr(code); - ASSERT_LOC(tokenizer.tokenize(istr, "test.cpp"), file, line); - - (tokenizer.simplifyIfAndWhileAssign)(); - - return tokenizer.tokens()->stringifyList(nullptr, false); - } - - void ifassign1() { - ASSERT_EQUALS("{ a = b ; if ( a ) { ; } }", simplifyIfAndWhileAssign("{if(a=b);}")); - ASSERT_EQUALS("{ a = b ( ) ; if ( a ) { ; } }", simplifyIfAndWhileAssign("{if((a=b()));}")); - ASSERT_EQUALS("{ a = b ( ) ; if ( ! ( a ) ) { ; } }", simplifyIfAndWhileAssign("{if(!(a=b()));}")); - ASSERT_EQUALS("{ a . x = b ( ) ; if ( ! ( a . x ) ) { ; } }", simplifyIfAndWhileAssign("{if(!(a->x=b()));}")); - ASSERT_EQUALS("void f ( ) { A ( ) a = b ; if ( a ) { ; } }", simplifyIfAndWhileAssign("void f() { A() if(a=b); }")); - ASSERT_EQUALS("void foo ( int a ) { a = b ( ) ; if ( a >= 0 ) { ; } }", tok("void foo(int a) {if((a=b())>=0);}")); - TODO_ASSERT_EQUALS("void foo ( A a ) { a . c = b ( ) ; if ( 0 <= a . c ) { ; } }", - "void foo ( A a ) { a . c = b ( ) ; if ( a . c >= 0 ) { ; } }", - tok("void foo(A a) {if((a.c=b())>=0);}")); - } - - void ifAssignWithCast() { - const char *code = "void foo()\n" - "{\n" - "FILE *f;\n" - "if( (f = fopen(\"foo\", \"r\")) == ((FILE*)NULL) )\n" - "return(-1);\n" - "fclose(f);\n" - "}\n"; - const char *expected = "void foo ( ) " - "{ " - "FILE * f ; " - "f = fopen ( \"foo\" , \"r\" ) ; " - "if ( f == NULL ) " - "{ " - "return ( -1 ) ; " - "} " - "fclose ( f ) ; " - "}"; - ASSERT_EQUALS(expected, tok(code)); - } - - void whileAssign1() { - ASSERT_EQUALS("{ a = b ; while ( a ) { b = 0 ; a = b ; } }", simplifyIfAndWhileAssign("{while(a=b) { b = 0; }}")); - ASSERT_EQUALS("{ a . b = c ; while ( a . b ) { c = 0 ; a . b = c ; } }", simplifyIfAndWhileAssign("{while(a.b=c) { c=0; }}")); - ASSERT_EQUALS("{ " - "struct hfs_bnode * node ; " - "struct hfs_btree * tree ; " - "node = tree . node_hash [ i ++ ] ; " - "while ( node ) { node = tree . node_hash [ i ++ ] ; } " - "}", - tok("{" - "struct hfs_bnode *node;" - "struct hfs_btree *tree;" - "while ((node = tree->node_hash[i++])) { }" - "}")); - ASSERT_EQUALS("{ char * s ; s = new char [ 10 ] ; while ( ! s ) { s = new char [ 10 ] ; } }", - tok("{ char *s; while (0 == (s=new char[10])) { } }")); - } - - void whileAssign2() { - // #1909 - Internal error - tok("void f()\n" - "{\n" - " int b;\n" - " while (b = sizeof (struct foo { int i0;}))\n" - " ;\n" - " if (!(0 <= b ))\n" - " ;\n" - "}"); - ASSERT_EQUALS("", errout.str()); - } - - void whileAssign3() { - // #4254 - Variable id - const char code[] = "void f() {\n" - " int a;\n" - " while (a = x());\n" - "}"; - ASSERT_EQUALS("\n\n##file 0\n" - "1: void f ( ) {\n" - "2: int a@1 ;\n" - "3: a@1 = x ( ) ; while ( a@1 ) { ; a@1 = x ( ) ; }\n" - "4: }\n", tokenizeDebugListing(code, true, "test.c")); - } - - void whileAssign4() { - errout.str(""); - - Tokenizer tokenizer(&settings0, this); - std::istringstream istr("{ while (!(m = q->push(x))) {} }"); - ASSERT(tokenizer.tokenize(istr, "test.cpp")); - tokenizer.simplifyTokenList2(); - - ASSERT_EQUALS("{ m = q . push < Message > ( x ) ; while ( ! m ) { m = q . push < Message > ( x ) ; } }", tokenizer.tokens()->stringifyList(nullptr, false)); - ASSERT(tokenizer.tokens()->tokAt(26) != nullptr); - if (tokenizer.tokens()->tokAt(26)) { - ASSERT(tokenizer.tokens()->linkAt(6) == tokenizer.tokens()->tokAt(8)); - ASSERT(tokenizer.tokens()->linkAt(24) == tokenizer.tokens()->tokAt(26)); - } - } - - void doWhileAssign() { - ASSERT_EQUALS("{ do { a = b ; } while ( a ) ; }", simplifyIfAndWhileAssign("{ do { } while(a=b); }")); - ASSERT_EQUALS("{ do { a . a = 0 ; a . b = c ; } while ( a . b ) ; }", simplifyIfAndWhileAssign("{ do { a.a = 0; } while(a.b=c); }")); - ASSERT_EQUALS("{ " - "struct hfs_bnode * node ; " - "struct hfs_btree * tree ; " - "do { node = tree . node_hash [ i ++ ] ; } while ( node ) ; " - "}", - tok("{" - "struct hfs_bnode *node;" - "struct hfs_btree *tree;" - "do { } while((node = tree->node_hash[i++]));" - "}")); - ASSERT_EQUALS("void foo ( ) { char * s ; do { s = new char [ 10 ] ; } while ( ! s ) ; }", - tok("void foo() { char *s; do { } while (0 == (s=new char[10])); }")); - // #4911 - ASSERT_EQUALS("void foo ( ) { do { current = f ( ) ; } while ( ( current ) != NULL ) ; }", simplifyIfAndWhileAssign("void foo() { do { } while((current=f()) != NULL); }")); - } - 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)); @@ -3316,7 +3086,7 @@ private: { const char code[] = "(1?(false?1:2):3);"; - ASSERT_EQUALS("( 2 ) ;", tok(code)); + ASSERT_EQUALS("( ( 2 ) ) ;", tok(code)); } { @@ -3419,7 +3189,7 @@ private: ASSERT_EQUALS("x = 1 + 2 * y ;", tok("x=1+2*y;")); ASSERT_EQUALS("x = 7 ;", tok("x=1+2*3;")); ASSERT_EQUALS("x = 47185 ;", tok("x=(65536*72/100);")); - ASSERT_EQUALS("x = 900 ;", tok("x = 1500000 / ((145000 - 55000) * 1000 / 54000);")); + ASSERT_EQUALS("x = 1500000 / ( ( 90000 ) * 1000 / 54000 ) ;", tok("x = 1500000 / ((145000 - 55000) * 1000 / 54000);")); ASSERT_EQUALS("int a [ 8 ] ;", tok("int a[5+6/2];")); ASSERT_EQUALS("int a [ 4 ] ;", tok("int a[(10)-1-5];")); ASSERT_EQUALS("int a [ i - 9 ] ;", tok("int a[i - 10 + 1];")); @@ -3458,7 +3228,7 @@ private: ASSERT_EQUALS("x ( -2 << 6 | 1 ) ;", tok("x(1-3<<6|5/3);")); // #4931 ASSERT_EQUALS("x ( 2 ) ;", tok("x(2|0*0&2>>1+0%2*1);")); // #4931 ASSERT_EQUALS("x ( 0 & 4 != 1 ) ;", tok("x(4%1<<1&4!=1);")); // #4931 (can be simplified further but it's not a problem) - ASSERT_EQUALS("x ( true ) ;", tok("x(0&&4>0==2||4);")); // #4931 + ASSERT_EQUALS("x ( 1 ) ;", tok("x(0&&4>0==2||4);")); // #4931 // don't remove these spaces.. ASSERT_EQUALS("new ( auto ) ( 4 ) ;", tok("new (auto)(4);")); @@ -3466,13 +3236,13 @@ private: void comparisons() { ASSERT_EQUALS("( 1 ) ;", tok("( 1 < 2 );")); - ASSERT_EQUALS("( x && true ) ;", tok("( x && 1 < 2 );")); + ASSERT_EQUALS("( x && 1 ) ;", tok("( x && 1 < 2 );")); ASSERT_EQUALS("( 5 ) ;", tok("( 1 < 2 && 3 < 4 ? 5 : 6 );")); ASSERT_EQUALS("( 6 ) ;", tok("( 1 > 2 && 3 > 4 ? 5 : 6 );")); } void simplifyCalculations() { - ASSERT_EQUALS("void foo ( char str [ ] ) { char x ; x = * str ; }", + ASSERT_EQUALS("void foo ( char str [ ] ) { char x ; x = ( * str ) ; }", tok("void foo ( char str [ ] ) { char x = 0 | ( * str ) ; }")); ASSERT_EQUALS("void foo ( ) { if ( b ) { } }", tok("void foo ( ) { if (b + 0) { } }")); @@ -3498,320 +3268,6 @@ private: } - - void simplifyFlowControl() { - const char code1[] = "void f() {\n" - " return;\n" - " y();\n" - "}"; - ASSERT_EQUALS("void f ( ) { return ; }", tokWithStdLib(code1)); - - const char code2[] = "void f() {\n" - " exit(0);\n" - " y();\n" - "}"; - ASSERT_EQUALS("void f ( ) { exit ( 0 ) ; }", tokWithStdLib(code2)); - - const char code3[] = "void f() {\n" - " x.abort();\n" - " y();\n" - "}"; - ASSERT_EQUALS("void f ( ) { x . abort ( ) ; y ( ) ; }", tokWithStdLib(code3)); - } - - void flowControl() { - { - ASSERT_EQUALS("void f ( ) { exit ( 0 ) ; }", tokWithStdLib("void f() { exit(0); foo(); }")); - ASSERT_EQUALS("void f ( ) { exit ( 0 ) ; }", tokWithStdLib("void f() { exit(0); if (m) foo(); }")); - ASSERT_EQUALS("void f ( int n ) { if ( n ) { exit ( 0 ) ; } foo ( ) ; }", tokWithStdLib("void f(int n) { if (n) { exit(0); } foo(); }")); - ASSERT_EQUALS("void f ( ) { exit ( 0 ) ; }", tokWithStdLib("void f() { exit(0); dead(); switch (n) { case 1: deadcode () ; default: deadcode (); } }")); - - ASSERT_EQUALS("int f ( int n ) { switch ( n ) { case 0 : ; exit ( 0 ) ; default : ; exit ( 0 ) ; } exit ( 0 ) ; }", - tokWithStdLib("int f(int n) { switch (n) {case 0: exit(0); n*=2; default: exit(0); n*=6;} exit(0); foo();}")); - //ticket #3132 - ASSERT_EQUALS("void f ( int i ) { goto label ; { label : ; exit ( 0 ) ; } }", tokWithStdLib("void f (int i) { goto label; switch(i) { label: exit(0); } }")); - //ticket #3148 - ASSERT_EQUALS("void f ( ) { MACRO ( exit ( 0 ) ) }", tokWithStdLib("void f() { MACRO(exit(0)) }")); - ASSERT_EQUALS("void f ( ) { MACRO ( bar1 , exit ( 0 ) ) }", tokWithStdLib("void f() { MACRO(bar1, exit(0)) }")); - } - - { - const char* code = "void f(){ " - " if (k>0) goto label; " - " exit(0); " - " if (tnt) " - " { " - " { " - " check(); " - " k=0; " - " } " - " label: " - " bar(); " - " } " - "}"; - ASSERT_EQUALS("void f ( ) { if ( k > 0 ) { goto label ; } exit ( 0 ) ; { label : ; bar ( ) ; } }", tokWithStdLib(code)); - } - - { - const char* code = "void foo () {" - " exit(0);" - " {" - " boo();" - " while (n) { --n; }" - " {" - " label:" - " ok();" - " }" - " }" - "}"; - ASSERT_EQUALS("void foo ( ) { exit ( 0 ) ; { label : ; ok ( ) ; } }", tokWithStdLib(code)); - } - - { - const char* code = "void foo () {" - " exit(0);" - " switch (n) {" - " case 1:" - " label:" - " foo(); break;" - " default:" - " break;" - " }" - "}"; - const char* expected = "void foo ( ) { exit ( 0 ) ; { label : ; foo ( ) ; break ; } }"; - ASSERT_EQUALS(expected, tokWithStdLib(code)); - } - - { - const char* code = "void foo () {" - " exit(0);" - " switch (n) {" - " case 1:" - " {" - " foo();" - " }" - " label:" - " bar();" - " }" - "}"; - const char* expected = "void foo ( ) { exit ( 0 ) ; { label : ; bar ( ) ; } }"; - ASSERT_EQUALS(expected, tokWithStdLib(code)); - } - - { - const char* code = "void foo () {" - " exit(0);" - " switch (n) {" - " case a:" - " {" - " foo();" - " }" - " case b|c:" - " bar();" - " }" - "}"; - const char* expected = "void foo ( ) { exit ( 0 ) ; }"; - ASSERT_EQUALS(expected, tokWithStdLib(code)); - } - - { - const char* code = "void foo () {" - " exit(0);" - " switch (n) {" - " case 1:" - " label:" - " foo(); break;" - " default:" - " break; break;" - " }" - "}"; - const char* expected = "void foo ( ) { exit ( 0 ) ; { label : ; foo ( ) ; break ; } }"; - ASSERT_EQUALS(expected, tokWithStdLib(code)); - } - - { - const char* code = "void foo () {" - " exit(0);" - " switch (n) {" - " case 1:" - " label:" - " foo(); break; break;" - " default:" - " break;" - " }" - "}"; - const char* expected = "void foo ( ) { exit ( 0 ) ; { label : ; foo ( ) ; break ; } }"; - ASSERT_EQUALS(expected, tokWithStdLib(code)); - } - - { - const char* code = "void foo () {" - " exit(0);" - " switch (n) {" - " case 1:" - " label:" - " foo(); break; break;" - " default:" - " break; break;" - " }" - "}"; - const char* expected = "void foo ( ) { exit ( 0 ) ; { label : ; foo ( ) ; break ; } }"; - ASSERT_EQUALS(expected, tokWithStdLib(code)); - } - - { - const char* code = "int f() { " - "switch (x) { case 1: exit(0); bar(); tack; { ticak(); exit(0) } exit(0);" - "case 2: exit(0); { random(); } tack(); " - "switch(y) { case 1: exit(0); case 2: exit(0); } " - "exit(0); } exit(0); }"; - ASSERT_EQUALS("int f ( ) { switch ( x ) { case 1 : ; exit ( 0 ) ; case 2 : ; exit ( 0 ) ; } exit ( 0 ) ; }",tokWithStdLib(code)); - } - - { - const char* code = "int f() {" - "switch (x) { case 1: exit(0); bar(); tack; { ticak(); exit(0); } exit(0);" - "case 2: switch(y) { case 1: exit(0); bar2(); foo(); case 2: exit(0); }" - "exit(0); } exit(0); }"; - const char* expected = "int f ( ) {" - " switch ( x ) { case 1 : ; exit ( 0 ) ;" - " case 2 : ; switch ( y ) { case 1 : ; exit ( 0 ) ; case 2 : ; exit ( 0 ) ; }" - " exit ( 0 ) ; } exit ( 0 ) ; }"; - ASSERT_EQUALS(expected,tokWithStdLib(code)); - } - - { - const char* code = "void foo () {" - " switch (i) { case 0: switch (j) { case 0: exit(0); }" - " case 1: switch (j) { case -1: exit(0); }" - " case 2: switch (j) { case -2: exit(0); }" - " case 3: if (blah6) {exit(0);} break; } }"; - const char* expected = "void foo ( ) {" - " switch ( i ) { case 0 : ; switch ( j ) { case 0 : ; exit ( 0 ) ; }" - " case 1 : ; switch ( j ) { case -1 : ; exit ( 0 ) ; }" - " case 2 : ; switch ( j ) { case -2 : ; exit ( 0 ) ; }" - " case 3 : ; if ( blah6 ) { exit ( 0 ) ; } break ; } }"; - ASSERT_EQUALS(expected, tokWithStdLib(code)); - } - - { - const char* code = "void foo () {" - " exit(0);" - " switch (i) { case 0: switch (j) { case 0: foo(); }" - " case 1: switch (j) { case -1: bar(); label:; ok(); }" - " case 3: if (blah6) { boo(); break; } } }"; - const char* expected = "void foo ( ) { exit ( 0 ) ; { { label : ; ok ( ) ; } case 3 : ; if ( blah6 ) { boo ( ) ; break ; } } }"; - ASSERT_EQUALS(expected, tokWithStdLib(code)); - } - - { - const char* code = "void foo() {" - " switch ( t ) {" - " case 0:" - " if ( t ) switch ( b ) {}" - " break;" - " case 1:" - " exit(0);" - " return 0;" - " }" - " return 0;" - "}"; - const char* expected = "void foo ( ) {" - " switch ( t ) {" - " case 0 : ;" - " if ( t ) { switch ( b ) { } }" - " break ;" - " case 1 : ;" - " exit ( 0 ) ;" - " }" - " return 0 ; " - "}"; - ASSERT_EQUALS(expected, tokWithStdLib(code)); - } - - { - const char code[] = "void foo()\n" - "{\n" - " A *a = 0;\n" - " if (!a) {\n" - " nondeadcode;\n" - " return;\n" - " dead;\n" - " }\n" - " stilldead;\n" - " a->_a;\n" - "}\n"; - const char expected[] = "void foo ( ) " - "{" - " A * a ; a = 0 ; {" - " nondeadcode ;" - " return ;" - " } " - "}"; - ASSERT_EQUALS(expected, tokWithStdLib(code)); - } - - { - const char code[] = "class Fred\n" - "{\n" - "public:\n" - " bool foo() const { return f; }\n" - " bool exit();\n" - "\n" - "private:\n" - " bool f;\n" - "};\n"; - const char expected[] = "class Fred " - "{" - " public:" - " bool foo ( ) const { return f ; }" - " bool exit ( ) ;" - "" - " private:" - " bool f ; " - "} ;"; - ASSERT_EQUALS(expected, tokWithStdLib(code)); - } - - { - const char code[] = "class abort { };\n" - "\n" - "class Fred\n" - "{\n" - " public:\n" - " bool foo() const { return f; }\n" - " abort exit();\n" - "\n" - " private:\n" - "bool f;\n" - "};\n"; - const char expected[] = "class abort { } ; " - "class Fred " - "{" - " public:" - " bool foo ( ) const { return f ; }" - " abort exit ( ) ;" - "" - " private:" - " bool f ; " - "} ;"; - ASSERT_EQUALS(expected, tokWithStdLib(code)); - } - - ASSERT_EQUALS("void foo ( ) { exit ( 0 ) ; }", - tokWithStdLib("void foo() { do { exit(0); } while (true); }")); - - // #6187 - tokWithStdLib("void foo() {\n" - " goto label;\n" - " for (int i = 0; i < 0; ++i) {\n" - " ;\n" - "label:\n" - " ;\n" - " }\n" - "}"); - } - void strcat1() { const char code[] = "; strcat(strcat(strcat(strcat(strcat(strcat(dst, \"this \"), \"\"), \"is \"), \"a \"), \"test\"), \".\");"; const char expect[] = "; " @@ -3875,89 +3331,6 @@ private: "1: int a@1 ; a@1 [ 13 ] ;\n", tokenizeDebugListing("int a; 13[a];")); } - void simplify_condition() { - { - const char code[] = - "void f(int a)\n" - "{\n" - "if (a && false) g();\n" - "}"; - ASSERT_EQUALS("void f ( int a ) { }", tok(code)); - } - - { - const char code[] = - "void f(int a)\n" - "{\n" - "if (false && a) g();\n" - "}"; - ASSERT_EQUALS("void f ( int a ) { }", tok(code)); - } - - { - const char code[] = - "void f(int a)\n" - "{\n" - "if (true || a) g();\n" - "}"; - ASSERT_EQUALS("void f ( int a ) { g ( ) ; }", tok(code)); - } - - { - const char code[] = - "void f(int a)\n" - "{\n" - "if (a || true) g();\n" - "}"; - ASSERT_EQUALS("void f ( int a ) { g ( ) ; }", tok(code)); - } - - { - const char code[] = - "void f(int a)\n" - "{\n" - "if (a || true || b) g();\n" - "}"; - ASSERT_EQUALS("void f ( int a ) { g ( ) ; }", tok(code)); - } - - { - const char code[] = - "void f(int a)\n" - "{\n" - "if (a && false && b) g();\n" - "}"; - ASSERT_EQUALS("void f ( int a ) { }", tok(code)); - } - - { - const char code[] = - "void f(int a)\n" - "{\n" - "if (a || (b && false && c) || d) g();\n" - "}"; - ASSERT_EQUALS("void f ( int a ) { if ( a || d ) { g ( ) ; } }", tok(code)); - } - - { - const char code[] = - "void f(int a)\n" - "{\n" - "if ((a && b) || true || (c && d)) g();\n" - "}"; - ASSERT_EQUALS("void f ( int a ) { g ( ) ; }", tok(code)); - } - - { - // #4931 - const char code[] = - "void f() {\n" - "if (12 && 7) g();\n" - "}"; - ASSERT_EQUALS("void f ( ) { g ( ) ; }", tok(code)); - } - } - void pointeralias1() { { @@ -4035,17 +3408,6 @@ private: ASSERT_EQUALS(expected, tok(code)); } - void simplifyRealloc() { - ASSERT_EQUALS("; free ( p ) ; p = 0 ;", tok("; p = realloc(p, 0);")); - ASSERT_EQUALS("; p = malloc ( 100 ) ;", tok("; p = realloc(0, 100);")); - ASSERT_EQUALS("; p = malloc ( 0 ) ;", tok("; p = realloc(0, 0);")); - ASSERT_EQUALS("; free ( q ) ; p = 0 ;", tok("; p = realloc(q, 0);")); - ASSERT_EQUALS("; free ( * q ) ; p = 0 ;", tok("; p = realloc(*q, 0);")); - ASSERT_EQUALS("; free ( f ( z ) ) ; p = 0 ;", tok("; p = realloc(f(z), 0);")); - ASSERT_EQUALS("; p = malloc ( n * m ) ;", tok("; p = realloc(0, n*m);")); - ASSERT_EQUALS("; p = malloc ( f ( 1 ) ) ;", tok("; p = realloc(0, f(1));")); - } - void simplifyFuncInWhile() { ASSERT_EQUALS("{ " "int cppcheck:r1 = fclose ( f ) ; " @@ -4573,19 +3935,6 @@ private: ASSERT_EQUALS("int x [ 13 ] = { [ 11 ] = 2 , [ 12 ] = 3 } ;", tok("int x[] = {[11]=2, [12]=3};")); } - void test_4881() { - const char code[] = "int evallex() {\n" - " int c, t;\n" - "again:\n" - " do {\n" - " if ((c = macroid(c)) == EOF_CHAR || c == '\\n') {\n" - " }\n" - " } while ((t = type[c]) == LET && catenate());\n" - "}\n"; - ASSERT_EQUALS("int evallex ( ) { int c ; int t ; again : ; do { c = macroid ( c ) ; if ( c == EOF_CHAR || c == '\\n' ) { } t = type [ c ] ; } while ( t == LET && catenate ( ) ) ; }", - tok(code, true)); - } - void simplifyOverride() { // ticket #5069 const char code[] = "void fun() {\n" " unsigned char override[] = {0x01, 0x02};\n" @@ -5562,19 +4911,6 @@ private: ASSERT_EQUALS(expected, tokenizeAndStringify(code, true)); } - void simplifyKnownVariables35() { - // Ticket #2353 - const char code[] = "int f() {" - " int x = 0;" - " if (x == 0) {" - " return 0;" - " }" - " return 10 / x;" - "}"; - const char expected[] = "int f ( ) { int x ; x = 0 ; { return 0 ; } }"; - ASSERT_EQUALS(expected, tokenizeAndStringify(code, true)); - } - void simplifyKnownVariables36() { // Ticket #2304 const char code[] = "void f() {" @@ -6279,7 +5615,7 @@ private: // remove static_cast.. void simplifyCasts2() { const char code[] = "t = (static_cast *>(&p));\n"; - ASSERT_EQUALS("t = & p ;", tok(code)); + ASSERT_EQUALS("t = ( & p ) ;", tok(code)); } void simplifyCasts3() {