| /* PR middle-end/99612 - Missing warning on incorrect memory order without |
| -Wsystem-headers |
| Verify that constants are propagated through calls to inline functions |
| even at -O0. |
| Also verify that the informational notes after each warning mention |
| the valid memore models for each function. |
| { dg-do compile } |
| { dg-options "-O0 -ftrack-macro-expansion=0" } */ |
| |
| #if !__cplusplus |
| # define bool _Bool |
| #endif |
| |
| extern int ei; |
| |
| static __attribute__ ((always_inline)) inline |
| int retval (int val) |
| { |
| return val; |
| } |
| |
| void test_load (int *pi) |
| { |
| int relaxed = retval (__ATOMIC_RELAXED); |
| *pi++ = __atomic_load_n (&ei, relaxed); |
| |
| int consume = retval (__ATOMIC_CONSUME); |
| *pi++ = __atomic_load_n (&ei, consume); |
| |
| int acquire = retval (__ATOMIC_ACQUIRE); |
| *pi++ = __atomic_load_n (&ei, acquire); |
| |
| int release = retval (__ATOMIC_RELEASE); |
| *pi++ = __atomic_load_n (&ei, release); // { dg-warning "invalid memory model 'memory_order_release'" } |
| // { dg-message "valid models are 'memory_order_relaxed', 'memory_order_seq_cst', 'memory_order_acquire', 'memory_order_consume'" "note" { target *-*-* } .-1 } |
| |
| int acq_rel = retval (__ATOMIC_ACQ_REL); |
| *pi++ = __atomic_load_n (&ei, acq_rel); // { dg-warning "invalid memory model 'memory_order_acq_rel'" } |
| |
| int seq_cst = retval (__ATOMIC_SEQ_CST); |
| *pi++ = __atomic_load_n (&ei, seq_cst); |
| |
| /* Verify a nonconstant range. */ |
| int r0_1 = *pi++; |
| if (r0_1 < 0 || 1 < r0_1) |
| r0_1 = 0; |
| *pi++ = __atomic_load_n (&ei, r0_1); |
| |
| /* Verify an unbounded range. */ |
| int unknown = *pi++; |
| *pi++ = __atomic_load_n (&ei, unknown); |
| } |
| |
| |
| void test_store (int *pi, int x) |
| { |
| int relaxed = retval (__ATOMIC_RELAXED); |
| __atomic_store_n (pi++, x, relaxed); |
| |
| int consume = retval (__ATOMIC_CONSUME); |
| __atomic_store_n (pi++, x, consume); // { dg-warning "invalid memory model 'memory_order_consume'" } |
| // { dg-message "valid models are 'memory_order_relaxed', 'memory_order_seq_cst', 'memory_order_release'" "note" { target *-*-* } .-1 } |
| |
| int acquire = retval (__ATOMIC_ACQUIRE); |
| __atomic_store_n (pi++, x, acquire); // { dg-warning "invalid memory model 'memory_order_acquire'" } |
| |
| int release = retval (__ATOMIC_RELEASE); |
| __atomic_store_n (pi++, x, release); |
| |
| int acq_rel = retval (__ATOMIC_ACQ_REL); |
| __atomic_store_n (pi++, x, acq_rel); // { dg-warning "invalid memory model 'memory_order_acq_rel'" } |
| |
| int seq_cst = retval (__ATOMIC_SEQ_CST); |
| __atomic_store_n (pi++, x, seq_cst); |
| |
| int unknown = *pi++; |
| __atomic_store_n (pi++, x, unknown); |
| } |
| |
| |
| /* All memory models are valid. */ |
| |
| void test_exchange (int *pi, int x) |
| { |
| int relaxed = retval (__ATOMIC_RELAXED); |
| __atomic_exchange_n (pi++, x, relaxed); |
| |
| int consume = retval (__ATOMIC_CONSUME); |
| __atomic_exchange_n (pi++, x, consume); |
| |
| int acquire = retval (__ATOMIC_ACQUIRE); |
| __atomic_exchange_n (pi++, x, acquire); |
| |
| int release = retval (__ATOMIC_RELEASE); |
| __atomic_exchange_n (pi++, x, release); |
| |
| int acq_rel = retval (__ATOMIC_ACQ_REL); |
| __atomic_exchange_n (pi++, x, acq_rel); |
| |
| int seq_cst = retval (__ATOMIC_SEQ_CST); |
| __atomic_exchange_n (pi++, x, seq_cst); |
| |
| int unknown = *pi++; |
| __atomic_exchange_n (pi++, x, unknown); |
| } |
| |
| |
| void test_compare_exchange (int *pi, int *pj, bool weak) |
| { |
| #define cmpxchg(x, expect, desire, sucs_ord, fail_ord) \ |
| __atomic_compare_exchange_n (x, expect, desire, weak, sucs_ord, fail_ord) |
| |
| int relaxed = retval (__ATOMIC_RELAXED); |
| cmpxchg (&ei, pi++, *pj++, relaxed, relaxed); |
| |
| int consume = retval (__ATOMIC_CONSUME); |
| cmpxchg (&ei, pi++, *pj++, relaxed, consume); // { dg-warning "failure memory model 'memory_order_consume' cannot be stronger than success memory model 'memory_order_relaxed'" } |
| |
| int acquire = retval (__ATOMIC_ACQUIRE); |
| cmpxchg (&ei, pi++, *pj++, relaxed, acquire); // { dg-warning "failure memory model 'memory_order_acquire' cannot be stronger than success memory model 'memory_order_relaxed'" } |
| |
| int release = retval (__ATOMIC_RELEASE); |
| cmpxchg (&ei, pi++, *pj++, relaxed, release); // { dg-warning "invalid failure memory model 'memory_order_release'" } |
| |
| int acq_rel = retval (__ATOMIC_ACQ_REL); |
| cmpxchg (&ei, pi++, *pj++, relaxed, acq_rel); // { dg-warning "invalid failure memory model 'memory_order_acq_rel'" } |
| |
| int seq_cst = retval (__ATOMIC_SEQ_CST); |
| 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'" } |
| |
| |
| cmpxchg (&ei, pi++, *pj++, consume, relaxed); |
| cmpxchg (&ei, pi++, *pj++, consume, consume); |
| cmpxchg (&ei, pi++, *pj++, consume, acquire); // { dg-warning "failure memory model 'memory_order_acquire' cannot be stronger than success memory model 'memory_order_consume'" } |
| cmpxchg (&ei, pi++, *pj++, consume, release); // { dg-warning "invalid failure memory model 'memory_order_release'" } |
| cmpxchg (&ei, pi++, *pj++, consume, acq_rel); // { dg-warning "invalid failure memory model 'memory_order_acq_rel'" } |
| 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'" } |
| |
| cmpxchg (&ei, pi++, *pj++, acquire, relaxed); |
| cmpxchg (&ei, pi++, *pj++, acquire, consume); |
| cmpxchg (&ei, pi++, *pj++, acquire, acquire); |
| cmpxchg (&ei, pi++, *pj++, acquire, release); // { dg-warning "invalid failure memory model 'memory_order_release'" } |
| cmpxchg (&ei, pi++, *pj++, acquire, acq_rel); // { dg-warning "invalid failure memory model 'memory_order_acq_rel'" } |
| 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'" } |
| |
| cmpxchg (&ei, pi++, *pj++, release, relaxed); |
| cmpxchg (&ei, pi++, *pj++, release, consume); |
| cmpxchg (&ei, pi++, *pj++, release, acquire); |
| cmpxchg (&ei, pi++, *pj++, release, release); // { dg-warning "invalid failure memory model 'memory_order_release'" } |
| cmpxchg (&ei, pi++, *pj++, release, acq_rel); // { dg-warning "invalid failure memory model 'memory_order_acq_rel'" } |
| 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'" } |
| |
| cmpxchg (&ei, pi++, *pj++, acq_rel, relaxed); |
| cmpxchg (&ei, pi++, *pj++, acq_rel, consume); |
| cmpxchg (&ei, pi++, *pj++, acq_rel, acquire); |
| cmpxchg (&ei, pi++, *pj++, acq_rel, release); // { dg-warning "invalid failure memory model 'memory_order_release'" } |
| cmpxchg (&ei, pi++, *pj++, acq_rel, acq_rel); // { dg-warning "invalid failure memory model 'memory_order_acq_rel'" } |
| 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'" } |
| |
| cmpxchg (&ei, pi++, *pj++, seq_cst, relaxed); |
| cmpxchg (&ei, pi++, *pj++, seq_cst, consume); |
| cmpxchg (&ei, pi++, *pj++, seq_cst, acquire); |
| cmpxchg (&ei, pi++, *pj++, seq_cst, release); // { dg-warning "invalid failure memory model 'memory_order_release'" } |
| cmpxchg (&ei, pi++, *pj++, seq_cst, acq_rel); // { dg-warning "invalid failure memory model 'memory_order_acq_rel'" } |
| cmpxchg (&ei, pi++, *pj++, seq_cst, seq_cst); |
| |
| int unknown = *pi++; |
| cmpxchg (&ei, pi++, *pj++, unknown, seq_cst); |
| cmpxchg (&ei, pi++, *pj++, relaxed, unknown); |
| } |
| |
| |
| /* All memory models are valid. */ |
| |
| void test_add_fetch (unsigned *pi, unsigned x) |
| { |
| int relaxed = retval (__ATOMIC_RELAXED); |
| __atomic_add_fetch (pi++, x, relaxed); |
| |
| int consume = retval (__ATOMIC_CONSUME); |
| __atomic_add_fetch (pi++, x, consume); |
| |
| int acquire = retval (__ATOMIC_ACQUIRE); |
| __atomic_add_fetch (pi++, x, acquire); |
| |
| int release = retval (__ATOMIC_RELEASE); |
| __atomic_add_fetch (pi++, x, release); |
| |
| int acq_rel = retval (__ATOMIC_ACQ_REL); |
| __atomic_add_fetch (pi++, x, acq_rel); |
| |
| int seq_cst = retval (__ATOMIC_SEQ_CST); |
| __atomic_add_fetch (pi++, x, seq_cst); |
| |
| int invalid; |
| if (x & 1) |
| { |
| invalid = retval (123); |
| __atomic_add_fetch (pi++, x, invalid); // { dg-warning "invalid memory model 123 for '\(unsigned int \)?__atomic_add_fetch" } |
| } |
| else |
| { |
| invalid = retval (456); |
| __atomic_add_fetch (pi++, x, invalid); // { dg-warning "invalid memory model 456 for '\(unsigned int \)?__atomic_add_fetch" } |
| } |
| } |
| |
| void test_sub_fetch (unsigned *pi, unsigned x) |
| { |
| int relaxed = retval (__ATOMIC_RELAXED); |
| __atomic_sub_fetch (pi++, x, relaxed); |
| |
| int consume = retval (__ATOMIC_CONSUME); |
| __atomic_sub_fetch (pi++, x, consume); |
| |
| int acquire = retval (__ATOMIC_ACQUIRE); |
| __atomic_sub_fetch (pi++, x, acquire); |
| |
| int release = retval (__ATOMIC_RELEASE); |
| __atomic_sub_fetch (pi++, x, release); |
| |
| int acq_rel = retval (__ATOMIC_ACQ_REL); |
| __atomic_sub_fetch (pi++, x, acq_rel); |
| |
| int seq_cst = retval (__ATOMIC_SEQ_CST); |
| __atomic_sub_fetch (pi++, x, seq_cst); |
| |
| int invalid; |
| if (x & 1) |
| { |
| invalid = retval (123); |
| __atomic_sub_fetch (pi++, x, invalid); // { dg-warning "invalid memory model 123 for '\(unsigned int \)?__atomic_sub_fetch" } |
| } |
| else |
| { |
| invalid = retval (456); |
| __atomic_sub_fetch (pi++, x, invalid); // { dg-warning "invalid memory model 456 for '\(unsigned int \)?__atomic_sub_fetch" } |
| } |
| } |