[clang] f484a04 - [clang] Suppress a dangling false positive when owner is moved in member initializer. (#114213)

via cfe-commits cfe-commits at lists.llvm.org
Fri Nov 1 05:33:01 PDT 2024


Author: Haojian Wu
Date: 2024-11-01T13:32:57+01:00
New Revision: f484a04d796123097572c5c2089fefa28e951747

URL: https://github.com/llvm/llvm-project/commit/f484a04d796123097572c5c2089fefa28e951747
DIFF: https://github.com/llvm/llvm-project/commit/f484a04d796123097572c5c2089fefa28e951747.diff

LOG: [clang] Suppress a dangling false positive when owner is moved in member initializer. (#114213)

This patch extends the filtering heuristic to apply for the
Lifetimebound code path.

This will suppress a common false positive:

```
namespace std {
template<typename T>
struct unique_ptr {
  T &operator*();
  T *get() const [[clang::lifetimebound]];
};
} // namespace std

struct X {
  X(std::unique_ptr<int> up) :
    pointer(up.get()), owner(std::move(up)) {}

  int *pointer;
  std::unique_ptr<int> owner;
};
```

See #114201.

Added: 
    

Modified: 
    clang/lib/Sema/CheckExprLifetime.cpp
    clang/test/Sema/warn-lifetime-analysis-nocfg.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/Sema/CheckExprLifetime.cpp b/clang/lib/Sema/CheckExprLifetime.cpp
index 357082fe329350..7f9b484ef6c05d 100644
--- a/clang/lib/Sema/CheckExprLifetime.cpp
+++ b/clang/lib/Sema/CheckExprLifetime.cpp
@@ -1261,12 +1261,12 @@ static void checkExprLifetimeImpl(Sema &SemaRef,
         if (pathContainsInit(Path))
           return false;
 
+        auto *DRE = dyn_cast<DeclRefExpr>(L);
         // Suppress false positives for code like the one below:
-        //   Ctor(unique_ptr<T> up) : member(*up), member2(move(up)) {}
-        if (IsLocalGslOwner && pathOnlyHandlesGslPointer(Path))
+        //   Ctor(unique_ptr<T> up) : pointer(up.get()), owner(move(up)) {}
+        if (DRE && isRecordWithAttr<OwnerAttr>(DRE->getType()))
           return false;
 
-        auto *DRE = dyn_cast<DeclRefExpr>(L);
         auto *VD = DRE ? dyn_cast<VarDecl>(DRE->getDecl()) : nullptr;
         if (!VD) {
           // A member was initialized to a local block.

diff  --git a/clang/test/Sema/warn-lifetime-analysis-nocfg.cpp b/clang/test/Sema/warn-lifetime-analysis-nocfg.cpp
index 688f55edfe84df..6a2af01ea5116c 100644
--- a/clang/test/Sema/warn-lifetime-analysis-nocfg.cpp
+++ b/clang/test/Sema/warn-lifetime-analysis-nocfg.cpp
@@ -384,6 +384,19 @@ struct X {
   std::unique_ptr<int> pointer;
 };
 
+struct [[gsl::Owner]] XOwner {
+  int* get() const [[clang::lifetimebound]];
+};
+struct X2 {
+  // A common usage that moves the passing owner to the class.
+  // verify no warning on this case.
+  X2(XOwner owner) :
+    pointee(owner.get()),
+    owner(std::move(owner)) {}
+  int* pointee;
+  XOwner owner;
+};
+
 std::vector<int>::iterator getIt();
 std::vector<int> getVec();
 


        


More information about the cfe-commits mailing list