Check for smart pointer release (#1206)

This commit is contained in:
Paul Fultz II 2018-05-05 11:06:49 -05:00 committed by Daniel Marjamäki
parent 02fde2025b
commit 067d82f0ea
2 changed files with 36 additions and 0 deletions

View File

@ -193,6 +193,19 @@ static bool isVarUsedInTree(const Token *tok, unsigned int varid)
return isVarUsedInTree(tok->astOperand1(), varid) || isVarUsedInTree(tok->astOperand2(), varid);
}
static bool isPointerReleased(const Token *startToken, const Token *endToken, unsigned int varid)
{
for (const Token *tok = startToken; tok && tok != endToken; tok = tok->next()) {
if (tok->varId() != varid)
continue;
if(Token::Match(tok, "%var% . release ( )"))
return true;
if(Token::Match(tok, "%var% ="))
return false;
}
return false;
}
void CheckLeakAutoVar::checkScope(const Token * const startToken,
VarInfo *varInfo,
std::set<unsigned int> notzero)
@ -565,6 +578,12 @@ void CheckLeakAutoVar::checkScope(const Token * const startToken,
if (!Token::Match(typeEndTok, "> %var% {|( %var% ,|)|}"))
continue;
tok = typeEndTok->linkAt(2);
unsigned varid = typeEndTok->next()->varId();
if(isPointerReleased(typeEndTok->tokAt(2), endToken, varid))
continue;
bool arrayDelete = false;
if (Token::findsimplematch(ftok->next(), "[ ]", typeEndTok))
arrayDelete = true;

View File

@ -109,6 +109,7 @@ private:
TEST_CASE(mismatchAllocDealloc);
TEST_CASE(smartPointerDeleter);
TEST_CASE(smartPointerRelease);
// Execution reaches a 'return'
TEST_CASE(return1);
@ -1253,6 +1254,22 @@ private:
"}\n", true);
ASSERT_EQUALS("", errout.str());
}
void smartPointerRelease() {
check("void f() {\n"
" int * i = new int;\n"
" std::unique_ptr<int> x(i);\n"
" x.release();\n"
" delete i;\n"
"}\n", true);
ASSERT_EQUALS("", errout.str());
check("void f() {\n"
" int * i = new int;\n"
" std::unique_ptr<int> x(i);\n"
" x.release();\n"
"}\n", true);
ASSERT_EQUALS("[test.cpp:5]: (error) Memory leak: i\n", errout.str());
}
void return1() {
check("int f() {\n"