Memory leaks: some refactorings and minor improvements

This commit is contained in:
Daniel Marjamäki 2010-01-24 21:48:39 +01:00
parent 65881b9346
commit 724c55b32a
2 changed files with 55 additions and 16 deletions

View File

@ -988,6 +988,8 @@ Token *CheckMemoryLeakInFunction::getcode(const Token *tok, std::list<const Toke
// Loops.. // Loops..
else if ((tok->str() == "for") || (tok->str() == "while")) else if ((tok->str() == "for") || (tok->str() == "while"))
{ {
isloop = true;
if (Token::simpleMatch(tok, "while ( true )") || if (Token::simpleMatch(tok, "while ( true )") ||
Token::simpleMatch(tok, "for ( ; ; )")) Token::simpleMatch(tok, "for ( ; ; )"))
{ {
@ -995,8 +997,39 @@ Token *CheckMemoryLeakInFunction::getcode(const Token *tok, std::list<const Toke
tok = tok->next()->link(); tok = tok->next()->link();
continue; continue;
} }
else if (alloctype == Fd && varid)
{
if (Token::Match(tok, "while ( 0 <= %varid% )", varid) ||
Token::Match(tok, "while ( %varid% != -1 )", varid))
{
addtoken("while(var)");
tok = tok->next()->link();
continue;
}
else if (Token::Match(tok, "while ( %varid% == -1 )", varid) ||
Token::Match(tok, "while ( %varid% < 0 )", varid))
{
addtoken("while(!var)");
tok = tok->next()->link();
continue;
}
}
else if (varid && Token::Match(tok, "while ( %varid% )", varid))
{
addtoken("while(var)");
tok = tok->next()->link();
continue;
}
else if (varid && Token::simpleMatch(tok, "while (") && notvar(tok->tokAt(2), varid, true))
{
addtoken("while(!var)");
tok = tok->next()->link();
continue;
}
addtoken("loop"); addtoken("loop");
isloop = true;
} }
else if ((tok->str() == "do")) else if ((tok->str() == "do"))
{ {
@ -1453,10 +1486,10 @@ void CheckMemoryLeakInFunction::simplifycode(Token *tok, bool &all)
continue; continue;
} }
// Reduce "alloc loop !var alloc ;" => "alloc ;" // Reduce "alloc while(!var) alloc ;" => "alloc ;"
if (Token::Match(tok2, "[;{}] alloc ; loop !var alloc ;")) if (Token::Match(tok2, "[;{}] alloc ; while(!var) alloc ;"))
{ {
Token::eraseTokens(tok2, tok2->tokAt(5)); Token::eraseTokens(tok2, tok2->tokAt(4));
done = false; done = false;
} }
@ -1584,6 +1617,13 @@ void CheckMemoryLeakInFunction::simplifycode(Token *tok, bool &all)
done = false; done = false;
} }
// Reduce "do { dealloc ; alloc ; } while(var) ;" => ";"
if (Token::simpleMatch(tok2->next(), "do { dealloc ; alloc ; } while(var) ;"))
{
Token::eraseTokens(tok2, tok2->tokAt(9));
done = false;
}
// Reduce "do { alloc ; } " => "alloc ;" // Reduce "do { alloc ; } " => "alloc ;"
/** @todo If the loop "do { alloc ; }" can be executed twice, reduce it to "loop alloc ;" */ /** @todo If the loop "do { alloc ; }" can be executed twice, reduce it to "loop alloc ;" */
if (Token::simpleMatch(tok2->next(), "do { alloc ; }")) if (Token::simpleMatch(tok2->next(), "do { alloc ; }"))

View File

@ -448,12 +448,15 @@ private:
// loop.. // loop..
ASSERT_EQUALS(";;loop{}", getcode("char *s; while (a) { }", "s")); ASSERT_EQUALS(";;loop{}", getcode("char *s; while (a) { }", "s"));
ASSERT_EQUALS(";;loopcallfunc{}", getcode("char *s; while (a()) { }", "s")); ASSERT_EQUALS(";;loopcallfunc{}", getcode("char *s; while (a()) { }", "s"));
ASSERT_EQUALS(";;loop{}", getcode("char *s; while (s) { }", "s"));
ASSERT_EQUALS(";;loop{}", getcode("char *s; for (a;b;c) { }", "s")); ASSERT_EQUALS(";;loop{}", getcode("char *s; for (a;b;c) { }", "s"));
ASSERT_EQUALS(";;loop{alloc;}", getcode("char *s; for (a;b;c) { s=malloc(10); }", "s")); ASSERT_EQUALS(";;loop{alloc;}", getcode("char *s; for (a;b;c) { s=malloc(10); }", "s"));
ASSERT_EQUALS(";;do{}loop;", getcode("char *s; do { } while (a);", "s")); ASSERT_EQUALS(";;do{}loop;", getcode("char *s; do { } while (a);", "s"));
ASSERT_EQUALS(";;while1{}", getcode("char *s; while(true) { }", "s")); ASSERT_EQUALS(";;while1{}", getcode("char *s; while(true) { }", "s"));
ASSERT_EQUALS(";;while1{}", getcode("char *s; for(;;) { }", "s")); ASSERT_EQUALS(";;while1{}", getcode("char *s; for(;;) { }", "s"));
ASSERT_EQUALS(";;while(var){}", getcode("char *s; while (s) { }", "s"));
ASSERT_EQUALS(";;while(!var){}", getcode("char *s; while (!s) { }", "s"));
ASSERT_EQUALS(";;alloc;while(var){}", getcode("int fd = open(); while (fd >= 0) { }", "fd"));
ASSERT_EQUALS(";;alloc;while(!var){}", getcode("int fd = open(); while (fd < 0) { }", "fd"));
// asprintf.. // asprintf..
ASSERT_EQUALS(";;alloc;", getcode("char *s; asprintf(&s, \"xyz\");", "s")); ASSERT_EQUALS(";;alloc;", getcode("char *s; asprintf(&s, \"xyz\");", "s"));
@ -562,22 +565,16 @@ private:
// replace "if ( ! var )" => "if(!var)" // replace "if ( ! var )" => "if(!var)"
for (Token *tok = tokenizer._tokens; tok; tok = tok->next()) for (Token *tok = tokenizer._tokens; tok; tok = tok->next())
{ {
if (Token::simpleMatch(tok, "if ( var )")) if (Token::Match(tok, "if|while ( var )"))
{ {
Token::eraseTokens(tok, tok->tokAt(4)); Token::eraseTokens(tok, tok->tokAt(4));
tok->str("if(var)"); tok->str(tok->str() + "(var)");
} }
else if (Token::simpleMatch(tok, "if ( ! var )")) else if (Token::Match(tok, "if|while ( ! var )"))
{ {
Token::eraseTokens(tok, tok->tokAt(5)); Token::eraseTokens(tok, tok->tokAt(5));
tok->str("if(!var)"); tok->str(tok->str() + "(!var)");
}
else if (Token::simpleMatch(tok, "! var"))
{
tok->deleteNext();
tok->str("!var");
} }
} }
@ -659,12 +656,14 @@ private:
ASSERT_EQUALS("; alloc ; alloc ;", simplifycode("; alloc ; do { alloc ; } loop ;")); ASSERT_EQUALS("; alloc ; alloc ;", simplifycode("; alloc ; do { alloc ; } loop ;"));
ASSERT_EQUALS("; exit ;", simplifycode("; alloc ; do { } loop ; exit ;")); ASSERT_EQUALS("; exit ;", simplifycode("; alloc ; do { } loop ; exit ;"));
ASSERT_EQUALS("; alloc ;", simplifycode("; alloc ; loop !var alloc ;")); ASSERT_EQUALS("; alloc ;", simplifycode("; alloc ; while(!var) alloc ;"));
ASSERT_EQUALS("; alloc ; dealloc ; return ;", simplifycode("; alloc ; while1 { if { dealloc ; return ; } }")); ASSERT_EQUALS("; alloc ; dealloc ; return ;", simplifycode("; alloc ; while1 { if { dealloc ; return ; } }"));
ASSERT_EQUALS("; alloc ; dealloc ; return ;", simplifycode("; alloc ; while1 { if { dealloc ; return ; } if { continue ; } }")); ASSERT_EQUALS("; alloc ; dealloc ; return ;", simplifycode("; alloc ; while1 { if { dealloc ; return ; } if { continue ; } }"));
ASSERT_EQUALS("; alloc ;", simplifycode("; alloc ; while1 { if { dealloc ; return ; } if { break ; } }")); ASSERT_EQUALS("; alloc ;", simplifycode("; alloc ; while1 { if { dealloc ; return ; } if { break ; } }"));
ASSERT_EQUALS(";", simplifycode("; do { dealloc ; alloc ; } while(var) ;"));
// callfunc.. // callfunc..
ASSERT_EQUALS("; callfunc ;\n;", simplifycode(";callfunc;")); ASSERT_EQUALS("; callfunc ;\n;", simplifycode(";callfunc;"));