https://github.com/DenisGZM updated https://github.com/llvm/llvm-project/pull/133107
>From c46eda67cd7434dcce5c1f29125a940dc4ff64ba Mon Sep 17 00:00:00 2001 From: Denis Gerasimov <deng...@gmail.com> Date: Wed, 26 Mar 2025 18:29:38 +0300 Subject: [PATCH 1/6] [CLANG] Enable alignas after GNU attributes --- clang/lib/Parse/ParseStmt.cpp | 5 +++++ clang/test/SemaCUDA/cuda-attr-order.cu | 15 +++++++++++++++ 2 files changed, 20 insertions(+) create mode 100644 clang/test/SemaCUDA/cuda-attr-order.cu diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp index 150b2879fc94f..33b9f63bcfa08 100644 --- a/clang/lib/Parse/ParseStmt.cpp +++ b/clang/lib/Parse/ParseStmt.cpp @@ -296,6 +296,11 @@ StmtResult Parser::ParseStatementOrDeclarationAfterAttributes( goto Retry; } + case tok::kw_alignas: { + ParseAlignmentSpecifier(CXX11Attrs); + goto Retry; + } + case tok::kw_template: { SourceLocation DeclEnd; ParseTemplateDeclarationOrSpecialization(DeclaratorContext::Block, DeclEnd, diff --git a/clang/test/SemaCUDA/cuda-attr-order.cu b/clang/test/SemaCUDA/cuda-attr-order.cu new file mode 100644 index 0000000000000..d3bf5b014d1c6 --- /dev/null +++ b/clang/test/SemaCUDA/cuda-attr-order.cu @@ -0,0 +1,15 @@ +// Verify that we can parse a simple CUDA file with different attributes order. +// RUN: %clang_cc1 "-triple" "nvptx-nvidia-cuda" -fsyntax-only -verify %s +// expected-no-diagnostics +#include "Inputs/cuda.h" + +struct alignas(16) float4 { + float x, y, z, w; +}; + +__attribute__((device)) float func() { + __shared__ alignas(alignof(float4)) float As[4][4]; // Both combinations + alignas(alignof(float4)) __shared__ float Bs[4][4]; // must be legal + + return As[0][0] + Bs[0][0]; +} >From 517ba9e99f06c23ec675f5bf808b84273f5b409d Mon Sep 17 00:00:00 2001 From: Denis Gerasimov <deng...@gmail.com> Date: Fri, 28 Mar 2025 18:27:49 +0300 Subject: [PATCH 2/6] [CLANG] Enable cxx11 attributes after gnu attributes in ParseCXXClassMemberDeclaration --- clang/lib/Parse/ParseDeclCXX.cpp | 7 +++++-- clang/test/AST/ast-dump-color.cpp | 2 +- clang/test/Index/annotate-attribute.cpp | 2 +- clang/test/Parser/cxx0x-attributes.cpp | 6 ++++++ clang/test/SemaCXX/warn-thread-safety-analysis.cpp | 8 ++++---- 5 files changed, 17 insertions(+), 8 deletions(-) diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp index 51fe0663a8d1a..42db9ceb89a2b 100644 --- a/clang/lib/Parse/ParseDeclCXX.cpp +++ b/clang/lib/Parse/ParseDeclCXX.cpp @@ -3035,10 +3035,13 @@ Parser::DeclGroupPtrTy Parser::ParseCXXClassMemberDeclaration( } ParsedAttributes DeclSpecAttrs(AttrFactory); - MaybeParseMicrosoftAttributes(DeclSpecAttrs); - // Hold late-parsed attributes so we can attach a Decl to them later. LateParsedAttrList CommonLateParsedAttrs; + while (MaybeParseCXX11Attributes(DeclAttrs) || + MaybeParseGNUAttributes(DeclSpecAttrs, &CommonLateParsedAttrs)) { + } + + MaybeParseMicrosoftAttributes(DeclSpecAttrs); // decl-specifier-seq: // Parse the common declaration-specifiers piece. diff --git a/clang/test/AST/ast-dump-color.cpp b/clang/test/AST/ast-dump-color.cpp index 87797f6bffc5b..2bd9ab7c3c841 100644 --- a/clang/test/AST/ast-dump-color.cpp +++ b/clang/test/AST/ast-dump-color.cpp @@ -91,7 +91,7 @@ struct Invalid { //CHECK: {{^}}[[Blue]]| `-[[RESET]][[MAGENTA]]DeclRefExpr[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:40[[RESET]]> [[Green]]'class Mutex':'Mutex'[[RESET]][[Cyan]] lvalue[[RESET]][[Cyan]][[RESET]] [[GREEN]]Var[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]][[CYAN]] 'mu1'[[RESET]] [[Green]]'class Mutex':'Mutex'[[RESET]] non_odr_use_unevaluated{{$}} //CHECK: {{^}}[[Blue]]|-[[RESET]][[GREEN]]CXXRecordDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:28:1[[RESET]], [[Yellow]]line:30:1[[RESET]]> [[Yellow]]line:28:8[[RESET]] struct[[CYAN]] Invalid[[RESET]] definition //CHECK: {{^}}[[Blue]]| |-[[RESET]][[GREEN]]CXXRecordDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:1[[RESET]], [[Yellow]]col:8[[RESET]]> [[Yellow]]col:8[[RESET]] implicit referenced struct[[CYAN]] Invalid[[RESET]] -//CHECK: {{^}}[[Blue]]| |-[[RESET]][[GREEN]]CXXConstructorDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:29:3[[RESET]], [[Yellow]]col:42[[RESET]]> [[Yellow]]col:29[[RESET]] invalid[[CYAN]] Invalid[[RESET]] [[Green]]'void (int)'[[RESET]] +//CHECK: {{^}}[[Blue]]| |-[[RESET]][[GREEN]]CXXConstructorDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:29:29[[RESET]], [[Yellow]]col:42[[RESET]]> [[Yellow]]col:29[[RESET]] invalid[[CYAN]] Invalid[[RESET]] [[Green]]'void (int)'[[RESET]] //CHECK: {{^}}[[Blue]]| | |-[[RESET]][[GREEN]]ParmVarDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:37[[RESET]], [[Yellow]]<invalid sloc>[[RESET]]> [[Yellow]]col:42[[RESET]] invalid [[Green]]'int'[[RESET]] //CHECK: {{^}}[[Blue]]| | `-[[RESET]][[BLUE]]NoInlineAttr[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:18[[RESET]]> //CHECK: {{^}}[[Blue]]| |-[[RESET]][[GREEN]]CXXConstructorDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:28:8[[RESET]]> [[Yellow]]col:8[[RESET]] implicit used constexpr[[CYAN]] Invalid[[RESET]] [[Green]]'void () noexcept'[[RESET]] inline diff --git a/clang/test/Index/annotate-attribute.cpp b/clang/test/Index/annotate-attribute.cpp index bf415fc8fe64d..6b5b0f1eab7d4 100644 --- a/clang/test/Index/annotate-attribute.cpp +++ b/clang/test/Index/annotate-attribute.cpp @@ -24,7 +24,7 @@ int templateFunction(T value) __attribute__((annotate("works"))); // CHECK: ClassDecl=Test:3:7 (Definition) Extent=[3:1 - 17:2] // CHECK-NEXT: CXXAccessSpecifier=:4:1 (Definition) Extent=[4:1 - 4:8] -// CHECK-NEXT: CXXMethod=aMethod:5:51 Extent=[5:3 - 5:60] +// CHECK-NEXT: CXXMethod=aMethod:5:51 Extent=[5:46 - 5:60] // CHECK-NEXT: attribute(annotate)=spiffy_method Extent=[5:18 - 5:43] // CHECK-NEXT: CXXAccessSpecifier=:7:1 (Definition) Extent=[7:1 - 7:43] // CHECK-NEXT: attribute(annotate)=works Extent=[7:23 - 7:40] diff --git a/clang/test/Parser/cxx0x-attributes.cpp b/clang/test/Parser/cxx0x-attributes.cpp index fad3010c98b9c..0ff5afa43b8a6 100644 --- a/clang/test/Parser/cxx0x-attributes.cpp +++ b/clang/test/Parser/cxx0x-attributes.cpp @@ -71,6 +71,12 @@ namespace test_misplacement { [[]] union union_attr2; //expected-error{{misplaced attributes}} [[]] enum E2 { }; //expected-error{{misplaced attributes}} } +struct S1 { __attribute__((deprecated)) alignas(16) int x; }; // expected-none +class C1 { __attribute__((deprecated)) alignas(16) int x; }; // expected-none + +void fn_with_decl() { + __attribute__((deprecated)) alignas(16) int x; // expected-none +} // Checks attributes placed at wrong syntactic locations of class specifiers. class [[]] [[]] diff --git a/clang/test/SemaCXX/warn-thread-safety-analysis.cpp b/clang/test/SemaCXX/warn-thread-safety-analysis.cpp index ac3ca5e0c12a8..ed7821b2affe4 100644 --- a/clang/test/SemaCXX/warn-thread-safety-analysis.cpp +++ b/clang/test/SemaCXX/warn-thread-safety-analysis.cpp @@ -2434,10 +2434,10 @@ class Foo { namespace WarnNoDecl { class Foo { - void foo(int a); __attribute__(( // \ - // expected-warning {{declaration does not declare anything}} - exclusive_locks_required(a))); // \ - // expected-warning {{attribute exclusive_locks_required ignored}} + void foo(int a); __attribute__(( + exclusive_locks_required(a))); // expected-warning {{declaration does not declare anything}} \ + // expected-warning {{attribute exclusive_locks_required ignored}} + }; } // end namespace WarnNoDecl >From 2b0665871eb8a87f481766fd399db1dfc1af7a38 Mon Sep 17 00:00:00 2001 From: Denis Gerasimov <deng...@gmail.com> Date: Fri, 4 Apr 2025 12:37:08 +0300 Subject: [PATCH 3/6] [CLANG] Move microsoft attrs into loop --- clang/include/clang/Parse/Parser.h | 5 ++++- clang/lib/Parse/ParseDeclCXX.cpp | 6 +++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h index c8ceef8f8987d..fed7879ba7c8d 100644 --- a/clang/include/clang/Parse/Parser.h +++ b/clang/include/clang/Parse/Parser.h @@ -3056,13 +3056,16 @@ class Parser : public CodeCompletionHandler { bool CouldBeBitField = false); Decl *ParseHLSLBuffer(SourceLocation &DeclEnd); - void MaybeParseMicrosoftAttributes(ParsedAttributes &Attrs) { + bool MaybeParseMicrosoftAttributes(ParsedAttributes &Attrs) { + bool AttrsParsed = false; if ((getLangOpts().MicrosoftExt || getLangOpts().HLSL) && Tok.is(tok::l_square)) { ParsedAttributes AttrsWithRange(AttrFactory); ParseMicrosoftAttributes(AttrsWithRange); + AttrsParsed = AttrsWithRange.size(); Attrs.takeAllFrom(AttrsWithRange); } + return AttrsParsed; } void ParseMicrosoftUuidAttributeArgs(ParsedAttributes &Attrs); void ParseMicrosoftAttributes(ParsedAttributes &Attrs); diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp index 42db9ceb89a2b..b46c1411ed777 100644 --- a/clang/lib/Parse/ParseDeclCXX.cpp +++ b/clang/lib/Parse/ParseDeclCXX.cpp @@ -3037,12 +3037,12 @@ Parser::DeclGroupPtrTy Parser::ParseCXXClassMemberDeclaration( ParsedAttributes DeclSpecAttrs(AttrFactory); // Hold late-parsed attributes so we can attach a Decl to them later. LateParsedAttrList CommonLateParsedAttrs; + while (MaybeParseCXX11Attributes(DeclAttrs) || - MaybeParseGNUAttributes(DeclSpecAttrs, &CommonLateParsedAttrs)) { + MaybeParseGNUAttributes(DeclSpecAttrs, &CommonLateParsedAttrs) || + MaybeParseMicrosoftAttributes(DeclSpecAttrs)) { } - MaybeParseMicrosoftAttributes(DeclSpecAttrs); - // decl-specifier-seq: // Parse the common declaration-specifiers piece. ParsingDeclSpec DS(*this, TemplateDiags); >From 04415ee7292d0853fc4848e14752a6cc7b57250a Mon Sep 17 00:00:00 2001 From: Denis Gerasimov <deng...@gmail.com> Date: Tue, 8 Apr 2025 21:23:00 +0300 Subject: [PATCH 4/6] [CLANG] Arbitrary attribute order --- clang/docs/ReleaseNotes.rst | 1 + clang/lib/Parse/ParseDeclCXX.cpp | 4 ++-- clang/lib/Parse/ParseStmt.cpp | 9 ++++----- clang/test/Parser/c2x-alignas.c | 23 +++++++++++++++++++++++ clang/test/Parser/cxx0x-attributes.cpp | 19 ++++++++++++++++--- 5 files changed, 46 insertions(+), 10 deletions(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 04ec2cfef679c..7c1b587e63d3a 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -364,6 +364,7 @@ Bug Fixes to C++ Support and the ``[[maybe_unused]]`` attribute is not applied. (#GH125810) - Clang now issues an error when placement new is used to modify a const-qualified variable in a ``constexpr`` function. (#GH131432) +- Clang now correctly parses arbitrary order of ``[[]]``, ``__attribute__`` and ``alignas`` attributes for declarations (#GH133107) Bug Fixes to AST Handling ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp index b46c1411ed777..8fe149b375d25 100644 --- a/clang/lib/Parse/ParseDeclCXX.cpp +++ b/clang/lib/Parse/ParseDeclCXX.cpp @@ -3040,8 +3040,8 @@ Parser::DeclGroupPtrTy Parser::ParseCXXClassMemberDeclaration( while (MaybeParseCXX11Attributes(DeclAttrs) || MaybeParseGNUAttributes(DeclSpecAttrs, &CommonLateParsedAttrs) || - MaybeParseMicrosoftAttributes(DeclSpecAttrs)) { - } + MaybeParseMicrosoftAttributes(DeclSpecAttrs)) + ; // decl-specifier-seq: // Parse the common declaration-specifiers piece. diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp index 33b9f63bcfa08..317220221018d 100644 --- a/clang/lib/Parse/ParseStmt.cpp +++ b/clang/lib/Parse/ParseStmt.cpp @@ -235,6 +235,10 @@ StmtResult Parser::ParseStatementOrDeclarationAfterAttributes( } default: { + if (getLangOpts().CPlusPlus && + MaybeParseCXX11Attributes(CXX11Attrs, true)) + goto Retry; + bool HaveAttrs = !CXX11Attrs.empty() || !GNUAttrs.empty(); auto IsStmtAttr = [](ParsedAttr &Attr) { return Attr.isStmtAttr(); }; bool AllAttrsAreStmtAttrs = llvm::all_of(CXX11Attrs, IsStmtAttr) && @@ -296,11 +300,6 @@ StmtResult Parser::ParseStatementOrDeclarationAfterAttributes( goto Retry; } - case tok::kw_alignas: { - ParseAlignmentSpecifier(CXX11Attrs); - goto Retry; - } - case tok::kw_template: { SourceLocation DeclEnd; ParseTemplateDeclarationOrSpecialization(DeclaratorContext::Block, DeclEnd, diff --git a/clang/test/Parser/c2x-alignas.c b/clang/test/Parser/c2x-alignas.c index 1658cb1c74496..9aac21a52c57a 100644 --- a/clang/test/Parser/c2x-alignas.c +++ b/clang/test/Parser/c2x-alignas.c @@ -2,3 +2,26 @@ _Alignas(int) struct c1; // expected-warning {{'_Alignas' attribute ignored}} alignas(int) struct c1; // expected-warning {{'alignas' attribute ignored}} + + +__attribute__(()) [[]] alignas(int) int a; // expected-none TODO: actually this line should be an error +__attribute__(()) alignas(int) [[]] int b; // expected-error {{an attribute list cannot appear here}} +__attribute__(()) alignas(int) int c; // expected-none +[[]] __attribute__(()) alignas(int) int d; // expected-none +alignas(int) [[]] __attribute__(()) int e; // expected-error {{an attribute list cannot appear here}} + +struct C1 { + __attribute__(()) [[]] alignas(int) int a; // expected-error {{an attribute list cannot appear here}} + __attribute__(()) alignas(int) [[]] int b; // expected-error {{an attribute list cannot appear here}} + __attribute__(()) alignas(int) int c; // expected-none + [[]] __attribute__(()) alignas(int) int d; // expected-none + alignas(int) [[]] __attribute__(()) int e; // expected-error {{an attribute list cannot appear here}} +}; + +void fn_with_decl() { + __attribute__(()) [[]] alignas(int) int a; // expected-error {{an attribute list cannot appear here}} + __attribute__(()) alignas(int) [[]] int b; // expected-error {{an attribute list cannot appear here}} + __attribute__(()) alignas(int) int c; // expected-none + [[]] __attribute__(()) alignas(int) int d; // expected-none + alignas(int) [[]] __attribute__(()) int e; // expected-error {{an attribute list cannot appear here}} +} \ No newline at end of file diff --git a/clang/test/Parser/cxx0x-attributes.cpp b/clang/test/Parser/cxx0x-attributes.cpp index 0ff5afa43b8a6..598f990122fcc 100644 --- a/clang/test/Parser/cxx0x-attributes.cpp +++ b/clang/test/Parser/cxx0x-attributes.cpp @@ -71,11 +71,24 @@ namespace test_misplacement { [[]] union union_attr2; //expected-error{{misplaced attributes}} [[]] enum E2 { }; //expected-error{{misplaced attributes}} } -struct S1 { __attribute__((deprecated)) alignas(16) int x; }; // expected-none -class C1 { __attribute__((deprecated)) alignas(16) int x; }; // expected-none + +__attribute__(()) [[]] alignas(int) int xx; // expected-none +__attribute__(()) alignas(int) [[]] int yy; // expected-none +[[]] __attribute__(()) alignas(int) int zz; // expected-none +alignas(int) [[]] __attribute__(()) int aa; // expected-none + +class C1 { + __attribute__(()) [[]] alignas(int) int x; // expected-none + __attribute__(()) alignas(int) [[]] int y; // expected-none + [[]] __attribute__(()) alignas(int) int z; // expected-none + alignas(int) [[]] __attribute__(()) int a; // expected-none +}; void fn_with_decl() { - __attribute__((deprecated)) alignas(16) int x; // expected-none + __attribute__(()) alignas(int) int x; // expected-none + __attribute__(()) alignas(int) [[]] int y; // expected-none + [[]] __attribute__(()) alignas(int) int z; // expected-none + alignas(int) [[]] __attribute__(()) int a; // expected-none } // Checks attributes placed at wrong syntactic locations of class specifiers. >From 4d0a4f0abe12d73ffef6f568d15e0a2ea3459892 Mon Sep 17 00:00:00 2001 From: Denis Gerasimov <deng...@gmail.com> Date: Tue, 8 Apr 2025 23:37:00 +0300 Subject: [PATCH 5/6] Style fix --- clang/lib/Parse/ParseStmt.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp index 5cfe06e2bf5bd..64d184695e981 100644 --- a/clang/lib/Parse/ParseStmt.cpp +++ b/clang/lib/Parse/ParseStmt.cpp @@ -235,8 +235,7 @@ StmtResult Parser::ParseStatementOrDeclarationAfterAttributes( } default: { - if (getLangOpts().CPlusPlus && - MaybeParseCXX11Attributes(CXX11Attrs, true)) + if (getLangOpts().CPlusPlus && MaybeParseCXX11Attributes(CXX11Attrs, true)) goto Retry; bool HaveAttrs = !CXX11Attrs.empty() || !GNUAttrs.empty(); >From e517ff644d0d99425e973be087b68530d077ca4b Mon Sep 17 00:00:00 2001 From: Denis Gerasimov <deng...@gmail.com> Date: Wed, 9 Apr 2025 12:05:46 +0300 Subject: [PATCH 6/6] [CLANG] Added more tests, removed range assert --- clang/lib/Parse/ParseStmt.cpp | 10 +++++----- clang/test/Parser/cxx0x-attributes.cpp | 11 ++++++++--- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp index 64d184695e981..1fc9d34a8ca27 100644 --- a/clang/lib/Parse/ParseStmt.cpp +++ b/clang/lib/Parse/ParseStmt.cpp @@ -263,11 +263,11 @@ StmtResult Parser::ParseStatementOrDeclarationAfterAttributes( GNUAttrs); } if (CXX11Attrs.Range.getBegin().isValid()) { - // The caller must guarantee that the CXX11Attrs appear before the - // GNUAttrs, and we rely on that here. - assert(GNUAttrs.Range.getBegin().isInvalid() || - GNUAttrs.Range.getBegin() > CXX11Attrs.Range.getBegin()); - DeclStart = CXX11Attrs.Range.getBegin(); + // Order of C++11 and GNU attributes is may be arbitrary. + DeclStart = GNUAttrs.Range.getBegin().isInvalid() + ? CXX11Attrs.Range.getBegin() + : std::min(CXX11Attrs.Range.getBegin(), + GNUAttrs.Range.getBegin()); } else if (GNUAttrs.Range.getBegin().isValid()) DeclStart = GNUAttrs.Range.getBegin(); return Actions.ActOnDeclStmt(Decl, DeclStart, DeclEnd); diff --git a/clang/test/Parser/cxx0x-attributes.cpp b/clang/test/Parser/cxx0x-attributes.cpp index 598f990122fcc..c01adaccbd6b5 100644 --- a/clang/test/Parser/cxx0x-attributes.cpp +++ b/clang/test/Parser/cxx0x-attributes.cpp @@ -72,16 +72,20 @@ namespace test_misplacement { [[]] enum E2 { }; //expected-error{{misplaced attributes}} } -__attribute__(()) [[]] alignas(int) int xx; // expected-none +__attribute__(()) alignas(int) int xx; // expected-none __attribute__(()) alignas(int) [[]] int yy; // expected-none [[]] __attribute__(()) alignas(int) int zz; // expected-none alignas(int) [[]] __attribute__(()) int aa; // expected-none +[[]] alignas(int) __attribute__(()) int bb; // expected-none +__attribute__(()) [[]] alignas(int) int cc; // expected-none class C1 { - __attribute__(()) [[]] alignas(int) int x; // expected-none + __attribute__(()) alignas(int) int x; // expected-none __attribute__(()) alignas(int) [[]] int y; // expected-none [[]] __attribute__(()) alignas(int) int z; // expected-none alignas(int) [[]] __attribute__(()) int a; // expected-none + [[]] alignas(int) __attribute__(()) int b; // expected-none + __attribute__(()) [[]] alignas(int) int c; // expected-none }; void fn_with_decl() { @@ -89,8 +93,9 @@ void fn_with_decl() { __attribute__(()) alignas(int) [[]] int y; // expected-none [[]] __attribute__(()) alignas(int) int z; // expected-none alignas(int) [[]] __attribute__(()) int a; // expected-none + [[]] alignas(int) __attribute__(()) int b; // expected-none + __attribute__(()) [[]] alignas(int) int c; // expected-none } - // Checks attributes placed at wrong syntactic locations of class specifiers. class [[]] [[]] attr_after_class_name_decl [[]] [[]]; // expected-error {{an attribute list cannot appear here}} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits