https://github.com/MitalAshok updated https://github.com/llvm/llvm-project/pull/96113
>From 453fea9fee85aef61c449761f24b0accecf03d29 Mon Sep 17 00:00:00 2001 From: Mital Ashok <mi...@mitalashok.co.uk> Date: Wed, 19 Jun 2024 21:03:34 +0100 Subject: [PATCH] [Clang] Do not allow `[[clang::lifetimebound]]` on explicit object member functions --- clang/include/clang/Basic/DiagnosticSemaKinds.td | 5 +++-- clang/lib/Sema/SemaDecl.cpp | 11 +++++++++-- clang/test/SemaCXX/attr-lifetimebound.cpp | 3 ++- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 8a92973236ddbd..94be9c874afe97 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -10066,8 +10066,9 @@ def warn_null_ret : Warning< InGroup<NonNull>; def err_lifetimebound_no_object_param : Error< - "'lifetimebound' attribute cannot be applied; %select{static |non-}0member " - "function has no implicit object parameter">; + "'lifetimebound' attribute cannot be applied; " + "%select{non-|static |explicit object }0" + "member function has no implicit object parameter">; def err_lifetimebound_ctor_dtor : Error< "'lifetimebound' attribute cannot be applied to a " "%select{constructor|destructor}0">; diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index d19a16cf2ba150..61a465ca55c5c7 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -6938,9 +6938,16 @@ static void checkAttributesAfterMerging(Sema &S, NamedDecl &ND) { // by applying it to the function type. if (const auto *A = ATL.getAttrAs<LifetimeBoundAttr>()) { const auto *MD = dyn_cast<CXXMethodDecl>(FD); - if (!MD || MD->isStatic()) { + int NoImplicitObjectError = -1; + if (!MD) + NoImplicitObjectError = 0; + else if (MD->isStatic()) + NoImplicitObjectError = 1; + else if (MD->isExplicitObjectMemberFunction()) + NoImplicitObjectError = 2; + if (NoImplicitObjectError != -1) { S.Diag(A->getLocation(), diag::err_lifetimebound_no_object_param) - << !MD << A->getRange(); + << NoImplicitObjectError << A->getRange(); } else if (isa<CXXConstructorDecl>(MD) || isa<CXXDestructorDecl>(MD)) { S.Diag(A->getLocation(), diag::err_lifetimebound_ctor_dtor) << isa<CXXDestructorDecl>(MD) << A->getRange(); diff --git a/clang/test/SemaCXX/attr-lifetimebound.cpp b/clang/test/SemaCXX/attr-lifetimebound.cpp index 7db0a4d64d2596..f4ca840cb276f9 100644 --- a/clang/test/SemaCXX/attr-lifetimebound.cpp +++ b/clang/test/SemaCXX/attr-lifetimebound.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -std=c++2a -verify %s +// RUN: %clang_cc1 -std=c++23 -verify %s namespace usage_invalid { // FIXME: Should we diagnose a void return type? @@ -9,6 +9,7 @@ namespace usage_invalid { A() [[clang::lifetimebound]]; // expected-error {{cannot be applied to a constructor}} ~A() [[clang::lifetimebound]]; // expected-error {{cannot be applied to a destructor}} static int *static_class_member() [[clang::lifetimebound]]; // expected-error {{static member function has no implicit object parameter}} + int *explicit_object(this A&) [[clang::lifetimebound]]; // expected-error {{explicit object member function has no implicit object parameter}} int not_function [[clang::lifetimebound]]; // expected-error {{only applies to parameters and implicit object parameters}} int [[clang::lifetimebound]] also_not_function; // expected-error {{cannot be applied to types}} }; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits