From a823d29da38fd5e7160c730068ddccb3b101d00b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Fri, 1 Jun 2012 19:01:19 +0200 Subject: [PATCH] Fixed #3809 (false positive: memory leak) --- lib/checkleakautovar.cpp | 10 ++++++++++ lib/checkmemoryleak.cpp | 3 +++ test/testleakautovar.cpp | 10 ++++++++++ test/testmemleak.cpp | 12 +++--------- 4 files changed, 26 insertions(+), 9 deletions(-) diff --git a/lib/checkleakautovar.cpp b/lib/checkleakautovar.cpp index a0b6fa8c1..779555de2 100644 --- a/lib/checkleakautovar.cpp +++ b/lib/checkleakautovar.cpp @@ -143,6 +143,16 @@ void CheckLeakAutoVar::check() varInfo.conditionalAlloc.clear(); + // Clear reference arguments from varInfo.. + std::map::iterator it = varInfo.alloctype.begin(); + while (it != varInfo.alloctype.end()) { + const Variable *var = symbolDatabase->getVariableFromVarId(it->first); + if (var && var->isArgument() && var->isReference()) + varInfo.alloctype.erase(it++); + else + ++it; + } + ret(i->classEnd, varInfo); } } diff --git a/lib/checkmemoryleak.cpp b/lib/checkmemoryleak.cpp index 77f13cf25..0f56c03c6 100644 --- a/lib/checkmemoryleak.cpp +++ b/lib/checkmemoryleak.cpp @@ -2228,6 +2228,9 @@ void CheckMemoryLeakInFunction::check() if (!var || (!var->isLocal() && !var->isArgument()) || var->isStatic() || !var->scope()) continue; + if (var->isArgument() && var->isReference()) + continue; + if (!var->isPointer() && var->typeStartToken()->str() != "int") continue; diff --git a/test/testleakautovar.cpp b/test/testleakautovar.cpp index 5e67dfbd5..c441f5f19 100644 --- a/test/testleakautovar.cpp +++ b/test/testleakautovar.cpp @@ -78,6 +78,9 @@ private: TEST_CASE(return2); TEST_CASE(return3); + // General tests: variable type, allocation type, etc + TEST_CASE(test1); + // Possible leak => Further configuration is needed for complete analysis TEST_CASE(configuration1); TEST_CASE(configuration2); @@ -378,6 +381,13 @@ private: ASSERT_EQUALS("", errout.str()); } + void test1() { // 3809 + check("void f(double*&p) {\n" + " p = malloc(0x100);\n" + "}"); + ASSERT_EQUALS("", errout.str()); + } + void configuration1() { // Possible leak => configuration is required for complete analysis // The user should be able to "white list" and "black list" functions. diff --git a/test/testmemleak.cpp b/test/testmemleak.cpp index e68df4654..bd9cba5dd 100644 --- a/test/testmemleak.cpp +++ b/test/testmemleak.cpp @@ -2515,16 +2515,10 @@ private: } void allocfunc11() { // ticket #3809 - false positive - check("class A \n" - "{\n" - " public:\n" - " virtual void f (double * & data_val) ;\n" - "};\n" - "void A::f (double * & data_val) \n" - "{\n" - " data_val = new double [10];\n" + check("void f (double * & data_val) {\n" + " data_val = malloc(0x100);\n" "}\n"); - TODO_ASSERT_EQUALS("","[test.cpp:9]: (error) Memory leak: data_val\n", errout.str()); + ASSERT_EQUALS("", errout.str()); } void throw1() {