Fix #9793 (false positive, memleak with lambda)

Skip scopes with lambdas (similar to how checkleakautovar does). In
order to fix this when the lambda is inside a for loop, make
hasInlineOrLambdaFunction() recursive. This should be what all existing
users want.
This commit is contained in:
Rikard Falkeborn 2020-07-07 21:36:14 +02:00
parent 6c90de0101
commit d5345052ab
3 changed files with 22 additions and 0 deletions

View File

@ -764,6 +764,8 @@ void CheckMemoryLeakStructMember::check()
continue;
if (var->typeEndToken()->isStandardType())
continue;
if (var->scope()->hasInlineOrLambdaFunction())
continue;
checkStructVariable(var);
}
}

View File

@ -4447,6 +4447,8 @@ bool Scope::hasInlineOrLambdaFunction() const
// Lambda function
if (s->type == Scope::eLambda)
return true;
if (s->hasInlineOrLambdaFunction())
return true;
}
return false;
}

View File

@ -1677,6 +1677,8 @@ private:
TEST_CASE(varid_2); // #5315: Analysis confused by ((variable).attribute) notation
TEST_CASE(customAllocation);
TEST_CASE(lambdaInForLoop); // #9793
}
void err() {
@ -2062,6 +2064,22 @@ private:
"}", false);
ASSERT_EQUALS("[test.c:7]: (error) Memory leak: abc.a\n", errout.str());
}
void lambdaInForLoop() { // #9793
check(
"struct S { int * p{nullptr}; };\n"
"int main()\n"
"{\n"
" S s;\n"
" s.p = new int[10];\n"
" for (int i = 0; i < 10; ++i) {\n"
" s.p[i] = []() { return 1; }();\n"
" }\n"
" delete[] s.p;\n"
" return 0;\n"
"}", true);
ASSERT_EQUALS("", errout.str());
}
};
REGISTER_TEST(TestMemleakStructMember)