[clang] [WebKit checkers] Treat std::bit_cast as a pointer conversion (PR #137476)
Ryosuke Niwa via cfe-commits
cfe-commits at lists.llvm.org
Wed Apr 30 15:48:58 PDT 2025
https://github.com/rniwa updated https://github.com/llvm/llvm-project/pull/137476
>From c76e86105b5ba03cc2a3c8399670b2b38eb8e6ea Mon Sep 17 00:00:00 2001
From: Ryosuke Niwa <rniwa at webkit.org>
Date: Sat, 26 Apr 2025 14:03:13 -0700
Subject: [PATCH 1/2] [WebKit checkers] Treat std::bit_cast as a pointer
conversion
WebKit repalced its use of WTF::bitwise_cast with std::bit_cast.
Add the support for recognizing it as a pointer conversion.
---
.../Checkers/WebKit/PtrTypesSemantics.cpp | 2 +-
.../Checkers/WebKit/call-args-checked-ptr.cpp | 8 ++++----
.../Analysis/Checkers/WebKit/call-args.cpp | 18 +++++++++---------
.../Checkers/WebKit/uncounted-obj-arg.cpp | 5 +++++
4 files changed, 19 insertions(+), 14 deletions(-)
diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp
index d7111bcb35115..edcf8e4feae4f 100644
--- a/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp
@@ -462,7 +462,7 @@ bool isPtrConversion(const FunctionDecl *F) {
const auto FunctionName = safeGetName(F);
if (FunctionName == "getPtr" || FunctionName == "WeakPtr" ||
FunctionName == "dynamicDowncast" || FunctionName == "downcast" ||
- FunctionName == "checkedDowncast" ||
+ FunctionName == "checkedDowncast" || FunctionName == "bit_cast" ||
FunctionName == "uncheckedDowncast" || FunctionName == "bitwise_cast" ||
FunctionName == "bridge_cast" || FunctionName == "bridge_id_cast" ||
FunctionName == "dynamic_cf_cast" || FunctionName == "checked_cf_cast" ||
diff --git a/clang/test/Analysis/Checkers/WebKit/call-args-checked-ptr.cpp b/clang/test/Analysis/Checkers/WebKit/call-args-checked-ptr.cpp
index 59f247d6d007c..d539891ed832d 100644
--- a/clang/test/Analysis/Checkers/WebKit/call-args-checked-ptr.cpp
+++ b/clang/test/Analysis/Checkers/WebKit/call-args-checked-ptr.cpp
@@ -173,14 +173,14 @@ namespace param_formarding_function {
namespace casts {
- CheckedObj* downcast(CheckedObj*) { return nullptr; }
-
- template<class T>
- T* bitwise_cast(T*) { return nullptr; }
+ CheckedObj* downcast(CheckedObj*);
+ template<class T> T* bitwise_cast(T*);
+ template<class T> T* bit_cast(T*);
void foo(CheckedObj* param) {
consume_ref_countable_ptr(downcast(param));
consume_ref_countable_ptr(bitwise_cast(param));
+ consume_ref_countable_ptr(bit_cast(param));
}
}
}
diff --git a/clang/test/Analysis/Checkers/WebKit/call-args.cpp b/clang/test/Analysis/Checkers/WebKit/call-args.cpp
index d95ae9216edcf..1a8bde29080ac 100644
--- a/clang/test/Analysis/Checkers/WebKit/call-args.cpp
+++ b/clang/test/Analysis/Checkers/WebKit/call-args.cpp
@@ -173,15 +173,15 @@ namespace param_formarding_function {
namespace casts {
- RefCountable* downcast(RefCountable*) { return nullptr; }
-
- template<class T>
- T* bitwise_cast(T*) { return nullptr; }
-
- void foo(RefCountable* param) {
- consume_ref_countable_ptr(downcast(param));
- consume_ref_countable_ptr(bitwise_cast(param));
- }
+ RefCountable* downcast(RefCountable*);
+ template<class T> T* bitwise_cast(T*);
+ template<class T> T* bit_cast(T*);
+
+ void foo(RefCountable* param) {
+ consume_ref_countable_ptr(downcast(param));
+ consume_ref_countable_ptr(bitwise_cast(param));
+ consume_ref_countable_ptr(bit_cast(param));
+ }
}
}
diff --git a/clang/test/Analysis/Checkers/WebKit/uncounted-obj-arg.cpp b/clang/test/Analysis/Checkers/WebKit/uncounted-obj-arg.cpp
index 69842264af56b..2c6ccb55e2ce8 100644
--- a/clang/test/Analysis/Checkers/WebKit/uncounted-obj-arg.cpp
+++ b/clang/test/Analysis/Checkers/WebKit/uncounted-obj-arg.cpp
@@ -77,6 +77,9 @@ T&& forward(T& arg);
template<typename T>
T&& move( T&& t );
+template<typename ToType, typename FromType>
+ToType bit_cast(FromType from);
+
#define offsetof(t, d) __builtin_offsetof(t, d)
} // namespace std
@@ -386,6 +389,7 @@ class RefCounted {
void trivial68() { point pt = { 1.0 }; }
unsigned trivial69() { return offsetof(OtherObj, children); }
DerivedNumber* trivial70() { [[clang::suppress]] return static_cast<DerivedNumber*>(number); }
+ unsigned trivial71() { return std::bit_cast<unsigned>(nullptr); }
static RefCounted& singleton() {
static RefCounted s_RefCounted;
@@ -577,6 +581,7 @@ class UnrelatedClass {
getFieldTrivial().trivial68(); // no-warning
getFieldTrivial().trivial69(); // no-warning
getFieldTrivial().trivial70(); // no-warning
+ getFieldTrivial().trivial71(); // no-warning
RefCounted::singleton().trivial18(); // no-warning
RefCounted::singleton().someFunction(); // no-warning
>From 49f3566bbf7d9b65b990c9b8dd883aa9b2a9403b Mon Sep 17 00:00:00 2001
From: Ryosuke Niwa <rniwa at webkit.org>
Date: Wed, 30 Apr 2025 15:48:43 -0700
Subject: [PATCH 2/2] Also fix TrivialFunctionAnalysisVisitor to recognize
std::bit_cast as trivial
---
.../Checkers/WebKit/PtrTypesSemantics.cpp | 6 +++++-
.../Checkers/WebKit/uncounted-local-vars.cpp | 14 ++++++++++++++
2 files changed, 19 insertions(+), 1 deletion(-)
diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp
index edcf8e4feae4f..0f0184c472f36 100644
--- a/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp
@@ -645,6 +645,10 @@ class TrivialFunctionAnalysisVisitor
auto *Callee = CE->getDirectCallee();
if (!Callee)
return false;
+
+ if (isPtrConversion(Callee))
+ return true;
+
const auto &Name = safeGetName(Callee);
if (Callee->isInStdNamespace() &&
@@ -658,7 +662,7 @@ class TrivialFunctionAnalysisVisitor
Name == "isMainThreadOrGCThread" || Name == "isMainRunLoop" ||
Name == "isWebThread" || Name == "isUIThread" ||
Name == "mayBeGCThread" || Name == "compilerFenceForCrash" ||
- Name == "bitwise_cast" || isTrivialBuiltinFunction(Callee))
+ isTrivialBuiltinFunction(Callee))
return true;
return IsFunctionTrivial(Callee);
diff --git a/clang/test/Analysis/Checkers/WebKit/uncounted-local-vars.cpp b/clang/test/Analysis/Checkers/WebKit/uncounted-local-vars.cpp
index 07b6de21df80f..0540ed93c5707 100644
--- a/clang/test/Analysis/Checkers/WebKit/uncounted-local-vars.cpp
+++ b/clang/test/Analysis/Checkers/WebKit/uncounted-local-vars.cpp
@@ -205,6 +205,20 @@ void foo2() {
}
} // namespace guardian_casts
+namespace casts {
+
+RefCountable* provide() { return nullptr; }
+RefCountable* downcast(RefCountable*);
+template<class T> T* bitwise_cast(T*);
+template<class T> T* bit_cast(T*);
+
+ void foo() {
+ auto* cast1 = downcast(provide());
+ auto* cast2 = bitwise_cast(provide());
+ auto* cast3 = bit_cast(provide());
+ }
+} // namespace casts
+
namespace guardian_ref_conversion_operator {
void foo() {
Ref<RefCountable> rc;
More information about the cfe-commits
mailing list