Fixed ticket #411 (false positive: resource leak in while loop)
This commit is contained in:
parent
13b8f10906
commit
453a5cdd47
|
@ -992,6 +992,7 @@ void CheckMemoryLeakInFunction::simplifycode(Token *tok, bool &all)
|
||||||
bool done = false;
|
bool done = false;
|
||||||
while (! done)
|
while (! done)
|
||||||
{
|
{
|
||||||
|
//tok->printOut("simplifycode loop..");
|
||||||
done = true;
|
done = true;
|
||||||
|
|
||||||
for (Token *tok2 = tok; tok2; tok2 = tok2 ? tok2->next() : NULL)
|
for (Token *tok2 = tok; tok2; tok2 = tok2 ? tok2->next() : NULL)
|
||||||
|
@ -1258,13 +1259,6 @@ void CheckMemoryLeakInFunction::simplifycode(Token *tok, bool &all)
|
||||||
done = false;
|
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 ;"
|
// Replace "loop if return ;" with "if return ;"
|
||||||
if (Token::simpleMatch(tok2->next(), "loop if return"))
|
if (Token::simpleMatch(tok2->next(), "loop if return"))
|
||||||
{
|
{
|
||||||
|
|
|
@ -2282,11 +2282,17 @@ void Tokenizer::unsignedint()
|
||||||
bool Tokenizer::simplifyIfAssign()
|
bool Tokenizer::simplifyIfAssign()
|
||||||
{
|
{
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
|
|
||||||
for (Token *tok = _tokens; tok; tok = tok->next())
|
for (Token *tok = _tokens; tok; tok = tok->next())
|
||||||
{
|
{
|
||||||
if (Token::Match(tok->next(), "if ( (| %var% =") ||
|
if (Token::Match(tok->next(), "if|while ( (| %var% =") ||
|
||||||
Token::Match(tok->next(), "if ( ! ( %var% ="))
|
Token::Match(tok->next(), "if|while ( ! ( %var% ="))
|
||||||
{
|
{
|
||||||
|
ret = true;
|
||||||
|
|
||||||
|
// simplifying a "while" condition ?
|
||||||
|
const bool iswhile(tok->next()->str() == "while");
|
||||||
|
|
||||||
// delete the "if"
|
// delete the "if"
|
||||||
tok->deleteNext();
|
tok->deleteNext();
|
||||||
|
|
||||||
|
@ -2321,7 +2327,7 @@ bool Tokenizer::simplifyIfAssign()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Insert "; if ( .."
|
// Insert "; if|while ( .."
|
||||||
if (tok2)
|
if (tok2)
|
||||||
{
|
{
|
||||||
tok2 = tok2->previous();
|
tok2 = tok2->previous();
|
||||||
|
@ -2330,9 +2336,37 @@ bool Tokenizer::simplifyIfAssign()
|
||||||
tok2->insertToken("(");
|
tok2->insertToken("(");
|
||||||
if (isNot)
|
if (isNot)
|
||||||
tok2->next()->insertToken("!");
|
tok2->next()->insertToken("!");
|
||||||
tok2->insertToken("if");
|
tok2->insertToken(iswhile ? "while" : "if");
|
||||||
tok2->insertToken(";");
|
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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -169,6 +169,7 @@ private:
|
||||||
TEST_CASE(forwhile8); // Bug 2429936
|
TEST_CASE(forwhile8); // Bug 2429936
|
||||||
TEST_CASE(forwhile9);
|
TEST_CASE(forwhile9);
|
||||||
TEST_CASE(forwhile10);
|
TEST_CASE(forwhile10);
|
||||||
|
TEST_CASE(forwhile11);
|
||||||
|
|
||||||
TEST_CASE(dowhile1);
|
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());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -100,6 +100,7 @@ private:
|
||||||
|
|
||||||
// Assignment in condition..
|
// Assignment in condition..
|
||||||
TEST_CASE(ifassign1);
|
TEST_CASE(ifassign1);
|
||||||
|
TEST_CASE(whileAssign);
|
||||||
|
|
||||||
// "if(0==x)" => "if(!x)"
|
// "if(0==x)" => "if(!x)"
|
||||||
TEST_CASE(ifnot);
|
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[])
|
std::string simplifyIfNot(const char code[])
|
||||||
{
|
{
|
||||||
// tokenize..
|
// tokenize..
|
||||||
|
|
Loading…
Reference in New Issue