diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/UncountedLambdaCapturesChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/UncountedLambdaCapturesChecker.cpp index 4ffdac5ca4873..9527993d0edeb 100644 --- a/clang/lib/StaticAnalyzer/Checkers/WebKit/UncountedLambdaCapturesChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/UncountedLambdaCapturesChecker.cpp @@ -267,6 +267,8 @@ class UncountedLambdaCapturesChecker auto OpCode = OpCE->getOperator(); if (OpCode == OO_Star || OpCode == OO_Amp) { auto *Callee = OpCE->getDirectCallee(); + if (!Callee) + return false; auto clsName = safeGetName(Callee->getParent()); if (!isRefType(clsName) || !OpCE->getNumArgs()) return false; @@ -276,9 +278,10 @@ class UncountedLambdaCapturesChecker } if (auto *UO = dyn_cast<UnaryOperator>(Arg)) { auto OpCode = UO->getOpcode(); - if (OpCode == UO_Deref || OpCode == UO_AddrOf) + if (OpCode == UO_Deref || OpCode == UO_AddrOf) { Arg = UO->getSubExpr()->IgnoreParenCasts(); - continue; + continue; + } } break; } while (Arg); diff --git a/clang/test/Analysis/Checkers/WebKit/uncounted-lambda-captures-decl-protects-this-crash.cpp b/clang/test/Analysis/Checkers/WebKit/uncounted-lambda-captures-decl-protects-this-crash.cpp new file mode 100644 index 0000000000000..840433db5133a --- /dev/null +++ b/clang/test/Analysis/Checkers/WebKit/uncounted-lambda-captures-decl-protects-this-crash.cpp @@ -0,0 +1,38 @@ +// RUN: %clang_analyze_cc1 -analyzer-checker=webkit.UncountedLambdaCapturesChecker -verify %s + +struct Foo { + int x; + int y; + Foo(int x, int y) : x(x) , y(y) { } +}; + +template <typename T> +struct Baz { + void ref() const; + void deref() const; + Foo operator*(); + bool operator!(); +}; + +inline Foo operator*(const Foo& a, const Foo& b); + +Baz<Foo> someFunction(); +template <typename CallbackType> void bar(CallbackType callback) { + auto baz = someFunction(); + callback(baz); +} + +struct Obj { + void ref() const; + void deref() const; + + void foo(Foo foo) { + bar([this](auto baz) { + // expected-warning@-1{{Captured raw-pointer 'this' to ref-counted type or CheckedPtr-capable type is unsafe [webkit.UncountedLambdaCapturesChecker]}} + bar([this, foo = *baz, foo2 = !baz](auto&&) { + // expected-warning@-1{{Captured raw-pointer 'this' to ref-counted type or CheckedPtr-capable type is unsafe [webkit.UncountedLambdaCapturesChecker]}} + someFunction(); + }); + }); + } +};