Fix #11796 FN memleak with brace init (#5708)

Co-authored-by: chrchr-github <chrchr@github>
This commit is contained in:
chrchr-github 2023-12-01 15:39:16 +01:00 committed by GitHub
parent 237bed8a91
commit d6a1a657df
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 31 additions and 6 deletions

View File

@ -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;
@ -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);
@ -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;

View File

@ -6621,6 +6621,17 @@ private:
ASSERT_EQUALS("[test.cpp:3]: (style, inconclusive) Technically the member function 'S::f' can be const.\n"
"[test.cpp:8]: (performance, inconclusive) Technically the member function 'S::g' can be static (but you may consider moving to unnamed namespace).\n",
errout.str());
checkConst("class C {\n" // #11653
"public:\n"
" void f(bool b) const;\n"
"};\n"
"void C::f(bool b) const {\n"
" if (b)\n"
" f(false);\n"
"}\n");
ASSERT_EQUALS("[test.cpp:5] -> [test.cpp:3]: (performance, inconclusive) Technically the member function 'C::f' can be static (but you may consider moving to unnamed namespace).\n",
errout.str());
}
void const90() { // #11637

View File

@ -88,6 +88,7 @@ private:
TEST_CASE(assign22); // #9139
TEST_CASE(assign23);
TEST_CASE(assign24); // #7440
TEST_CASE(assign25);
TEST_CASE(isAutoDealloc);
@ -571,6 +572,16 @@ private:
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];"