Refactoring CheckMemoryLeaks

This commit is contained in:
Daniel Marjamäki 2010-09-04 10:06:34 +02:00
parent f490ebcf88
commit beb4dddb2e
1 changed files with 76 additions and 81 deletions

View File

@ -809,30 +809,25 @@ const char * CheckMemoryLeakInFunction::call_func(const Token *tok, std::list<co
} }
static void addtoken(Token **rettail, const Token *tok, const std::string &str)
{
(*rettail)->insertToken(str);
(*rettail) = (*rettail)->next();
(*rettail)->linenr(tok->linenr());
(*rettail)->fileIndex(tok->fileIndex());
}
Token *CheckMemoryLeakInFunction::getcode(const Token *tok, std::list<const Token *> callstack, const unsigned int varid, CheckMemoryLeak::AllocType &alloctype, CheckMemoryLeak::AllocType &dealloctype, bool classmember, unsigned int sz) Token *CheckMemoryLeakInFunction::getcode(const Token *tok, std::list<const Token *> callstack, const unsigned int varid, CheckMemoryLeak::AllocType &alloctype, CheckMemoryLeak::AllocType &dealloctype, bool classmember, unsigned int sz)
{ {
Token *rethead = 0, *rettail = 0; Token *rethead = 0, *rettail = 0;
#define addtoken(_str) \
{ \
if (rettail) \
{ \
rettail->insertToken(_str); \
rettail = rettail->next(); \
} \
else \
{ \
rethead = new Token(0); \
rettail = rethead; \
rettail->str(_str); \
} \
\
rettail->linenr( tok->linenr() ); \
rettail->fileIndex( tok->fileIndex() ); \
}
// The first token should be ";" // The first token should be ";"
addtoken(";"); rethead = new Token(0);
rethead->str(";");
rethead->linenr(tok->linenr());
rethead->fileIndex(tok->fileIndex());
rettail = rethead;
bool isloop = false; bool isloop = false;
@ -842,12 +837,12 @@ Token *CheckMemoryLeakInFunction::getcode(const Token *tok, std::list<const Toke
{ {
if (tok->str() == "{") if (tok->str() == "{")
{ {
addtoken("{"); addtoken(&rettail, tok, "{");
++indentlevel; ++indentlevel;
} }
else if (tok->str() == "}") else if (tok->str() == "}")
{ {
addtoken("}"); addtoken(&rettail, tok, "}");
if (indentlevel <= 0) if (indentlevel <= 0)
break; break;
--indentlevel; --indentlevel;
@ -860,7 +855,7 @@ Token *CheckMemoryLeakInFunction::getcode(const Token *tok, std::list<const Toke
isloop &= (parlevel > 0); isloop &= (parlevel > 0);
if (parlevel == 0 && tok->str() == ";") if (parlevel == 0 && tok->str() == ";")
addtoken(";"); addtoken(&rettail, tok, ";");
if (varid == 0) if (varid == 0)
{ {
@ -871,11 +866,11 @@ Token *CheckMemoryLeakInFunction::getcode(const Token *tok, std::list<const Toke
if (tok->next()->str() == "__cppcheck_lock") if (tok->next()->str() == "__cppcheck_lock")
{ {
addtoken("alloc"); addtoken(&rettail, tok, "alloc");
} }
else else
{ {
addtoken("dealloc"); addtoken(&rettail, tok, "dealloc");
} }
tok = tok->tokAt(3); tok = tok->tokAt(3);
@ -884,7 +879,7 @@ Token *CheckMemoryLeakInFunction::getcode(const Token *tok, std::list<const Toke
if (Token::simpleMatch(tok, "if (")) if (Token::simpleMatch(tok, "if ("))
{ {
addtoken("if"); addtoken(&rettail, tok, "if");
tok = tok->next()->link(); tok = tok->next()->link();
continue; continue;
} }
@ -932,8 +927,8 @@ Token *CheckMemoryLeakInFunction::getcode(const Token *tok, std::list<const Toke
alloc = getReallocationType(tok->tokAt(2), varid); alloc = getReallocationType(tok->tokAt(2), varid);
if (alloc != CheckMemoryLeak::No) if (alloc != CheckMemoryLeak::No)
{ {
addtoken("realloc"); addtoken(&rettail, tok, "realloc");
addtoken(";"); addtoken(&rettail, tok, ";");
realloc = true; realloc = true;
tok = tok->tokAt(2); tok = tok->tokAt(2);
continue; continue;
@ -969,7 +964,7 @@ Token *CheckMemoryLeakInFunction::getcode(const Token *tok, std::list<const Toke
if (alloc != No) if (alloc != No)
{ {
if (! realloc) if (! realloc)
addtoken("alloc"); addtoken(&rettail, tok, "alloc");
if (alloctype != No && alloctype != alloc) if (alloctype != No && alloctype != alloc)
alloc = Many; alloc = Many;
@ -1007,7 +1002,7 @@ Token *CheckMemoryLeakInFunction::getcode(const Token *tok, std::list<const Toke
} }
} }
addtoken((rhs ? "use" : "assign")); addtoken(&rettail, tok, (rhs ? "use" : "assign"));
} }
} }
@ -1021,7 +1016,7 @@ Token *CheckMemoryLeakInFunction::getcode(const Token *tok, std::list<const Toke
else if (dealloc != No) else if (dealloc != No)
{ {
addtoken("dealloc"); addtoken(&rettail, tok, "dealloc");
if (dealloctype != No && dealloctype != dealloc) if (dealloctype != No && dealloctype != dealloc)
dealloc = Many; dealloc = Many;
@ -1045,14 +1040,14 @@ Token *CheckMemoryLeakInFunction::getcode(const Token *tok, std::list<const Toke
if (Token::Match(tok, "if ( 0 <= %varid% )", varid) || if (Token::Match(tok, "if ( 0 <= %varid% )", varid) ||
Token::Match(tok, "if ( %varid% != -1 )", varid)) Token::Match(tok, "if ( %varid% != -1 )", varid))
{ {
addtoken("if(var)"); addtoken(&rettail, tok, "if(var)");
tok = tok->next()->link(); tok = tok->next()->link();
continue; continue;
} }
else if (Token::Match(tok, "if ( %varid% == -1 )", varid) || else if (Token::Match(tok, "if ( %varid% == -1 )", varid) ||
Token::Match(tok, "if ( %varid% < 0 )", varid)) Token::Match(tok, "if ( %varid% < 0 )", varid))
{ {
addtoken("if(!var)"); addtoken(&rettail, tok, "if(!var)");
tok = tok->next()->link(); tok = tok->next()->link();
continue; continue;
} }
@ -1060,14 +1055,14 @@ Token *CheckMemoryLeakInFunction::getcode(const Token *tok, std::list<const Toke
if (Token::Match(tok, "if ( %varid% )", varid)) if (Token::Match(tok, "if ( %varid% )", varid))
{ {
addtoken("if(var)"); addtoken(&rettail, tok, "if(var)");
// Make sure the "use" will not be added // Make sure the "use" will not be added
tok = tok->next()->link(); tok = tok->next()->link();
} }
else if (Token::simpleMatch(tok, "if (") && notvar(tok->tokAt(2), varid, true)) else if (Token::simpleMatch(tok, "if (") && notvar(tok->tokAt(2), varid, true))
{ {
addtoken("if(!var)"); addtoken(&rettail, tok, "if(!var)");
} }
else else
{ {
@ -1086,8 +1081,8 @@ Token *CheckMemoryLeakInFunction::getcode(const Token *tok, std::list<const Toke
} }
if (Token::Match(tok2, "close|pclose|fclose|closedir ( %varid% )", varid)) if (Token::Match(tok2, "close|pclose|fclose|closedir ( %varid% )", varid))
{ {
addtoken("dealloc"); addtoken(&rettail, tok, "dealloc");
addtoken(";"); addtoken(&rettail, tok, ";");
dep = true; dep = true;
break; break;
} }
@ -1117,8 +1112,8 @@ Token *CheckMemoryLeakInFunction::getcode(const Token *tok, std::list<const Toke
} }
if (use) if (use)
{ {
addtoken("use"); addtoken(&rettail, tok, "use");
addtoken(";"); addtoken(&rettail, tok, ";");
break; break;
} }
} }
@ -1126,17 +1121,17 @@ Token *CheckMemoryLeakInFunction::getcode(const Token *tok, std::list<const Toke
if (Token::Match(tok, "if ( ! %varid% &&", varid)) if (Token::Match(tok, "if ( ! %varid% &&", varid))
{ {
addtoken("if(!var)"); addtoken(&rettail, tok, "if(!var)");
} }
else if (tok->next() && else if (tok->next() &&
tok->next()->link() && tok->next()->link() &&
Token::Match(tok->next()->link()->tokAt(-3), "&& ! %varid%", varid)) Token::Match(tok->next()->link()->tokAt(-3), "&& ! %varid%", varid))
{ {
addtoken("if(!var)"); addtoken(&rettail, tok, "if(!var)");
} }
else else
{ {
addtoken((dep ? "ifv" : "if")); addtoken(&rettail, tok, (dep ? "ifv" : "if"));
} }
tok = tok->next(); tok = tok->next();
@ -1148,19 +1143,19 @@ Token *CheckMemoryLeakInFunction::getcode(const Token *tok, std::list<const Toke
if ((tok->str() == "else") || (tok->str() == "switch")) if ((tok->str() == "else") || (tok->str() == "switch"))
{ {
addtoken(tok->str().c_str()); addtoken(&rettail, tok, tok->str());
} }
else if ((tok->str() == "case")) else if ((tok->str() == "case"))
{ {
addtoken("case"); addtoken(&rettail, tok, "case");
addtoken(";"); addtoken(&rettail, tok, ";");
} }
else if ((tok->str() == "default")) else if ((tok->str() == "default"))
{ {
addtoken("default"); addtoken(&rettail, tok, "default");
addtoken(";"); addtoken(&rettail, tok, ";");
} }
// Loops.. // Loops..
@ -1171,15 +1166,15 @@ Token *CheckMemoryLeakInFunction::getcode(const Token *tok, std::list<const Toke
if (Token::simpleMatch(tok, "while ( true )") || if (Token::simpleMatch(tok, "while ( true )") ||
Token::simpleMatch(tok, "for ( ; ; )")) Token::simpleMatch(tok, "for ( ; ; )"))
{ {
addtoken("while1"); addtoken(&rettail, tok, "while1");
tok = tok->next()->link(); tok = tok->next()->link();
continue; continue;
} }
else if (varid && getDeallocationType(tok->tokAt(2), varid) != No) else if (varid && getDeallocationType(tok->tokAt(2), varid) != No)
{ {
addtoken("dealloc"); addtoken(&rettail, tok, "dealloc");
addtoken(";"); addtoken(&rettail, tok, ";");
} }
else if (alloctype == Fd && varid) else if (alloctype == Fd && varid)
@ -1187,14 +1182,14 @@ Token *CheckMemoryLeakInFunction::getcode(const Token *tok, std::list<const Toke
if (Token::Match(tok, "while ( 0 <= %varid% )", varid) || if (Token::Match(tok, "while ( 0 <= %varid% )", varid) ||
Token::Match(tok, "while ( %varid% != -1 )", varid)) Token::Match(tok, "while ( %varid% != -1 )", varid))
{ {
addtoken("while(var)"); addtoken(&rettail, tok, "while(var)");
tok = tok->next()->link(); tok = tok->next()->link();
continue; continue;
} }
else if (Token::Match(tok, "while ( %varid% == -1 )", varid) || else if (Token::Match(tok, "while ( %varid% == -1 )", varid) ||
Token::Match(tok, "while ( %varid% < 0 )", varid)) Token::Match(tok, "while ( %varid% < 0 )", varid))
{ {
addtoken("while(!var)"); addtoken(&rettail, tok, "while(!var)");
tok = tok->next()->link(); tok = tok->next()->link();
continue; continue;
} }
@ -1202,49 +1197,49 @@ Token *CheckMemoryLeakInFunction::getcode(const Token *tok, std::list<const Toke
else if (varid && Token::Match(tok, "while ( %varid% )", varid)) else if (varid && Token::Match(tok, "while ( %varid% )", varid))
{ {
addtoken("while(var)"); addtoken(&rettail, tok, "while(var)");
tok = tok->next()->link(); tok = tok->next()->link();
continue; continue;
} }
else if (varid && Token::simpleMatch(tok, "while (") && notvar(tok->tokAt(2), varid, true)) else if (varid && Token::simpleMatch(tok, "while (") && notvar(tok->tokAt(2), varid, true))
{ {
addtoken("while(!var)"); addtoken(&rettail, tok, "while(!var)");
tok = tok->next()->link(); tok = tok->next()->link();
continue; continue;
} }
addtoken("loop"); addtoken(&rettail, tok, "loop");
} }
else if ((tok->str() == "do")) else if ((tok->str() == "do"))
{ {
addtoken("do"); addtoken(&rettail, tok, "do");
} }
if (varid > 0 && isloop && notvar(tok, varid)) if (varid > 0 && isloop && notvar(tok, varid))
{ {
addtoken("!var"); addtoken(&rettail, tok, "!var");
} }
// continue / break.. // continue / break..
if (tok->str() == "continue") if (tok->str() == "continue")
{ {
addtoken("continue"); addtoken(&rettail, tok, "continue");
} }
else if (tok->str() == "break") else if (tok->str() == "break")
{ {
addtoken("break"); addtoken(&rettail, tok, "break");
} }
else if (tok->str() == "goto") else if (tok->str() == "goto")
{ {
addtoken("goto"); addtoken(&rettail, tok, "goto");
} }
// Return.. // Return..
else if (tok->str() == "return") else if (tok->str() == "return")
{ {
addtoken("return"); addtoken(&rettail, tok, "return");
if (varid == 0) if (varid == 0)
{ {
addtoken(";"); addtoken(&rettail, tok, ";");
while (tok && tok->str() != ";") while (tok && tok->str() != ";")
tok = tok->next(); tok = tok->next();
if (!tok) if (!tok)
@ -1260,14 +1255,14 @@ Token *CheckMemoryLeakInFunction::getcode(const Token *tok, std::list<const Toke
tok2 = tok2->next(); tok2 = tok2->next();
if (Token::Match(tok2, "> ( %varid% )", varid)) if (Token::Match(tok2, "> ( %varid% )", varid))
{ {
addtoken("use"); addtoken(&rettail, tok, "use");
tok = tok2->tokAt(3); tok = tok2->tokAt(3);
} }
} }
else if (varid && Token::Match(tok, "return strcpy|strncpy|memcpy ( %varid%", varid)) else if (varid && Token::Match(tok, "return strcpy|strncpy|memcpy ( %varid%", varid))
{ {
addtoken("use"); addtoken(&rettail, tok, "use");
tok = tok->tokAt(2); tok = tok->tokAt(2);
} }
@ -1304,14 +1299,14 @@ Token *CheckMemoryLeakInFunction::getcode(const Token *tok, std::list<const Toke
} }
} }
if (use) if (use)
addtoken("use"); addtoken(&rettail, tok, "use");
addtoken(";"); addtoken(&rettail, tok, ";");
} }
} }
// throw.. // throw..
else if (Token::Match(tok, "try|throw|catch")) else if (Token::Match(tok, "try|throw|catch"))
addtoken(tok->strAt(0)); addtoken(&rettail, tok, tok->str());
// Assignment.. // Assignment..
if (varid) if (varid)
@ -1337,11 +1332,11 @@ Token *CheckMemoryLeakInFunction::getcode(const Token *tok, std::list<const Toke
} }
if (used) if (used)
addtoken("use"); addtoken(&rettail, tok, "use");
} }
else if (Token::Match(tok->previous(), "[;{}=(,+-*/] %varid% [", varid)) else if (Token::Match(tok->previous(), "[;{}=(,+-*/] %varid% [", varid))
{ {
addtoken("use_"); addtoken(&rettail, tok, "use_");
} }
} }
@ -1353,8 +1348,8 @@ Token *CheckMemoryLeakInFunction::getcode(const Token *tok, std::list<const Toke
{ {
if (!Token::Match(tok, "if|for|while|switch")) if (!Token::Match(tok, "if|for|while|switch"))
{ {
addtoken("exit"); addtoken(&rettail, tok, "exit");
addtoken(";"); addtoken(&rettail, tok, ";");
tok = tok->next()->link(); tok = tok->next()->link();
continue; continue;
} }
@ -1386,7 +1381,7 @@ Token *CheckMemoryLeakInFunction::getcode(const Token *tok, std::list<const Toke
} }
if (tok2->varId() == varid) if (tok2->varId() == varid)
{ {
addtoken("::use"); addtoken(&rettail, tok, "::use");
break; break;
} }
} }
@ -1396,7 +1391,7 @@ Token *CheckMemoryLeakInFunction::getcode(const Token *tok, std::list<const Toke
{ {
if (varid > 0 && Token::Match(tok, "%var% ( close|fclose|pclose ( %varid% ) ) ;", varid)) if (varid > 0 && Token::Match(tok, "%var% ( close|fclose|pclose ( %varid% ) ) ;", varid))
{ {
addtoken("dealloc"); addtoken(&rettail, tok, "dealloc");
tok = tok->next()->link(); tok = tok->next()->link();
continue; continue;
} }
@ -1407,27 +1402,27 @@ Token *CheckMemoryLeakInFunction::getcode(const Token *tok, std::list<const Toke
{ {
if (allocpar) if (allocpar)
{ {
addtoken(str); addtoken(&rettail, tok, str);
tok = tok->next()->link(); tok = tok->next()->link();
} }
else if (varid == 0 || str != std::string("alloc")) else if (varid == 0 || str != std::string("alloc"))
{ {
addtoken(str); addtoken(&rettail, tok, str);
} }
else if (Token::Match(tok->tokAt(-2), "%varid% =", varid)) else if (Token::Match(tok->tokAt(-2), "%varid% =", varid))
{ {
addtoken(str); addtoken(&rettail, tok, str);
} }
} }
else if (varid > 0 && else if (varid > 0 &&
getReallocationType(tok, varid) != No && getReallocationType(tok, varid) != No &&
tok->tokAt(2)->varId() == varid) tok->tokAt(2)->varId() == varid)
{ {
addtoken("if"); addtoken(&rettail, tok, "if");
addtoken("{"); addtoken(&rettail, tok, "{");
addtoken("dealloc"); addtoken(&rettail, tok, "dealloc");
addtoken(";"); addtoken(&rettail, tok, ";");
addtoken("}"); addtoken(&rettail, tok, "}");
tok = tok->next()->link(); tok = tok->next()->link();
continue; continue;
} }
@ -1451,7 +1446,7 @@ Token *CheckMemoryLeakInFunction::getcode(const Token *tok, std::list<const Toke
break; break;
else if (tok2->varId() == varid) else if (tok2->varId() == varid)
{ {
addtoken("use"); addtoken(&rettail, tok, "use");
break; break;
} }
} }
@ -1461,7 +1456,7 @@ Token *CheckMemoryLeakInFunction::getcode(const Token *tok, std::list<const Toke
// Linux lists.. // Linux lists..
if (varid > 0 && Token::Match(tok, "[=(,] & %varid% [.[,)]", varid)) if (varid > 0 && Token::Match(tok, "[=(,] & %varid% [.[,)]", varid))
{ {
addtoken("&use"); addtoken(&rettail, tok, "&use");
} }
} }