Fixed #1074 (Exception safety: auto deallocated classes don't leak)
This commit is contained in:
parent
c6f913ac3e
commit
1002457b17
|
@ -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()
|
||||
{
|
||||
if (!_settings->isEnabled("exceptNew"))
|
||||
|
@ -112,7 +105,7 @@ void CheckExceptionSafety::unsafeNew()
|
|||
unsafeNewError(tok->previous(), varname);
|
||||
break;
|
||||
}
|
||||
if (!autodealloc(tok->tokAt(2), _tokenizer->tokens()))
|
||||
if (!_settings->isAutoDealloc(tok->strAt(2)))
|
||||
{
|
||||
varname = tok->strAt(-1);
|
||||
}
|
||||
|
@ -159,7 +152,7 @@ void CheckExceptionSafety::unsafeNew()
|
|||
unsafeNewError(tok, varname);
|
||||
break;
|
||||
}
|
||||
if (!autodealloc(tok->tokAt(3), _tokenizer->tokens()))
|
||||
if (!_settings->isAutoDealloc(tok->strAt(3)))
|
||||
varname = tok->str();
|
||||
}
|
||||
}
|
||||
|
@ -176,7 +169,8 @@ void CheckExceptionSafety::unsafeNew()
|
|||
varname = "";
|
||||
}
|
||||
|
||||
if (Token::Match(tok, "[;{}] %type% * %var% ;"))
|
||||
if (Token::Match(tok, "[;{}] %type% * %var% ;") &&
|
||||
!_settings->isAutoDealloc(tok->strAt(1)))
|
||||
{
|
||||
tok = tok->tokAt(3);
|
||||
if (tok->varId())
|
||||
|
|
|
@ -40,7 +40,7 @@ private:
|
|||
TEST_CASE(deallocThrow);
|
||||
}
|
||||
|
||||
void check(const std::string &code)
|
||||
void check(const std::string &code, const std::string &autodealloc = "")
|
||||
{
|
||||
// Tokenize..
|
||||
Tokenizer tokenizer;
|
||||
|
@ -54,6 +54,8 @@ private:
|
|||
// Check char variable usage..
|
||||
Settings settings;
|
||||
settings.addEnabled("all");
|
||||
std::istringstream istr2(autodealloc.c_str());
|
||||
settings.autoDealloc(istr2);
|
||||
CheckExceptionSafety checkExceptionSafety(&tokenizer, &settings, this);
|
||||
checkExceptionSafety.runSimplifiedChecks(&tokenizer, &settings, this);
|
||||
}
|
||||
|
@ -69,15 +71,13 @@ private:
|
|||
|
||||
void newnew()
|
||||
{
|
||||
const std::string AB("class A { }; class B { }; ");
|
||||
|
||||
check(AB + "C::C() : a(new A), b(new B) { }");
|
||||
check("C::C() : a(new A), b(new B) { }");
|
||||
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());
|
||||
|
||||
check(AB + "C::C()\n"
|
||||
check("C::C()\n"
|
||||
"{\n"
|
||||
" a = new A;\n"
|
||||
" b = new B;\n"
|
||||
|
@ -106,6 +106,13 @@ private:
|
|||
" delete a2;\n"
|
||||
"}\n");
|
||||
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()
|
||||
|
|
Loading…
Reference in New Issue