| /* 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" } | |
| } | |
| } |