
Besides the C++ FE changes, I've noticed that the C FE didn't reject #pragma omp atomic capture compare { v = x; x = y; } and other forms of atomic swap, this patch fixes that too. And the c-family/ routine needed quite a few changes so that the new code in it works fine with both FEs. 2021-09-17 Jakub Jelinek <jakub@redhat.com> gcc/c-family/ * c-omp.c (c_finish_omp_atomic): Avoid creating TARGET_EXPR if test is true, use create_tmp_var_raw instead of create_tmp_var and add a zero initializer to TARGET_EXPRs that had NULL initializer. When omitting operands after v = x, use type of v rather than type of x. Fix type of vtmp TARGET_EXPR. gcc/c/ * c-parser.c (c_parser_omp_atomic): Reject atomic swap if capture is true. gcc/cp/ * cp-tree.h (finish_omp_atomic): Add r and weak arguments. * parser.c (cp_parser_omp_atomic): Update function comment for OpenMP 5.1 atomics, parse OpenMP 5.1 atomics and fail, compare and weak clauses. * semantics.c (finish_omp_atomic): Add r and weak arguments, handle them, handle COND_EXPRs. * pt.c (tsubst_expr): Adjust for COND_EXPR forms that finish_omp_atomic can now produce. gcc/testsuite/ * c-c++-common/gomp/atomic-18.c: Expect same diagnostics in C++ as in C. * c-c++-common/gomp/atomic-25.c: Drop c effective target. * c-c++-common/gomp/atomic-26.c: Likewise. * c-c++-common/gomp/atomic-27.c: Likewise. * c-c++-common/gomp/atomic-28.c: Likewise. * c-c++-common/gomp/atomic-29.c: Likewise. * c-c++-common/gomp/atomic-30.c: Likewise. Adjust expected diagnostics for C++ when it differs from C. (foo): Change return type from double to void. * g++.dg/gomp/atomic-5.C: Adjust expected diagnostics wording. * g++.dg/gomp/atomic-20.C: New test. libgomp/ * testsuite/libgomp.c-c++-common/atomic-19.c: Drop c effective target. Use /* */ comments instead of //. * testsuite/libgomp.c-c++-common/atomic-20.c: Likewise. * testsuite/libgomp.c-c++-common/atomic-21.c: Likewise. * testsuite/libgomp.c++/atomic-16.C: New test. * testsuite/libgomp.c++/atomic-17.C: New test.
49 lines
1.2 KiB
C
49 lines
1.2 KiB
C
/* { dg-do run } */
|
|
|
|
double d;
|
|
long double ld;
|
|
|
|
int
|
|
main ()
|
|
{
|
|
double e = __builtin_copysign (0.0, -1.0), v;
|
|
long double le = __builtin_copysignl (0.0L, -1.0L), lv;
|
|
if (__builtin_memcmp (&d, &e, sizeof (d)) != 0)
|
|
{
|
|
/* Verify == comparison for atomics is done as with memcmp. */
|
|
#pragma omp atomic compare
|
|
d = d == e ? 5.0 : d;
|
|
#pragma omp atomic read
|
|
v = d;
|
|
if (v != 0.0)
|
|
__builtin_abort ();
|
|
#pragma omp atomic compare
|
|
d = d == 0.0 ? 5.0 : d;
|
|
#pragma omp atomic read
|
|
v = d;
|
|
if (v != 5.0)
|
|
__builtin_abort ();
|
|
}
|
|
if (__builtin_memcmp (&ld, &le, sizeof (ld)) != 0)
|
|
{
|
|
__builtin_memset (&ld, 0xff, sizeof (ld));
|
|
#pragma omp atomic write
|
|
ld = 0.0L;
|
|
__asm volatile ("" : : "g" (&ld) : "memory");
|
|
/* Verify == comparison for atomics is done as with memcmp
|
|
with __builtin_clear_padding if needed. */
|
|
#pragma omp atomic compare
|
|
ld = ld == le ? 5.0L : ld;
|
|
#pragma omp atomic read
|
|
lv = ld;
|
|
if (lv != 0.0L)
|
|
__builtin_abort ();
|
|
#pragma omp atomic compare
|
|
ld = ld == 0.0L ? 5.0L : ld;
|
|
#pragma omp atomic read
|
|
lv = ld;
|
|
if (lv != 5.0L)
|
|
__builtin_abort ();
|
|
}
|
|
return 0;
|
|
}
|