CheckMemoryLeak: Refactoring the check
This commit is contained in:
parent
c833b51b25
commit
0575781a67
|
@ -480,6 +480,101 @@ static void CheckMemoryLeak_CheckScope_All( const TOKEN *Tok1, const char varnam
|
||||||
|
|
||||||
extern bool ShowAll;
|
extern bool ShowAll;
|
||||||
|
|
||||||
|
static TOKEN *getcode(const TOKEN *tok, const char varname[])
|
||||||
|
{
|
||||||
|
const char *varnames[2];
|
||||||
|
varnames[0] = varname;
|
||||||
|
varnames[1] = 0;
|
||||||
|
|
||||||
|
TOKEN *rethead = 0, *rettail = 0;
|
||||||
|
#define addtoken(_str) \
|
||||||
|
{ \
|
||||||
|
TOKEN *newtok = new TOKEN; \
|
||||||
|
newtok->str = _str; \
|
||||||
|
newtok->linenr = tok->linenr; \
|
||||||
|
newtok->FileIndex = tok->FileIndex; \
|
||||||
|
newtok->next = 0; \
|
||||||
|
if (rettail) \
|
||||||
|
rettail->next = newtok; \
|
||||||
|
else \
|
||||||
|
rethead = newtok; \
|
||||||
|
rettail=newtok; \
|
||||||
|
}
|
||||||
|
|
||||||
|
AllocType alloctype = No;
|
||||||
|
AllocType dealloctype = No;
|
||||||
|
|
||||||
|
int indentlevel = 0;
|
||||||
|
int parlevel = 0;
|
||||||
|
for ( ; tok; tok = tok->next )
|
||||||
|
{
|
||||||
|
if ( tok->str[0] == '{' )
|
||||||
|
{
|
||||||
|
addtoken( "{" );
|
||||||
|
indentlevel++;
|
||||||
|
}
|
||||||
|
else if ( tok->str[0] == '}' )
|
||||||
|
{
|
||||||
|
addtoken( "}" );
|
||||||
|
if ( indentlevel <= 0 )
|
||||||
|
break;
|
||||||
|
indentlevel--;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( tok->str[0] == '(' )
|
||||||
|
parlevel++;
|
||||||
|
else if ( tok->str[0] == ')' )
|
||||||
|
parlevel--;
|
||||||
|
|
||||||
|
if ( parlevel == 0 && tok->str[0]==';')
|
||||||
|
addtoken(";");
|
||||||
|
|
||||||
|
if (Match(tok, "[(;{}] %var1% = ", varnames))
|
||||||
|
{
|
||||||
|
AllocType alloc = GetAllocationType(gettok(tok,3));
|
||||||
|
if ( alloc != No )
|
||||||
|
{
|
||||||
|
addtoken("alloc");
|
||||||
|
if (alloctype!=No && alloctype!=alloc)
|
||||||
|
MismatchError(tok, varname);
|
||||||
|
if (dealloctype!=No && dealloctype!=alloc)
|
||||||
|
MismatchError(tok, varname);
|
||||||
|
alloctype = alloc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AllocType dealloc = GetDeallocationType(tok, varnames);
|
||||||
|
if ( dealloc != No )
|
||||||
|
{
|
||||||
|
addtoken("dealloc");
|
||||||
|
if (alloctype!=No && alloctype!=dealloc)
|
||||||
|
MismatchError(tok, varname);
|
||||||
|
if (dealloctype!=No && dealloctype!=dealloc)
|
||||||
|
MismatchError(tok, varname);
|
||||||
|
dealloctype = dealloc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const int SIZE = 6;
|
||||||
|
const char *str[SIZE] = {"if","else","for","while","switch","return"};
|
||||||
|
for (int i = 0; i < SIZE; ++i)
|
||||||
|
{
|
||||||
|
if (strcmp(tok->str, str[i])==0)
|
||||||
|
addtoken(tok->str);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Assignment..
|
||||||
|
if ( Match(tok,"[)=] %var1%", varnames) )
|
||||||
|
addtoken("use");
|
||||||
|
|
||||||
|
// Function parameter..
|
||||||
|
if ( Match(tok, "[(,] %var1% [,)]", varnames) )
|
||||||
|
addtoken("use");
|
||||||
|
}
|
||||||
|
|
||||||
|
return rethead;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Simpler but less powerful than "CheckMemoryLeak_CheckScope_All"
|
// Simpler but less powerful than "CheckMemoryLeak_CheckScope_All"
|
||||||
static void CheckMemoryLeak_CheckScope( const TOKEN *Tok1, const char varname[] )
|
static void CheckMemoryLeak_CheckScope( const TOKEN *Tok1, const char varname[] )
|
||||||
{
|
{
|
||||||
|
@ -489,70 +584,38 @@ static void CheckMemoryLeak_CheckScope( const TOKEN *Tok1, const char varname[]
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *varnames[2];
|
TOKEN *tok = getcode( Tok1, varname );
|
||||||
varnames[0] = varname;
|
|
||||||
varnames[1] = 0;
|
|
||||||
|
|
||||||
AllocType Alloc = No;
|
// If the variable is not allocated at all => no memory leak
|
||||||
|
if (findmatch(tok, "alloc") == 0)
|
||||||
bool isfunc = false;
|
|
||||||
bool isreturn = false;
|
|
||||||
|
|
||||||
int indentlevel = 0;
|
|
||||||
for (const TOKEN *tok = Tok1 ; tok; tok = tok->next )
|
|
||||||
{
|
{
|
||||||
if (tok->str[0]=='{')
|
deleteTokens(tok);
|
||||||
indentlevel++;
|
return;
|
||||||
|
|
||||||
else if (tok->str[0]=='}')
|
|
||||||
{
|
|
||||||
indentlevel--;
|
|
||||||
if ( indentlevel < 0 )
|
|
||||||
{
|
|
||||||
if ( Alloc != No )
|
|
||||||
MemoryLeak( tok, varname );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Allocated..
|
|
||||||
if ( Alloc == No && Match(tok, "[(;{}] %var1% =", varnames) )
|
|
||||||
Alloc = GetAllocationType( gettok(tok, 3) );
|
|
||||||
|
|
||||||
// Deallocated..
|
|
||||||
AllocType dealloc = GetDeallocationType( tok, varnames );
|
|
||||||
if ( dealloc != No )
|
|
||||||
{
|
|
||||||
if ( Alloc != No && Alloc != dealloc )
|
|
||||||
MismatchError( tok, varname );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( Match(tok,";") )
|
|
||||||
isfunc = isreturn = false;
|
|
||||||
|
|
||||||
// Assignment..
|
|
||||||
if ( Match(tok, "[=)&] %var1%", varnames) )
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Assuming that it's deallocated if it's passed as parameter to a
|
|
||||||
// function
|
|
||||||
if ( Match(tok, "%var% (") &&
|
|
||||||
strcmp(tok->str,"if") &&
|
|
||||||
strcmp(tok->str,"for") &&
|
|
||||||
strcmp(tok->str,"while"))
|
|
||||||
{
|
|
||||||
isfunc = true;
|
|
||||||
}
|
|
||||||
if (isfunc && Match(tok,"[(,] %var1% [,)]", varnames))
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Return variable..
|
|
||||||
if (Match(tok, "return"))
|
|
||||||
isreturn = true;
|
|
||||||
if (isreturn && Match(tok,varname))
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// reduce the code..
|
||||||
|
for (TOKEN *tok2 = tok ; tok2; tok2 = tok2->next )
|
||||||
|
{
|
||||||
|
while (Match(tok2,"[;{}] ;"))
|
||||||
|
{
|
||||||
|
TOKEN *next = tok2->next;
|
||||||
|
tok2->next = tok2->next->next;
|
||||||
|
delete next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ! findmatch(tok,"dealloc") &&
|
||||||
|
! findmatch(tok,"return") &&
|
||||||
|
! findmatch(tok,"use") )
|
||||||
|
{
|
||||||
|
const TOKEN *last = tok;
|
||||||
|
while (last->next)
|
||||||
|
last = last->next;
|
||||||
|
MemoryLeak(last, varname);
|
||||||
|
}
|
||||||
|
|
||||||
|
deleteTokens(tok);
|
||||||
}
|
}
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
|
@ -348,3 +348,26 @@ bool Match(const TOKEN *tok, const char pattern[], const char *varname1[], const
|
||||||
}
|
}
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
const TOKEN *findmatch(const TOKEN *tok, const char pattern[], const char *varname1[], const char *varname2[])
|
||||||
|
{
|
||||||
|
for ( ; tok; tok = tok->next)
|
||||||
|
{
|
||||||
|
if ( Match(tok, pattern, varname1, varname2) )
|
||||||
|
return tok;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void deleteTokens(TOKEN *tok)
|
||||||
|
{
|
||||||
|
while (tok)
|
||||||
|
{
|
||||||
|
TOKEN *next = tok->next;
|
||||||
|
delete tok;
|
||||||
|
tok = next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,8 @@ void CheckGlobalFunctionUsage(const std::vector<std::string> &filenames);
|
||||||
|
|
||||||
bool Match(const TOKEN *tok, const char pattern[], const char *varname1[]=0, const char *varname2[]=0);
|
bool Match(const TOKEN *tok, const char pattern[], const char *varname1[]=0, const char *varname2[]=0);
|
||||||
|
|
||||||
|
const TOKEN *findmatch(const TOKEN *tok, const char pattern[], const char *varname1[]=0, const char *varname2[]=0);
|
||||||
|
|
||||||
|
void deleteTokens(TOKEN *tok);
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue