llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: NeKon69 <details> <summary>Changes</summary> With this patch, we suggest adding the `clang::lifetimebound` attribute on the canonical declaration instead of first trying to find a redeclaration of the function in another file and falling back to the definition when none is found. Fixes #<!-- -->198624 --- Full diff: https://github.com/llvm/llvm-project/pull/198784.diff 3 Files Affected: - (modified) clang/lib/Analysis/LifetimeSafety/Checker.cpp (+11-46) - (modified) clang/test/Sema/warn-lifetime-safety-fixits.cpp (+4-5) - (modified) clang/test/Sema/warn-lifetime-safety-suggestions.cpp (+12-12) ``````````diff diff --git a/clang/lib/Analysis/LifetimeSafety/Checker.cpp b/clang/lib/Analysis/LifetimeSafety/Checker.cpp index d6a15139aa4ea..4b9d195411179 100644 --- a/clang/lib/Analysis/LifetimeSafety/Checker.cpp +++ b/clang/lib/Analysis/LifetimeSafety/Checker.cpp @@ -353,66 +353,31 @@ class LifetimeChecker { Scope}; } - /// Returns the declaration of a function that is visible across translation - /// units, if such a declaration exists and is different from the definition. - static const FunctionDecl *getCrossTUDecl(const FunctionDecl &FD, - SourceManager &SM) { - if (!FD.isExternallyVisible()) - return nullptr; - const FileID DefinitionFile = SM.getFileID(FD.getLocation()); - for (const FunctionDecl *Redecl : FD.redecls()) - if (SM.getFileID(Redecl->getLocation()) != DefinitionFile) - return Redecl; - - return nullptr; - } - - static const FunctionDecl *getCrossTUDecl(const ParmVarDecl &PVD, - SourceManager &SM) { - if (const auto *FD = dyn_cast<FunctionDecl>(PVD.getDeclContext())) - return getCrossTUDecl(*FD, SM); - return nullptr; - } - - static void suggestWithScopeForParmVar(LifetimeSafetySemaHelper *SemaHelper, - const ParmVarDecl *PVD, - SourceManager &SM, - EscapingTarget EscapeTarget) { + void suggestWithScopeForParmVar(const ParmVarDecl *PVD, + EscapingTarget EscapeTarget) { if (llvm::isa<const VarDecl *>(EscapeTarget)) return; - if (const FunctionDecl *CrossTUDecl = getCrossTUDecl(*PVD, SM)) - SemaHelper->suggestLifetimeboundToParmVar( - WarningScope::CrossTU, - CrossTUDecl->getParamDecl(PVD->getFunctionScopeIndex()), - EscapeTarget); - else - SemaHelper->suggestLifetimeboundToParmVar(WarningScope::IntraTU, PVD, - EscapeTarget); + auto [Parm, Scope] = getCanonicalDeclForAttr(cast<FunctionDecl>(FD), PVD); + SemaHelper->suggestLifetimeboundToParmVar(Scope, Parm, EscapeTarget); } - static void - suggestWithScopeForImplicitThis(LifetimeSafetySemaHelper *SemaHelper, - const CXXMethodDecl *MD, SourceManager &SM, - const Expr *EscapeExpr) { - if (const FunctionDecl *CrossTUDecl = getCrossTUDecl(*MD, SM)) - SemaHelper->suggestLifetimeboundToImplicitThis( - WarningScope::CrossTU, cast<CXXMethodDecl>(CrossTUDecl), EscapeExpr); - else - SemaHelper->suggestLifetimeboundToImplicitThis(WarningScope::IntraTU, MD, - EscapeExpr); + void suggestWithScopeForImplicitThis(const CXXMethodDecl *MD, + const Expr *EscapeExpr) { + auto [MethodDecl, Scope] = getCanonicalDeclForAttr(MD); + SemaHelper->suggestLifetimeboundToImplicitThis(Scope, MethodDecl, + EscapeExpr); } void suggestAnnotations() { if (!SemaHelper) return; - SourceManager &SM = AST.getSourceManager(); for (auto [Target, EscapeTarget] : AnnotationWarningsMap) { if (const auto *PVD = Target.dyn_cast<const ParmVarDecl *>()) - suggestWithScopeForParmVar(SemaHelper, PVD, SM, EscapeTarget); + suggestWithScopeForParmVar(PVD, EscapeTarget); else if (const auto *MD = Target.dyn_cast<const CXXMethodDecl *>()) { if (const auto *EscapeExpr = EscapeTarget.dyn_cast<const Expr *>()) - suggestWithScopeForImplicitThis(SemaHelper, MD, SM, EscapeExpr); + suggestWithScopeForImplicitThis(MD, EscapeExpr); else llvm_unreachable("Implicit this can only escape via Expr (return)"); } diff --git a/clang/test/Sema/warn-lifetime-safety-fixits.cpp b/clang/test/Sema/warn-lifetime-safety-fixits.cpp index 88d8bd379de8b..d9c7e8d3f0519 100644 --- a/clang/test/Sema/warn-lifetime-safety-fixits.cpp +++ b/clang/test/Sema/warn-lifetime-safety-fixits.cpp @@ -69,12 +69,11 @@ int *arr_default(int a[2] = nullptr) { return a; } -// FIXME: Iterate over redecls and add [[clang::lifetimebound]] View multi_decl(View a); +// CHECK: :[[@LINE-1]]:17: warning: parameter in intra-TU function should be marked +// CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:23-[[@LINE-2]]:23}:" {{\[\[}}clang::lifetimebound]]" View multi_decl(View a); View multi_decl(View a) { - // CHECK: :[[@LINE-1]]:17: warning: parameter in intra-TU function should be marked - // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:23-[[@LINE-2]]:23}:" {{\[\[}}clang::lifetimebound]]" return a; } @@ -145,10 +144,10 @@ struct OutOfLine { OutOfLine() {} ~OutOfLine() {} const OutOfLine &get() const; + // CHECK: :[[@LINE-1]]:31: warning: implicit this in intra-TU function should be marked + // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:31-[[@LINE-2]]:31}:" {{\[\[}}clang::lifetimebound]]" }; const OutOfLine &OutOfLine::get() const { - // CHECK: :[[@LINE-1]]:40: warning: implicit this in intra-TU function should be marked - // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:40-[[@LINE-2]]:40}:" {{\[\[}}clang::lifetimebound]]" return *this; } diff --git a/clang/test/Sema/warn-lifetime-safety-suggestions.cpp b/clang/test/Sema/warn-lifetime-safety-suggestions.cpp index 973c610eb58ab..5122e634e594f 100644 --- a/clang/test/Sema/warn-lifetime-safety-suggestions.cpp +++ b/clang/test/Sema/warn-lifetime-safety-suggestions.cpp @@ -46,8 +46,8 @@ inline View inline_header_return_view(View a) { // expected-warning {{parameter return a; // expected-note {{param returned here}} } -View redeclared_in_header(View a); -inline View redeclared_in_header(View a) { // expected-warning {{parameter in intra-TU function should be marked [[clang::lifetimebound]]}} +View redeclared_in_header(View a); // expected-warning {{parameter in intra-TU function should be marked [[clang::lifetimebound]]}} +inline View redeclared_in_header(View a) { return a; // expected-note {{param returned here}} } @@ -177,8 +177,8 @@ View reassigned_to_another_parameter( return a; // expected-note {{param returned here}} } -View intra_tu_func_redecl(View a); -View intra_tu_func_redecl(View a) { // expected-warning {{parameter in intra-TU function should be marked [[clang::lifetimebound]]}}. +View intra_tu_func_redecl(View a); // expected-warning {{parameter in intra-TU function should be marked [[clang::lifetimebound]]}}. +View intra_tu_func_redecl(View a) { return a; // expected-note {{param returned here}} } } @@ -282,25 +282,25 @@ MyObj* return_pointer_by_func(MyObj* a) { // expected-warning {{paramete } // namespace correct_order_inference namespace incorrect_order_inference_view { -View return_view_callee(View a); +View return_view_callee(View a); // expected-warning {{parameter in intra-TU function should be marked [[clang::lifetimebound]]}}. View return_view_caller(View a) { // expected-warning {{parameter in intra-TU function should be marked [[clang::lifetimebound]]}}. return return_view_callee(a); // expected-note {{param returned here}} } -View return_view_callee(View a) { // expected-warning {{parameter in intra-TU function should be marked [[clang::lifetimebound]]}}. +View return_view_callee(View a) { return a; // expected-note {{param returned here}} } } // namespace incorrect_order_inference_view namespace incorrect_order_inference_object { -MyObj* return_object_callee(MyObj* a); +MyObj* return_object_callee(MyObj* a); // expected-warning {{parameter in intra-TU function should be marked [[clang::lifetimebound]]}}. MyObj* return_object_caller(MyObj* a) { // expected-warning {{parameter in intra-TU function should be marked [[clang::lifetimebound]]}}. return return_object_callee(a); // expected-note {{param returned here}} } -MyObj* return_object_callee(MyObj* a) { // expected-warning {{parameter in intra-TU function should be marked [[clang::lifetimebound]]}}. +MyObj* return_object_callee(MyObj* a) { return a; // expected-note {{param returned here}} } } // namespace incorrect_order_inference_object @@ -322,13 +322,13 @@ View inference_top_level_return_stack_view() { } // namespace simple_annotation_inference namespace inference_in_order_with_redecls { -View inference_callee_return_identity(View a); -View inference_callee_return_identity(View a) { // expected-warning {{parameter in intra-TU function should be marked [[clang::lifetimebound]]}}. +View inference_callee_return_identity(View a); // expected-warning {{parameter in intra-TU function should be marked [[clang::lifetimebound]]}}. +View inference_callee_return_identity(View a) { return a; // expected-note {{param returned here}} } -View inference_caller_forwards_callee(View a); -View inference_caller_forwards_callee(View a) { // expected-warning {{parameter in intra-TU function should be marked [[clang::lifetimebound]]}}. +View inference_caller_forwards_callee(View a); // expected-warning {{parameter in intra-TU function should be marked [[clang::lifetimebound]]}}. +View inference_caller_forwards_callee(View a) { return inference_callee_return_identity(a); // expected-note {{param returned here}} } `````````` </details> https://github.com/llvm/llvm-project/pull/198784 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
