diff --git a/lib/checkmemoryleak.cpp b/lib/checkmemoryleak.cpp index d02bb607b33..eceef0c5c1e 100644 --- a/lib/checkmemoryleak.cpp +++ b/lib/checkmemoryleak.cpp @@ -1052,6 +1052,9 @@ void CheckMemoryLeakNoVarImpl::checkForUnreleasedInputArgument(const Scope *scop if (alloc == New || alloc == NewArray) { const Token* typeTok = arg->next(); bool bail = !typeTok->isStandardType() && + (!typeTok->valueType() || + (typeTok->valueType()->type < ValueType::Type::SMART_POINTER && + typeTok->valueType()->type != ValueType::Type::POD)) && !mSettings.library.detectContainerOrIterator(typeTok) && !mSettings.library.podtype(typeTok->expressionString()); if (bail && typeTok->type() && typeTok->type()->classScope && diff --git a/test/testmemleak.cpp b/test/testmemleak.cpp index 6e3d28010a1..f368b362882 100644 --- a/test/testmemleak.cpp +++ b/test/testmemleak.cpp @@ -2613,6 +2613,21 @@ class TestMemleakNoVar : public TestFixture { ASSERT_EQUALS("[test.cpp:2:19]: (error) Allocation with new, strlen doesn't release it. [leakNoVarFunctionCall]\n" "[test.cpp:5:20]: (error) Allocation with new, strlen doesn't release it. [leakNoVarFunctionCall]\n", errout_str()); + + check("int* f1() { return new int; }\n" // #14808 + "std::string* f2() { return new std::string(\"abc\"); }\n" + "std::clock_t* f3() { return new std::clock_t; }\n" + "QWidget* f4(QObject* parent) { return new QWidget(parent); }\n" + "void g(QObject* parent) {\n" + " assert(f1());\n" + " assert(f2());\n" + " assert(f3());\n" + " assert(f4(parent));\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:6:12]: (error) Allocation with f1, assert doesn't release it. [leakNoVarFunctionCall]\n" + "[test.cpp:7:12]: (error) Allocation with f2, assert doesn't release it. [leakNoVarFunctionCall]\n" + "[test.cpp:8:12]: (error) Allocation with f3, assert doesn't release it. [leakNoVarFunctionCall]\n", + errout_str()); } void missingAssignment() {