1 // RUN: %clang_cc1 -fsyntax-only -fdouble-square-bracket-attributes -verify %s
2 // RUN: %clang_cc1 -fsyntax-only -std=gnu2x -verify %s
3 
4 enum [[]] E {
5   One [[]],
6   Two,
7   Three [[]]
8 };
9 
10 enum [[]] { Four };
11 [[]] enum E2 { Five }; // expected-error {{misplaced attributes}}
12 
13 // FIXME: this diagnostic can be improved.
14 enum { [[]] Six }; // expected-error {{expected identifier}}
15 
16 // FIXME: this diagnostic can be improved.
17 enum E3 [[]] { Seven }; // expected-error {{expected identifier or '('}}
18 
19 struct [[]] S1 {
20   int i [[]];
21   int [[]] j;
22   int k[10] [[]];
23   int l[[]][10];
24   [[]] int m, n;
25   int o [[]] : 12;
26   int [[]] : 0; // OK, attribute applies to the type.
27   int p, [[]] : 0; // expected-error {{an attribute list cannot appear here}}
28   int q, [[]] r; // expected-error {{an attribute list cannot appear here}}
29 };
30 
31 [[]] struct S2 { int a; }; // expected-error {{misplaced attributes}}
32 struct S3 [[]] { int a; }; // expected-error {{an attribute list cannot appear here}}
33 
34 union [[]] U {
35   double d [[]];
36   [[]] int i;
37 };
38 
39 [[]] union U2 { double d; }; // expected-error {{misplaced attributes}}
40 union U3 [[]] { double d; }; // expected-error {{an attribute list cannot appear here}}
41 
42 struct [[]] IncompleteStruct;
43 union [[]] IncompleteUnion;
44 enum [[]] IncompleteEnum;
45 enum __attribute__((deprecated)) IncompleteEnum2;
46 
47 [[]] void f1(void);
48 void [[]] f2(void);
49 void f3 [[]] (void);
50 void f4(void) [[]];
51 
52 void f5(int i [[]], [[]] int j, int [[]] k);
53 
f6(a,b)54 void f6(a, b) [[]] int a; int b; { // expected-error {{an attribute list cannot appear here}}
55 }
56 
57 // FIXME: technically, an attribute list cannot appear here, but we currently
58 // parse it as part of the return type of the function, which is reasonable
59 // behavior given that we *don't* want to parse it as part of the K&R parameter
60 // declarations. It is disallowed to avoid a parsing ambiguity we already
61 // handle well.
62 int (*f7(a, b))(int, int) [[]] int a; int b; {
63   return 0;
64 }
65 
66 [[]] int a, b;
67 int c [[]], d [[]];
68 
f8(void)69 void f8(void) [[]] {
70   [[]] int i, j;
71   int k, l [[]];
72 }
73 
f9(void)74 [[]] void f9(void) {
75   int i[10] [[]];
76   int (*fp1)(void)[[]];
77   int (*fp2 [[]])(void);
78 
79   int * [[]] *ipp;
80 }
81 
82 void f10(int j[static 10] [[]], int k[*] [[]]);
83 
f11(void)84 void f11(void) {
85   [[]] {}
86   [[]] if (1) {}
87 
88   [[]] switch (1) {
89   [[]] case 1: [[]] break;
90   [[]] default: break;
91   }
92 
93   goto foo;
94   [[]] foo: (void)1;
95 
96   [[]] for (;;);
97   [[]] while (1);
98   [[]] do [[]] { } while(1);
99 
100   [[]] (void)1;
101 
102   [[]];
103 
104   (void)sizeof(int [4][[]]);
105   (void)sizeof(struct [[]] S3 { int a [[]]; });
106 
107   [[]] return;
108 }
109 
110 [[attr]] void f12(void); // expected-warning {{unknown attribute 'attr' ignored}}
111 [[vendor::attr]] void f13(void); // expected-warning {{unknown attribute 'attr' ignored}}
112 
113 // Ensure that asm statements properly handle double colons.
test_asm(void)114 void test_asm(void) {
115   asm("ret" :::);
116   asm("foo" :: "r" (xx)); // expected-error {{use of undeclared identifier 'xx'}}
117 }
118 
119 // Do not allow 'using' to introduce vendor attribute namespaces.
120 [[using vendor: attr1, attr2]] void f14(void); // expected-error {{expected ']'}} \
121                                                // expected-warning {{unknown attribute 'vendor' ignored}} \
122                                                // expected-warning {{unknown attribute 'using' ignored}}
123 
124 struct [[]] S4 *s; // expected-error {{an attribute list cannot appear here}}
125 struct S5 {};
126 int c = sizeof(struct [[]] S5); // expected-error {{an attribute list cannot appear here}}
127