[clang] [webkit.UncountedLambdaCapturesChecker] Fix a crash in declProtectsThis (PR #127309)
Ryosuke Niwa via cfe-commits
cfe-commits at lists.llvm.org
Sat Feb 15 02:49:40 PST 2025
https://github.com/rniwa updated https://github.com/llvm/llvm-project/pull/127309
>From 715da2e5ec5cd64416a5dab9017a9c43a6ca8e78 Mon Sep 17 00:00:00 2001
From: Ryosuke Niwa <rniwa at webkit.org>
Date: Sat, 15 Feb 2025 01:33:47 -0800
Subject: [PATCH 1/2] [webkit.UncountedLambdaCapturesChecker] Fix a crash in
declProtectsThis
Add a missing nullptr check to declProtectsThis.
---
.../WebKit/UncountedLambdaCapturesChecker.cpp | 2 +
...mbda-captures-decl-protects-this-crash.cpp | 38 +++++++++++++++++++
2 files changed, 40 insertions(+)
create mode 100644 clang/test/Analysis/Checkers/WebKit/uncounted-lambda-captures-decl-protects-this-crash.cpp
diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/UncountedLambdaCapturesChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/UncountedLambdaCapturesChecker.cpp
index 4ffdac5ca4873..aee43bdd983a0 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;
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..0d25c599ffb3e
--- /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*();
+};
+
+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 at -1{{Captured raw-pointer 'this' to ref-counted type or CheckedPtr-capable type is unsafe [webkit.UncountedLambdaCapturesChecker]}}
+ bar([this, foo = *baz](auto&&) {
+ // expected-warning at -1{{Captured raw-pointer 'this' to ref-counted type or CheckedPtr-capable type is unsafe [webkit.UncountedLambdaCapturesChecker]}}
+ someFunction();
+ });
+ });
+ }
+};
+
>From 2eb33277e1154965a21b3d7a26de00cb58505e1a Mon Sep 17 00:00:00 2001
From: Ryosuke Niwa <rniwa at webkit.org>
Date: Sat, 15 Feb 2025 02:49:06 -0800
Subject: [PATCH 2/2] Also fix an infinite loop in declProtectsThis.
---
.../Checkers/WebKit/UncountedLambdaCapturesChecker.cpp | 5 +++--
.../uncounted-lambda-captures-decl-protects-this-crash.cpp | 4 ++--
2 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/UncountedLambdaCapturesChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/UncountedLambdaCapturesChecker.cpp
index aee43bdd983a0..9527993d0edeb 100644
--- a/clang/lib/StaticAnalyzer/Checkers/WebKit/UncountedLambdaCapturesChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/UncountedLambdaCapturesChecker.cpp
@@ -278,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
index 0d25c599ffb3e..840433db5133a 100644
--- 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
@@ -11,6 +11,7 @@ struct Baz {
void ref() const;
void deref() const;
Foo operator*();
+ bool operator!();
};
inline Foo operator*(const Foo& a, const Foo& b);
@@ -28,11 +29,10 @@ struct Obj {
void foo(Foo foo) {
bar([this](auto baz) {
// expected-warning at -1{{Captured raw-pointer 'this' to ref-counted type or CheckedPtr-capable type is unsafe [webkit.UncountedLambdaCapturesChecker]}}
- bar([this, foo = *baz](auto&&) {
+ bar([this, foo = *baz, foo2 = !baz](auto&&) {
// expected-warning at -1{{Captured raw-pointer 'this' to ref-counted type or CheckedPtr-capable type is unsafe [webkit.UncountedLambdaCapturesChecker]}}
someFunction();
});
});
}
};
-
More information about the cfe-commits
mailing list