111
|
1 /* Test for _Atomic in C11. Test of valid code. See c11-atomic-2.c
|
|
2 for more exhaustive tests of assignment cases. */
|
|
3 /* { dg-do compile } */
|
|
4 /* { dg-options "-std=c11 -pedantic-errors" } */
|
|
5
|
|
6 /* The use of _Atomic as a qualifier, and of _Atomic (type-name), give
|
|
7 the same type. */
|
|
8 extern _Atomic int a;
|
|
9 extern _Atomic (int) a;
|
|
10 extern int *_Atomic b;
|
|
11 extern _Atomic (int *) b;
|
|
12 extern void f (int [_Atomic]);
|
|
13 extern void f (int *_Atomic);
|
|
14
|
|
15 /* _Atomic may be applied to arbitrary types, with or without other
|
|
16 qualifiers, and assignments may be made as with non-atomic
|
|
17 types. Structure and union elements may be atomic. */
|
|
18 _Atomic int ai1, ai2;
|
|
19 int i1;
|
|
20 volatile _Atomic long double ald1;
|
|
21 const _Atomic long double ald2;
|
|
22 long double ld1;
|
|
23 _Atomic _Complex double acd1, acd2;
|
|
24 _Complex double d1;
|
|
25 _Atomic volatile _Bool ab1;
|
|
26 int *p;
|
|
27 int *_Atomic restrict ap;
|
|
28 struct s { char c[1000]; };
|
|
29 _Atomic struct s as1;
|
|
30 struct s s1;
|
|
31 struct t { _Atomic int i; };
|
|
32 _Atomic struct t at1;
|
|
33 _Atomic struct t *atp1;
|
|
34 struct t t1;
|
|
35 union u { char c[1000]; };
|
|
36 _Atomic union u au1;
|
|
37 union u u1;
|
|
38 union v { _Atomic int i; };
|
|
39 _Atomic union v av1;
|
|
40 union v v1;
|
|
41
|
|
42 void
|
|
43 func (_Atomic volatile long al1)
|
|
44 {
|
|
45 ai1 = ai2;
|
|
46 ai1 = i1;
|
|
47 i1 = ai2;
|
|
48 ai1 = ald2;
|
|
49 ald1 = d1;
|
|
50 ld1 = acd2;
|
|
51 acd1 += ab1;
|
|
52 acd2 /= ai1;
|
|
53 p = ap;
|
|
54 ap = p;
|
|
55 ab1 = p;
|
|
56 as1 = s1;
|
|
57 s1 = as1;
|
|
58 at1 = t1;
|
|
59 t1 = at1;
|
|
60 /* It's unclear whether the undefined behavior (6.5.2.3#5) for
|
|
61 accessing elements of atomic structures and unions is at
|
|
62 translation or execution time; presume here that it's at
|
|
63 execution time. */
|
|
64 t1.i = at1.i; /* { dg-warning "accessing a member .i. of an atomic structure" } */
|
|
65 at1.i = t1.i; /* { dg-warning "accessing a member .i. of an atomic structure" } */
|
|
66 atp1->i = t1.i; /* { dg-warning "accessing a member .i. of an atomic structure" } */
|
|
67 au1 = u1;
|
|
68 u1 = au1;
|
|
69 av1 = v1;
|
|
70 v1 = av1;
|
|
71 v1.i = av1.i; /* { dg-warning "accessing a member .i. of an atomic union" } */
|
|
72 av1.i = v1.i; /* { dg-warning "accessing a member .i. of an atomic union" } */
|
|
73 /* _Atomic is valid on register variables, even if not particularly
|
|
74 useful. */
|
|
75 register _Atomic volatile int ra1 = 1, ra2 = 2;
|
|
76 ra1 = ra2;
|
|
77 ra2 = ra1;
|
|
78 /* And on parameters. */
|
|
79 al1 = ra1;
|
|
80 ra2 = al1;
|
|
81 }
|
|
82
|
|
83 /* A function may return an atomic type. */
|
|
84 _Atomic int
|
|
85 func2 (int i)
|
|
86 {
|
|
87 return i;
|
|
88 }
|
|
89
|
|
90 /* Casts may specify atomic type. */
|
|
91 int
|
|
92 func3 (int i)
|
|
93 {
|
|
94 return func2 ((_Atomic long) i);
|
|
95 }
|
|
96
|
|
97 /* The _Atomic void type is valid. */
|
|
98 _Atomic void *avp;
|
|
99
|
|
100 /* An array of atomic elements is valid (the elements being atomic,
|
|
101 not the array). */
|
|
102 _Atomic int aa[10];
|
|
103 int
|
|
104 func4 (void)
|
|
105 {
|
|
106 return aa[2];
|
|
107 }
|
|
108
|
|
109 /* Increment and decrement are valid for atomic types when they are
|
|
110 valid for non-atomic types. */
|
|
111 void
|
|
112 func5 (void)
|
|
113 {
|
|
114 ald1++;
|
|
115 ald1--;
|
|
116 ++ald1;
|
|
117 --ald1;
|
|
118 ai1++;
|
|
119 ai1--;
|
|
120 ++ai1;
|
|
121 --ai1;
|
|
122 ab1++;
|
|
123 ab1--;
|
|
124 ++ab1;
|
|
125 --ab1;
|
|
126 ap++;
|
|
127 ap--;
|
|
128 ++ap;
|
|
129 --ap;
|
|
130 }
|
|
131
|
|
132 /* Compound literals may have atomic type. */
|
|
133 _Atomic int *aiclp = &(_Atomic int) { 1 };
|
|
134
|
|
135 /* Test unary & and *. */
|
|
136 void
|
|
137 func6 (void)
|
|
138 {
|
|
139 int i = *aiclp;
|
|
140 _Atomic int *p = &ai2;
|
|
141 }
|
|
142
|
|
143 /* Casts to atomic type are valid (although the _Atomic has little
|
|
144 effect because the result is an rvalue). */
|
|
145 int i2 = (_Atomic int) 1.0;
|
|
146
|
|
147 /* For pointer subtraction and comparisons, _Atomic does not count as
|
|
148 a qualifier. Likewise for conditional expressions. */
|
|
149 _Atomic int *xaip1;
|
|
150 volatile _Atomic int *xaip2;
|
|
151 void *xvp1;
|
|
152
|
|
153 void
|
|
154 func7 (void)
|
|
155 {
|
|
156 int r;
|
|
157 r = xaip1 - xaip2;
|
|
158 r = xaip1 < xaip2;
|
|
159 r = xaip1 > xaip2;
|
|
160 r = xaip1 <= xaip2;
|
|
161 r = xaip1 >= xaip2;
|
|
162 r = xaip1 == xaip2;
|
|
163 r = xaip1 != xaip2;
|
|
164 r = xaip1 == xvp1;
|
|
165 r = xaip1 != xvp1;
|
|
166 r = xvp1 == xaip1;
|
|
167 r = xvp1 != xaip1;
|
|
168 r = xaip1 == 0;
|
|
169 r = ((void *) 0) == xaip2;
|
|
170 (void) (r ? xaip1 : xaip2);
|
|
171 (void) (r ? xvp1 : xaip2);
|
|
172 (void) (r ? xaip2 : xvp1);
|
|
173 (void) (r ? xaip1 : 0);
|
|
174 (void) (r ? 0 : xaip1);
|
|
175 /* The result of a conditional expression between a pointer to
|
|
176 qualified or unqualified (but not atomic) void, and a pointer to
|
|
177 an atomic type, is a pointer to appropriately qualified, not
|
|
178 atomic, void. As such, it is valid to use further in conditional
|
|
179 expressions with other pointer types. */
|
|
180 (void) (r ? xaip1 : (r ? xaip1 : xvp1));
|
|
181 }
|
|
182
|
|
183 /* Pointer += and -= integer is valid. */
|
|
184 void
|
|
185 func8 (void)
|
|
186 {
|
|
187 b += 1;
|
|
188 b -= 2ULL;
|
|
189 ap += 3;
|
|
190 }
|
|
191
|
|
192 /* Various other cases of simple assignment are valid (some already
|
|
193 tested above). */
|
|
194 void
|
|
195 func9 (void)
|
|
196 {
|
|
197 ap = 0;
|
|
198 ap = (void *) 0;
|
|
199 xvp1 = atp1;
|
|
200 atp1 = xvp1;
|
|
201 }
|
|
202
|
|
203 /* Test compatibility of function types in cases where _Atomic matches
|
|
204 (see c11-atomic-3.c for corresponding cases where it doesn't
|
|
205 match). */
|
|
206 void fc0a (int const);
|
|
207 void fc0a (int);
|
|
208 void fc0b (int _Atomic);
|
|
209 void fc0b (int _Atomic);
|
|
210 void fc1a (int);
|
|
211 void
|
|
212 fc1a (x)
|
|
213 volatile int x;
|
|
214 {
|
|
215 }
|
|
216 void fc1b (_Atomic int);
|
|
217 void
|
|
218 fc1b (x)
|
|
219 volatile _Atomic int x;
|
|
220 {
|
|
221 }
|
|
222 void
|
|
223 fc2a (x)
|
|
224 const int x;
|
|
225 {
|
|
226 }
|
|
227 void fc2a (int); /* { dg-warning "follows non-prototype" } */
|
|
228 void
|
|
229 fc2b (x)
|
|
230 _Atomic int x;
|
|
231 {
|
|
232 }
|
|
233 void fc2b (_Atomic int); /* { dg-warning "follows non-prototype" } */
|
|
234 void fc3a (int);
|
|
235 void
|
|
236 fc3a (x)
|
|
237 volatile short x;
|
|
238 {
|
|
239 }
|
|
240 void fc3b (_Atomic int);
|
|
241 void
|
|
242 fc3b (x)
|
|
243 _Atomic short x;
|
|
244 {
|
|
245 }
|
|
246 void
|
|
247 fc4a (x)
|
|
248 const short x;
|
|
249 {
|
|
250 }
|
|
251 void fc4a (int); /* { dg-warning "follows non-prototype" } */
|
|
252 void
|
|
253 fc4b (x)
|
|
254 _Atomic short x;
|
|
255 {
|
|
256 }
|
|
257 void fc4b (_Atomic int); /* { dg-warning "follows non-prototype" } */
|
|
258
|
|
259 /* Test cases involving C_MAYBE_CONST_EXPR work. */
|
|
260 void
|
|
261 func10 (_Atomic int *p)
|
|
262 {
|
|
263 p[0 / 0] = 1; /* { dg-warning "division by zero" } */
|
|
264 p[0 / 0] += 1; /* { dg-warning "division by zero" } */
|
|
265 *p = 0 / 0; /* { dg-warning "division by zero" } */
|
|
266 *p += 0 / 0; /* { dg-warning "division by zero" } */
|
|
267 }
|