[clang] [CLANG] Enable alignas after GNU attributes (PR #133107)
via cfe-commits
cfe-commits at lists.llvm.org
Wed Apr 9 02:27:17 PDT 2025
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 <dengzmm at 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 <dengzmm at 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 <dengzmm at 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 <dengzmm at 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 <dengzmm at 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 <dengzmm at 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}}
More information about the cfe-commits
mailing list