Improved the "CheckMemoryLeak::functionReturnType"

This commit is contained in:
Daniel Marjamäki 2009-06-15 21:13:39 +02:00
parent 0c059af3cb
commit a81b6487bf
3 changed files with 57 additions and 7 deletions

View File

@ -51,7 +51,7 @@ bool CheckMemoryLeak::isclass(const Tokenizer *_tokenizer, const Token *tok) con
}
//---------------------------------------------------------------------------
CheckMemoryLeak::AllocType CheckMemoryLeak::GetAllocationType(const Token *tok2)
CheckMemoryLeak::AllocType CheckMemoryLeak::GetAllocationType(const Token *tok2) const
{
// What we may have...
// * var = (char *)malloc(10);
@ -272,15 +272,57 @@ CheckMemoryLeak::AllocType CheckMemoryLeak::functionReturnType(const Token *tok)
{
if (parlevel != 1)
return No;
if (Token::Match(tok, ") const| { return new %type% ; }"))
return New;
if (Token::Match(tok, ") const| { return new %type% [ %any% ] ; }"))
return NewArray;
break;
}
tok = tok->next();
}
// Is this the start of a function?
if (!Token::Match(tok, ") const| {"))
return No;
while (tok->str() != "{")
tok = tok->next();
tok = tok ? tok->next() : 0;
// Inspect the statements..
std::string varname;
AllocType allocType = No;
while (tok)
{
// variable declaration..
if (Token::Match(tok, "%type% * %var% ;"))
{
tok = tok->tokAt(4);
continue;
}
if (varname.empty() && Token::Match(tok,"%var% = "))
{
varname = tok->str();
allocType = GetAllocationType(tok->tokAt(2));
if (allocType == No)
return No;
while (tok && tok->str() != ";")
tok = tok->next();
tok = tok ? tok->next() : 0;
continue;
}
if (tok->str() == "return")
{
if (varname.size() && Token::Match(tok->next(), (varname + " ;").c_str()))
return allocType;
if (Token::Match(tok, "return new %type% ;"))
return New;
if (Token::Match(tok, "return new %type% [ %any% ] ;"))
return NewArray;
}
return No;
}
return No;
}

View File

@ -52,7 +52,7 @@ public:
void MemoryLeak(const Token *tok, const char varname[], AllocType alloctype, bool all);
void MismatchError(const Token *Tok1, const std::list<const Token *> &callstack, const char varname[]);
AllocType GetDeallocationType(const Token *tok, const char *varnames[]);
AllocType GetAllocationType(const Token *tok2);
AllocType GetAllocationType(const Token *tok2) const;
AllocType GetReallocationType(const Token *tok2);
bool isclass(const Tokenizer *_tokenizer, const Token *typestr) const;

View File

@ -70,6 +70,15 @@ private:
"{ return new char[100]; }";
ASSERT_EQUALS(CheckMemoryLeak::NewArray, functionReturnType(code));
}
{
const char code[] = "char *foo()\n"
"{\n"
" char *p = new char[100];\n"
" return p;\n"
"}";
ASSERT_EQUALS(CheckMemoryLeak::NewArray, functionReturnType(code));
}
}
};
@ -1436,7 +1445,6 @@ private:
void throw1()
{
check("void foo()\n"