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

>From 9ad57f3a6e129a25471d298edfc6c0fd82c8c634 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena <[email protected]>
Date: Thu, 25 Jun 2026 10:10:35 +0000
Subject: [PATCH 1/2] suggesionsopt-in-suggestions

---
 .../Analysis/Analyses/LifetimeSafety/Checker.h     |  3 ++-
 .../Analyses/LifetimeSafety/LifetimeSafety.h       |  4 ++++
 clang/lib/Analysis/LifetimeSafety/Checker.cpp      | 14 ++++++++++----
 .../lib/Analysis/LifetimeSafety/LifetimeSafety.cpp |  7 ++-----
 clang/lib/Sema/AnalysisBasedWarnings.cpp           | 13 ++++++++++---
 clang/lib/Sema/SemaLifetimeSafety.h                | 13 +++++++++++++
 6 files changed, 41 insertions(+), 13 deletions(-)

diff --git a/clang/include/clang/Analysis/Analyses/LifetimeSafety/Checker.h 
b/clang/include/clang/Analysis/Analyses/LifetimeSafety/Checker.h
index 1ad3f9da61f60..99ad816311e74 100644
--- a/clang/include/clang/Analysis/Analyses/LifetimeSafety/Checker.h
+++ b/clang/include/clang/Analysis/Analyses/LifetimeSafety/Checker.h
@@ -29,7 +29,8 @@ void runLifetimeChecker(const LoanPropagationAnalysis 
&LoanPropagation,
                         const MovedLoansAnalysis &MovedLoans,
                         const LiveOriginsAnalysis &LiveOrigins,
                         FactManager &FactMgr, AnalysisDeclContext &ADC,
-                        LifetimeSafetySemaHelper *SemaHelper);
+                        LifetimeSafetySemaHelper *SemaHelper,
+                        const LifetimeSafetyOpts &LSOpts);
 
 } // namespace clang::lifetimes::internal
 
diff --git 
a/clang/include/clang/Analysis/Analyses/LifetimeSafety/LifetimeSafety.h 
b/clang/include/clang/Analysis/Analyses/LifetimeSafety/LifetimeSafety.h
index 28886b826f72f..80a23f18baebd 100644
--- a/clang/include/clang/Analysis/Analyses/LifetimeSafety/LifetimeSafety.h
+++ b/clang/include/clang/Analysis/Analyses/LifetimeSafety/LifetimeSafety.h
@@ -38,6 +38,9 @@ struct LifetimeSafetyOpts {
   /// Maximum number of CFG blocks to analyze. Functions with larger CFGs will
   /// be skipped.
   size_t MaxCFGBlocks;
+
+  /// Whether to suggest lifetime annotations.
+  bool SuggestAnnotations;
 };
 
 /// Enum to track functions visible across or within TU.
@@ -157,6 +160,7 @@ class LifetimeSafetySemaHelper {
 /// The main entry point for the analysis.
 void runLifetimeSafetyAnalysis(AnalysisDeclContext &AC,
                                LifetimeSafetySemaHelper *SemaHelper,
+                               const LifetimeSafetyOpts &Opts,
                                LifetimeSafetyStats &Stats, bool CollectStats);
 
 namespace internal {
diff --git a/clang/lib/Analysis/LifetimeSafety/Checker.cpp 
b/clang/lib/Analysis/LifetimeSafety/Checker.cpp
index c258a1dc3596c..746ebbfb15c39 100644
--- a/clang/lib/Analysis/LifetimeSafety/Checker.cpp
+++ b/clang/lib/Analysis/LifetimeSafety/Checker.cpp
@@ -68,6 +68,7 @@ class LifetimeChecker {
   LifetimeSafetySemaHelper *SemaHelper;
   ASTContext &AST;
   const Decl *FD;
+  const LifetimeSafetyOpts &LSOpts;
 
   static SourceLocation
   GetFactLoc(llvm::PointerUnion<const UseFact *, const OriginEscapesFact *> F) 
{
@@ -87,10 +88,11 @@ class LifetimeChecker {
                   const MovedLoansAnalysis &MovedLoans,
                   const LiveOriginsAnalysis &LiveOrigins, FactManager &FM,
                   AnalysisDeclContext &ADC,
-                  LifetimeSafetySemaHelper *SemaHelper)
+                  LifetimeSafetySemaHelper *SemaHelper,
+                  const LifetimeSafetyOpts &LSOpts)
       : LoanPropagation(LoanPropagation), MovedLoans(MovedLoans),
         LiveOrigins(LiveOrigins), FactMgr(FM), SemaHelper(SemaHelper),
-        AST(ADC.getASTContext()), FD(ADC.getDecl()) {
+        AST(ADC.getASTContext()), FD(ADC.getDecl()), LSOpts(LSOpts) {
     for (const CFGBlock *B : *ADC.getAnalysis<PostOrderCFGView>())
       for (const Fact *F : FactMgr.getFacts(B))
         if (const auto *EF = F->getAs<ExpireFact>())
@@ -398,6 +400,9 @@ class LifetimeChecker {
   void suggestAnnotations() {
     if (!SemaHelper)
       return;
+    if (!LSOpts.SuggestAnnotations)
+      return;
+    llvm::TimeTraceScope TimeTrace("SuggestAnnotations");
     for (auto [Target, EscapeTarget] : AnnotationWarningsMap) {
       if (const auto *PVD = Target.dyn_cast<const ParmVarDecl *>())
         suggestWithScopeForParmVar(PVD, EscapeTarget);
@@ -535,9 +540,10 @@ void runLifetimeChecker(const LoanPropagationAnalysis &LP,
                         const MovedLoansAnalysis &MovedLoans,
                         const LiveOriginsAnalysis &LO, FactManager &FactMgr,
                         AnalysisDeclContext &ADC,
-                        LifetimeSafetySemaHelper *SemaHelper) {
+                        LifetimeSafetySemaHelper *SemaHelper,
+                        const LifetimeSafetyOpts &LSOpts) {
   llvm::TimeTraceScope TimeProfile("LifetimeChecker");
-  LifetimeChecker Checker(LP, MovedLoans, LO, FactMgr, ADC, SemaHelper);
+  LifetimeChecker Checker(LP, MovedLoans, LO, FactMgr, ADC, SemaHelper, 
LSOpts);
 }
 
 } // namespace clang::lifetimes::internal
diff --git a/clang/lib/Analysis/LifetimeSafety/LifetimeSafety.cpp 
b/clang/lib/Analysis/LifetimeSafety/LifetimeSafety.cpp
index 714f979fa5ee7..680095a54177c 100644
--- a/clang/lib/Analysis/LifetimeSafety/LifetimeSafety.cpp
+++ b/clang/lib/Analysis/LifetimeSafety/LifetimeSafety.cpp
@@ -96,7 +96,7 @@ void LifetimeSafetyAnalysis::run() {
       Factory.MovedLoansMapFactory);
 
   runLifetimeChecker(*LoanPropagation, *MovedLoans, *LiveOrigins, *FactMgr, AC,
-                     SemaHelper);
+                     SemaHelper, LSOpts);
 
   DEBUG_WITH_TYPE("PrintCFG", Cfg.dump(AC.getASTContext().getLangOpts(),
                                        /*ShowColors=*/true));
@@ -122,11 +122,8 @@ void collectLifetimeStats(AnalysisDeclContext &AC, 
OriginManager &OM,
 
 void runLifetimeSafetyAnalysis(AnalysisDeclContext &AC,
                                LifetimeSafetySemaHelper *SemaHelper,
+                               const LifetimeSafetyOpts &LSOpts,
                                LifetimeSafetyStats &Stats, bool CollectStats) {
-  LifetimeSafetyOpts LSOpts;
-  LSOpts.MaxCFGBlocks =
-      AC.getASTContext().getLangOpts().LifetimeSafetyMaxCFGBlocks;
-
   internal::LifetimeSafetyAnalysis Analysis(AC, SemaHelper, LSOpts);
   Analysis.run();
   if (CollectStats)
diff --git a/clang/lib/Sema/AnalysisBasedWarnings.cpp 
b/clang/lib/Sema/AnalysisBasedWarnings.cpp
index 52fe7765c6c6a..d39763a8732ca 100644
--- a/clang/lib/Sema/AnalysisBasedWarnings.cpp
+++ b/clang/lib/Sema/AnalysisBasedWarnings.cpp
@@ -2928,8 +2928,12 @@ LifetimeSafetyTUAnalysis(Sema &S, TranslationUnitDecl 
*TU,
     AC.getCFGBuildOptions().AddInitializers = true;
     AC.getCFGBuildOptions().AddCXXDefaultInitExprInCtors = true;
     AC.getCFGBuildOptions().setAllAlwaysAdd();
-    if (AC.getCFG())
-      runLifetimeSafetyAnalysis(AC, &SemaHelper, LSStats, S.CollectStats);
+    if (AC.getCFG()) {
+      lifetimes::LifetimeSafetyOpts LSOpts;
+      LSOpts.MaxCFGBlocks = S.getLangOpts().LifetimeSafetyMaxCFGBlocks;
+      LSOpts.SuggestAnnotations = 
lifetimes::ShouldSuggestLifetimeAnnotations(S, FD);
+      runLifetimeSafetyAnalysis(AC, &SemaHelper, LSOpts, LSStats, 
S.CollectStats);
+    }
   }
 }
 
@@ -3164,8 +3168,11 @@ void clang::sema::AnalysisBasedWarnings::IssueWarnings(
   if (EnableLifetimeSafetyAnalysis) {
     if (AC.getCFG()) {
       lifetimes::LifetimeSafetySemaHelperImpl LifetimeSafetySemaHelper(S);
+      lifetimes::LifetimeSafetyOpts LSOpts;
+      LSOpts.MaxCFGBlocks = S.getLangOpts().LifetimeSafetyMaxCFGBlocks;
+      LSOpts.SuggestAnnotations = 
lifetimes::ShouldSuggestLifetimeAnnotations(S, D);
       lifetimes::runLifetimeSafetyAnalysis(AC, &LifetimeSafetySemaHelper,
-                                           LSStats, S.CollectStats);
+                                           LSOpts, LSStats, S.CollectStats);
     }
   }
   // Check for violations of "called once" parameter properties.
diff --git a/clang/lib/Sema/SemaLifetimeSafety.h 
b/clang/lib/Sema/SemaLifetimeSafety.h
index 7c78a6a1e8c31..c15c8609845b6 100644
--- a/clang/lib/Sema/SemaLifetimeSafety.h
+++ b/clang/lib/Sema/SemaLifetimeSafety.h
@@ -76,6 +76,19 @@ inline bool IsLifetimeSafetyEnabled(Sema &S, const Decl *D) {
   return false;
 }
 
+inline bool ShouldSuggestLifetimeAnnotations(Sema &S, const Decl *D) {
+  DiagnosticsEngine &Diags = S.getDiagnostics();
+  constexpr unsigned DiagIDs[] = {
+      diag::warn_lifetime_safety_intra_tu_param_suggestion,
+      diag::warn_lifetime_safety_cross_tu_param_suggestion,
+      diag::warn_lifetime_safety_intra_tu_this_suggestion,
+      diag::warn_lifetime_safety_cross_tu_this_suggestion};
+  for (unsigned DiagID : DiagIDs)
+    if (!Diags.isIgnored(DiagID, D->getBeginLoc()))
+      return true;
+  return false;
+}
+
 class LifetimeSafetySemaHelperImpl : public LifetimeSafetySemaHelper {
 
 public:

>From 761abd1fbf088a2e2799133c6abed50e3120d2ca Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena <[email protected]>
Date: Thu, 25 Jun 2026 10:12:51 +0000
Subject: [PATCH 2/2] add tests

---
 .../annotation-suggestions-disabled.cpp        | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)
 create mode 100644 
clang/test/Sema/LifetimeSafety/annotation-suggestions-disabled.cpp

diff --git a/clang/test/Sema/LifetimeSafety/annotation-suggestions-disabled.cpp 
b/clang/test/Sema/LifetimeSafety/annotation-suggestions-disabled.cpp
new file mode 100644
index 0000000000000..ca5b3b7a65dd1
--- /dev/null
+++ b/clang/test/Sema/LifetimeSafety/annotation-suggestions-disabled.cpp
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -fsyntax-only -flifetime-safety-inference 
-fexperimental-lifetime-safety-tu-analysis -Wlifetime-safety -Wno-dangling -I%S 
-verify %s
+
+#include "Inputs/lifetime-analysis.h"
+
+struct View;
+struct [[gsl::Owner]] MyObj {
+  View getView() const [[clang::lifetimebound]];
+};
+struct [[gsl::Pointer()]] View {
+  View(const MyObj&);
+};
+
+// This would normally trigger a suggestion warning if 
-Wlifetime-safety-suggestions was on.
+// Since it is off, we expect NO warnings or notes here.
+// expected-no-diagnostics
+View return_view_directly(View a) {
+  return a; 
+}

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

Reply via email to