(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.dg/
c11-atomic-1.c
       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  }