diff --git a/src/checkmemoryleak.cpp b/src/checkmemoryleak.cpp index 50055add1..24c0f0bb7 100644 --- a/src/checkmemoryleak.cpp +++ b/src/checkmemoryleak.cpp @@ -992,6 +992,7 @@ void CheckMemoryLeakInFunction::simplifycode(Token *tok, bool &all) bool done = false; while (! done) { + //tok->printOut("simplifycode loop.."); done = true; for (Token *tok2 = tok; tok2; tok2 = tok2 ? tok2->next() : NULL) @@ -1258,13 +1259,6 @@ void CheckMemoryLeakInFunction::simplifycode(Token *tok, bool &all) done = false; } - // Replace "loop !var alloc ;" with " alloc ;" - if (Token::Match(tok2->next(), "loop !var alloc ;")) - { - Token::eraseTokens(tok2, tok2->tokAt(3)); - done = false; - } - // Replace "loop if return ;" with "if return ;" if (Token::simpleMatch(tok2->next(), "loop if return")) { diff --git a/src/tokenize.cpp b/src/tokenize.cpp index 9507a2993..494ea9cc3 100644 --- a/src/tokenize.cpp +++ b/src/tokenize.cpp @@ -2282,11 +2282,17 @@ void Tokenizer::unsignedint() bool Tokenizer::simplifyIfAssign() { bool ret = false; + for (Token *tok = _tokens; tok; tok = tok->next()) { - if (Token::Match(tok->next(), "if ( (| %var% =") || - Token::Match(tok->next(), "if ( ! ( %var% =")) + if (Token::Match(tok->next(), "if|while ( (| %var% =") || + Token::Match(tok->next(), "if|while ( ! ( %var% =")) { + ret = true; + + // simplifying a "while" condition ? + const bool iswhile(tok->next()->str() == "while"); + // delete the "if" tok->deleteNext(); @@ -2321,7 +2327,7 @@ bool Tokenizer::simplifyIfAssign() } } - // Insert "; if ( .." + // Insert "; if|while ( .." if (tok2) { tok2 = tok2->previous(); @@ -2330,9 +2336,37 @@ bool Tokenizer::simplifyIfAssign() tok2->insertToken("("); if (isNot) tok2->next()->insertToken("!"); - tok2->insertToken("if"); + tok2->insertToken(iswhile ? "while" : "if"); tok2->insertToken(";"); - ret = true; + + // If it's a while loop.. insert the assignment in the loop + if (iswhile) + { + indentlevel = 0; + Token *tok3 = tok2; + for (tok3 = tok2; tok3; tok3 = tok3->next()) + { + if (tok3->str() == "{") + ++indentlevel; + else if (tok3->str() == "}") + { + if (indentlevel <= 1) + break; + --indentlevel; + } + } + + if (tok3 && indentlevel == 1) + { + tok3 = tok3->previous(); + for (tok2 = tok2->next(); tok2 && tok2 != tok; tok2 = tok2->previous()) + { + tok3->insertToken(tok2->str().c_str()); + tok3->next()->fileIndex(tok2->fileIndex()); + tok3->next()->linenr(tok2->linenr()); + } + } + } } } } diff --git a/test/testmemleak.cpp b/test/testmemleak.cpp index e9fcaef3f..7ce92577a 100644 --- a/test/testmemleak.cpp +++ b/test/testmemleak.cpp @@ -169,6 +169,7 @@ private: TEST_CASE(forwhile8); // Bug 2429936 TEST_CASE(forwhile9); TEST_CASE(forwhile10); + TEST_CASE(forwhile11); TEST_CASE(dowhile1); @@ -1027,6 +1028,18 @@ private: } + void forwhile11() + { + check("int main()\n" + "{\n" + " FILE *stream=NULL;\n" + " while((stream = fopen(name,\"r\")) == NULL)\n" + " { }\n" + " if(stream!=NULL) fclose(stream);\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); + } + diff --git a/test/testsimplifytokens.cpp b/test/testsimplifytokens.cpp index 5f4763257..458a83936 100644 --- a/test/testsimplifytokens.cpp +++ b/test/testsimplifytokens.cpp @@ -100,6 +100,7 @@ private: // Assignment in condition.. TEST_CASE(ifassign1); + TEST_CASE(whileAssign); // "if(0==x)" => "if(!x)" TEST_CASE(ifnot); @@ -938,6 +939,14 @@ private: } + void whileAssign() + { + ASSERT_EQUALS("; a = b ; while ( a ) { b = 0 ; a = b ; }", simplifyIfAssign(";while(a=b) { b = 0; }")); + //ASSERT_EQUALS("; a = b ( ) ; if ( ( a ) ) ;", simplifyIfAssign(";if((a=b()));")); + //ASSERT_EQUALS("; a = b ( ) ; if ( ! ( a ) ) ;", simplifyIfAssign(";if(!(a=b()));")); + } + + std::string simplifyIfNot(const char code[]) { // tokenize..