diff --git a/lib/checkclass.cpp b/lib/checkclass.cpp index bacbbed3b..2eae9e589 100644 --- a/lib/checkclass.cpp +++ b/lib/checkclass.cpp @@ -2699,9 +2699,12 @@ bool CheckClass::checkThisUseAfterFreeRecursive(const Scope *classScope, const F } else if (isDestroyed && Token::Match(tok->previous(), "!!. %name%") && tok->variable() && tok->variable()->scope() == classScope && !tok->variable()->isStatic() && !tok->variable()->isArgument()) { thisUseAfterFree(selfPointer->nameToken(), *freeToken, tok); return true; - } else if (*freeToken && Token::Match(tok, "return|throw")) + } else if (*freeToken && Token::Match(tok, "return|throw")) { // TODO return tok->str() == "throw"; + } else if (tok->str() == "{" && tok->scope()->type == Scope::ScopeType::eLambda) { + tok = tok->link(); + } } return false; } diff --git a/test/testclass.cpp b/test/testclass.cpp index c7c955170..769ca6456 100644 --- a/test/testclass.cpp +++ b/test/testclass.cpp @@ -7306,6 +7306,22 @@ private: "\n" "C* C::instanceSingleton;"); ASSERT_EQUALS("", errout.str()); + + // Avoid false positive when pointer is deleted in lambda + checkThisUseAfterFree("class C {\n" + "public:\n" + " void foo();\n" + " void set() { p = this; }\n" + " void dostuff() {}\n" + " C* p;\n" + "};\n" + "\n" + "void C::foo() {\n" + " auto done = [this] () { delete p; };\n" + " dostuff();\n" + " done();\n" + "}"); + ASSERT_EQUALS("", errout.str()); } };