https://github.com/usx95 updated 
https://github.com/llvm/llvm-project/pull/174741

>From ce2cb8555280945312f4afaca6b72331c3b1477c Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena <[email protected]>
Date: Tue, 16 Dec 2025 12:13:42 +0000
Subject: [PATCH] only-for-owners

---
 .../LifetimeSafety/FactsGenerator.cpp         | 16 ++++++
 .../unittests/Analysis/LifetimeSafetyTest.cpp | 52 +++++++++++++++++++
 2 files changed, 68 insertions(+)

diff --git a/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp 
b/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp
index fe5fabc6d6405..b10c61f1cb6b7 100644
--- a/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp
+++ b/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp
@@ -485,6 +485,14 @@ void FactsGenerator::handleFunctionCall(const Expr *Call,
     }
     return PVD ? PVD->hasAttr<clang::LifetimeBoundAttr>() : false;
   };
+  auto shouldTrackPointerImplicitObjectArg = [FD](unsigned I) -> bool {
+    const auto *Method = dyn_cast<CXXMethodDecl>(FD);
+    if (!Method || !Method->isInstance())
+      return false;
+    return I == 0 &&
+           isGslPointerType(Method->getFunctionObjectParameterType()) &&
+           shouldTrackImplicitObjectArg(Method);
+  };
   if (Args.empty())
     return;
   bool KillSrc = true;
@@ -505,6 +513,14 @@ void FactsGenerator::handleFunctionCall(const Expr *Call,
         flow(CallList, ArgList, KillSrc);
         KillSrc = false;
       }
+    } else if (shouldTrackPointerImplicitObjectArg(I)) {
+      assert(ArgList->getLength() >= 2 &&
+             "Object arg of pointer type should have atleast two origins");
+      // See through the GSLPointer reference to see the pointer's value.
+      CurrentBlockFacts.push_back(FactMgr.createFact<OriginFlowFact>(
+          CallList->getOuterOriginID(),
+          ArgList->peelOuterOrigin()->getOuterOriginID(), KillSrc));
+      KillSrc = false;
     } else if (IsArgLifetimeBound(I)) {
       // Lifetimebound on a non-GSL-ctor function means the returned
       // pointer/reference itself must not outlive the arguments. This
diff --git a/clang/unittests/Analysis/LifetimeSafetyTest.cpp 
b/clang/unittests/Analysis/LifetimeSafetyTest.cpp
index 3afb44656d78a..f4eb5b22610e4 100644
--- a/clang/unittests/Analysis/LifetimeSafetyTest.cpp
+++ b/clang/unittests/Analysis/LifetimeSafetyTest.cpp
@@ -1751,6 +1751,58 @@ TEST_F(LifetimeAnalysisTest, 
TrackImplicitObjectArg_MapFind) {
   EXPECT_THAT(Origin("it"), HasLoansTo({"m"}, "p1"));
 }
 
+
+TEST_F(LifetimeAnalysisTest, TrackImplicitObjectArg_GSLPointerArg) {
+  SetupTest(R"(
+    namespace std {
+
+    template<typename T>
+    struct basic_string_view {
+      basic_string_view();
+      basic_string_view(const T *);
+      const T *begin() const;
+      const T *data() const;
+    };
+    using string_view = basic_string_view<char>;
+
+    template<typename T>
+    struct basic_string {
+      basic_string();
+      basic_string(const T *);
+      const T *c_str() const;
+      operator basic_string_view<T> () const;
+      const T *data() const;
+    };
+    using string = basic_string<char>;
+    }
+
+    void target() {
+      std::string s1;
+      std::string_view sv1 = s1;
+      
+      std::string s2;
+      const char* sv2 = std::string_view(s2).begin();
+      
+      std::string s3;
+      const char* sv3 = std::string_view(s3).data();
+      
+      std::string s4;
+      std::string_view sv4 = std::string_view{std::string_view(s4).data()};
+            
+      std::string s5;
+      const char* data5 = std::string_view(s5).data();
+      std::string_view sv5 = data5;
+      POINT(end);
+    }
+  )");
+  EXPECT_THAT(Origin("sv1"), HasLoansTo({"s1"}, "end"));
+  EXPECT_THAT(Origin("sv2"), HasLoansTo({"s2"}, "end"));
+  EXPECT_THAT(Origin("sv3"), HasLoansTo({"s3"}, "end"));
+  // FIXME: Handle GSL pointer construction from raw pointers.
+  EXPECT_THAT(Origin("sv4"), HasLoansTo({}, "end"));
+  EXPECT_THAT(Origin("sv5"), HasLoansTo({}, "end"));
+}
+
 // ========================================================================= //
 //                    Tests for shouldTrackFirstArgument
 // ========================================================================= //

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

Reply via email to