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

>From 8474b6182e3ffa2cfa69260101ce71b548fac64b Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena <[email protected]>
Date: Wed, 7 Oct 2026 14:10:53 +0000
Subject: [PATCH] field-origin-escape

---
 .../Analyses/LifetimeSafety/LifetimeSafety.h  |  6 ++
 .../Analysis/Analyses/LifetimeSafety/Loans.h  | 43 +++++---
 clang/include/clang/Basic/DiagnosticGroups.td |  7 ++
 .../clang/Basic/DiagnosticSemaKinds.td        |  5 +
 clang/lib/Analysis/LifetimeSafety/Checker.cpp | 26 +++++
 .../LifetimeSafety/FactsGenerator.cpp         | 15 ++-
 clang/lib/Analysis/LifetimeSafety/Loans.cpp   | 16 +++
 clang/lib/Sema/SemaLifetimeSafety.h           | 16 +++
 .../LifetimeSafety/annotation-suggestions.cpp | 97 ++++++++++++++++++-
 9 files changed, 212 insertions(+), 19 deletions(-)

diff --git 
a/clang/include/clang/Analysis/Analyses/LifetimeSafety/LifetimeSafety.h 
b/clang/include/clang/Analysis/Analyses/LifetimeSafety/LifetimeSafety.h
index 6854902059e5017..e6fbc2a5caee720 100644
--- a/clang/include/clang/Analysis/Analyses/LifetimeSafety/LifetimeSafety.h
+++ b/clang/include/clang/Analysis/Analyses/LifetimeSafety/LifetimeSafety.h
@@ -46,6 +46,7 @@ struct LifetimeSafetyOpts {
   bool CheckLifetimeboundViolations;
   bool CheckMisplacedLifetimebound;
   bool CheckInapplicableLifetimebound;
+  bool CheckFieldOriginEscape;
 };
 
 /// Enum to track functions visible across or within TU.
@@ -164,6 +165,11 @@ class LifetimeSafetySemaHelper {
                                                   const CXXMethodDecl *MD,
                                                   const Expr *EscapeExpr) {}
 
+  // Reports when a member function returns an origin of a field.
+  virtual void reportFieldOriginEscape(const CXXMethodDecl *MD,
+                                       const FieldDecl *FD,
+                                       const Expr *EscapeExpr) {}
+
   // Adds inferred lifetime bound attribute for implicit this to its
   // TypeSourceInfo.
   virtual void addLifetimeBoundToImplicitThis(const CXXMethodDecl *MD) {}
diff --git a/clang/include/clang/Analysis/Analyses/LifetimeSafety/Loans.h 
b/clang/include/clang/Analysis/Analyses/LifetimeSafety/Loans.h
index 00c931e4f9f66c6..cf70c132fc18a07 100644
--- a/clang/include/clang/Analysis/Analyses/LifetimeSafety/Loans.h
+++ b/clang/include/clang/Analysis/Analyses/LifetimeSafety/Loans.h
@@ -70,32 +70,42 @@ class PathElement {
   const FieldDecl *FD;
 };
 
-/// Represents the base of a placeholder access path, which is either a
-/// function parameter or the implicit 'this' object of an instance method.
-/// Placeholder paths never expire within the function scope, as they represent
-/// storage from the caller's scope.
+/// Represents the base of a placeholder access path, which is a function
+/// parameter, the implicit 'this' object of an instance method, or a field of
+/// the enclosing class. Placeholder paths never expire within the function
+/// scope, as they represent storage from the caller's or object's scope.
 class PlaceholderBase : public llvm::FoldingSetNode {
-  llvm::PointerUnion<const ParmVarDecl *, const CXXMethodDecl *> ParamOrMethod;
+  llvm::PointerUnion<const ParmVarDecl *, const CXXMethodDecl *,
+                     const FieldDecl *>
+      ParamMethodOrField;
 
 public:
-  PlaceholderBase(const ParmVarDecl *PVD) : ParamOrMethod(PVD) {}
-  PlaceholderBase(const CXXMethodDecl *MD) : ParamOrMethod(MD) {}
+  PlaceholderBase(const ParmVarDecl *PVD) : ParamMethodOrField(PVD) {}
+  PlaceholderBase(const CXXMethodDecl *MD) : ParamMethodOrField(MD) {}
+  PlaceholderBase(const FieldDecl *FD) : ParamMethodOrField(FD) {}
 
   const ParmVarDecl *getParmVarDecl() const {
-    return ParamOrMethod.dyn_cast<const ParmVarDecl *>();
+    return ParamMethodOrField.dyn_cast<const ParmVarDecl *>();
   }
 
   const CXXMethodDecl *getImplicitThisParent() const {
-    return ParamOrMethod.dyn_cast<const CXXMethodDecl *>();
+    return ParamMethodOrField.dyn_cast<const CXXMethodDecl *>();
   }
 
-  using KeyTy = llvm::PointerUnion<const ParmVarDecl *, const CXXMethodDecl *>;
+  const FieldDecl *getFieldDecl() const {
+    return ParamMethodOrField.dyn_cast<const FieldDecl *>();
+  }
+
+  using KeyTy = llvm::PointerUnion<const ParmVarDecl *, const CXXMethodDecl *,
+                                   const FieldDecl *>;
 
-  static void Profile(llvm::FoldingSetNodeID &ID, KeyTy ParamOrMethod) {
-    ID.AddPointer(ParamOrMethod.getOpaqueValue());
+  static void Profile(llvm::FoldingSetNodeID &ID, KeyTy ParamMethodOrField) {
+    ID.AddPointer(ParamMethodOrField.getOpaqueValue());
   }
 
-  void Profile(llvm::FoldingSetNodeID &ID) const { Profile(ID, ParamOrMethod); 
}
+  void Profile(llvm::FoldingSetNodeID &ID) const {
+    Profile(ID, ParamMethodOrField);
+  }
 };
 
 /// Represents the storage location being borrowed, e.g., a specific stack
@@ -229,6 +239,9 @@ class LoanManager {
   Loan *createPlaceholderLoan(const CXXMethodDecl *MD) {
     return createLoan(AccessPath(getOrCreatePlaceholderBase(MD)));
   }
+  Loan *createPlaceholderLoan(const FieldDecl *FD) {
+    return createLoan(AccessPath(getOrCreatePlaceholderBase(FD)));
+  }
 
   const Loan *getLoan(LoanID ID) const {
     assert(ID.Value < AllLoans.size());
@@ -240,9 +253,11 @@ class LoanManager {
 private:
   LoanID getNextLoanID() { return NextLoanID++; }
 
-  /// Gets or creates a placeholder base for a given parameter or method.
+  /// Gets or creates a placeholder base for a given parameter, method, or
+  /// field.
   const PlaceholderBase *getOrCreatePlaceholderBase(const ParmVarDecl *PVD);
   const PlaceholderBase *getOrCreatePlaceholderBase(const CXXMethodDecl *MD);
+  const PlaceholderBase *getOrCreatePlaceholderBase(const FieldDecl *FD);
 
   LoanID NextLoanID{0};
 
diff --git a/clang/include/clang/Basic/DiagnosticGroups.td 
b/clang/include/clang/Basic/DiagnosticGroups.td
index 1da7698944b24b2..5ad1136d66fea15 100644
--- a/clang/include/clang/Basic/DiagnosticGroups.td
+++ b/clang/include/clang/Basic/DiagnosticGroups.td
@@ -744,6 +744,13 @@ Validates correct usage and adherence to lifetime safety 
annotations like [[clan
   }];
 }
 
+def LifetimeSafetyFieldOriginEscape
+    : DiagGroup<"lifetime-safety-field-origin-escape"> {
+  code Documentation = [{
+Detects member functions returning an origin of a field (such as a pointer, 
reference, or view field).
+  }];
+}
+
 def LifetimeSafetyAll : DiagGroup<"lifetime-safety-all",
                                   [LifetimeSafety,
                                   LifetimeSafetySuggestions,
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 9208aba1445d7eb..1b333bdb60d2e0b 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -11143,6 +11143,11 @@ def warn_lifetime_safety_noescape_escapes
       InGroup<LifetimeSafetyNoescape>,
       DefaultIgnore;
 
+def warn_lifetime_safety_field_origin_escape
+    : Warning<"return value depends on the lifetime of the object referenced 
by %0, which cannot be expressed with [[clang::lifetimebound]]">,
+      InGroup<LifetimeSafetyFieldOriginEscape>,
+      DefaultIgnore;
+
 // For non-floating point, expressions of the form x == x or x != x
 // should result in a warning, since these always evaluate to a constant.
 // Array comparisons have similar warnings
diff --git a/clang/lib/Analysis/LifetimeSafety/Checker.cpp 
b/clang/lib/Analysis/LifetimeSafety/Checker.cpp
index fbf345460b6d859..adb866567aa6a78 100644
--- a/clang/lib/Analysis/LifetimeSafety/Checker.cpp
+++ b/clang/lib/Analysis/LifetimeSafety/Checker.cpp
@@ -60,6 +60,7 @@ class LifetimeChecker {
   llvm::DenseMap<LoanID, PendingWarning> FinalWarningsMap;
   llvm::DenseMap<AnnotationTarget, EscapingTarget> AnnotationWarningsMap;
   llvm::DenseMap<const ParmVarDecl *, EscapingTarget> NoescapeWarningsMap;
+  llvm::DenseMap<const FieldDecl *, const Expr *> FieldOriginEscapesMap;
   llvm::DenseSet<const Decl *> VerifiedLiftimeboundEscapes;
   const LoanPropagationAnalysis &LoanPropagation;
   const MovedLoansAnalysis &MovedLoans;
@@ -105,6 +106,8 @@ class LifetimeChecker {
           checkAnnotations(OEF);
     issuePendingWarnings();
     suggestAnnotations();
+    if (LSOpts.CheckFieldOriginEscape)
+      reportFieldOriginEscapes();
     if (LSOpts.CheckNoescapeViolations)
       reportNoescapeViolations();
     if (LSOpts.CheckLifetimeboundViolations)
@@ -171,6 +174,16 @@ class LifetimeChecker {
           AnnotationWarningsMap.try_emplace(MD, ReturnEsc->getReturnExpr());
       }
     };
+    auto CheckField = [&](const FieldDecl *Field) {
+      if (!LSOpts.CheckFieldOriginEscape)
+        return;
+      if (auto *ReturnEsc = dyn_cast<ReturnEscapeFact>(OEF)) {
+        if (OriginList *RetList = FactMgr.getOriginMgr().getOrCreateList(
+                ReturnEsc->getReturnExpr());
+            RetList && RetList->getOuterOriginID() == EscapedOID)
+          FieldOriginEscapesMap.try_emplace(Field, ReturnEsc->getReturnExpr());
+      }
+    };
     auto MovedAtEscape = MovedLoans.getMovedLoans(OEF);
     for (LoanID LID : EscapedLoans) {
       const Loan *L = FactMgr.getLoanMgr().getLoan(LID);
@@ -181,6 +194,8 @@ class LifetimeChecker {
         CheckParam(PVD, /*IsMoved=*/MovedAtEscape.lookup(LID));
       else if (const auto *MD = PB->getImplicitThisParent())
         CheckImplicitThis(MD);
+      else if (const auto *Field = PB->getFieldDecl())
+        CheckField(Field);
     }
   }
 
@@ -446,6 +461,17 @@ class LifetimeChecker {
     }
   }
 
+  void reportFieldOriginEscapes() {
+    if (!SemaHelper)
+      return;
+    const auto *MD = dyn_cast<CXXMethodDecl>(FD);
+    if (!MD)
+      return;
+    llvm::TimeTraceScope TimeTrace("ReportFieldOriginEscapes");
+    for (auto [Field, EscapeExpr] : FieldOriginEscapesMap)
+      SemaHelper->reportFieldOriginEscape(MD, Field, EscapeExpr);
+  }
+
   void reportNoescapeViolations() {
     llvm::TimeTraceScope TimeTrace("ReportNoescapeViolations");
     for (auto [PVD, EscapeTarget] : NoescapeWarningsMap) {
diff --git a/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp 
b/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp
index d1113783ab882ab..ba3106517e88d87 100644
--- a/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp
+++ b/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp
@@ -1214,10 +1214,21 @@ llvm::SmallVector<Fact *> 
FactsGenerator::issuePlaceholderLoans() {
   llvm::SmallVector<Fact *> PlaceholderLoanFacts;
   if (auto ThisOrigins = FactMgr.getOriginMgr().getThisOrigins()) {
     OriginList *List = *ThisOrigins;
-    const Loan *L =
-        FactMgr.getLoanMgr().createPlaceholderLoan(cast<CXXMethodDecl>(FD));
+    const auto *MD = cast<CXXMethodDecl>(FD);
+    const Loan *L = FactMgr.getLoanMgr().createPlaceholderLoan(MD);
     PlaceholderLoanFacts.push_back(
         FactMgr.createFact<IssueFact>(L->getID(), List->getOuterOriginID()));
+    if (!isa<CXXConstructorDecl>(MD))
+      if (const CXXRecordDecl *ClassDecl = MD->getParent()->getDefinition())
+        for (const FieldDecl *Field : ClassDecl->fields()) {
+          OriginList *FieldList = getOriginsList(*Field);
+          if (!FieldList)
+            continue;
+          const Loan *FieldLoan =
+              FactMgr.getLoanMgr().createPlaceholderLoan(Field);
+          PlaceholderLoanFacts.push_back(FactMgr.createFact<IssueFact>(
+              FieldLoan->getID(), FieldList->getOuterOriginID()));
+        }
   }
   for (const ParmVarDecl *PVD : FD->parameters()) {
     OriginList *List = getOriginsList(*PVD);
diff --git a/clang/lib/Analysis/LifetimeSafety/Loans.cpp 
b/clang/lib/Analysis/LifetimeSafety/Loans.cpp
index e6cbd922d20c724..c15f9b499b35b8e 100644
--- a/clang/lib/Analysis/LifetimeSafety/Loans.cpp
+++ b/clang/lib/Analysis/LifetimeSafety/Loans.cpp
@@ -21,6 +21,8 @@ void AccessPath::dump(llvm::raw_ostream &OS) const {
       OS << "$" << PVD->getNameAsString();
     else if (PB->getImplicitThisParent())
       OS << "$this";
+    else if (const auto *FD = PB->getFieldDecl())
+      OS << "$this." << FD->getNameAsString();
   } else if (const auto *E = getAsNewAllocation())
     OS << "NewAllocation at " << E;
   else
@@ -62,4 +64,18 @@ LoanManager::getOrCreatePlaceholderBase(const CXXMethodDecl 
*MD) {
   PlaceholderBases.insert(NewPB, InsertToken);
   return NewPB;
 }
+
+const PlaceholderBase *
+LoanManager::getOrCreatePlaceholderBase(const FieldDecl *FD) {
+  llvm::FoldingSetNodeID ID;
+  PlaceholderBase::Profile(ID, FD);
+  llvm::FoldingSetInsertToken InsertToken;
+  if (PlaceholderBase *Existing = PlaceholderBases.lookup(ID, InsertToken))
+    return Existing;
+
+  void *Mem = LoanAllocator.Allocate<PlaceholderBase>();
+  PlaceholderBase *NewPB = new (Mem) PlaceholderBase(FD);
+  PlaceholderBases.insert(NewPB, InsertToken);
+  return NewPB;
+}
 } // namespace clang::lifetimes::internal
diff --git a/clang/lib/Sema/SemaLifetimeSafety.h 
b/clang/lib/Sema/SemaLifetimeSafety.h
index 52ee8c0037b8d0f..3f2bfb4d4d9886f 100644
--- a/clang/lib/Sema/SemaLifetimeSafety.h
+++ b/clang/lib/Sema/SemaLifetimeSafety.h
@@ -72,6 +72,11 @@ inline bool ShouldCheckInapplicableLifetimebound(Sema &S, 
const Decl *D) {
       diag::warn_lifetime_safety_inapplicable_lifetimebound, D->getBeginLoc());
 }
 
+inline bool ShouldCheckFieldOriginEscape(Sema &S, const Decl *D) {
+  return !S.getDiagnostics().isIgnored(
+      diag::warn_lifetime_safety_field_origin_escape, D->getBeginLoc());
+}
+
 inline bool ShouldSuggestLifetimeAnnotations(Sema &S, const Decl *D) {
   DiagnosticsEngine &Diags = S.getDiagnostics();
   constexpr unsigned DiagIDs[] = {
@@ -114,6 +119,7 @@ inline bool IsLifetimeSafetyEnabled(Sema &S, const Decl *D) 
{
          ShouldCheckLifetimeboundViolations(S, D) ||
          ShouldCheckMisplacedLifetimebound(S, D) ||
          ShouldCheckInapplicableLifetimebound(S, D) ||
+         ShouldCheckFieldOriginEscape(S, D) ||
          ShouldSuggestLifetimeAnnotations(S, D);
 }
 
@@ -127,6 +133,7 @@ inline LifetimeSafetyOpts GetLifetimeSafetyOpts(Sema &S, 
const Decl *D) {
   LSOpts.CheckMisplacedLifetimebound = ShouldCheckMisplacedLifetimebound(S, D);
   LSOpts.CheckInapplicableLifetimebound =
       ShouldCheckInapplicableLifetimebound(S, D);
+  LSOpts.CheckFieldOriginEscape = ShouldCheckFieldOriginEscape(S, D);
   return LSOpts;
 }
 
@@ -458,6 +465,15 @@ class LifetimeSafetySemaHelperImpl : public 
LifetimeSafetySemaHelper {
         << EscapeExpr->getSourceRange();
   }
 
+  void reportFieldOriginEscape(const CXXMethodDecl *MD, const FieldDecl *FD,
+                               const Expr *EscapeExpr) override {
+    S.Diag(MD->getLocation(), diag::warn_lifetime_safety_field_origin_escape)
+        << getDiagSubjectDescription(FD) << MD->getNameInfo().getSourceRange();
+
+    S.Diag(EscapeExpr->getBeginLoc(), diag::note_lifetime_safety_returned_here)
+        << EscapeExpr->getSourceRange();
+  }
+
   void reportNoescapeViolation(const ParmVarDecl *ParmWithNoescape,
                                const Expr *EscapeExpr) override {
     S.Diag(ParmWithNoescape->getBeginLoc(),
diff --git a/clang/test/Sema/LifetimeSafety/annotation-suggestions.cpp 
b/clang/test/Sema/LifetimeSafety/annotation-suggestions.cpp
index 4deb6d1f8688d64..b095d48365b2cc1 100644
--- a/clang/test/Sema/LifetimeSafety/annotation-suggestions.cpp
+++ b/clang/test/Sema/LifetimeSafety/annotation-suggestions.cpp
@@ -1,8 +1,8 @@
 // RUN: rm -rf %t
 // RUN: split-file %s %t
-// RUN: %clang_cc1 -fsyntax-only -flifetime-safety-inference 
-fexperimental-lifetime-safety-tu-analysis -Wlifetime-safety-suggestions 
-Wlifetime-safety -Wlifetime-safety-annotation-placement -Wno-dangling -I%t 
-I%S -verify %t/test_source.cpp
-// RUN: %clang_cc1 -fsyntax-only -std=c++23 -flifetime-safety-inference 
-fexperimental-lifetime-safety-tu-analysis -Wlifetime-safety-suggestions 
-Wlifetime-safety -Wno-dangling -I%t -I%S -verify %t/test_source.cpp
-// RUN: %clang_cc1 -flifetime-safety-inference 
-fexperimental-lifetime-safety-tu-analysis -Wlifetime-safety-suggestions 
-Wlifetime-safety -Wno-dangling -I%t -I%S -fixit %t/test_source.cpp
+// RUN: %clang_cc1 -fsyntax-only -flifetime-safety-inference 
-fexperimental-lifetime-safety-tu-analysis -Wlifetime-safety-suggestions 
-Wlifetime-safety -Wlifetime-safety-annotation-placement 
-Wlifetime-safety-field-origin-escape -Wno-dangling -I%t -I%S -verify 
%t/test_source.cpp
+// RUN: %clang_cc1 -fsyntax-only -std=c++23 -flifetime-safety-inference 
-fexperimental-lifetime-safety-tu-analysis -Wlifetime-safety-suggestions 
-Wlifetime-safety -Wlifetime-safety-field-origin-escape -Wno-dangling -I%t -I%S 
-verify %t/test_source.cpp
+// RUN: %clang_cc1 -flifetime-safety-inference 
-fexperimental-lifetime-safety-tu-analysis -Wlifetime-safety-suggestions 
-Wlifetime-safety -Wlifetime-safety-field-origin-escape -Wno-dangling -I%t -I%S 
-fixit %t/test_source.cpp
 // RUN: %clang_cc1 -fsyntax-only -flifetime-safety-inference 
-fexperimental-lifetime-safety-tu-analysis -Wlifetime-safety-suggestions 
-Wno-dangling -I%t -I%S -Werror=lifetime-safety-suggestions %t/test_source.cpp
 
 View definition_before_header(View a);
@@ -700,3 +700,94 @@ S foo() {
   return S(create_up());
 }
 } // namespace GH193747
+
+namespace field_origin_escape {
+
+class Context {
+public:
+  // This method should be annotated with lifetimebound.
+  std::string_view method() const { // expected-warning {{implicit this in 
intra-TU function should be marked [[clang::lifetimebound]]}}
+    return method_;                 // expected-note {{param returned here}}
+  }
+
+private:
+  std::string method_ = "42";
+};
+
+class ContextAnnotated {
+public:
+  std::string_view method() const [[clang::lifetimebound]] {
+    return method_;
+  }
+
+private:
+  std::string method_ = "42";
+};
+
+class ContextWrapper {
+public:
+  explicit ContextWrapper(Context &inner,          // expected-warning 
{{parameter in intra-TU constructor should be marked [[clang::lifetimebound]]}}
+                          ContextAnnotated &annot) // expected-warning 
{{parameter in intra-TU constructor should be marked [[clang::lifetimebound]]}}
+      : inner_(inner), annot_(annot) {}
+
+  Context &inner() const { // expected-warning {{return value depends on the 
lifetime of the object referenced by field 'inner_', which cannot be expressed 
with [[clang::lifetimebound]]}}
+    return inner_;         // expected-note {{returned here}}
+  }
+
+  // This method should NOT be annotated with lifetimebound.
+  std::string_view method() const { // expected-warning {{return value depends 
on the lifetime of the object referenced by field 'inner_', which cannot be 
expressed with [[clang::lifetimebound]]}}
+    return inner_.method();         // expected-note {{returned here}}
+  }
+
+  std::string_view annot_method() const { // expected-warning {{return value 
depends on the lifetime of the object referenced by field 'annot_', which 
cannot be expressed with [[clang::lifetimebound]]}}
+    return annot_.method();               // expected-note {{returned here}}
+  }
+
+private:
+  Context &inner_;          // expected-note {{escapes to this field}}
+  ContextAnnotated &annot_; // expected-note {{escapes to this field}}
+};
+
+struct FieldTypes {
+  int val_;
+  int *ptr_;
+  int &ref_;
+  std::string str_;
+  std::string_view view_;
+
+  // Loans to fields (depend on enclosing object, not field origin).
+  int &get_val_ref() { // expected-warning {{implicit this in intra-TU 
function should be marked [[clang::lifetimebound]]}}
+    return val_;       // expected-note {{param returned here}}
+  }
+  int *get_val_ptr() { // expected-warning {{implicit this in intra-TU 
function should be marked [[clang::lifetimebound]]}}
+    return &val_;      // expected-note {{param returned here}}
+  }
+  std::string_view get_str_view() const { // expected-warning {{implicit this 
in intra-TU function should be marked [[clang::lifetimebound]]}}
+    return str_;                          // expected-note {{param returned 
here}}
+  }
+  int *&get_ptr_ref() { // expected-warning {{implicit this in intra-TU 
function should be marked [[clang::lifetimebound]]}}
+    return ptr_;        // expected-note {{param returned here}}
+  }
+
+  // Origins of fields -> field-origin-escape warning, no lifetimebound 
suggestion on 'this'.
+  int *get_ptr() const { // expected-warning {{return value depends on the 
lifetime of the object referenced by field 'ptr_', which cannot be expressed 
with [[clang::lifetimebound]]}}
+    return ptr_;         // expected-note {{returned here}}
+  }
+  int &get_ptr_deref() const { // expected-warning {{return value depends on 
the lifetime of the object referenced by field 'ptr_', which cannot be 
expressed with [[clang::lifetimebound]]}}
+    return *ptr_;              // expected-note {{returned here}}
+  }
+  int &get_ref() const { // expected-warning {{return value depends on the 
lifetime of the object referenced by field 'ref_', which cannot be expressed 
with [[clang::lifetimebound]]}}
+    return ref_;         // expected-note {{returned here}}
+  }
+  int *get_ref_addr() const { // expected-warning {{return value depends on 
the lifetime of the object referenced by field 'ref_', which cannot be 
expressed with [[clang::lifetimebound]]}}
+    return &ref_;             // expected-note {{returned here}}
+  }
+  std::string_view get_view() const { // expected-warning {{return value 
depends on the lifetime of the object referenced by field 'view_', which cannot 
be expressed with [[clang::lifetimebound]]}}
+    return view_;                     // expected-note {{returned here}}
+  }
+  const char *get_view_data() const { // expected-warning {{return value 
depends on the lifetime of the object referenced by field 'view_', which cannot 
be expressed with [[clang::lifetimebound]]}}
+    return view_.data();              // expected-note {{returned here}}
+  }
+};
+
+} // namespace field_origin_escape

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

Reply via email to