1 /* PR c/68966 - atomic_fetch_* on atomic_bool not diagnosed
2    Test to verify that calls to __atomic_fetch_op funcions with a _Bool
3    argument are rejected.  This is necessary because GCC expects that
4    all initialized _Bool objects have a specific representation and
5    allowing atomic operations to change it would break the invariant.  */
6 /* { dg-do compile } */
7 /* { dg-options "-pedantic-errors -std=c11" } */
8 
9 
test_atomic_bool(_Atomic _Bool * a)10 void test_atomic_bool (_Atomic _Bool *a)
11 {
12   enum { SEQ_CST = __ATOMIC_SEQ_CST };
13 
14   __atomic_fetch_add (a, 1, SEQ_CST);   /* { dg-error "operand type ._Atomic _Bool \\*. is incompatible with argument 1 of .__atomic_fetch_add." } */
15   __atomic_fetch_sub (a, 1, SEQ_CST);   /* { dg-error "operand type ._Atomic _Bool \\*. is incompatible with argument 1 of .__atomic_fetch_sub." } */
16   __atomic_fetch_and (a, 1, SEQ_CST);   /* { dg-error "operand type ._Atomic _Bool \\*. is incompatible with argument 1 of .__atomic_fetch_and." } */
17   __atomic_fetch_xor (a, 1, SEQ_CST);   /* { dg-error "operand type ._Atomic _Bool \\*. is incompatible with argument 1 of .__atomic_fetch_xor." } */
18   __atomic_fetch_or (a, 1, SEQ_CST);   /* { dg-error "operand type ._Atomic _Bool \\*. is incompatible with argument 1 of .__atomic_fetch_or." } */
19   __atomic_fetch_nand (a, 1, SEQ_CST);   /* { dg-error "operand type ._Atomic _Bool \\*. is incompatible with argument 1 of .__atomic_fetch_nand." } */
20 
21   __atomic_add_fetch (a, 1, SEQ_CST);   /* { dg-error "operand type ._Atomic _Bool \\*. is incompatible with argument 1 of .__atomic_add_fetch." } */
22   __atomic_sub_fetch (a, 1, SEQ_CST);   /* { dg-error "operand type ._Atomic _Bool \\*. is incompatible with argument 1 of .__atomic_sub_fetch." } */
23   __atomic_and_fetch (a, 1, SEQ_CST);   /* { dg-error "operand type ._Atomic _Bool \\*. is incompatible with argument 1 of .__atomic_and_fetch." } */
24   __atomic_xor_fetch (a, 1, SEQ_CST);   /* { dg-error "operand type ._Atomic _Bool \\*. is incompatible with argument 1 of .__atomic_xor_fetch." } */
25   __atomic_or_fetch (a, 1, SEQ_CST);   /* { dg-error "operand type ._Atomic _Bool \\*. is incompatible with argument 1 of .__atomic_or_fetch." } */
26   __atomic_nand_fetch (a, 1, SEQ_CST);   /* { dg-error "operand type ._Atomic _Bool \\*. is incompatible with argument 1 of .__atomic_nand_fetch." } */
27 
28   /* The following are valid and must be accepted.  */
29   _Bool val = 0, ret = 0;
30   __atomic_exchange (a, &val, &ret, SEQ_CST);
31   __atomic_exchange_n (a, val, SEQ_CST);
32   __atomic_compare_exchange (a, &val, &ret, !1, SEQ_CST, SEQ_CST);
33   __atomic_compare_exchange_n (a, &val, ret, !1, SEQ_CST, SEQ_CST);
34   __atomic_test_and_set (a, SEQ_CST);
35   __atomic_clear (a, SEQ_CST);
36 }
37 
test_bool(_Bool * b)38 void test_bool (_Bool *b)
39 {
40   enum { SEQ_CST = __ATOMIC_SEQ_CST };
41 
42   __atomic_fetch_add (b, 1, SEQ_CST);   /* { dg-error "operand type ._Bool \\*. is incompatible with argument 1 of .__atomic_fetch_add." } */
43   __atomic_fetch_sub (b, 1, SEQ_CST);   /* { dg-error "operand type ._Bool \\*. is incompatible with argument 1 of .__atomic_fetch_sub." } */
44   __atomic_fetch_and (b, 1, SEQ_CST);   /* { dg-error "operand type ._Bool \\*. is incompatible with argument 1 of .__atomic_fetch_and." } */
45   __atomic_fetch_xor (b, 1, SEQ_CST);   /* { dg-error "operand type ._Bool \\*. is incompatible with argument 1 of .__atomic_fetch_xor." } */
46   __atomic_fetch_or (b, 1, SEQ_CST);   /* { dg-error "operand type ._Bool \\*. is incompatible with argument 1 of .__atomic_fetch_or." } */
47   __atomic_fetch_nand (b, 1, SEQ_CST);   /* { dg-error "operand type ._Bool \\*. is incompatible with argument 1 of .__atomic_fetch_nand." } */
48 
49   __atomic_add_fetch (b, 1, SEQ_CST);   /* { dg-error "operand type ._Bool \\*. is incompatible with argument 1 of .__atomic_add_fetch." } */
50   __atomic_sub_fetch (b, 1, SEQ_CST);   /* { dg-error "operand type ._Bool \\*. is incompatible with argument 1 of .__atomic_sub_fetch." } */
51   __atomic_and_fetch (b, 1, SEQ_CST);   /* { dg-error "operand type ._Bool \\*. is incompatible with argument 1 of .__atomic_and_fetch." } */
52   __atomic_xor_fetch (b, 1, SEQ_CST);   /* { dg-error "operand type ._Bool \\*. is incompatible with argument 1 of .__atomic_xor_fetch." } */
53   __atomic_or_fetch (b, 1, SEQ_CST);   /* { dg-error "operand type ._Bool \\*. is incompatible with argument 1 of .__atomic_or_fetch." } */
54   __atomic_nand_fetch (b, 1, SEQ_CST);   /* { dg-error "operand type ._Bool \\*. is incompatible with argument 1 of .__atomic_nand_fetch." } */
55 
56   /* The following are valid and must be accepted.  */
57   _Bool val = 0, ret = 0;
58   __atomic_exchange (b, &val, &ret, SEQ_CST);
59   __atomic_exchange_n (b, val, SEQ_CST);
60   __atomic_compare_exchange (b, &val, &ret, !1, SEQ_CST, SEQ_CST);
61   __atomic_compare_exchange_n (b, &val, ret, !1, SEQ_CST, SEQ_CST);
62   __atomic_test_and_set (b, SEQ_CST);
63   __atomic_clear (b, SEQ_CST);
64 }
65