[clang] bcbe9d6 - [Clang] Do not allow `[[clang::lifetimebound]]` on explicit object member functions (#96113)
via cfe-commits
cfe-commits at lists.llvm.org
Sun Aug 18 09:07:51 PDT 2024
Author: Mital Ashok
Date: 2024-08-18T18:07:47+02:00
New Revision: bcbe9d6c776bc02bfe8f911607240af0d1775d79
URL: https://github.com/llvm/llvm-project/commit/bcbe9d6c776bc02bfe8f911607240af0d1775d79
DIFF: https://github.com/llvm/llvm-project/commit/bcbe9d6c776bc02bfe8f911607240af0d1775d79.diff
LOG: [Clang] Do not allow `[[clang::lifetimebound]]` on explicit object member functions (#96113)
Previously, `[[clang::lifetimebound]]` applied to an explicit object
member function did nothing and was silently ignored.
Now issue the error diagnostic `'lifetimebound' attribute cannot be
applied; explicit object member function has no implicit object
parameter`
Added:
Modified:
clang/docs/ReleaseNotes.rst
clang/include/clang/Basic/DiagnosticSemaKinds.td
clang/lib/Sema/SemaDecl.cpp
clang/test/SemaCXX/attr-lifetimebound.cpp
Removed:
################################################################################
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index a4257ea1f48c11..b78c0229de4898 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -193,6 +193,9 @@ Attribute Changes in Clang
- The ``hybrid_patchable`` attribute is now supported on ARM64EC targets. It can be used to specify
that a function requires an additional x86-64 thunk, which may be patched at runtime.
+- ``[[clang::lifetimebound]]`` is now explicitly disallowed on explicit object member functions
+ where they were previously silently ignored.
+
Improvements to Clang's diagnostics
-----------------------------------
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 9c15b5fa571a39..503e93f9257137 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -6939,9 +6939,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}}
};
More information about the cfe-commits
mailing list