[clang] [analyzer] Treat bitwise_cast, std::addressof, and new as trivial in WebKit checkers. (PR #91830)

Ryosuke Niwa via cfe-commits cfe-commits at lists.llvm.org
Fri May 10 20:09:56 PDT 2024


https://github.com/rniwa updated https://github.com/llvm/llvm-project/pull/91830

>From 7773b0635aabeba769c0050e243f26008795d84b Mon Sep 17 00:00:00 2001
From: Ryosuke Niwa <rniwa at apple.com>
Date: Fri, 10 May 2024 18:42:07 -0700
Subject: [PATCH 1/5] [analyzer] Treat bitwise_cast, std::addressof, and new as
 trivial in WebKit checkers.

---
 .../Checkers/WebKit/PtrTypesSemantics.cpp     |  7 +++++-
 .../Checkers/WebKit/uncounted-obj-arg.cpp     | 22 +++++++++++++++++++
 2 files changed, 28 insertions(+), 1 deletion(-)

diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp
index 3abfa4cbb295d..23d97819a8bcd 100644
--- a/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp
@@ -351,7 +351,8 @@ class TrivialFunctionAnalysisVisitor
 
     if (Name == "WTFCrashWithInfo" || Name == "WTFBreakpointTrap" ||
         Name == "WTFReportAssertionFailure" ||
-        Name == "compilerFenceForCrash" || Name.find("__builtin") == 0)
+        Name == "compilerFenceForCrash" || Name == "bitwise_cast" ||
+        Name == "addressof" || Name.find("__builtin") == 0)
       return true;
 
     return TrivialFunctionAnalysis::isTrivialImpl(Callee, Cache);
@@ -428,6 +429,10 @@ class TrivialFunctionAnalysisVisitor
     return TrivialFunctionAnalysis::isTrivialImpl(CE->getConstructor(), Cache);
   }
 
+  bool VisitCXXNewExpr(const CXXNewExpr* NE) {
+    return VisitChildren(NE);
+  }
+
   bool VisitImplicitCastExpr(const ImplicitCastExpr *ICE) {
     return Visit(ICE->getSubExpr());
   }
diff --git a/clang/test/Analysis/Checkers/WebKit/uncounted-obj-arg.cpp b/clang/test/Analysis/Checkers/WebKit/uncounted-obj-arg.cpp
index 6ca7677511d73..197b2ee8a7359 100644
--- a/clang/test/Analysis/Checkers/WebKit/uncounted-obj-arg.cpp
+++ b/clang/test/Analysis/Checkers/WebKit/uncounted-obj-arg.cpp
@@ -47,6 +47,12 @@ void isIntegralOrPointerType(T, Types... types)
 void WTFCrashWithInfoImpl(int line, const char* file, const char* function, int counter, unsigned long reason);
 void WTFCrashWithInfo(int line, const char* file, const char* function, int counter);
 
+template<typename ToType, typename FromType>
+ToType bitwise_cast(FromType from);
+
+template<typename T>
+T* addressof(T& arg);
+
 template<typename T>
 ALWAYS_INLINE unsigned long wtfCrashArg(T* arg) { return reinterpret_cast<unsigned long>(arg); }
 
@@ -234,6 +240,11 @@ class RefCounted {
   void trivial38() { v++; if (__builtin_expect(!!(number), 1)) (*number)++; }
   int trivial39() { return -v; }
   int trivial40() { return v << 2; }
+  unsigned trivial41() { v = ++s_v; return v; }
+  unsigned trivial42() { return bitwise_cast<unsigned long>(nullptr); }
+  Number* trivial43() { return addressof(*number); }
+  Number* trivial44() { return new Number(1); }
+  ComplexNumber* trivial45() { return new ComplexNumber(); }
 
   static RefCounted& singleton() {
     static RefCounted s_RefCounted;
@@ -312,13 +323,17 @@ class RefCounted {
   void nonTrivial16() { complex++; }
   ComplexNumber nonTrivial17() { return complex << 2; }
   ComplexNumber nonTrivial18() { return +complex; }
+  ComplexNumber* nonTrivial19() { return new ComplexNumber(complex); }
 
+  static unsigned s_v;
   unsigned v { 0 };
   Number* number { nullptr };
   ComplexNumber complex;
   Enum enumValue { Enum::Value1 };
 };
 
+unsigned RefCounted::s_v = 0;
+
 RefCounted* refCountedObj();
 
 void test()
@@ -377,6 +392,11 @@ class UnrelatedClass {
     getFieldTrivial().trivial38(); // no-warning
     getFieldTrivial().trivial39(); // no-warning
     getFieldTrivial().trivial40(); // no-warning
+    getFieldTrivial().trivial41(); // no-warning
+    getFieldTrivial().trivial42(); // no-warning
+    getFieldTrivial().trivial43(); // no-warning
+    getFieldTrivial().trivial44(); // no-warning
+    getFieldTrivial().trivial45(); // no-warning
 
     RefCounted::singleton().trivial18(); // no-warning
     RefCounted::singleton().someFunction(); // no-warning
@@ -419,6 +439,8 @@ class UnrelatedClass {
     // expected-warning at -1{{Call argument for 'this' parameter is uncounted and unsafe}}
     getFieldTrivial().nonTrivial18();
     // expected-warning at -1{{Call argument for 'this' parameter is uncounted and unsafe}}
+    getFieldTrivial().nonTrivial19();
+    // expected-warning at -1{{Call argument for 'this' parameter is uncounted and unsafe}}
   }
 };
 

>From f630c7233926d5512817fbda500d127ebfa0e231 Mon Sep 17 00:00:00 2001
From: Ryosuke Niwa <rniwa at apple.com>
Date: Fri, 10 May 2024 18:47:36 -0700
Subject: [PATCH 2/5] Fix formatting.

---
 .../lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp  | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp
index 23d97819a8bcd..6a6ffa43c1323 100644
--- a/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp
@@ -429,9 +429,7 @@ class TrivialFunctionAnalysisVisitor
     return TrivialFunctionAnalysis::isTrivialImpl(CE->getConstructor(), Cache);
   }
 
-  bool VisitCXXNewExpr(const CXXNewExpr* NE) {
-    return VisitChildren(NE);
-  }
+  bool VisitCXXNewExpr(const CXXNewExpr* NE) { return VisitChildren(NE); }
 
   bool VisitImplicitCastExpr(const ImplicitCastExpr *ICE) {
     return Visit(ICE->getSubExpr());

>From 15d17e2b3e342e9a7950f8f8d6297993ec35b040 Mon Sep 17 00:00:00 2001
From: Ryosuke Niwa <rniwa at apple.com>
Date: Fri, 10 May 2024 18:51:41 -0700
Subject: [PATCH 3/5] Fix formatting 2.

---
 clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp
index 6a6ffa43c1323..cb22de9d11e56 100644
--- a/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp
@@ -429,7 +429,7 @@ class TrivialFunctionAnalysisVisitor
     return TrivialFunctionAnalysis::isTrivialImpl(CE->getConstructor(), Cache);
   }
 
-  bool VisitCXXNewExpr(const CXXNewExpr* NE) { return VisitChildren(NE); }
+  bool VisitCXXNewExpr(const CXXNewExpr *NE) { return VisitChildren(NE); }
 
   bool VisitImplicitCastExpr(const ImplicitCastExpr *ICE) {
     return Visit(ICE->getSubExpr());

>From 705c6c974c3fc6c5b5eda15c895e089ae5e1a467 Mon Sep 17 00:00:00 2001
From: Ryosuke Niwa <rniwa at apple.com>
Date: Fri, 10 May 2024 20:00:27 -0700
Subject: [PATCH 4/5] Allow isMainThread and its variants in a trivial
 expression.

---
 .../Checkers/WebKit/PtrTypesSemantics.cpp     |  4 +++-
 .../Checkers/WebKit/uncounted-obj-arg.cpp     | 23 ++++++++++++++-----
 2 files changed, 20 insertions(+), 7 deletions(-)

diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp
index cb22de9d11e56..ad493587affa0 100644
--- a/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp
@@ -350,7 +350,9 @@ class TrivialFunctionAnalysisVisitor
     const auto &Name = safeGetName(Callee);
 
     if (Name == "WTFCrashWithInfo" || Name == "WTFBreakpointTrap" ||
-        Name == "WTFReportAssertionFailure" ||
+        Name == "WTFReportAssertionFailure" || Name == "isMainThread" ||
+        Name == "isMainThreadOrGCThread" || Name == "isMainRunLoop" ||
+        Name == "isWebThread" || Name == "isUIThread" ||
         Name == "compilerFenceForCrash" || Name == "bitwise_cast" ||
         Name == "addressof" || Name.find("__builtin") == 0)
       return true;
diff --git a/clang/test/Analysis/Checkers/WebKit/uncounted-obj-arg.cpp b/clang/test/Analysis/Checkers/WebKit/uncounted-obj-arg.cpp
index 197b2ee8a7359..e3af9d34b3752 100644
--- a/clang/test/Analysis/Checkers/WebKit/uncounted-obj-arg.cpp
+++ b/clang/test/Analysis/Checkers/WebKit/uncounted-obj-arg.cpp
@@ -47,12 +47,6 @@ void isIntegralOrPointerType(T, Types... types)
 void WTFCrashWithInfoImpl(int line, const char* file, const char* function, int counter, unsigned long reason);
 void WTFCrashWithInfo(int line, const char* file, const char* function, int counter);
 
-template<typename ToType, typename FromType>
-ToType bitwise_cast(FromType from);
-
-template<typename T>
-T* addressof(T& arg);
-
 template<typename T>
 ALWAYS_INLINE unsigned long wtfCrashArg(T* arg) { return reinterpret_cast<unsigned long>(arg); }
 
@@ -65,6 +59,18 @@ void WTFCrashWithInfo(int line, const char* file, const char* function, int coun
     WTFCrashWithInfoImpl(line, file, function, counter, wtfCrashArg(reason));
 }
 
+template<typename ToType, typename FromType>
+ToType bitwise_cast(FromType from);
+
+template<typename T>
+T* addressof(T& arg);
+
+bool isMainThread();
+bool isMainThreadOrGCThread();
+bool isMainRunLoop();
+bool isWebThread();
+bool isUIThread();
+
 enum class Flags : unsigned short {
   Flag1 = 1 << 0,
   Flag2 = 1 << 1,
@@ -245,6 +251,11 @@ class RefCounted {
   Number* trivial43() { return addressof(*number); }
   Number* trivial44() { return new Number(1); }
   ComplexNumber* trivial45() { return new ComplexNumber(); }
+  void trivial46() { ASSERT(isMainThread()); }
+  void trivial47() { ASSERT(isMainThreadOrGCThread()); }
+  void trivial48() { ASSERT(isMainRunLoop()); }
+  void trivial49() { ASSERT(isWebThread()); }
+  void trivial50() { ASSERT(isUIThread()); }
 
   static RefCounted& singleton() {
     static RefCounted s_RefCounted;

>From 5f2f81c14dbbf7de46cc799fbc6b2c3586273d03 Mon Sep 17 00:00:00 2001
From: Ryosuke Niwa <rniwa at apple.com>
Date: Fri, 10 May 2024 20:09:29 -0700
Subject: [PATCH 5/5] Add the missing test cases.

---
 clang/test/Analysis/Checkers/WebKit/uncounted-obj-arg.cpp | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/clang/test/Analysis/Checkers/WebKit/uncounted-obj-arg.cpp b/clang/test/Analysis/Checkers/WebKit/uncounted-obj-arg.cpp
index e3af9d34b3752..073f3252160ee 100644
--- a/clang/test/Analysis/Checkers/WebKit/uncounted-obj-arg.cpp
+++ b/clang/test/Analysis/Checkers/WebKit/uncounted-obj-arg.cpp
@@ -408,6 +408,11 @@ class UnrelatedClass {
     getFieldTrivial().trivial43(); // no-warning
     getFieldTrivial().trivial44(); // no-warning
     getFieldTrivial().trivial45(); // no-warning
+    getFieldTrivial().trivial46(); // no-warning
+    getFieldTrivial().trivial47(); // no-warning
+    getFieldTrivial().trivial48(); // no-warning
+    getFieldTrivial().trivial49(); // no-warning
+    getFieldTrivial().trivial50(); // no-warning
 
     RefCounted::singleton().trivial18(); // no-warning
     RefCounted::singleton().someFunction(); // no-warning



More information about the cfe-commits mailing list