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
This commit is contained in:
chrchr-github 2022-06-28 14:02:02 +02:00 committed by GitHub
parent cdeebc15ea
commit 2223cd24b9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 25 additions and 6 deletions

View File

@ -991,7 +991,7 @@ void CheckMemoryLeakNoVar::checkForUnreleasedInputArgument(const Scope *scope)
// parse the executable scope until tok is reached... // parse the executable scope until tok is reached...
for (const Token *tok = scope->bodyStart; tok != scope->bodyEnd; tok = tok->next()) { for (const Token *tok = scope->bodyStart; tok != scope->bodyEnd; tok = tok->next()) {
// allocating memory in parameter for function call.. // allocating memory in parameter for function call..
if (!Token::Match(tok, "%name% (")) if (tok->varId() || !Token::Match(tok, "%name% ("))
continue; continue;
// check if the output of the function is assigned // check if the output of the function is assigned
@ -1014,10 +1014,11 @@ void CheckMemoryLeakNoVar::checkForUnreleasedInputArgument(const Scope *scope)
const std::vector<const Token *> args = getArguments(tok); const std::vector<const Token *> args = getArguments(tok);
for (const Token* arg : args) { for (const Token* arg : args) {
if (arg->isOp()) if (arg->isOp() && !(tok->isKeyword() && arg->str() == "*")) // e.g. switch (*new int)
continue; continue;
if (!(mTokenizer->isCPP() && Token::simpleMatch(arg, "new"))) { while (arg->astOperand1()) {
while (arg->astOperand1()) if (mTokenizer->isCPP() && Token::simpleMatch(arg, "new"))
break;
arg = arg->astOperand1(); arg = arg->astOperand1();
} }
if (getAllocationType(arg, 0) == No) if (getAllocationType(arg, 0) == No)

View File

@ -1722,7 +1722,7 @@ void CheckOther::charBitOpError(const Token *tok)
static bool isType(const Token * tok, bool unknown) static bool isType(const Token * tok, bool unknown)
{ {
if (Token::Match(tok, "%type%")) if (tok && (tok->isStandardType() || (!tok->isKeyword() && Token::Match(tok, "%type%"))))
return true; return true;
if (Token::simpleMatch(tok, "::")) if (Token::simpleMatch(tok, "::"))
return isType(tok->astOperand2(), unknown); return isType(tok->astOperand2(), unknown);

View File

@ -662,6 +662,11 @@ private:
" +\" y = \" + b;\n" " +\" y = \" + b;\n"
"}\n", /*inconclusive*/ true); "}\n", /*inconclusive*/ true);
ASSERT_EQUALS("[test.cpp:3]: (warning, inconclusive) Found suspicious operator '+', result is not used.\n", errout.str()); ASSERT_EQUALS("[test.cpp:3]: (warning, inconclusive) Found suspicious operator '+', result is not used.\n", errout.str());
check("void f() {\n"
" *new int;\n"
"}\n", /*inconclusive*/ true);
ASSERT_EQUALS("[test.cpp:2]: (warning, inconclusive) Found suspicious operator '*', result is not used.\n", errout.str());
} }
void vardecl() { void vardecl() {

View File

@ -2615,6 +2615,19 @@ private:
ASSERT_EQUALS("[test.cpp:1]: (error) Return value of allocation function 'new' is not stored.\n" ASSERT_EQUALS("[test.cpp:1]: (error) Return value of allocation function 'new' is not stored.\n"
"[test.cpp:2]: (error) Return value of allocation function 'new' is not stored.\n", "[test.cpp:2]: (error) Return value of allocation function 'new' is not stored.\n",
errout.str()); errout.str());
check("void f() {\n" // #11157
" switch (*new int) { case 42: break; }\n"
" switch (*malloc(42)) { case 42: break; }\n"
"}\n");
ASSERT_EQUALS("[test.cpp:2]: (error) Allocation with new, switch doesn't release it.\n"
"[test.cpp:3]: (error) Allocation with malloc, switch doesn't release it.\n",
errout.str());
check("void f() {\n"
" Ref<StringBuffer> remove(new StringBuffer());\n"
"}\n");
ASSERT_EQUALS("", errout.str());
} }
void smartPointerFunctionParam() { void smartPointerFunctionParam() {