Fixed #1074 (Exception safety: auto deallocated classes don't leak)

This commit is contained in:
Daniel Marjamäki 2009-12-12 18:56:26 +01:00
parent c6f913ac3e
commit 1002457b17
2 changed files with 17 additions and 16 deletions

View File

@ -75,13 +75,6 @@ void CheckExceptionSafety::destructors()
} }
static bool autodealloc(const Token * const C, const Token * const tokens)
{
if (C->isStandardType())
return false;
return !Token::findmatch(tokens, ("class " + C->str() + " {").c_str());
}
void CheckExceptionSafety::unsafeNew() void CheckExceptionSafety::unsafeNew()
{ {
if (!_settings->isEnabled("exceptNew")) if (!_settings->isEnabled("exceptNew"))
@ -112,7 +105,7 @@ void CheckExceptionSafety::unsafeNew()
unsafeNewError(tok->previous(), varname); unsafeNewError(tok->previous(), varname);
break; break;
} }
if (!autodealloc(tok->tokAt(2), _tokenizer->tokens())) if (!_settings->isAutoDealloc(tok->strAt(2)))
{ {
varname = tok->strAt(-1); varname = tok->strAt(-1);
} }
@ -159,7 +152,7 @@ void CheckExceptionSafety::unsafeNew()
unsafeNewError(tok, varname); unsafeNewError(tok, varname);
break; break;
} }
if (!autodealloc(tok->tokAt(3), _tokenizer->tokens())) if (!_settings->isAutoDealloc(tok->strAt(3)))
varname = tok->str(); varname = tok->str();
} }
} }
@ -176,7 +169,8 @@ void CheckExceptionSafety::unsafeNew()
varname = ""; varname = "";
} }
if (Token::Match(tok, "[;{}] %type% * %var% ;")) if (Token::Match(tok, "[;{}] %type% * %var% ;") &&
!_settings->isAutoDealloc(tok->strAt(1)))
{ {
tok = tok->tokAt(3); tok = tok->tokAt(3);
if (tok->varId()) if (tok->varId())

View File

@ -40,7 +40,7 @@ private:
TEST_CASE(deallocThrow); TEST_CASE(deallocThrow);
} }
void check(const std::string &code) void check(const std::string &code, const std::string &autodealloc = "")
{ {
// Tokenize.. // Tokenize..
Tokenizer tokenizer; Tokenizer tokenizer;
@ -54,6 +54,8 @@ private:
// Check char variable usage.. // Check char variable usage..
Settings settings; Settings settings;
settings.addEnabled("all"); settings.addEnabled("all");
std::istringstream istr2(autodealloc.c_str());
settings.autoDealloc(istr2);
CheckExceptionSafety checkExceptionSafety(&tokenizer, &settings, this); CheckExceptionSafety checkExceptionSafety(&tokenizer, &settings, this);
checkExceptionSafety.runSimplifiedChecks(&tokenizer, &settings, this); checkExceptionSafety.runSimplifiedChecks(&tokenizer, &settings, this);
} }
@ -69,15 +71,13 @@ private:
void newnew() void newnew()
{ {
const std::string AB("class A { }; class B { }; "); check("C::C() : a(new A), b(new B) { }");
check(AB + "C::C() : a(new A), b(new B) { }");
ASSERT_EQUALS("[test.cpp:1]: (style) Upon exception there is memory leak: a\n", errout.str()); ASSERT_EQUALS("[test.cpp:1]: (style) Upon exception there is memory leak: a\n", errout.str());
check("C::C() : a(new A), b(new B) { }"); check("C::C() : a(new A), b(new B) { }", "A\nB\n");
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
check(AB + "C::C()\n" check("C::C()\n"
"{\n" "{\n"
" a = new A;\n" " a = new A;\n"
" b = new B;\n" " b = new B;\n"
@ -106,6 +106,13 @@ private:
" delete a2;\n" " delete a2;\n"
"}\n"); "}\n");
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
check("void a()\n"
"{\n"
" A *a = new A;\n"
" B *b = new B;\n"
"}\n", "A\n");
ASSERT_EQUALS("", errout.str());
} }
void realloc() void realloc()