PR c/64856
[official-gcc.git] / gcc / testsuite / gcc.dg / c11-atomic-1.c
blobc7f9a1ef464c5c3b869cbcf4e266e601ea20dce7
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" } */
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);
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;
42 void
43 func (_Atomic volatile long al1)
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;
65 at1.i = t1.i;
66 atp1->i = t1.i;
67 au1 = u1;
68 u1 = au1;
69 av1 = v1;
70 v1 = av1;
71 v1.i = av1.i;
72 av1.i = v1.i;
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;
83 /* A function may return an atomic type. */
84 _Atomic int
85 func2 (int i)
87 return i;
90 /* Casts may specify atomic type. */
91 int
92 func3 (int i)
94 return func2 ((_Atomic long) i);
97 /* The _Atomic void type is valid. */
98 _Atomic void *avp;
100 /* An array of atomic elements is valid (the elements being atomic,
101 not the array). */
102 _Atomic int aa[10];
104 func4 (void)
106 return aa[2];
109 /* Increment and decrement are valid for atomic types when they are
110 valid for non-atomic types. */
111 void
112 func5 (void)
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;
132 /* Compound literals may have atomic type. */
133 _Atomic int *aiclp = &(_Atomic int) { 1 };
135 /* Test unary & and *. */
136 void
137 func6 (void)
139 int i = *aiclp;
140 _Atomic int *p = &ai2;
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;
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;
153 void
154 func7 (void)
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));
183 /* Pointer += and -= integer is valid. */
184 void
185 func8 (void)
187 b += 1;
188 b -= 2ULL;
189 ap += 3;
192 /* Various other cases of simple assignment are valid (some already
193 tested above). */
194 void
195 func9 (void)
197 ap = 0;
198 ap = (void *) 0;
199 xvp1 = atp1;
200 atp1 = xvp1;
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;
216 void fc1b (_Atomic int);
217 void
218 fc1b (x)
219 volatile _Atomic int x;
222 void
223 fc2a (x)
224 const int x;
227 void fc2a (int); /* { dg-warning "follows non-prototype" } */
228 void
229 fc2b (x)
230 _Atomic int x;
233 void fc2b (_Atomic int); /* { dg-warning "follows non-prototype" } */
234 void fc3a (int);
235 void
236 fc3a (x)
237 volatile short x;
240 void fc3b (_Atomic int);
241 void
242 fc3b (x)
243 _Atomic short x;
246 void
247 fc4a (x)
248 const short x;
251 void fc4a (int); /* { dg-warning "follows non-prototype" } */
252 void
253 fc4b (x)
254 _Atomic short x;
257 void fc4b (_Atomic int); /* { dg-warning "follows non-prototype" } */
259 /* Test cases involving C_MAYBE_CONST_EXPR work. */
260 void
261 func10 (_Atomic int *p)
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" } */