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
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. */
20 volatile _Atomic
long double ald1
;
21 const _Atomic
long double ald2
;
23 _Atomic _Complex
double acd1
, acd2
;
25 _Atomic
volatile _Bool ab1
;
27 int *_Atomic restrict ap
;
28 struct s
{ char c
[1000]; };
31 struct t
{ _Atomic
int i
; };
33 _Atomic
struct t
*atp1
;
35 union u
{ char c
[1000]; };
38 union v
{ _Atomic
int i
; };
43 func (_Atomic
volatile long al1
)
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
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" } */
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
75 register _Atomic
volatile int ra1
= 1, ra2
= 2;
78 /* And on parameters. */
83 /* A function may return an atomic type. */
90 /* Casts may specify atomic type. */
94 return func2 ((_Atomic
long) i
);
97 /* The _Atomic void type is valid. */
100 /* An array of atomic elements is valid (the elements being atomic,
109 /* Increment and decrement are valid for atomic types when they are
110 valid for non-atomic types. */
132 /* Compound literals may have atomic type. */
133 _Atomic
int *aiclp
= &(_Atomic
int) { 1 };
135 /* Test unary & and *. */
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. */
150 volatile _Atomic
int *xaip2
;
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. */
192 /* Various other cases of simple assignment are valid (some already
203 /* Test compatibility of function types in cases where _Atomic matches
204 (see c11-atomic-3.c for corresponding cases where it doesn't
206 void fc0a (int const);
208 void fc0b (int _Atomic
);
209 void fc0b (int _Atomic
);
216 void fc1b (_Atomic
int);
219 volatile _Atomic
int x
;
227 void fc2a (int); /* { dg-warning "follows non-prototype" } */
233 void fc2b (_Atomic
int); /* { dg-warning "follows non-prototype" } */
240 void fc3b (_Atomic
int);
251 void fc4a (int); /* { dg-warning "follows non-prototype" } */
257 void fc4b (_Atomic
int); /* { dg-warning "follows non-prototype" } */
259 /* Test cases involving C_MAYBE_CONST_EXPR work. */
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" } */