Author: Zhijie Wang
Date: 2026-03-06T11:38:21+01:00
New Revision: 2205a23801d4e0cca3cd28670b611a7f6adbeb06

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

LOG: [LifetimeSafety] Fix false negative for GSL Owner type with arrow operator 
(#184725)

`shouldTrackImplicitObjectArg` tracks whether a method call's return
value depends on the implicit object's lifetime. It already handles
operator* on Owner types (return reference), but misses operator->
(return pointer). This fix adds `OO_Arrow` handling for Owner types.

Only affects CFG (-Wlifetime-safety) analysis paths.

Fixes #184361

Added: 
    

Modified: 
    clang/lib/Analysis/LifetimeSafety/LifetimeAnnotations.cpp
    clang/test/Sema/Inputs/lifetime-analysis.h
    clang/test/Sema/warn-lifetime-safety.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/Analysis/LifetimeSafety/LifetimeAnnotations.cpp 
b/clang/lib/Analysis/LifetimeSafety/LifetimeAnnotations.cpp
index 0d3da898137a6..4852f444a51b3 100644
--- a/clang/lib/Analysis/LifetimeSafety/LifetimeAnnotations.cpp
+++ b/clang/lib/Analysis/LifetimeSafety/LifetimeAnnotations.cpp
@@ -153,7 +153,12 @@ bool shouldTrackImplicitObjectArg(const CXXMethodDecl 
*Callee,
 
   if (isPointerLikeType(Callee->getReturnType())) {
     if (!Callee->getIdentifier())
-      return false;
+      // e.g., std::optional<T>::operator->() returns T*.
+      return RunningUnderLifetimeSafety
+                 ? Callee->getParent()->hasAttr<OwnerAttr>() &&
+                       Callee->getOverloadedOperator() ==
+                           OverloadedOperatorKind::OO_Arrow
+                 : false;
     return IteratorMembers.contains(Callee->getName()) ||
            InnerPointerGetters.contains(Callee->getName()) ||
            ContainerFindFns.contains(Callee->getName());

diff  --git a/clang/test/Sema/Inputs/lifetime-analysis.h 
b/clang/test/Sema/Inputs/lifetime-analysis.h
index 1b07f4f13467f..85b5a5fe5e07f 100644
--- a/clang/test/Sema/Inputs/lifetime-analysis.h
+++ b/clang/test/Sema/Inputs/lifetime-analysis.h
@@ -188,6 +188,7 @@ struct unique_ptr {
   ~unique_ptr();
   T* release();
   T &operator*();
+  T *operator->();
   T *get() const;
 };
 
@@ -204,6 +205,7 @@ struct optional {
   template<typename U>
   optional(optional<U>&& __t);
 
+  T *operator->();
   T &operator*() &;
   T &&operator*() &&;
   T &value() &;

diff  --git a/clang/test/Sema/warn-lifetime-safety.cpp 
b/clang/test/Sema/warn-lifetime-safety.cpp
index 097f3279d8e54..a75c70aa3674a 100644
--- a/clang/test/Sema/warn-lifetime-safety.cpp
+++ b/clang/test/Sema/warn-lifetime-safety.cpp
@@ -1746,3 +1746,41 @@ View test3(std::string a) {
   return b;                 // expected-note {{returned here}}
 }
 } // namespace non_trivial_views
+
+namespace OwnerArrowOperator {
+void test_optional_arrow() {
+  const char* p;
+  {
+    std::optional<std::string> opt;
+    p = opt->data();  // expected-warning {{object whose reference is captured 
does not live long enough}}
+  }                   // expected-note {{destroyed here}}
+  (void)*p;           // expected-note {{later used here}}
+}
+
+void test_optional_arrow_lifetimebound() {
+  View v;
+  {
+    std::optional<MyObj> opt;
+    v = opt->getView();  // expected-warning {{object whose reference is 
captured does not live long enough}}
+  }                      // expected-note {{destroyed here}}
+  v.use();               // expected-note {{later used here}}
+}
+
+void test_unique_ptr_arrow() {
+  const char* p;
+  {
+    std::unique_ptr<std::string> up;
+    p = up->data();  // expected-warning {{object whose reference is captured 
does not live long enough}}
+  }                  // expected-note {{destroyed here}}
+  (void)*p;          // expected-note {{later used here}}
+}
+
+void test_optional_view_arrow() {
+    const char* p;
+    {
+        std::optional<std::string_view> opt;
+        p = opt->data();
+    }
+    (void)*p;
+}
+} // namespace OwnerArrowOperator


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

Reply via email to