diff --git a/lib/checkleakautovar.cpp b/lib/checkleakautovar.cpp index bdf255fff..c35665aca 100644 --- a/lib/checkleakautovar.cpp +++ b/lib/checkleakautovar.cpp @@ -246,7 +246,7 @@ static bool isLocalVarNoAutoDealloc(const Token *varTok, const bool isCpp) return false; // Don't check reference variables - if (var->isReference()) + if (var->isReference() && !var->isArgument()) return false; // non-pod variable @@ -1077,7 +1077,7 @@ void CheckLeakAutoVar::ret(const Token *tok, VarInfo &varInfo, const bool isEndO if (used && it->second.status == VarInfo::DEALLOC) deallocReturnError(tok, it->second.allocTok, var->name()); - else if (!used && !it->second.managed()) { + else if (!used && !it->second.managed() && !var->isReference()) { const auto use = possibleUsage.find(varid); if (use == possibleUsage.end()) { leakError(tok, var->name(), it->second.type); diff --git a/test/testleakautovar.cpp b/test/testleakautovar.cpp index 04d7ad1e1..790f28098 100644 --- a/test/testleakautovar.cpp +++ b/test/testleakautovar.cpp @@ -2324,11 +2324,32 @@ private: ASSERT_EQUALS("", errout.str()); } - void test1() { // 3809 - check("void f(double*&p) {\n" + void test1() { + check("void f(double*&p) {\n" // 3809 " p = malloc(0x100);\n" "}", /*cpp*/ true); ASSERT_EQUALS("", errout.str()); + + check("void f(int*& p) {\n" // #4400 + " p = (int*)malloc(4);\n" + " p = (int*)malloc(4);\n" + "}\n", /*cpp*/ true); + ASSERT_EQUALS("[test.cpp:3]: (error) Memory leak: p\n", errout.str()); + + check("void f() {\n" + " int* p = (int*)malloc(4);\n" + " int*& r = p;\n" + " r = (int*)malloc(4);\n" + "}\n", /*cpp*/ true); + TODO_ASSERT_EQUALS("[test.cpp:4]: (error) Memory leak: p\n", "", errout.str()); + + check("void f() {\n" + " int* p = (int*)malloc(4);\n" + " int*& r = p;\n" + " free(r);\n" + " p = (int*)malloc(4);\n" + "}\n", /*cpp*/ true); + TODO_ASSERT_EQUALS("", "[test.cpp:6]: (error) Memory leak: p\n", errout.str()); } void test2() { // 3899