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  
      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  
      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  }