Improving the accuracy of the memory leaks detecting

This commit is contained in:
Daniel Marjamäki 2007-05-17 17:25:20 +00:00
parent b08536db35
commit 775a62be69
1 changed files with 77 additions and 24 deletions

View File

@ -29,7 +29,7 @@ void Tokenize(const char FileName[]);
std::vector<std::string> VariableNames; std::vector<std::string> VariableNames;
struct STATEMENT struct STATEMENT
{ {
enum etype {OBRACE, EBRACE, DECL, ASSIGN, NEW, DELETE, NEWARRAY, DELETEARRAY, USE}; enum etype {OBRACE, EBRACE, DECL, ASSIGN, NEW, DELETE, NEWARRAY, DELETEARRAY, USE, RETURN};
etype Type; etype Type;
unsigned int VarIndex; unsigned int VarIndex;
TOKEN *Token; TOKEN *Token;
@ -626,7 +626,7 @@ void CreateStatementList()
else if (indentlevel >= 1) else if (indentlevel >= 1)
{ {
// Declaring variables.. // Declaring variables..
if (IsName(tok->str)) if (IsName(tok->str) && strcmp(tok->str,"delete") && strcmp(tok->str,"return"))
{ {
const char *str1 = getstr(tok, 1); const char *str1 = getstr(tok, 1);
bool decl = IsName(str1) || str1[0]=='*'; bool decl = IsName(str1) || str1[0]=='*';
@ -720,6 +720,20 @@ void CreateStatementList()
break; break;
} }
} }
// Return..
for (TOKEN *tok2 = tok; tok2; tok2 = tok2->next)
{
if (strcmp(tok2->str,";")==0)
break;
if (strcmp(tok2->str,"return")==0 &&
IsName(getstr(tok2,1)) &&
strcmp(getstr(tok2,2),";")==0)
{
AppendStatement(STATEMENT::RETURN, tok2, getstr(tok2,1));
}
}
} }
} }
@ -733,41 +747,50 @@ void CreateStatementList()
switch (s.Type) switch (s.Type)
{ {
case STATEMENT::OBRACE: case STATEMENT::OBRACE:
std::cout << "{\n"; std::cout << "{";
break; break;
case STATEMENT::EBRACE: case STATEMENT::EBRACE:
std::cout << "}\n"; std::cout << "}";
break; break;
case STATEMENT::DECL: case STATEMENT::DECL:
std::cout << "decl " << VariableNames[s.VarIndex] << "\n"; std::cout << "decl " << VariableNames[s.VarIndex];
break; break;
case STATEMENT::ASSIGN: case STATEMENT::ASSIGN:
std::cout << "assign " << VariableNames[s.VarIndex] << "\n"; std::cout << "assign " << VariableNames[s.VarIndex];
break; break;
case STATEMENT::NEW: case STATEMENT::NEW:
std::cout << "new " << VariableNames[s.VarIndex] << "\n"; std::cout << "new " << VariableNames[s.VarIndex];
break; break;
case STATEMENT::NEWARRAY: case STATEMENT::NEWARRAY:
std::cout << "new[] " << VariableNames[s.VarIndex] << "\n"; std::cout << "new[] " << VariableNames[s.VarIndex];
break; break;
case STATEMENT::DELETE: case STATEMENT::DELETE:
std::cout << "delete " << VariableNames[s.VarIndex] << "\n"; std::cout << "delete " << VariableNames[s.VarIndex];
break; break;
case STATEMENT::DELETEARRAY: case STATEMENT::DELETEARRAY:
std::cout << "delete[] " << VariableNames[s.VarIndex] << "\n"; std::cout << "delete[] " << VariableNames[s.VarIndex];
break; break;
case STATEMENT::USE: case STATEMENT::USE:
std::cout << "use " << VariableNames[s.VarIndex] << "\n"; std::cout << "use " << VariableNames[s.VarIndex];
break;
case STATEMENT::RETURN:
std::cout << "return " << VariableNames[s.VarIndex];
break;
default:
std::cout << "ERROR. Unknown code!!";
break; break;
} }
std::cout << "\n";
} }
} }
} }
@ -1011,22 +1034,24 @@ void CheckMemoryLeak()
if (varlist[i]->indentlevel != indentlevel) if (varlist[i]->indentlevel != indentlevel)
continue; continue;
// This is highly inaccurate at the moment if (varlist[i]->value == _variable::New || varlist[i]->value == _variable::NewA)
//if (Debug) {
//{ std::ostringstream ostr;
// if (varlist[i]->value == _variable::New || varlist[i]->value == _variable::NewA) ostr << FileLine(it->Token) << ": Memory leak:" << VariableNames[varlist[i]->varindex];
// { ReportErr(ostr.str());
// std::ostringstream ostr; }
// ostr << FileLine(it->Token) << ": Memory leak:" << VariableNames[varlist[i]->varindex];
// ReportErr(ostr.str());
// }
//}
// Delete this instance.. // Delete this instance..
delete varlist[i]; delete varlist[i];
varlist.erase(varlist.begin()+i); varlist.erase(varlist.begin()+i);
} }
} }
// Make sure the varlist is empty..
if (indentlevel <= 1)
varlist.clear();
if (indentlevel > 0)
indentlevel--; indentlevel--;
break; break;
@ -1063,8 +1088,8 @@ void CheckMemoryLeak()
if (a1 ^ a2) if (a1 ^ a2)
{ {
std::cout << (a1 ? "new[]" : "new") << "\n"; //std::cout << (a1 ? "new[]" : "new") << "\n";
std::cout << (a2 ? "delete[]" : "delete") << "\n"; //std::cout << (a2 ? "delete[]" : "delete") << "\n";
std::ostringstream ostr; std::ostringstream ostr;
ostr << FileLine(it->Token) << ": Mismatching allocation and deallocation '" << VariableNames[varlist[i]->varindex] << "'"; ostr << FileLine(it->Token) << ": Mismatching allocation and deallocation '" << VariableNames[varlist[i]->varindex] << "'";
@ -1091,6 +1116,34 @@ void CheckMemoryLeak()
case STATEMENT::ASSIGN: case STATEMENT::ASSIGN:
case STATEMENT::USE: case STATEMENT::USE:
for (unsigned int i = 0; i < varlist.size(); i++)
{
if ( varlist[i]->varindex == it->VarIndex )
{
varlist[i]->value = _variable::Data;
break;
}
}
break;
case STATEMENT::RETURN:
for (unsigned int i = 0; i < varlist.size(); i++)
{
if ( varlist[i]->varindex == it->VarIndex )
{
varlist[i]->value = _variable::Any;
}
else if (varlist[i]->value==_variable::New ||
varlist[i]->value==_variable::NewA )
{
std::ostringstream ostr;
ostr << FileLine(it->Token) << ": Memory leak:" << VariableNames[varlist[i]->varindex];
ReportErr(ostr.str());
varlist[i]->value = _variable::Any;
break;
}
}
break; break;
} }
} }