* Fix #8433 FN unused variable not detected when there is lambda * Format * Fix tests * Check lambda return * Add test * Undo, add test * simpleMatch() * Rename test
This commit is contained in:
parent
e621f721fc
commit
8eabf5c211
|
@ -720,8 +720,6 @@ void CheckMemoryLeakStructMember::check()
|
|||
continue;
|
||||
if (var->typeEndToken()->isStandardType())
|
||||
continue;
|
||||
if (var->scope()->hasInlineOrLambdaFunction())
|
||||
continue;
|
||||
checkStructVariable(var);
|
||||
}
|
||||
}
|
||||
|
@ -921,7 +919,7 @@ void CheckMemoryLeakStructMember::checkStructVariable(const Variable * const var
|
|||
}
|
||||
|
||||
// Returning from function..
|
||||
else if (tok3->str() == "return") {
|
||||
else if ((tok3->scope()->type != Scope::ScopeType::eLambda || tok3->scope() == variable->scope()) && tok3->str() == "return") {
|
||||
// Returning from function without deallocating struct member?
|
||||
if (!Token::Match(tok3, "return %varid% ;", structid) &&
|
||||
!Token::Match(tok3, "return & %varid%", structid) &&
|
||||
|
|
|
@ -5149,6 +5149,15 @@ const Type* SymbolDatabase::findVariableType(const Scope *start, const Token *ty
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
static bool hasEmptyCaptureList(const Token* tok) {
|
||||
if (!Token::simpleMatch(tok, "{"))
|
||||
return false;
|
||||
const Token* listTok = tok->astParent();
|
||||
if (Token::simpleMatch(listTok, "("))
|
||||
listTok = listTok->astParent();
|
||||
return Token::simpleMatch(listTok, "[ ]");
|
||||
}
|
||||
|
||||
bool Scope::hasInlineOrLambdaFunction() const
|
||||
{
|
||||
return std::any_of(nestedList.begin(), nestedList.end(), [&](const Scope* s) {
|
||||
|
@ -5156,7 +5165,7 @@ bool Scope::hasInlineOrLambdaFunction() const
|
|||
if (s->type == Scope::eUnconditional && Token::simpleMatch(s->bodyStart->previous(), ") {"))
|
||||
return true;
|
||||
// Lambda function
|
||||
if (s->type == Scope::eLambda)
|
||||
if (s->type == Scope::eLambda && !hasEmptyCaptureList(s->bodyStart))
|
||||
return true;
|
||||
if (s->hasInlineOrLambdaFunction())
|
||||
return true;
|
||||
|
|
|
@ -2131,15 +2131,13 @@ private:
|
|||
" FILE*f=fopen(fname,a);\n"
|
||||
" std::shared_ptr<FILE> fp{f, [](FILE* x) { free(f); }};\n"
|
||||
"}", true);
|
||||
TODO_ASSERT_EQUALS(
|
||||
"[test.cpp:2] -> [test.cpp:3]: (error) Mismatching allocation and deallocation: f\n", "", errout.str());
|
||||
ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:3]: (error) Mismatching allocation and deallocation: f\n", errout.str());
|
||||
|
||||
check("void f() {\n"
|
||||
" FILE*f=fopen(fname,a);\n"
|
||||
" std::shared_ptr<FILE> fp{f, [](FILE* x) {}};\n"
|
||||
"}", true);
|
||||
TODO_ASSERT_EQUALS(
|
||||
"[test.cpp:2] -> [test.cpp:3]: (error) Mismatching allocation and deallocation: f\n", "", errout.str());
|
||||
ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:3]: (error) Mismatching allocation and deallocation: f\n", errout.str());
|
||||
|
||||
check("class C;\n"
|
||||
"void f() {\n"
|
||||
|
|
|
@ -1737,7 +1737,7 @@ private:
|
|||
|
||||
TEST_CASE(customAllocation);
|
||||
|
||||
TEST_CASE(lambdaInForLoop); // #9793
|
||||
TEST_CASE(lambdaInScope); // #9793
|
||||
}
|
||||
|
||||
void err() {
|
||||
|
@ -2228,8 +2228,8 @@ private:
|
|||
ASSERT_EQUALS("[test.c:7]: (error) Memory leak: abc.a\n", errout.str());
|
||||
}
|
||||
|
||||
void lambdaInForLoop() { // #9793
|
||||
check(
|
||||
void lambdaInScope() {
|
||||
check( // #9793
|
||||
"struct S { int * p{nullptr}; };\n"
|
||||
"int main()\n"
|
||||
"{\n"
|
||||
|
@ -2242,6 +2242,35 @@ private:
|
|||
" return 0;\n"
|
||||
"}", true);
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
check(
|
||||
"struct S { int* p; };\n"
|
||||
"void f() {\n"
|
||||
" auto g = []() {\n"
|
||||
" S s;\n"
|
||||
" s.p = new int;\n"
|
||||
" };\n"
|
||||
"}\n", true);
|
||||
ASSERT_EQUALS("[test.cpp:6]: (error) Memory leak: s.p\n", errout.str());
|
||||
|
||||
check(
|
||||
"struct S { int* p; };\n"
|
||||
"void f() {\n"
|
||||
" S s;\n"
|
||||
" s.p = new int;\n"
|
||||
" auto g = [&]() {\n"
|
||||
" delete s.p;\n"
|
||||
" };\n"
|
||||
" g();\n"
|
||||
"}\n"
|
||||
"void h() {\n"
|
||||
" S s;\n"
|
||||
" s.p = new int;\n"
|
||||
" [&]() {\n"
|
||||
" delete s.p;\n"
|
||||
" }();\n"
|
||||
"}\n", true);
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -6328,6 +6328,13 @@ private:
|
|||
" });\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
functionVariableUsage("int f() {\n" // #8433
|
||||
" float a;\n"
|
||||
" auto lambda = []() {};\n"
|
||||
" return 0;\n"
|
||||
"}\n");
|
||||
ASSERT_EQUALS("[test.cpp:2]: (style) Unused variable: a\n", errout.str());
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue