(root)/
gcc-13.2.0/
gcc/
testsuite/
c-c++-common/
Winvalid-memory-model.c
       1  /* PR middle-end/99612 - Missing warning on incorrect memory order without
       2     -Wsystem-headers
       3     Verify that constants are propagated through calls to inline functions
       4     even at -O0.
       5     Also verify that the informational notes after each warning mention
       6     the valid memore models for each function.
       7     { dg-do compile }
       8     { dg-options "-O0 -ftrack-macro-expansion=0" } */
       9  
      10  #if !__cplusplus
      11  # define bool _Bool
      12  #endif
      13  
      14  extern int ei;
      15  
      16  static __attribute__ ((always_inline)) inline
      17  int retval (int val)
      18  {
      19    return val;
      20  }
      21  
      22  void test_load (int *pi)
      23  {
      24    int relaxed = retval (__ATOMIC_RELAXED);
      25    *pi++ = __atomic_load_n (&ei, relaxed);
      26  
      27    int consume = retval (__ATOMIC_CONSUME);
      28    *pi++ = __atomic_load_n (&ei, consume);
      29  
      30    int acquire = retval (__ATOMIC_ACQUIRE);
      31    *pi++ = __atomic_load_n (&ei, acquire);
      32  
      33    int release = retval (__ATOMIC_RELEASE);
      34    *pi++ = __atomic_load_n (&ei, release);   // { dg-warning "invalid memory model 'memory_order_release'" }
      35    // { dg-message "valid models are 'memory_order_relaxed', 'memory_order_seq_cst', 'memory_order_acquire', 'memory_order_consume'" "note" { target *-*-* } .-1 }
      36  
      37    int acq_rel = retval (__ATOMIC_ACQ_REL);
      38    *pi++ = __atomic_load_n (&ei, acq_rel);   // { dg-warning "invalid memory model 'memory_order_acq_rel'" }
      39  
      40    int seq_cst = retval (__ATOMIC_SEQ_CST);
      41    *pi++ = __atomic_load_n (&ei, seq_cst);
      42  
      43    /* Verify a nonconstant range.  */
      44    int r0_1 = *pi++;
      45    if (r0_1 < 0 || 1 < r0_1)
      46      r0_1 = 0;
      47    *pi++ = __atomic_load_n (&ei, r0_1);
      48  
      49    /* Verify an unbounded range.  */
      50    int unknown = *pi++;
      51    *pi++ = __atomic_load_n (&ei, unknown);
      52  }
      53  
      54  
      55  void test_store (int *pi, int x)
      56  {
      57    int relaxed = retval (__ATOMIC_RELAXED);
      58    __atomic_store_n (pi++, x, relaxed);
      59  
      60    int consume = retval (__ATOMIC_CONSUME);
      61    __atomic_store_n (pi++, x, consume);      // { dg-warning "invalid memory model 'memory_order_consume'" }
      62    // { dg-message "valid models are 'memory_order_relaxed', 'memory_order_seq_cst', 'memory_order_release'" "note" { target *-*-* } .-1 }
      63  
      64    int acquire = retval (__ATOMIC_ACQUIRE);
      65    __atomic_store_n (pi++, x, acquire);      // { dg-warning "invalid memory model 'memory_order_acquire'" }
      66  
      67    int release = retval (__ATOMIC_RELEASE);
      68    __atomic_store_n (pi++, x, release);
      69  
      70    int acq_rel = retval (__ATOMIC_ACQ_REL);
      71    __atomic_store_n (pi++, x, acq_rel);      // { dg-warning "invalid memory model 'memory_order_acq_rel'" }
      72  
      73    int seq_cst = retval (__ATOMIC_SEQ_CST);
      74    __atomic_store_n (pi++, x, seq_cst);
      75  
      76    int unknown = *pi++;
      77    __atomic_store_n (pi++, x, unknown);
      78  }
      79  
      80  
      81  /* All memory models are valid.  */
      82  
      83  void test_exchange (int *pi, int x)
      84  {
      85    int relaxed = retval (__ATOMIC_RELAXED);
      86    __atomic_exchange_n (pi++, x, relaxed);
      87  
      88    int consume = retval (__ATOMIC_CONSUME);
      89    __atomic_exchange_n (pi++, x, consume);
      90  
      91    int acquire = retval (__ATOMIC_ACQUIRE);
      92    __atomic_exchange_n (pi++, x, acquire);
      93  
      94    int release = retval (__ATOMIC_RELEASE);
      95    __atomic_exchange_n (pi++, x, release);
      96  
      97    int acq_rel = retval (__ATOMIC_ACQ_REL);
      98    __atomic_exchange_n (pi++, x, acq_rel);
      99  
     100    int seq_cst = retval (__ATOMIC_SEQ_CST);
     101    __atomic_exchange_n (pi++, x, seq_cst);
     102  
     103    int unknown = *pi++;
     104    __atomic_exchange_n (pi++, x, unknown);
     105  }
     106  
     107  
     108  void test_compare_exchange (int *pi, int *pj, bool weak)
     109  {
     110  #define cmpxchg(x, expect, desire, sucs_ord, fail_ord) \
     111    __atomic_compare_exchange_n (x, expect, desire, weak, sucs_ord, fail_ord)
     112  
     113    int relaxed = retval (__ATOMIC_RELAXED);
     114    cmpxchg (&ei, pi++, *pj++, relaxed, relaxed);
     115  
     116    int consume = retval (__ATOMIC_CONSUME);
     117    cmpxchg (&ei, pi++, *pj++, relaxed, consume);   // { dg-warning "failure memory model 'memory_order_consume' cannot be stronger than success memory model 'memory_order_relaxed'" }
     118  
     119    int acquire = retval (__ATOMIC_ACQUIRE);
     120    cmpxchg (&ei, pi++, *pj++, relaxed, acquire);   // { dg-warning "failure memory model 'memory_order_acquire' cannot be stronger than success memory model 'memory_order_relaxed'" }
     121  
     122    int release = retval (__ATOMIC_RELEASE);
     123    cmpxchg (&ei, pi++, *pj++, relaxed, release);   // { dg-warning "invalid failure memory model 'memory_order_release'" }
     124  
     125    int acq_rel = retval (__ATOMIC_ACQ_REL);
     126    cmpxchg (&ei, pi++, *pj++, relaxed, acq_rel);   // { dg-warning "invalid failure memory model 'memory_order_acq_rel'" }
     127  
     128    int seq_cst = retval (__ATOMIC_SEQ_CST);
     129    cmpxchg (&ei, pi++, *pj++, relaxed, seq_cst);   // { dg-warning "failure memory model 'memory_order_seq_cst' cannot be stronger than success memory model 'memory_order_relaxed'" }
     130  
     131  
     132    cmpxchg (&ei, pi++, *pj++, consume, relaxed);
     133    cmpxchg (&ei, pi++, *pj++, consume, consume);
     134    cmpxchg (&ei, pi++, *pj++, consume, acquire);   // { dg-warning "failure memory model 'memory_order_acquire' cannot be stronger than success memory model 'memory_order_consume'" }
     135    cmpxchg (&ei, pi++, *pj++, consume, release);   // { dg-warning "invalid failure memory model 'memory_order_release'" }
     136    cmpxchg (&ei, pi++, *pj++, consume, acq_rel);   // { dg-warning "invalid failure memory model 'memory_order_acq_rel'" }
     137    cmpxchg (&ei, pi++, *pj++, consume, seq_cst);   // { dg-warning "failure memory model 'memory_order_seq_cst' cannot be stronger than success memory model 'memory_order_consume'" }
     138  
     139    cmpxchg (&ei, pi++, *pj++, acquire, relaxed);
     140    cmpxchg (&ei, pi++, *pj++, acquire, consume);
     141    cmpxchg (&ei, pi++, *pj++, acquire, acquire);
     142    cmpxchg (&ei, pi++, *pj++, acquire, release);   // { dg-warning "invalid failure memory model 'memory_order_release'" }
     143    cmpxchg (&ei, pi++, *pj++, acquire, acq_rel);   // { dg-warning "invalid failure memory model 'memory_order_acq_rel'" }
     144    cmpxchg (&ei, pi++, *pj++, acquire, seq_cst);   // { dg-warning "failure memory model 'memory_order_seq_cst' cannot be stronger than success memory model 'memory_order_acquire'" }
     145  
     146    cmpxchg (&ei, pi++, *pj++, release, relaxed);
     147    cmpxchg (&ei, pi++, *pj++, release, consume);
     148    cmpxchg (&ei, pi++, *pj++, release, acquire);
     149    cmpxchg (&ei, pi++, *pj++, release, release);   // { dg-warning "invalid failure memory model 'memory_order_release'" }
     150    cmpxchg (&ei, pi++, *pj++, release, acq_rel);   // { dg-warning "invalid failure memory model 'memory_order_acq_rel'" }
     151    cmpxchg (&ei, pi++, *pj++, release, seq_cst);   // { dg-warning "failure memory model 'memory_order_seq_cst' cannot be stronger than success memory model 'memory_order_release'" }
     152  
     153    cmpxchg (&ei, pi++, *pj++, acq_rel, relaxed);
     154    cmpxchg (&ei, pi++, *pj++, acq_rel, consume);
     155    cmpxchg (&ei, pi++, *pj++, acq_rel, acquire);
     156    cmpxchg (&ei, pi++, *pj++, acq_rel, release);   // { dg-warning "invalid failure memory model 'memory_order_release'" }
     157    cmpxchg (&ei, pi++, *pj++, acq_rel, acq_rel);   // { dg-warning "invalid failure memory model 'memory_order_acq_rel'" }
     158    cmpxchg (&ei, pi++, *pj++, acq_rel, seq_cst);   // { dg-warning "failure memory model 'memory_order_seq_cst' cannot be stronger than success memory model 'memory_order_acq_rel'" }
     159  
     160    cmpxchg (&ei, pi++, *pj++, seq_cst, relaxed);
     161    cmpxchg (&ei, pi++, *pj++, seq_cst, consume);
     162    cmpxchg (&ei, pi++, *pj++, seq_cst, acquire);
     163    cmpxchg (&ei, pi++, *pj++, seq_cst, release);   // { dg-warning "invalid failure memory model 'memory_order_release'" }
     164    cmpxchg (&ei, pi++, *pj++, seq_cst, acq_rel);   // { dg-warning "invalid failure memory model 'memory_order_acq_rel'" }
     165    cmpxchg (&ei, pi++, *pj++, seq_cst, seq_cst);
     166  
     167    int unknown = *pi++;
     168    cmpxchg (&ei, pi++, *pj++, unknown, seq_cst);
     169    cmpxchg (&ei, pi++, *pj++, relaxed, unknown);
     170  }
     171  
     172  
     173  /* All memory models are valid.  */
     174  
     175  void test_add_fetch (unsigned *pi, unsigned x)
     176  {
     177    int relaxed = retval (__ATOMIC_RELAXED);
     178    __atomic_add_fetch (pi++, x, relaxed);
     179  
     180    int consume = retval (__ATOMIC_CONSUME);
     181    __atomic_add_fetch (pi++, x, consume);
     182  
     183    int acquire = retval (__ATOMIC_ACQUIRE);
     184    __atomic_add_fetch (pi++, x, acquire);
     185  
     186    int release = retval (__ATOMIC_RELEASE);
     187    __atomic_add_fetch (pi++, x, release);
     188  
     189    int acq_rel = retval (__ATOMIC_ACQ_REL);
     190    __atomic_add_fetch (pi++, x, acq_rel);
     191  
     192    int seq_cst = retval (__ATOMIC_SEQ_CST);
     193    __atomic_add_fetch (pi++, x, seq_cst);
     194  
     195    int invalid;
     196    if (x & 1)
     197      {
     198        invalid = retval (123);
     199        __atomic_add_fetch (pi++, x, invalid);  // { dg-warning "invalid memory model 123 for '\(unsigned int \)?__atomic_add_fetch" }
     200      }
     201    else
     202      {
     203        invalid = retval (456);
     204        __atomic_add_fetch (pi++, x, invalid);  // { dg-warning "invalid memory model 456 for '\(unsigned int \)?__atomic_add_fetch" }
     205      }
     206  }
     207  
     208  void test_sub_fetch (unsigned *pi, unsigned x)
     209  {
     210    int relaxed = retval (__ATOMIC_RELAXED);
     211    __atomic_sub_fetch (pi++, x, relaxed);
     212  
     213    int consume = retval (__ATOMIC_CONSUME);
     214    __atomic_sub_fetch (pi++, x, consume);
     215  
     216    int acquire = retval (__ATOMIC_ACQUIRE);
     217    __atomic_sub_fetch (pi++, x, acquire);
     218  
     219    int release = retval (__ATOMIC_RELEASE);
     220    __atomic_sub_fetch (pi++, x, release);
     221  
     222    int acq_rel = retval (__ATOMIC_ACQ_REL);
     223    __atomic_sub_fetch (pi++, x, acq_rel);
     224  
     225    int seq_cst = retval (__ATOMIC_SEQ_CST);
     226    __atomic_sub_fetch (pi++, x, seq_cst);
     227  
     228    int invalid;
     229    if (x & 1)
     230      {
     231        invalid = retval (123);
     232        __atomic_sub_fetch (pi++, x, invalid);  // { dg-warning "invalid memory model 123 for '\(unsigned int \)?__atomic_sub_fetch" }
     233      }
     234    else
     235      {
     236        invalid = retval (456);
     237        __atomic_sub_fetch (pi++, x, invalid);  // { dg-warning "invalid memory model 456 for '\(unsigned int \)?__atomic_sub_fetch" }
     238      }
     239  }