https://github.com/a-tarasyuk updated https://github.com/llvm/llvm-project/pull/124920
>From bd731e4be65fc9c1746aa6a8f63d206eb54bb2be Mon Sep 17 00:00:00 2001 From: Oleksandr T <oleksandr.taras...@outlook.com> Date: Wed, 29 Jan 2025 15:17:06 +0200 Subject: [PATCH 01/13] [Clang] disallow attributes on void parameters --- clang/docs/ReleaseNotes.rst | 2 ++ clang/lib/Parse/ParseDecl.cpp | 7 +++++++ clang/test/Parser/cxx0x-attributes.cpp | 9 +++++++++ 3 files changed, 18 insertions(+) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 7fafe2807bd388..0c87e52007d546 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -100,6 +100,8 @@ Removed Compiler Flags Attribute Changes in Clang -------------------------- +- Clang now disallows the use of attributes on void parameters. (#GH108819) + Improvements to Clang's diagnostics ----------------------------------- diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index f136d5007e8a5f..0b88dd4449b1e2 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -7986,6 +7986,13 @@ void Parser::ParseParameterDeclarationClause( if (getLangOpts().HLSL) MaybeParseHLSLAnnotations(DS.getAttributes()); + if (ParmDeclarator.getIdentifier() == nullptr && + ParmDeclarator.getDeclarationAttributes().size() && + ParmDeclarator.getDeclSpec().getTypeSpecType() == DeclSpec::TST_void) { + SourceRange AttrRange = ParmDeclarator.getDeclarationAttributes().Range; + Diag(AttrRange.getBegin(), diag::err_attributes_not_allowed) << AttrRange; + } + if (Tok.is(tok::kw_requires)) { // User tried to define a requires clause in a parameter declaration, // which is surely not a function declaration. diff --git a/clang/test/Parser/cxx0x-attributes.cpp b/clang/test/Parser/cxx0x-attributes.cpp index fad3010c98b9c2..13fcdd142fa841 100644 --- a/clang/test/Parser/cxx0x-attributes.cpp +++ b/clang/test/Parser/cxx0x-attributes.cpp @@ -453,3 +453,12 @@ namespace P2361 { } alignas(int) struct AlignAsAttribute {}; // expected-error {{misplaced attributes; expected attributes here}} + +namespace GH108819 { +void a([[maybe_unused]] void) {} // expected-error {{an attribute list cannot appear here}} \ + // expected-warning {{use of the 'maybe_unused' attribute is a C++17 extension}} +void b([[deprecated]] void) {} // expected-error {{an attribute list cannot appear here}} \ + // expected-warning {{use of the 'deprecated' attribute is a C++14 extension}} +void c([[clang::lifetimebound]] void) {} // expected-error {{an attribute list cannot appear here}} +void d([[clang::annotate("a", "b", 1)]] void) {} // expected-error {{an attribute list cannot appear here}} +} >From 063f76730ebfd289f5340d0d8477a43a5ea965c2 Mon Sep 17 00:00:00 2001 From: Oleksandr T <oleksandr.taras...@outlook.com> Date: Wed, 29 Jan 2025 15:54:48 +0200 Subject: [PATCH 02/13] remove unnecessary name check --- clang/lib/Parse/ParseDecl.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index 0b88dd4449b1e2..934c16c9591520 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -7986,8 +7986,7 @@ void Parser::ParseParameterDeclarationClause( if (getLangOpts().HLSL) MaybeParseHLSLAnnotations(DS.getAttributes()); - if (ParmDeclarator.getIdentifier() == nullptr && - ParmDeclarator.getDeclarationAttributes().size() && + if (ParmDeclarator.getDeclarationAttributes().size() && ParmDeclarator.getDeclSpec().getTypeSpecType() == DeclSpec::TST_void) { SourceRange AttrRange = ParmDeclarator.getDeclarationAttributes().Range; Diag(AttrRange.getBegin(), diag::err_attributes_not_allowed) << AttrRange; >From 3f3431513ad59111794953d27e64608b3ce2e6e1 Mon Sep 17 00:00:00 2001 From: Oleksandr T <oleksandr.taras...@outlook.com> Date: Wed, 29 Jan 2025 16:07:18 +0200 Subject: [PATCH 03/13] use empty instead of size --- clang/lib/Parse/ParseDecl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index 934c16c9591520..963b59565953d4 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -7986,7 +7986,7 @@ void Parser::ParseParameterDeclarationClause( if (getLangOpts().HLSL) MaybeParseHLSLAnnotations(DS.getAttributes()); - if (ParmDeclarator.getDeclarationAttributes().size() && + if (!ParmDeclarator.getDeclarationAttributes().empty() && ParmDeclarator.getDeclSpec().getTypeSpecType() == DeclSpec::TST_void) { SourceRange AttrRange = ParmDeclarator.getDeclarationAttributes().Range; Diag(AttrRange.getBegin(), diag::err_attributes_not_allowed) << AttrRange; >From 9919006df9ec32023b2bf179b72f9ebaf977bd08 Mon Sep 17 00:00:00 2001 From: Oleksandr T <oleksandr.taras...@outlook.com> Date: Thu, 30 Jan 2025 22:35:16 +0200 Subject: [PATCH 04/13] move handling of void parameter attributes to sema decl --- clang/include/clang/Basic/DiagnosticSemaKinds.td | 2 ++ clang/lib/Parse/ParseDecl.cpp | 6 ------ clang/lib/Sema/SemaDecl.cpp | 9 +++++++++ .../test/Misc/pragma-attribute-strict-subjects.c | 16 ++++++++-------- clang/test/Parser/cxx0x-attributes.cpp | 9 --------- clang/test/SemaCXX/attr-cxx0x.cpp | 11 +++++++++++ 6 files changed, 30 insertions(+), 23 deletions(-) diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index db911ed121e951..59bc932e9f2203 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -3830,6 +3830,8 @@ def warn_type_attribute_wrong_type : Warning< "'%0' only applies to %select{function|pointer|" "Objective-C object or block pointer}1 types; type here is %2">, InGroup<IgnoredAttributes>; +def warn_attribute_on_void_param: Warning< + "attribute %0 cannot be applied to a 'void' parameter">, InGroup<IgnoredAttributes>; def err_type_attribute_wrong_type : Error< warn_type_attribute_wrong_type.Summary>; def warn_incomplete_encoded_type : Warning< diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index 963b59565953d4..f136d5007e8a5f 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -7986,12 +7986,6 @@ void Parser::ParseParameterDeclarationClause( if (getLangOpts().HLSL) MaybeParseHLSLAnnotations(DS.getAttributes()); - if (!ParmDeclarator.getDeclarationAttributes().empty() && - ParmDeclarator.getDeclSpec().getTypeSpecType() == DeclSpec::TST_void) { - SourceRange AttrRange = ParmDeclarator.getDeclarationAttributes().Range; - Diag(AttrRange.getBegin(), diag::err_attributes_not_allowed) << AttrRange; - } - if (Tok.is(tok::kw_requires)) { // User tried to define a requires clause in a parameter declaration, // which is surely not a function declaration. diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 3cad9827fdab69..ac5aab92b03ae2 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -10326,6 +10326,15 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, } } + if (FTIHasSingleVoidParameter(FTI)) { + ParmVarDecl *Param = cast<ParmVarDecl>(FTI.Params[0].Param); + if (Param->hasAttrs()) { + for (const auto *A : Param->attrs()) + Diag(A->getLoc(), diag::warn_attribute_on_void_param) + << A << A->getRange(); + } + } + if (!getLangOpts().CPlusPlus) { // In C, find all the tag declarations from the prototype and move them // into the function DeclContext. Remove them from the surrounding tag diff --git a/clang/test/Misc/pragma-attribute-strict-subjects.c b/clang/test/Misc/pragma-attribute-strict-subjects.c index 807977fb252aa6..3f8b553fb5011f 100644 --- a/clang/test/Misc/pragma-attribute-strict-subjects.c +++ b/clang/test/Misc/pragma-attribute-strict-subjects.c @@ -50,8 +50,8 @@ struct testRecoverStrictnessStruct { }; #pragma clang attribute pop -#pragma clang attribute push (__attribute__((abi_tag("a"))), apply_to = any(function, record(unless(is_union)), variable, enum)) -// expected-error@-1 {{attribute 'abi_tag' cannot be applied to 'enum'}} +#pragma clang attribute push (__attribute__((abi_tag("a"))), apply_to = any(function, record(unless(is_union)), variable, enum)) // expected-warning {{attribute 'abi_tag' cannot be applied to a 'void' parameter}} + // expected-error@-1 {{attribute 'abi_tag' cannot be applied to 'enum'}} int testRecoverExtraVar = 0; // CHECK-LABEL: VarDecl{{.*}} testRecoverExtraVar @@ -90,7 +90,7 @@ struct testSubset1Struct { }; #pragma clang attribute pop -#pragma clang attribute push (__attribute__((abi_tag("a"))), apply_to = variable) +#pragma clang attribute push (__attribute__((abi_tag("a"))), apply_to = variable) // expected-warning {{attribute 'abi_tag' cannot be applied to a 'void' parameter}} int testSubset2Var; // CHECK-LABEL: VarDecl{{.*}} testSubset2Var @@ -122,7 +122,7 @@ struct testSubset3Struct { }; #pragma clang attribute pop -#pragma clang attribute push (__attribute__((abi_tag("a"))), apply_to = any(function, variable)) +#pragma clang attribute push (__attribute__((abi_tag("a"))), apply_to = any(function, variable)) // expected-warning {{attribute 'abi_tag' cannot be applied to a 'void' parameter}} int testSubset4Var; // CHECK-LABEL: VarDecl{{.*}} testSubset4Var @@ -138,7 +138,7 @@ struct testSubset4Struct { }; #pragma clang attribute pop -#pragma clang attribute push (__attribute__((abi_tag("a"))), apply_to = any(variable, record(unless(is_union)))) +#pragma clang attribute push (__attribute__((abi_tag("a"))), apply_to = any(variable, record(unless(is_union)))) // expected-warning {{attribute 'abi_tag' cannot be applied to a 'void' parameter}} int testSubset5Var; // CHECK-LABEL: VarDecl{{.*}} testSubset5Var @@ -170,7 +170,7 @@ struct testSubset6Struct { }; #pragma clang attribute pop -#pragma clang attribute push (__attribute__((abi_tag("a"))), apply_to = any(record(unless(is_union)), function, variable)) +#pragma clang attribute push (__attribute__((abi_tag("a"))), apply_to = any(record(unless(is_union)), function, variable)) // expected-warning {{attribute 'abi_tag' cannot be applied to a 'void' parameter}} int testSubset7Var; // CHECK-LABEL: VarDecl{{.*}} testSubset7Var @@ -187,8 +187,8 @@ struct testSubset7Struct { }; #pragma clang attribute pop -#pragma clang attribute push (__attribute__((abi_tag("a"))), apply_to = any(record(unless(is_union)), function, variable, enum, enum_constant)) -// expected-error@-1 {{attribute 'abi_tag' cannot be applied to 'enum_constant', and 'enum'}} +#pragma clang attribute push (__attribute__((abi_tag("a"))), apply_to = any(record(unless(is_union)), function, variable, enum, enum_constant)) // expected-warning {{attribute 'abi_tag' cannot be applied to a 'void' parameter}} + // expected-error@-1 {{attribute 'abi_tag' cannot be applied to 'enum_constant', and 'enum'}} int testSubsetRecoverVar; // CHECK-LABEL: VarDecl{{.*}} testSubsetRecoverVar diff --git a/clang/test/Parser/cxx0x-attributes.cpp b/clang/test/Parser/cxx0x-attributes.cpp index 13fcdd142fa841..fad3010c98b9c2 100644 --- a/clang/test/Parser/cxx0x-attributes.cpp +++ b/clang/test/Parser/cxx0x-attributes.cpp @@ -453,12 +453,3 @@ namespace P2361 { } alignas(int) struct AlignAsAttribute {}; // expected-error {{misplaced attributes; expected attributes here}} - -namespace GH108819 { -void a([[maybe_unused]] void) {} // expected-error {{an attribute list cannot appear here}} \ - // expected-warning {{use of the 'maybe_unused' attribute is a C++17 extension}} -void b([[deprecated]] void) {} // expected-error {{an attribute list cannot appear here}} \ - // expected-warning {{use of the 'deprecated' attribute is a C++14 extension}} -void c([[clang::lifetimebound]] void) {} // expected-error {{an attribute list cannot appear here}} -void d([[clang::annotate("a", "b", 1)]] void) {} // expected-error {{an attribute list cannot appear here}} -} diff --git a/clang/test/SemaCXX/attr-cxx0x.cpp b/clang/test/SemaCXX/attr-cxx0x.cpp index 4d64d2b0cd8c63..5c2e9f7553389e 100644 --- a/clang/test/SemaCXX/attr-cxx0x.cpp +++ b/clang/test/SemaCXX/attr-cxx0x.cpp @@ -53,3 +53,14 @@ alignas(4) auto PR19252 = 0; // Check the diagnostic message class alignas(void) AlignasVoid {}; // expected-error {{invalid application of 'alignas' to an incomplete type 'void'}} + +namespace GH108819 { +void a([[maybe_unused]] void) {} // expected-warning {{attribute 'maybe_unused' cannot be applied to a 'void' parameter}}\ + // expected-warning {{use of the 'maybe_unused' attribute is a C++17 extension}} +void b([[deprecated, maybe_unused]] void) {} // expected-warning {{attribute 'deprecated' cannot be applied to a 'void' parameter}} \ + // expected-warning {{attribute 'maybe_unused' cannot be applied to a 'void' parameter}} \ + // expected-warning {{use of the 'deprecated' attribute is a C++14 extension}} \ + // expected-warning {{use of the 'maybe_unused' attribute is a C++17 extension}} +void c([[clang::lifetimebound]] void) {} // expected-warning {{attribute 'lifetimebound' cannot be applied to a 'void' parameter}} +void d([[clang::annotate("a", "b", 1)]] void) {} // expected-warning {{attribute 'annotate' cannot be applied to a 'void' parameter}} +} >From 8abec1edd1853109e2803318461865b6bf525bee Mon Sep 17 00:00:00 2001 From: Oleksandr T <oleksandr.taras...@outlook.com> Date: Fri, 31 Jan 2025 16:02:36 +0200 Subject: [PATCH 05/13] remove useless hasAttrs condition --- clang/lib/Sema/SemaDecl.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index ac5aab92b03ae2..9d269f2e4d6583 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -10328,10 +10328,9 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, if (FTIHasSingleVoidParameter(FTI)) { ParmVarDecl *Param = cast<ParmVarDecl>(FTI.Params[0].Param); - if (Param->hasAttrs()) { - for (const auto *A : Param->attrs()) - Diag(A->getLoc(), diag::warn_attribute_on_void_param) - << A << A->getRange(); + for (const auto *A : Param->attrs()) + Diag(A->getLoc(), diag::warn_attribute_on_void_param) + << A << A->getRange(); } } >From cb11b95b9727303a12a129c28429710e4621ece6 Mon Sep 17 00:00:00 2001 From: Oleksandr T <oleksandr.taras...@outlook.com> Date: Fri, 31 Jan 2025 16:02:53 +0200 Subject: [PATCH 06/13] update release notes --- clang/docs/ReleaseNotes.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 721968d246ccae..4248d2fa2ee8fb 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -107,7 +107,7 @@ Removed Compiler Flags Attribute Changes in Clang -------------------------- -- Clang now disallows the use of attributes on void parameters. (#GH108819) +- Clang now diagnoses use of declaration attributes on void parameters. (#GH108819) Improvements to Clang's diagnostics ----------------------------------- >From 58d50217930955152954af1f2fd16f2a21bcf059 Mon Sep 17 00:00:00 2001 From: Oleksandr T <oleksandr.taras...@outlook.com> Date: Fri, 31 Jan 2025 16:03:00 +0200 Subject: [PATCH 07/13] fix formatting --- clang/include/clang/Basic/DiagnosticSemaKinds.td | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 98a12ba31539c5..7a2593a5269c6d 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -3831,7 +3831,8 @@ def warn_type_attribute_wrong_type : Warning< "Objective-C object or block pointer}1 types; type here is %2">, InGroup<IgnoredAttributes>; def warn_attribute_on_void_param: Warning< - "attribute %0 cannot be applied to a 'void' parameter">, InGroup<IgnoredAttributes>; + "attribute %0 cannot be applied to a 'void' parameter">, + InGroup<IgnoredAttributes>; def err_type_attribute_wrong_type : Error< warn_type_attribute_wrong_type.Summary>; def warn_incomplete_encoded_type : Warning< >From 8491f8724806e0a946598233683109171da586dd Mon Sep 17 00:00:00 2001 From: Oleksandr T <oleksandr.taras...@outlook.com> Date: Fri, 31 Jan 2025 16:11:15 +0200 Subject: [PATCH 08/13] fix formatting --- clang/lib/Sema/SemaDecl.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 9d269f2e4d6583..05fd6c268ae599 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -10331,7 +10331,6 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, for (const auto *A : Param->attrs()) Diag(A->getLoc(), diag::warn_attribute_on_void_param) << A << A->getRange(); - } } if (!getLangOpts().CPlusPlus) { >From 8dc35b4c2fe59be7cd76ac067032f987f46aa839 Mon Sep 17 00:00:00 2001 From: Oleksandr T <oleksandr.taras...@outlook.com> Date: Mon, 3 Feb 2025 22:15:38 +0200 Subject: [PATCH 09/13] exclude void parameters in pragma attrs push diagnostics --- clang/lib/Sema/SemaAttr.cpp | 5 +++++ .../test/Misc/pragma-attribute-strict-subjects.c | 16 ++++++++-------- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/clang/lib/Sema/SemaAttr.cpp b/clang/lib/Sema/SemaAttr.cpp index 6907fa91e28c20..778adfd0fba726 100644 --- a/clang/lib/Sema/SemaAttr.cpp +++ b/clang/lib/Sema/SemaAttr.cpp @@ -1190,6 +1190,11 @@ void Sema::ActOnPragmaAttributePop(SourceLocation PragmaLoc, void Sema::AddPragmaAttributes(Scope *S, Decl *D) { if (PragmaAttributeStack.empty()) return; + + if (ParmVarDecl *P = dyn_cast<ParmVarDecl>(D)) + if (P->getIdentifier() == nullptr && P->getType()->isVoidType()) + return; + for (auto &Group : PragmaAttributeStack) { for (auto &Entry : Group.Entries) { ParsedAttr *Attribute = Entry.Attribute; diff --git a/clang/test/Misc/pragma-attribute-strict-subjects.c b/clang/test/Misc/pragma-attribute-strict-subjects.c index 3f8b553fb5011f..807977fb252aa6 100644 --- a/clang/test/Misc/pragma-attribute-strict-subjects.c +++ b/clang/test/Misc/pragma-attribute-strict-subjects.c @@ -50,8 +50,8 @@ struct testRecoverStrictnessStruct { }; #pragma clang attribute pop -#pragma clang attribute push (__attribute__((abi_tag("a"))), apply_to = any(function, record(unless(is_union)), variable, enum)) // expected-warning {{attribute 'abi_tag' cannot be applied to a 'void' parameter}} - // expected-error@-1 {{attribute 'abi_tag' cannot be applied to 'enum'}} +#pragma clang attribute push (__attribute__((abi_tag("a"))), apply_to = any(function, record(unless(is_union)), variable, enum)) +// expected-error@-1 {{attribute 'abi_tag' cannot be applied to 'enum'}} int testRecoverExtraVar = 0; // CHECK-LABEL: VarDecl{{.*}} testRecoverExtraVar @@ -90,7 +90,7 @@ struct testSubset1Struct { }; #pragma clang attribute pop -#pragma clang attribute push (__attribute__((abi_tag("a"))), apply_to = variable) // expected-warning {{attribute 'abi_tag' cannot be applied to a 'void' parameter}} +#pragma clang attribute push (__attribute__((abi_tag("a"))), apply_to = variable) int testSubset2Var; // CHECK-LABEL: VarDecl{{.*}} testSubset2Var @@ -122,7 +122,7 @@ struct testSubset3Struct { }; #pragma clang attribute pop -#pragma clang attribute push (__attribute__((abi_tag("a"))), apply_to = any(function, variable)) // expected-warning {{attribute 'abi_tag' cannot be applied to a 'void' parameter}} +#pragma clang attribute push (__attribute__((abi_tag("a"))), apply_to = any(function, variable)) int testSubset4Var; // CHECK-LABEL: VarDecl{{.*}} testSubset4Var @@ -138,7 +138,7 @@ struct testSubset4Struct { }; #pragma clang attribute pop -#pragma clang attribute push (__attribute__((abi_tag("a"))), apply_to = any(variable, record(unless(is_union)))) // expected-warning {{attribute 'abi_tag' cannot be applied to a 'void' parameter}} +#pragma clang attribute push (__attribute__((abi_tag("a"))), apply_to = any(variable, record(unless(is_union)))) int testSubset5Var; // CHECK-LABEL: VarDecl{{.*}} testSubset5Var @@ -170,7 +170,7 @@ struct testSubset6Struct { }; #pragma clang attribute pop -#pragma clang attribute push (__attribute__((abi_tag("a"))), apply_to = any(record(unless(is_union)), function, variable)) // expected-warning {{attribute 'abi_tag' cannot be applied to a 'void' parameter}} +#pragma clang attribute push (__attribute__((abi_tag("a"))), apply_to = any(record(unless(is_union)), function, variable)) int testSubset7Var; // CHECK-LABEL: VarDecl{{.*}} testSubset7Var @@ -187,8 +187,8 @@ struct testSubset7Struct { }; #pragma clang attribute pop -#pragma clang attribute push (__attribute__((abi_tag("a"))), apply_to = any(record(unless(is_union)), function, variable, enum, enum_constant)) // expected-warning {{attribute 'abi_tag' cannot be applied to a 'void' parameter}} - // expected-error@-1 {{attribute 'abi_tag' cannot be applied to 'enum_constant', and 'enum'}} +#pragma clang attribute push (__attribute__((abi_tag("a"))), apply_to = any(record(unless(is_union)), function, variable, enum, enum_constant)) +// expected-error@-1 {{attribute 'abi_tag' cannot be applied to 'enum_constant', and 'enum'}} int testSubsetRecoverVar; // CHECK-LABEL: VarDecl{{.*}} testSubsetRecoverVar >From 54a2172f08991faea133c05532c13227b664cec4 Mon Sep 17 00:00:00 2001 From: Oleksandr T <oleksandr.taras...@outlook.com> Date: Tue, 4 Feb 2025 16:32:34 +0200 Subject: [PATCH 10/13] remove identifier check --- clang/lib/Sema/SemaAttr.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clang/lib/Sema/SemaAttr.cpp b/clang/lib/Sema/SemaAttr.cpp index 778adfd0fba726..3b49084e972378 100644 --- a/clang/lib/Sema/SemaAttr.cpp +++ b/clang/lib/Sema/SemaAttr.cpp @@ -1191,8 +1191,8 @@ void Sema::AddPragmaAttributes(Scope *S, Decl *D) { if (PragmaAttributeStack.empty()) return; - if (ParmVarDecl *P = dyn_cast<ParmVarDecl>(D)) - if (P->getIdentifier() == nullptr && P->getType()->isVoidType()) + if (const auto *P = dyn_cast<ParmVarDecl>(D)) + if (P->getType()->isVoidType()) return; for (auto &Group : PragmaAttributeStack) { >From 3a2b9d19d3be8fec4008bc01eab5acec0651d14b Mon Sep 17 00:00:00 2001 From: Oleksandr T <oleksandr.taras...@outlook.com> Date: Tue, 4 Feb 2025 16:34:25 +0200 Subject: [PATCH 11/13] use auto instead of explicit type --- clang/lib/Sema/SemaDecl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index f994fb5cb2a13f..ac4d83aefac577 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -10330,7 +10330,7 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, } if (FTIHasSingleVoidParameter(FTI)) { - ParmVarDecl *Param = cast<ParmVarDecl>(FTI.Params[0].Param); + const auto *Param = cast<ParmVarDecl>(FTI.Params[0].Param); for (const auto *A : Param->attrs()) Diag(A->getLoc(), diag::warn_attribute_on_void_param) << A << A->getRange(); >From da7d0093a4a1954ca0878d2082f4f67e750654c5 Mon Sep 17 00:00:00 2001 From: Oleksandr T <oleksandr.taras...@outlook.com> Date: Tue, 4 Feb 2025 23:25:47 +0200 Subject: [PATCH 12/13] move invalid attribute handling on void parameters to SemaType --- clang/lib/Sema/SemaDecl.cpp | 7 ------- clang/lib/Sema/SemaType.cpp | 5 +++++ 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index ac4d83aefac577..1755b37fc8f295 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -10329,13 +10329,6 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, } } - if (FTIHasSingleVoidParameter(FTI)) { - const auto *Param = cast<ParmVarDecl>(FTI.Params[0].Param); - for (const auto *A : Param->attrs()) - Diag(A->getLoc(), diag::warn_attribute_on_void_param) - << A << A->getRange(); - } - if (!getLangOpts().CPlusPlus) { // In C, find all the tag declarations from the prototype and move them // into the function DeclContext. Remove them from the surrounding tag diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index 1fa5239a597c88..f788e4bfd0d5c0 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -5183,6 +5183,11 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state, if (ParamTy.hasQualifiers()) S.Diag(DeclType.Loc, diag::err_void_param_qualified); + for (const auto *A : Param->attrs()) { + S.Diag(A->getLoc(), diag::warn_attribute_on_void_param) + << A << A->getRange(); + } + // Reject, but continue to parse 'float(this void)' as // 'float(void)'. if (Param->isExplicitObjectParameter()) { >From c77d82d9ddd4f44ae38fd5e562577c1aab9a47bc Mon Sep 17 00:00:00 2001 From: Oleksandr T <oleksandr.taras...@outlook.com> Date: Tue, 4 Feb 2025 23:26:10 +0200 Subject: [PATCH 13/13] add additional test cases --- clang/test/SemaCXX/attr-cxx0x.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/clang/test/SemaCXX/attr-cxx0x.cpp b/clang/test/SemaCXX/attr-cxx0x.cpp index 5c2e9f7553389e..58180a21ca8e97 100644 --- a/clang/test/SemaCXX/attr-cxx0x.cpp +++ b/clang/test/SemaCXX/attr-cxx0x.cpp @@ -63,4 +63,16 @@ void b([[deprecated, maybe_unused]] void) {} // expected-warning {{attribute // expected-warning {{use of the 'maybe_unused' attribute is a C++17 extension}} void c([[clang::lifetimebound]] void) {} // expected-warning {{attribute 'lifetimebound' cannot be applied to a 'void' parameter}} void d([[clang::annotate("a", "b", 1)]] void) {} // expected-warning {{attribute 'annotate' cannot be applied to a 'void' parameter}} + +struct S { + void e([[maybe_unused]] void) {} // expected-warning {{attribute 'maybe_unused' cannot be applied to a 'void' parameter}} \ + // expected-warning {{use of the 'maybe_unused' attribute is a C++17 extension}} +}; + +template <typename T> +void f([[maybe_unused]] void) {} // expected-warning {{attribute 'maybe_unused' cannot be applied to a 'void' parameter}} \ + // expected-warning {{use of the 'maybe_unused' attribute is a C++17 extension}} + +auto g = []([[maybe_unused]] void) { }; // expected-warning {{attribute 'maybe_unused' cannot be applied to a 'void' parameter}} \ + // expected-warning {{use of the 'maybe_unused' attribute is a C++17 extension}} } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits