memory leaks: Added checking of deallocate to see that the pointer isn't deallocated already

This commit is contained in:
Daniel Marjamäki 2009-01-15 20:34:39 +00:00
parent 218c107b6f
commit 4cfb8ad1cb
4 changed files with 1569 additions and 1539 deletions

View File

@ -1014,8 +1014,8 @@ void CheckMemoryLeakClass::simplifycode(Token *tok)
done = false; done = false;
} }
// Reduce "[;{}] alloc ; dealloc ;" => "[;{}]" // Reduce "[;{}] alloc ; dealloc ; !!dealloc" => "[;{}]"
if (Token::Match(tok2, "[;{}] alloc ; dealloc ;")) if (Token::Match(tok2, "[;{}] alloc ; dealloc ; !!dealloc"))
{ {
erase(tok2, tok2->tokAt(5)); erase(tok2, tok2->tokAt(5));
done = false; done = false;
@ -1177,7 +1177,7 @@ void CheckMemoryLeakClass::CheckMemoryLeak_CheckScope(const Token *Tok1, const c
} }
simplifycode(tok); simplifycode(tok);
//tok->printOut( "simplifycode result" ); tok->printOut("simplifycode result");
// If the variable is not allocated at all => no memory leak // If the variable is not allocated at all => no memory leak
if (Token::findmatch(tok, "alloc") == 0) if (Token::findmatch(tok, "alloc") == 0)
@ -1214,6 +1214,11 @@ void CheckMemoryLeakClass::CheckMemoryLeak_CheckScope(const Token *Tok1, const c
MemoryLeak(result->tokAt(2), varname, alloctype); MemoryLeak(result->tokAt(2), varname, alloctype);
} }
else if ((result = Token::findmatch(tok, "dealloc ; dealloc ;")) != NULL)
{
_errorLogger->reportErr(ErrorMessage::deallocDealloc(_tokenizer, result->tokAt(2)));
}
else if (! Token::findmatch(tok, "dealloc") && else if (! Token::findmatch(tok, "dealloc") &&
! Token::findmatch(tok, "use") && ! Token::findmatch(tok, "use") &&
! Token::findmatch(tok, "return use ;")) ! Token::findmatch(tok, "return use ;"))

View File

@ -147,6 +147,15 @@ public:
return true; return true;
} }
static std::string deallocDealloc(const Tokenizer *tokenizer, const Token *Location)
{
return msg1(tokenizer, Location) + "Deallocating a deallocated pointer";
}
static bool deallocDealloc(const Settings &s)
{
return true;
}
static std::string cstyleCast(const Tokenizer *tokenizer, const Token *Location) static std::string cstyleCast(const Tokenizer *tokenizer, const Token *Location)
{ {
return msg1(tokenizer, Location) + "C-style pointer casting"; return msg1(tokenizer, Location) + "C-style pointer casting";

View File

@ -165,6 +165,9 @@ private:
TEST_CASE(dealloc_use_4); TEST_CASE(dealloc_use_4);
TEST_CASE(dealloc_use_5); TEST_CASE(dealloc_use_5);
TEST_CASE(dealloc_use_6); TEST_CASE(dealloc_use_6);
// free a free'd pointer
TEST_CASE(freefree);
} }
@ -1587,6 +1590,18 @@ private:
ASSERT_EQUALS(std::string(""), errout.str()); ASSERT_EQUALS(std::string(""), errout.str());
} }
void freefree()
{
check("void foo()\n"
"{\n"
" char *str = malloc(100);\n"
" free(str);\n"
" free(str);\n"
"}\n");
ASSERT_EQUALS(std::string("[test.cpp:5]: Deallocating a deallocated pointer\n"), errout.str());
}
}; };
REGISTER_TEST(TestMemleak) REGISTER_TEST(TestMemleak)

View File

@ -72,6 +72,7 @@ int main()
err.push_back(Message("mismatchAllocDealloc", Message::std, "Mismatching allocation and deallocation: %1", "varname")); err.push_back(Message("mismatchAllocDealloc", Message::std, "Mismatching allocation and deallocation: %1", "varname"));
err.push_back(Message("memleak", Message::std, "Memory leak: %1", "varname")); err.push_back(Message("memleak", Message::std, "Memory leak: %1", "varname"));
err.push_back(Message("resourceLeak", Message::std, "Resource leak: %1", "varname")); err.push_back(Message("resourceLeak", Message::std, "Resource leak: %1", "varname"));
err.push_back(Message("deallocDealloc", Message::std, "Deallocating a deallocated pointer"));
// checkother.cpp.. // checkother.cpp..
err.push_back(Message("cstyleCast", Message::style, "C-style pointer casting")); err.push_back(Message("cstyleCast", Message::style, "C-style pointer casting"));