llvmorg-github-actions[bot] wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Ryosuke Niwa (rniwa)

<details>
<summary>Changes</summary>

Ignore the destructor of CXXBindTemporaryExpr when returning a value with copy 
elision.

---
Full diff: https://github.com/llvm/llvm-project/pull/200481.diff


3 Files Affected:

- (modified) clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp 
(+13-1) 
- (modified) clang/test/Analysis/Checkers/WebKit/mock-types.h (+1) 
- (modified) clang/test/Analysis/Checkers/WebKit/nodelete-annotation.cpp 
(+11-1) 


``````````diff
diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp 
b/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp
index f1515701cc6f3..6ce2954471e6b 100644
--- a/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp
@@ -706,8 +706,20 @@ class TrivialFunctionAnalysisVisitor
 
   bool VisitReturnStmt(const ReturnStmt *RS) {
     // A return statement is allowed as long as the return value is trivial.
-    if (auto *RV = RS->getRetValue())
+    if (auto *RV = RS->getRetValue()) {
+      if (auto *ExprWithClean = dyn_cast<ExprWithCleanups>(RV)) {
+        if (ExprWithClean->isPRValue())
+          RV = ExprWithClean->getSubExpr();
+      }
+      if (auto *SubE = RV->IgnoreParenCasts()) {
+        if (auto *BTE = dyn_cast<CXXBindTemporaryExpr>(SubE)) {
+          // Ignore the destructor of BTE if copy elision is in effect.
+          if (RV->getType() == BTE->getType())
+            return Visit(BTE->getSubExpr());
+        }
+      }
       return Visit(RV);
+    }
     return true;
   }
 
diff --git a/clang/test/Analysis/Checkers/WebKit/mock-types.h 
b/clang/test/Analysis/Checkers/WebKit/mock-types.h
index af63268ac9695..de5c2d35f2408 100644
--- a/clang/test/Analysis/Checkers/WebKit/mock-types.h
+++ b/clang/test/Analysis/Checkers/WebKit/mock-types.h
@@ -202,6 +202,7 @@ template <typename T> struct RefPtr {
     t = o.t;
     o.t = tmp;
   }
+  operator T*() { return t; }
   T *get() const { return t; }
   T *operator->() const { return t; }
   T &operator*() const { return *t; }
diff --git a/clang/test/Analysis/Checkers/WebKit/nodelete-annotation.cpp 
b/clang/test/Analysis/Checkers/WebKit/nodelete-annotation.cpp
index 6906afb7fa0f6..871b0afcb89fd 100644
--- a/clang/test/Analysis/Checkers/WebKit/nodelete-annotation.cpp
+++ b/clang/test/Analysis/Checkers/WebKit/nodelete-annotation.cpp
@@ -316,10 +316,19 @@ class Derived : public Base<Type> {
 };
 
 struct Data {
-  static Ref<Data> create() {
+  static Ref<Data> [[clang::annotate_type("webkit.nodelete")]] create() {
     return adoptRef(*new Data);
   }
 
+  static Ref<Data> [[clang::annotate_type("webkit.nodelete")]] create(double) {
+    return adoptRef(*new Data(RefCountable::create()->next()));
+    // expected-warning@-1{{A function 'create' has 
[[clang::annotate_type("webkit.nodelete")]] but it contains code that could 
destruct an object}}
+  }
+
+  static Data* [[clang::annotate_type("webkit.nodelete")]] create(int) {
+    return adoptRef(new Data); // expected-warning{{A function 'create' has 
[[clang::annotate_type("webkit.nodelete")]] but it contains code that could 
destruct an object}}
+  }
+
   void ref() {
     ++refCount;
   }
@@ -338,6 +347,7 @@ struct Data {
   
 protected:
   Data() = default;
+  Data(RefCountable*) { }
 
 private:
   unsigned refCount { 0 };

``````````

</details>


https://github.com/llvm/llvm-project/pull/200481
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to