Fix #1469 (False positive: Resource leak when fclose() is inside while)
http://sourceforge.net/apps/trac/cppcheck/ticket/1469
This commit is contained in:
parent
fe30c1ca9d
commit
b88126a669
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -350,6 +350,11 @@ private:
|
|||
*/
|
||||
void simplifyWhile0();
|
||||
|
||||
/**
|
||||
* Simplify while(func(f))
|
||||
*/
|
||||
void simplifyFuncInWhile();
|
||||
|
||||
/**
|
||||
* Replace enum with constant value
|
||||
*/
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue