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
