diff --git a/lib/checkmemoryleak.cpp b/lib/checkmemoryleak.cpp index d074df2cb..e6d3af291 100644 --- a/lib/checkmemoryleak.cpp +++ b/lib/checkmemoryleak.cpp @@ -991,7 +991,7 @@ void CheckMemoryLeakNoVar::checkForUnreleasedInputArgument(const Scope *scope) // parse the executable scope until tok is reached... for (const Token *tok = scope->bodyStart; tok != scope->bodyEnd; tok = tok->next()) { // allocating memory in parameter for function call.. - if (!Token::Match(tok, "%name% (")) + if (tok->varId() || !Token::Match(tok, "%name% (")) continue; // check if the output of the function is assigned @@ -1014,11 +1014,12 @@ void CheckMemoryLeakNoVar::checkForUnreleasedInputArgument(const Scope *scope) const std::vector args = getArguments(tok); for (const Token* arg : args) { - if (arg->isOp()) + if (arg->isOp() && !(tok->isKeyword() && arg->str() == "*")) // e.g. switch (*new int) continue; - if (!(mTokenizer->isCPP() && Token::simpleMatch(arg, "new"))) { - while (arg->astOperand1()) - arg = arg->astOperand1(); + while (arg->astOperand1()) { + if (mTokenizer->isCPP() && Token::simpleMatch(arg, "new")) + break; + arg = arg->astOperand1(); } if (getAllocationType(arg, 0) == No) continue; diff --git a/lib/checkother.cpp b/lib/checkother.cpp index b63e5820f..232630992 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -1722,7 +1722,7 @@ void CheckOther::charBitOpError(const Token *tok) 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; if (Token::simpleMatch(tok, "::")) return isType(tok->astOperand2(), unknown); diff --git a/test/testincompletestatement.cpp b/test/testincompletestatement.cpp index 8485db656..755ae7983 100644 --- a/test/testincompletestatement.cpp +++ b/test/testincompletestatement.cpp @@ -662,6 +662,11 @@ private: " +\" y = \" + b;\n" "}\n", /*inconclusive*/ true); 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() { diff --git a/test/testmemleak.cpp b/test/testmemleak.cpp index 659596e58..e45b8a9d0 100644 --- a/test/testmemleak.cpp +++ b/test/testmemleak.cpp @@ -2615,6 +2615,19 @@ private: 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", 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 remove(new StringBuffer());\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); } void smartPointerFunctionParam() {