Skip to content

Commit 2223cd2

Browse files
Fix #11157 FN: leakNoVarFunctionCall (switch condition) (#4240)
* Fix #10857 FN: leakNoVarFunctionCall * Fix TODO * Fix #10858 FN: leakNoVarFunctionCall (if ( b && malloc ) ) * #11155 FN: leakNoVarFunctionCall (ternary operator) * Fix #11157 FN: leakNoVarFunctionCall (switch condition) * Fix FN constStatement * Fix FP leakNoVarFunctionCall
1 parent cdeebc1 commit 2223cd2

4 files changed

Lines changed: 25 additions & 6 deletions

File tree

lib/checkmemoryleak.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -991,7 +991,7 @@ void CheckMemoryLeakNoVar::checkForUnreleasedInputArgument(const Scope *scope)
991991
// parse the executable scope until tok is reached...
992992
for (const Token *tok = scope->bodyStart; tok != scope->bodyEnd; tok = tok->next()) {
993993
// allocating memory in parameter for function call..
994-
if (!Token::Match(tok, "%name% ("))
994+
if (tok->varId() || !Token::Match(tok, "%name% ("))
995995
continue;
996996

997997
// check if the output of the function is assigned
@@ -1014,11 +1014,12 @@ void CheckMemoryLeakNoVar::checkForUnreleasedInputArgument(const Scope *scope)
10141014

10151015
const std::vector<const Token *> args = getArguments(tok);
10161016
for (const Token* arg : args) {
1017-
if (arg->isOp())
1017+
if (arg->isOp() && !(tok->isKeyword() && arg->str() == "*")) // e.g. switch (*new int)
10181018
continue;
1019-
if (!(mTokenizer->isCPP() && Token::simpleMatch(arg, "new"))) {
1020-
while (arg->astOperand1())
1021-
arg = arg->astOperand1();
1019+
while (arg->astOperand1()) {
1020+
if (mTokenizer->isCPP() && Token::simpleMatch(arg, "new"))
1021+
break;
1022+
arg = arg->astOperand1();
10221023
}
10231024
if (getAllocationType(arg, 0) == No)
10241025
continue;

lib/checkother.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1722,7 +1722,7 @@ void CheckOther::charBitOpError(const Token *tok)
17221722

17231723
static bool isType(const Token * tok, bool unknown)
17241724
{
1725-
if (Token::Match(tok, "%type%"))
1725+
if (tok && (tok->isStandardType() || (!tok->isKeyword() && Token::Match(tok, "%type%"))))
17261726
return true;
17271727
if (Token::simpleMatch(tok, "::"))
17281728
return isType(tok->astOperand2(), unknown);

test/testincompletestatement.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -662,6 +662,11 @@ class TestIncompleteStatement : public TestFixture {
662662
" +\" y = \" + b;\n"
663663
"}\n", /*inconclusive*/ true);
664664
ASSERT_EQUALS("[test.cpp:3]: (warning, inconclusive) Found suspicious operator '+', result is not used.\n", errout.str());
665+
666+
check("void f() {\n"
667+
" *new int;\n"
668+
"}\n", /*inconclusive*/ true);
669+
ASSERT_EQUALS("[test.cpp:2]: (warning, inconclusive) Found suspicious operator '*', result is not used.\n", errout.str());
665670
}
666671

667672
void vardecl() {

test/testmemleak.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2615,6 +2615,19 @@ class TestMemleakNoVar : public TestFixture {
26152615
ASSERT_EQUALS("[test.cpp:1]: (error) Return value of allocation function 'new' is not stored.\n"
26162616
"[test.cpp:2]: (error) Return value of allocation function 'new' is not stored.\n",
26172617
errout.str());
2618+
2619+
check("void f() {\n" // #11157
2620+
" switch (*new int) { case 42: break; }\n"
2621+
" switch (*malloc(42)) { case 42: break; }\n"
2622+
"}\n");
2623+
ASSERT_EQUALS("[test.cpp:2]: (error) Allocation with new, switch doesn't release it.\n"
2624+
"[test.cpp:3]: (error) Allocation with malloc, switch doesn't release it.\n",
2625+
errout.str());
2626+
2627+
check("void f() {\n"
2628+
" Ref<StringBuffer> remove(new StringBuffer());\n"
2629+
"}\n");
2630+
ASSERT_EQUALS("", errout.str());
26182631
}
26192632

26202633
void smartPointerFunctionParam() {

0 commit comments

Comments
 (0)