Co-authored-by: chrchr-github <chrchr@github>
This commit is contained in:
parent
237bed8a91
commit
d6a1a657df
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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];"
|
||||
|
|
Loading…
Reference in New Issue