https://github.com/zeyi2 created 
https://github.com/llvm/llvm-project/pull/204045

None

>From 1ee4bc273b8a1ecc17e8645a13ee97986d397ab2 Mon Sep 17 00:00:00 2001
From: Zeyi Xu <[email protected]>
Date: Tue, 16 Jun 2026 10:02:39 +0800
Subject: [PATCH] [LifetimeSafety] Prefer macro spelling for lifetimebound
 fix-its

---
 clang/lib/Sema/SemaLifetimeSafety.h           | 26 ++++++++++----
 .../test/Sema/warn-lifetime-safety-fixits.cpp | 34 +++++++++++++++++++
 2 files changed, 54 insertions(+), 6 deletions(-)

diff --git a/clang/lib/Sema/SemaLifetimeSafety.h 
b/clang/lib/Sema/SemaLifetimeSafety.h
index 6da4953dea56d..f76fb6a58b8f9 100644
--- a/clang/lib/Sema/SemaLifetimeSafety.h
+++ b/clang/lib/Sema/SemaLifetimeSafety.h
@@ -19,6 +19,7 @@
 #include "clang/Analysis/Analyses/LifetimeSafety/LifetimeSafety.h"
 #include "clang/Basic/DiagnosticSema.h"
 #include "clang/Lex/Lexer.h"
+#include "clang/Lex/Preprocessor.h"
 #include "clang/Sema/Sema.h"
 #include <string>
 
@@ -403,27 +404,39 @@ class LifetimeSafetySemaHelperImpl : public 
LifetimeSafetySemaHelper {
   }
 
 private:
-  std::pair<SourceLocation, StringRef>
+  std::string getLifetimeBoundFixItText(SourceLocation Loc, bool LeadingSpace) 
{
+    const Preprocessor &PP = S.getPreprocessor();
+    const StringRef Spelling = PP.getLastMacroWithSpelling(
+        Loc, {tok::l_square, tok::l_square, PP.getIdentifierInfo("clang"),
+              tok::coloncolon, PP.getIdentifierInfo("lifetimebound"),
+              tok::r_square, tok::r_square});
+    const std::string Text =
+        Spelling.empty() ? "[[clang::lifetimebound]]" : Spelling.str();
+    return LeadingSpace ? " " + Text : Text + " ";
+  }
+
+  std::pair<SourceLocation, std::string>
   getLifetimeBoundFixIt(const ParmVarDecl *Decl) {
     SourceLocation InsertionPoint = Lexer::getLocForEndOfToken(
         Decl->getEndLoc(), 0, S.getSourceManager(), S.getLangOpts());
-    StringRef FixItText = " [[clang::lifetimebound]]";
+    bool LeadingSpace = true;
 
     if (!Decl->getIdentifier()) {
       // For unnamed parameters, placing attributes after the type would be
       // parsed as a type attribute, not a parameter attribute.
       InsertionPoint = Decl->getBeginLoc();
-      FixItText = "[[clang::lifetimebound]] ";
+      LeadingSpace = false;
     } else if (Decl->hasDefaultArg()) {
       // If the parameter has a default argument, place the attribute after the
       // named argument.
       InsertionPoint = Lexer::getLocForEndOfToken(
           Decl->getLocation(), 0, S.getSourceManager(), S.getLangOpts());
     }
-    return {InsertionPoint, FixItText};
+    return {InsertionPoint,
+            getLifetimeBoundFixItText(InsertionPoint, LeadingSpace)};
   }
 
-  std::pair<SourceLocation, StringRef>
+  std::pair<SourceLocation, std::string>
   getLifetimeBoundFixIt(const CXXMethodDecl *MD) {
     const auto MDL = MD->getTypeSourceInfo()->getTypeLoc();
     SourceLocation InsertionPoint = Lexer::getLocForEndOfToken(
@@ -444,7 +457,8 @@ class LifetimeSafetySemaHelperImpl : public 
LifetimeSafetySemaHelper {
               ->getLocation(),
           0, S.getSourceManager(), S.getLangOpts());
     }
-    return {InsertionPoint, " [[clang::lifetimebound]]"};
+    return {InsertionPoint, getLifetimeBoundFixItText(InsertionPoint,
+                                                      /*LeadingSpace=*/true)};
   }
 
   std::string getDiagSubjectDescription(const ValueDecl *VD) {
diff --git a/clang/test/Sema/warn-lifetime-safety-fixits.cpp 
b/clang/test/Sema/warn-lifetime-safety-fixits.cpp
index d9c7e8d3f0519..e1a89f9047457 100644
--- a/clang/test/Sema/warn-lifetime-safety-fixits.cpp
+++ b/clang/test/Sema/warn-lifetime-safety-fixits.cpp
@@ -174,3 +174,37 @@ struct TrailingReturn {
     return data;
   }
 };
+
+#define MY_LIFETIMEBOUND_MACRO [[clang::lifetimebound]]
+
+View unnamed_macro(View);
+// CHECK: :[[@LINE-1]]:20: warning: parameter in intra-TU function should be 
marked
+// CHECK: 
fix-it:"{{.*}}":{[[@LINE-2]]:20-[[@LINE-2]]:20}:"MY_LIFETIMEBOUND_MACRO "
+View unnamed_macro(View a) {
+  return a;
+}
+
+View return_view_with_macro(View a) {
+  // CHECK: :[[@LINE-1]]:29: warning: parameter in intra-TU function should be 
marked
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:35-[[@LINE-2]]:35}:" 
MY_LIFETIMEBOUND_MACRO"
+  return a;
+}
+
+#define FIRST_LIFETIMEBOUND_MACRO [[clang::lifetimebound]]
+#define SECOND_LIFETIMEBOUND_MACRO [[clang::lifetimebound]]
+
+View return_view_with_latest_macro(View a) {
+  // CHECK: :[[@LINE-1]]:36: warning: parameter in intra-TU function should be 
marked
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:42-[[@LINE-2]]:42}:" 
SECOND_LIFETIMEBOUND_MACRO"
+  return a;
+}
+
+struct MacroMember {
+  MyObj data;
+
+  View get_view() {
+    // CHECK: :[[@LINE-1]]:18: warning: implicit this in intra-TU function 
should be marked
+    // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:18-[[@LINE-2]]:18}:" 
SECOND_LIFETIMEBOUND_MACRO"
+    return data;
+  }
+};

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

Reply via email to