Fix #1469 (False positive: Resource leak when fclose() is inside while)

http://sourceforge.net/apps/trac/cppcheck/ticket/1469
This commit is contained in:
Reijo Tomperi 2010-03-06 16:28:52 +02:00
parent fe30c1ca9d
commit b88126a669
3 changed files with 73 additions and 0 deletions

View File

@ -3064,6 +3064,7 @@ bool Tokenizer::simplifyTokenList()
simplifyComparisonOrder();
simplifyNestedStrcat();
simplifyWhile0();
simplifyFuncInWhile();
simplifyIfAssign(); // could be affected by simplifyIfNot
@ -6627,3 +6628,37 @@ void Tokenizer::simplifyWhile0()
}
}
void Tokenizer::simplifyFuncInWhile()
{
for (Token *tok = _tokens; tok; tok = tok->next())
{
if (!Token::Match(tok, "while ( %var% ( %var% ) ) {"))
continue;
Token *func = tok->tokAt(2);
Token *var = tok->tokAt(4);
Token *end = tok->tokAt(7)->link();
if (!end)
break;
tok->str("int");
tok->insertToken("cppcheck:r");
tok->tokAt(1)->insertToken("=");
tok->tokAt(2)->insertToken(func->str());
tok->tokAt(3)->insertToken("(");
tok->tokAt(4)->insertToken(var->str());
tok->tokAt(5)->varId(var->varId());
tok->tokAt(5)->insertToken(")");
tok->tokAt(6)->insertToken(";");
tok->tokAt(7)->insertToken("while");
tok->tokAt(9)->insertToken("cppcheck:r");
Token::createMutualLinks(tok->tokAt(4), tok->tokAt(6));
end->previous()->insertToken("cppcheck:r");
end->previous()->insertToken("=");
Token::move(func, func->tokAt(3), end->previous());
end->previous()->insertToken(";");
tok = end;
}
}

View File

@ -350,6 +350,11 @@ private:
*/
void simplifyWhile0();
/**
* Simplify while(func(f))
*/
void simplifyFuncInWhile();
/**
* Replace enum with constant value
*/

View File

@ -216,6 +216,9 @@ private:
// 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);
}
std::string tok(const char code[], bool simplify = true)
@ -4035,6 +4038,36 @@ private:
ASSERT_EQUALS("; free ( p ) ; p = 0 ;",
tok("; p = realloc(p,0);"));
}
void simplifyFuncInWhile()
{
ASSERT_EQUALS("int cppcheck:r = fclose ( f ) ; "
"while ( cppcheck:r ) "
"{ "
"foo ( ) ; "
"cppcheck:r = fclose ( f ) ; "
"}",
tok("while(fclose(f))foo();"));
ASSERT_EQUALS("int cppcheck:r = fclose ( f ) ; "
"while ( cppcheck:r ) "
"{ "
"; cppcheck:r = fclose ( f ) ; "
"}",
tok("while(fclose(f));"));
ASSERT_EQUALS("int cppcheck:r = fclose ( f ) ; "
"while ( cppcheck:r ) "
"{ "
"; cppcheck:r = fclose ( f ) ; "
"} "
"int cppcheck:r = fclose ( g ) ; "
"while ( cppcheck:r ) "
"{ "
"; cppcheck:r = fclose ( g ) ; "
"}",
tok("while(fclose(f)); while(fclose(g));"));
}
};
REGISTER_TEST(TestSimplifyTokens)