xref: /llvm-project/clang/test/Parser/c2x-attributes.c (revision 98322d3eb43168a6a64c1a15a1e754e15c04aa2f)
1 // RUN: %clang_cc1 -fsyntax-only -verify=expected,notc2x -Wno-strict-prototypes %s
2 // RUN: %clang_cc1 -fsyntax-only -std=gnu2x -verify=expected,c2x %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 [[deprecated([""])]] int WrongArgs; // expected-error {{expected string literal as argument of 'deprecated' attribute}}
20 [[,,,,,]] int Commas1; // ok
21 [[,, maybe_unused]] int Commas2; // ok
22 [[maybe_unused,,,]] int Commas3; // ok
23 [[,,maybe_unused,]] int Commas4; // ok
24 [[foo bar]] int NoComma; // expected-error {{expected ','}} \
25                          // expected-warning {{unknown attribute 'foo' ignored}}
26 
27 
28 [[deprecated(L"abc")]] void unevaluated_string(void);
29 // expected-warning@-1 {{encoding prefix 'L' on an unevaluated string literal has no effect}}
30 
31 [[nodiscard("\123")]] int unevaluated_string2(void);
32 // expected-error@-1 {{invalid escape sequence '\123' in an unevaluated string literal}}
33 
34 struct [[]] S1 {
35   int i [[]];
36   int [[]] j;
37   int k[10] [[]];
38   int l[[]][10];
39   [[]] int m, n;
40   int o [[]] : 12;
41   int [[]] : 0; // OK, attribute applies to the type.
42   int p, [[]] : 0; // expected-error {{an attribute list cannot appear here}}
43   int q, [[]] r; // expected-error {{an attribute list cannot appear here}}
44   [[]] int; // expected-error {{an attribute list cannot appear here}} \
45             // expected-warning {{declaration does not declare anything}}
46 };
47 
48 [[]] struct S2 { int a; }; // expected-error {{misplaced attributes}}
49 struct S3 [[]] { int a; }; // expected-error {{an attribute list cannot appear here}}
50 
51 union [[]] U {
52   double d [[]];
53   [[]] int i;
54 };
55 
56 [[]] union U2 { double d; }; // expected-error {{misplaced attributes}}
57 union U3 [[]] { double d; }; // expected-error {{an attribute list cannot appear here}}
58 
59 struct [[]] IncompleteStruct;
60 union [[]] IncompleteUnion;
61 enum [[]] IncompleteEnum;
62 enum __attribute__((deprecated)) IncompleteEnum2;
63 
64 [[]] void f1(void);
65 void [[]] f2(void);
66 void f3 [[]] (void);
67 void f4(void) [[]];
68 
69 void f5(int i [[]], [[]] int j, int [[]] k);
70 
f6(a,b)71 void f6(a, b) [[]] int a; int b; { // notc2x-error {{an attribute list cannot appear here}} \
72                                       c2x-error {{unknown type name 'a'}} \
73                                       c2x-error {{unknown type name 'b'}} \
74                                       c2x-error {{expected ';' after top level declarator}} \
75                                       c2x-error {{expected identifier or '('}}
76 }
77 
78 // FIXME: technically, an attribute list cannot appear here, but we currently
79 // parse it as part of the return type of the function, which is reasonable
80 // behavior given that we *don't* want to parse it as part of the K&R parameter
81 // declarations. It is disallowed to avoid a parsing ambiguity we already
82 // handle well.
83 int (*f7(a, b))(int, int) [[]] int a; int b; { // c2x-error {{unknown type name 'a'}} \
84                                                   c2x-error {{unknown type name 'b'}} \
85                                                   c2x-error {{expected ';' after top level declarator}} \
86                                                   c2x-error {{expected identifier or '('}}
87 
88   return 0;
89 }
90 
91 [[]] int a, b;
92 int c [[]], d [[]];
93 
f8(void)94 void f8(void) [[]] {
95   [[]] int i, j;
96   int k, l [[]];
97 }
98 
f9(void)99 [[]] void f9(void) {
100   int i[10] [[]];
101   int (*fp1)(void)[[]];
102   int (*fp2 [[]])(void);
103 
104   int * [[]] *ipp;
105 }
106 
107 void f10(int j[static 10] [[]], int k[*] [[]]);
108 
f11(void)109 void f11(void) {
110   [[]] {}
111   [[]] if (1) {}
112 
113   [[]] switch (1) {
114   [[]] case 1: [[]] break;
115   [[]] default: break;
116   }
117 
118   goto foo;
119   [[]] foo: (void)1;
120 
121   [[]] for (;;);
122   [[]] while (1);
123   [[]] do [[]] { } while(1);
124 
125   [[]] (void)1;
126 
127   [[]];
128 
129   (void)sizeof(int [4][[]]);
130   (void)sizeof(struct [[]] S3 { int a [[]]; });
131 
132   [[]] return;
133 }
134 
135 [[attr]] void f12(void); // expected-warning {{unknown attribute 'attr' ignored}}
136 [[vendor::attr]] void f13(void); // expected-warning {{unknown attribute 'attr' ignored}}
137 
138 // Ensure that asm statements properly handle double colons.
test_asm(void)139 void test_asm(void) {
140   asm("ret" :::);
141   asm("foo" :: "r" (xx)); // expected-error {{use of undeclared identifier 'xx'}}
142 }
143 
144 // Do not allow 'using' to introduce vendor attribute namespaces.
145 [[using vendor: attr1, attr2]] void f14(void); // expected-error {{expected ','}} \
146                                                // expected-warning {{unknown attribute 'using' ignored}}
147 
148 struct [[]] S4 *s; // expected-error {{an attribute list cannot appear here}}
149 struct S5 {};
150 int c = sizeof(struct [[]] S5); // expected-error {{an attribute list cannot appear here}}
151 
152 // Ensure that '::' outside of attributes does not crash and is not treated as scope
153 double n::v; // expected-error {{expected ';' after top level declarator}}
154