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()
|
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())
|
||||||
|
|
|
@ -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()
|
||||||
|
|
Loading…
Reference in New Issue