diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/RefCntblBaseVirtualDtorChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/RefCntblBaseVirtualDtorChecker.cpp index ecba5f9aa23ee..e80246f49a310 100644 --- a/clang/lib/StaticAnalyzer/Checkers/WebKit/RefCntblBaseVirtualDtorChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/RefCntblBaseVirtualDtorChecker.cpp @@ -72,7 +72,7 @@ class DerefFuncDeleteExprVisitor if (name == "ensureOnMainThread" || name == "ensureOnMainRunLoop") { for (unsigned i = 0; i < CE->getNumArgs(); ++i) { auto *Arg = CE->getArg(i); - if (VisitLabmdaArgument(Arg)) + if (VisitLambdaArgument(Arg)) return true; } } @@ -80,17 +80,24 @@ class DerefFuncDeleteExprVisitor return false; } - bool VisitLabmdaArgument(const Expr *E) { + bool VisitLambdaArgument(const Expr *E) { E = E->IgnoreParenCasts(); if (auto *TempE = dyn_cast(E)) E = TempE->getSubExpr(); + E = E->IgnoreParenCasts(); + if (auto *Ref = dyn_cast(E)) { + if (auto *VD = dyn_cast_or_null(Ref->getDecl())) + return VisitLambdaArgument(VD->getInit()); + return false; + } + if (auto *Lambda = dyn_cast(E)) { + if (VisitBody(Lambda->getBody())) + return true; + } if (auto *ConstructE = dyn_cast(E)) { for (unsigned i = 0; i < ConstructE->getNumArgs(); ++i) { - auto *Arg = ConstructE->getArg(i); - if (auto *Lambda = dyn_cast(Arg)) { - if (VisitBody(Lambda->getBody())) - return true; - } + if (VisitLambdaArgument(ConstructE->getArg(i))) + return true; } } return false; diff --git a/clang/test/Analysis/Checkers/WebKit/ref-cntbl-crtp-base-no-virtual-dtor.cpp b/clang/test/Analysis/Checkers/WebKit/ref-cntbl-crtp-base-no-virtual-dtor.cpp index 01527addb5299..33c60ea8ca64d 100644 --- a/clang/test/Analysis/Checkers/WebKit/ref-cntbl-crtp-base-no-virtual-dtor.cpp +++ b/clang/test/Analysis/Checkers/WebKit/ref-cntbl-crtp-base-no-virtual-dtor.cpp @@ -119,6 +119,11 @@ template ensureOnMainThread([this] { delete static_cast(this); }); + } else if constexpr (destructionThread == DestructionThread::MainRunLoop) { + auto deleteThis = [this] { + delete static_cast(this); + }; + ensureOnMainThread(deleteThis); } } @@ -230,3 +235,16 @@ class FancyRefCountedClass4 final : public BadNestedThreadSafeRefCounted { +public: + static Ref create() + { + return adoptRef(*new FancyRefCountedClass5()); + } + + virtual ~FancyRefCountedClass5(); + +private: + FancyRefCountedClass5(); +};