Check for smart pointer release (#1206)
This commit is contained in:
parent
02fde2025b
commit
067d82f0ea
|
@ -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;
|
||||
|
|
|
@ -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"
|
||||
|
|
Loading…
Reference in New Issue