https://github.com/bricknerb created https://github.com/llvm/llvm-project/pull/114203
Fixes: https://github.com/llvm/llvm-project/issues/107556 >From 82d89b8b5d1e5faebefed57f3289eb43ad9f8d65 Mon Sep 17 00:00:00 2001 From: Boaz Brickner <brick...@google.com> Date: Wed, 30 Oct 2024 11:24:07 +0100 Subject: [PATCH 1/2] [clang] Output an error when [[lifetimebound]] attribute is applied on a function implicit object parameter while the function returns void Fixes: #107556 --- clang/docs/ReleaseNotes.rst | 4 ++-- clang/include/clang/Basic/DiagnosticSemaKinds.td | 5 ++++- clang/lib/Sema/SemaDecl.cpp | 8 +++++++- clang/test/SemaCXX/attr-lifetimebound.cpp | 3 +-- 4 files changed, 14 insertions(+), 6 deletions(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 920a2369f96435..5559875c0ebb7c 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -134,8 +134,8 @@ C++ Specific Potentially Breaking Changes unsigned operator""_udl_name(unsigned long long); - Clang will now produce an error diagnostic when [[clang::lifetimebound]] is - applied on a parameter of a function that returns void. This was previously - ignored and had no effect. (#GH107556) + applied on a parameter or an implicit object parameter of a function that + returns void. This was previously ignored and had no effect. (#GH107556) .. code-block:: c++ diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 9b9bdd7c800e37..681c2757b7c76d 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -10097,9 +10097,12 @@ def err_lifetimebound_no_object_param : Error< def err_lifetimebound_ctor_dtor : Error< "'lifetimebound' attribute cannot be applied to a " "%select{constructor|destructor}0">; -def err_lifetimebound_void_return_type : Error< +def err_lifetimebound_parameter_void_return_type : Error< "'lifetimebound' attribute cannot be applied to a parameter of a function " "that returns void">; +def err_lifetimebound_implicit_object_parameter_void_return_type : Error< + "'lifetimebound' attribute cannot be applied to an implicit object " + "parameter of a function that returns void">; // CHECK: returning address/reference of stack memory def warn_ret_stack_addr_ref : Warning< diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index f8e5f3c6d309d6..c09ff4d1975e24 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -6967,6 +6967,11 @@ static void checkAttributesAfterMerging(Sema &S, NamedDecl &ND) { } else if (isa<CXXConstructorDecl>(MD) || isa<CXXDestructorDecl>(MD)) { S.Diag(A->getLocation(), diag::err_lifetimebound_ctor_dtor) << isa<CXXDestructorDecl>(MD) << A->getRange(); + } else if (FD->getReturnType()->isVoidType()) { + S.Diag( + FD->getLocation(), + diag:: + err_lifetimebound_implicit_object_parameter_void_return_type); } } } @@ -6978,7 +6983,8 @@ static void checkAttributesAfterMerging(Sema &S, NamedDecl &ND) { // only if the function returns a value. if (auto *A = P->getAttr<LifetimeBoundAttr>()) { if (!isa<CXXConstructorDecl>(FD) && FD->getReturnType()->isVoidType()) { - S.Diag(A->getLocation(), diag::err_lifetimebound_void_return_type); + S.Diag(A->getLocation(), + diag::err_lifetimebound_parameter_void_return_type); } } } diff --git a/clang/test/SemaCXX/attr-lifetimebound.cpp b/clang/test/SemaCXX/attr-lifetimebound.cpp index 804d61fb62ca40..81e9193cf76a04 100644 --- a/clang/test/SemaCXX/attr-lifetimebound.cpp +++ b/clang/test/SemaCXX/attr-lifetimebound.cpp @@ -11,8 +11,7 @@ namespace usage_invalid { 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}} - // FIXME: Should diagnose a void return type. - void void_return_member() [[clang::lifetimebound]]; + void void_return_member() [[clang::lifetimebound]]; // expected-error {{'lifetimebound' attribute cannot be applied to an implicit object parameter of a function that returns void}} }; int *attr_with_param(int ¶m [[clang::lifetimebound(42)]]); // expected-error {{takes no arguments}} } >From ae34279079f482c22eaa6c128c7e4df96ae11f5d Mon Sep 17 00:00:00 2001 From: Boaz Brickner <brick...@google.com> Date: Wed, 30 Oct 2024 11:24:07 +0100 Subject: [PATCH 2/2] [clang] Output an error when [[lifetimebound]] attribute is applied on a function implicit object parameter while the function returns void Fixes: #107556 --- clang/docs/ReleaseNotes.rst | 4 ++-- clang/include/clang/Basic/DiagnosticSemaKinds.td | 5 ++++- clang/lib/Sema/SemaDecl.cpp | 8 +++++++- clang/test/SemaCXX/attr-lifetimebound.cpp | 3 +-- 4 files changed, 14 insertions(+), 6 deletions(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 6085352dfafe6b..61fc2ff5a9aeed 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -140,8 +140,8 @@ C++ Specific Potentially Breaking Changes unsigned operator""_udl_name(unsigned long long); - Clang will now produce an error diagnostic when [[clang::lifetimebound]] is - applied on a parameter of a function that returns void. This was previously - ignored and had no effect. (#GH107556) + applied on a parameter or an implicit object parameter of a function that + returns void. This was previously ignored and had no effect. (#GH107556) .. code-block:: c++ diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 34ff49d7238a7f..3168337acb621f 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -10101,9 +10101,12 @@ def err_lifetimebound_no_object_param : Error< def err_lifetimebound_ctor_dtor : Error< "'lifetimebound' attribute cannot be applied to a " "%select{constructor|destructor}0">; -def err_lifetimebound_void_return_type : Error< +def err_lifetimebound_parameter_void_return_type : Error< "'lifetimebound' attribute cannot be applied to a parameter of a function " "that returns void">; +def err_lifetimebound_implicit_object_parameter_void_return_type : Error< + "'lifetimebound' attribute cannot be applied to an implicit object " + "parameter of a function that returns void">; // CHECK: returning address/reference of stack memory def warn_ret_stack_addr_ref : Warning< diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index f8e5f3c6d309d6..c09ff4d1975e24 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -6967,6 +6967,11 @@ static void checkAttributesAfterMerging(Sema &S, NamedDecl &ND) { } else if (isa<CXXConstructorDecl>(MD) || isa<CXXDestructorDecl>(MD)) { S.Diag(A->getLocation(), diag::err_lifetimebound_ctor_dtor) << isa<CXXDestructorDecl>(MD) << A->getRange(); + } else if (FD->getReturnType()->isVoidType()) { + S.Diag( + FD->getLocation(), + diag:: + err_lifetimebound_implicit_object_parameter_void_return_type); } } } @@ -6978,7 +6983,8 @@ static void checkAttributesAfterMerging(Sema &S, NamedDecl &ND) { // only if the function returns a value. if (auto *A = P->getAttr<LifetimeBoundAttr>()) { if (!isa<CXXConstructorDecl>(FD) && FD->getReturnType()->isVoidType()) { - S.Diag(A->getLocation(), diag::err_lifetimebound_void_return_type); + S.Diag(A->getLocation(), + diag::err_lifetimebound_parameter_void_return_type); } } } diff --git a/clang/test/SemaCXX/attr-lifetimebound.cpp b/clang/test/SemaCXX/attr-lifetimebound.cpp index 804d61fb62ca40..81e9193cf76a04 100644 --- a/clang/test/SemaCXX/attr-lifetimebound.cpp +++ b/clang/test/SemaCXX/attr-lifetimebound.cpp @@ -11,8 +11,7 @@ namespace usage_invalid { 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}} - // FIXME: Should diagnose a void return type. - void void_return_member() [[clang::lifetimebound]]; + void void_return_member() [[clang::lifetimebound]]; // expected-error {{'lifetimebound' attribute cannot be applied to an implicit object parameter of a function that returns void}} }; int *attr_with_param(int ¶m [[clang::lifetimebound(42)]]); // expected-error {{takes no arguments}} } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits