Skip to content

Commit

Permalink
Fix #11796 FN memleak with brace init
Browse files Browse the repository at this point in the history
  • Loading branch information
chrchr-github committed Nov 29, 2023
1 parent a8eb971 commit 048591f
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 6 deletions.
15 changes: 9 additions & 6 deletions lib/checkleakautovar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,8 @@ bool CheckLeakAutoVar::checkScope(const Token * const startToken,

// check each token
{
const Token * nextTok = checkTokenInsideExpression(tok, varInfo);
const bool isInit = Token::Match(tok, "%var% {|(") && tok->variable() && tok == tok->variable()->nameToken();
const Token * nextTok = isInit ? nullptr : checkTokenInsideExpression(tok, varInfo);
if (nextTok) {
tok = nextTok;
continue;
Expand All @@ -337,26 +338,28 @@ bool CheckLeakAutoVar::checkScope(const Token * const startToken,


// look for end of statement
if (!Token::Match(tok, "[;{},]") || Token::Match(tok->next(), "[;{},]"))
const bool isInit = Token::Match(tok->tokAt(-1), "%var% {|(") && tok->tokAt(-1)->variable() && tok->tokAt(-1) == tok->tokAt(-1)->variable()->nameToken();
if ((!Token::Match(tok, "[;{},]") || Token::Match(tok->next(), "[;{},]")) && !(isInit && tok->str() == "("))
continue;

if (Token::Match(tok, "[;{},] %var% ["))
continue;

tok = tok->next();
if (!isInit)
tok = tok->next();
if (!tok || tok == endToken)
break;

if (Token::Match(tok, "const %type%"))
tok = tok->tokAt(2);

while (tok->str() == "(")
while (!isInit && tok->str() == "(")
tok = tok->next();
while (tok->isUnaryOp("*") && tok->astOperand1()->isUnaryOp("&"))
tok = tok->astOperand1()->astOperand1();

// parse statement, skip to last member
const Token *varTok = tok;
const Token* varTok = isInit ? tok->tokAt(-1) : tok;
while (Token::Match(varTok, "%name% ::|. %name% !!("))
varTok = varTok->tokAt(2);

Expand All @@ -381,7 +384,7 @@ bool CheckLeakAutoVar::checkScope(const Token * const startToken,
};

// assignment..
if (const Token* const tokAssignOp = isAssignment(varTok)) {
if (const Token* const tokAssignOp = isInit ? varTok : isAssignment(varTok)) {

if (Token::simpleMatch(tokAssignOp->astOperand1(), "."))
continue;
Expand Down
11 changes: 11 additions & 0 deletions test/testleakautovar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ class TestLeakAutoVar : public TestFixture {
TEST_CASE(assign22); // #9139
TEST_CASE(assign23);
TEST_CASE(assign24); // #7440
TEST_CASE(assign25);

TEST_CASE(isAutoDealloc);

Expand Down Expand Up @@ -571,6 +572,16 @@ class TestLeakAutoVar : public TestFixture {
ASSERT_EQUALS("[test.c:5]: (error) Memory leak: p\n", errout.str());
}

void assign25() {
check("void f() {\n" // #11796
" int* p{ new int };\n"
" int* q(new int);\n"
"}", true);
ASSERT_EQUALS("[test.cpp:4]: (error) Memory leak: p\n"
"[test.cpp:4]: (error) Memory leak: q\n",
errout.str());
}

void isAutoDealloc() {
check("void f() {\n"
" char *p = new char[100];"
Expand Down

0 comments on commit 048591f

Please sign in to comment.