aboutsummaryrefslogtreecommitdiff
path: root/gcc/testsuite
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2021-09-17 11:28:31 +0200
committerJakub Jelinek <jakub@redhat.com>2021-09-17 11:28:31 +0200
commit3a2bcffac602f5de56537a77db1062984bcefd45 (patch)
treeae688b9db0bfa75b79552f4d331ba4758e7a69cb /gcc/testsuite
parent48b3caffcacc99adf72ba1be189a7d9ebc4190be (diff)
downloadgcc-3a2bcffac602f5de56537a77db1062984bcefd45.zip
gcc-3a2bcffac602f5de56537a77db1062984bcefd45.tar.gz
gcc-3a2bcffac602f5de56537a77db1062984bcefd45.tar.bz2
openmp: Add support for OpenMP 5.1 atomics for C++
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.
Diffstat (limited to 'gcc/testsuite')
-rw-r--r--gcc/testsuite/c-c++-common/gomp/atomic-18.c8
-rw-r--r--gcc/testsuite/c-c++-common/gomp/atomic-25.c2
-rw-r--r--gcc/testsuite/c-c++-common/gomp/atomic-26.c2
-rw-r--r--gcc/testsuite/c-c++-common/gomp/atomic-27.c2
-rw-r--r--gcc/testsuite/c-c++-common/gomp/atomic-28.c2
-rw-r--r--gcc/testsuite/c-c++-common/gomp/atomic-29.c2
-rw-r--r--gcc/testsuite/c-c++-common/gomp/atomic-30.c97
-rw-r--r--gcc/testsuite/g++.dg/gomp/atomic-20.C104
-rw-r--r--gcc/testsuite/g++.dg/gomp/atomic-5.C2
9 files changed, 164 insertions, 57 deletions
diff --git a/gcc/testsuite/c-c++-common/gomp/atomic-18.c b/gcc/testsuite/c-c++-common/gomp/atomic-18.c
index b389c6a..a8ed3c7 100644
--- a/gcc/testsuite/c-c++-common/gomp/atomic-18.c
+++ b/gcc/testsuite/c-c++-common/gomp/atomic-18.c
@@ -12,14 +12,12 @@ foo (int j)
v = i;
#pragma omp atomic acquire , write /* { dg-error "incompatible with 'acquire' clause" } */
i = v;
- #pragma omp atomic capture hint (0) capture /* { dg-error "too many 'capture' clauses" "" { target c } } */
- /* { dg-error "too many atomic clauses" "" { target c++ } .-1 } */
+ #pragma omp atomic capture hint (0) capture /* { dg-error "too many 'capture' clauses" } */
v = i = i + 1;
#pragma omp atomic hint(j + 2) /* { dg-error "constant integer expression" } */
i = i + 1;
#pragma omp atomic hint(f) /* { dg-error "integ" } */
i = i + 1;
- #pragma omp atomic foobar /* { dg-error "expected 'read', 'write', 'update', 'capture', 'compare', 'weak', 'fail', 'seq_cst', 'acq_rel', 'release', 'relaxed' or 'hint' clause" "" { target c } } */
- /* { dg-error "expected 'read', 'write', 'update', 'capture', 'seq_cst', 'acq_rel', 'release', 'relaxed' or 'hint' clause" "" { target c++ } .-1 } */
- i = i + 1; /* { dg-error "expected end of line before" "" { target *-*-* } .-2 } */
+ #pragma omp atomic foobar /* { dg-error "expected 'read', 'write', 'update', 'capture', 'compare', 'weak', 'fail', 'seq_cst', 'acq_rel', 'release', 'relaxed' or 'hint' clause" } */
+ i = i + 1; /* { dg-error "expected end of line before" "" { target *-*-* } .-1 } */
}
diff --git a/gcc/testsuite/c-c++-common/gomp/atomic-25.c b/gcc/testsuite/c-c++-common/gomp/atomic-25.c
index a5196a5..653ef18 100644
--- a/gcc/testsuite/c-c++-common/gomp/atomic-25.c
+++ b/gcc/testsuite/c-c++-common/gomp/atomic-25.c
@@ -1,4 +1,4 @@
-/* { dg-do compile { target c } } */
+/* { dg-do compile } */
int x, r, z;
double d, v;
diff --git a/gcc/testsuite/c-c++-common/gomp/atomic-26.c b/gcc/testsuite/c-c++-common/gomp/atomic-26.c
index c7e65db..b7a4a1f 100644
--- a/gcc/testsuite/c-c++-common/gomp/atomic-26.c
+++ b/gcc/testsuite/c-c++-common/gomp/atomic-26.c
@@ -1,4 +1,4 @@
-/* { dg-do compile { target c } } */
+/* { dg-do compile } */
int x;
double d;
diff --git a/gcc/testsuite/c-c++-common/gomp/atomic-27.c b/gcc/testsuite/c-c++-common/gomp/atomic-27.c
index 3d61717..8f1e7e9 100644
--- a/gcc/testsuite/c-c++-common/gomp/atomic-27.c
+++ b/gcc/testsuite/c-c++-common/gomp/atomic-27.c
@@ -1,5 +1,5 @@
/* PR middle-end/88968 */
-/* { dg-do compile { target c } } */
+/* { dg-do compile } */
struct __attribute__((packed)) S {
unsigned int a : 16;
diff --git a/gcc/testsuite/c-c++-common/gomp/atomic-28.c b/gcc/testsuite/c-c++-common/gomp/atomic-28.c
index 50cf223..853ae1c 100644
--- a/gcc/testsuite/c-c++-common/gomp/atomic-28.c
+++ b/gcc/testsuite/c-c++-common/gomp/atomic-28.c
@@ -1,4 +1,4 @@
-/* { dg-do compile { target c } } */
+/* { dg-do compile } */
/* { dg-additional-options "-O2 -fdump-tree-ompexp" } */
/* { dg-final { scan-tree-dump-times "\.ATOMIC_COMPARE_EXCHANGE \\\(\[^\n\r]*, 4, 5, 5\\\);" 1 "ompexp" { target sync_int_long } } } */
/* { dg-final { scan-tree-dump-times "\.ATOMIC_COMPARE_EXCHANGE \\\(\[^\n\r]*, 4, 4, 2\\\);" 1 "ompexp" { target sync_int_long } } } */
diff --git a/gcc/testsuite/c-c++-common/gomp/atomic-29.c b/gcc/testsuite/c-c++-common/gomp/atomic-29.c
index 97fe33b..1081e43 100644
--- a/gcc/testsuite/c-c++-common/gomp/atomic-29.c
+++ b/gcc/testsuite/c-c++-common/gomp/atomic-29.c
@@ -1,4 +1,4 @@
-/* { dg-do compile { target c } } */
+/* { dg-do compile } */
/* { dg-additional-options "-O2 -fdump-tree-ompexp" } */
/* { dg-additional-options "-march=pentium" { target ia32 } } */
/* { dg-final { scan-tree-dump-times "\.ATOMIC_COMPARE_EXCHANGE \\\(\[^\n\r]*, 8, 5, 5\\\);" 1 "ompexp" { target sync_long_long } } } */
diff --git a/gcc/testsuite/c-c++-common/gomp/atomic-30.c b/gcc/testsuite/c-c++-common/gomp/atomic-30.c
index f36de70..37a30bb 100644
--- a/gcc/testsuite/c-c++-common/gomp/atomic-30.c
+++ b/gcc/testsuite/c-c++-common/gomp/atomic-30.c
@@ -1,9 +1,9 @@
-/* { dg-do compile { target c } } */
+/* { dg-do compile } */
int x;
double d, g;
-double
+void
foo (int y, double e, long double f)
{
double v;
@@ -21,18 +21,18 @@ foo (int y, double e, long double f)
#pragma omp atomic compare
if (d + e) { d = e; } /* { dg-error "expected '==', '<' or '>' comparison in 'if' condition" } */
#pragma omp atomic capture compare
- { r = d >= e; if (r) { d = f; } } /* { dg-error "expected '==', '<' or '>' comparison in 'if' condition" } */
- #pragma omp atomic capture compare
- { r = d <= e; if (r) { d = f; } } /* { dg-error "expected '==', '<' or '>' comparison in 'if' condition" } */
- #pragma omp atomic capture compare
- { r = d > e; if (r) { d = f; } } /* { dg-error "expected '==', '<' or '>' comparison in 'if' condition" } */
- #pragma omp atomic capture compare
- { r = d < e; if (r) { d = f; } } /* { dg-error "expected '==', '<' or '>' comparison in 'if' condition" } */
- #pragma omp atomic capture compare
- { r = d != e; if (r) { d = f; } } /* { dg-error "expected '==', '<' or '>' comparison in 'if' condition" } */
- #pragma omp atomic capture compare
- { r = d + e; if (r) { d = f; } } /* { dg-error "expected '==', '<' or '>' comparison in 'if' condition" } */
- #pragma omp atomic capture compare
+ { r = d >= e; if (r) { d = f; } } /* { dg-error "expected '==', '<' or '>' comparison in 'if' condition" "" { target c } } */
+ #pragma omp atomic capture compare /* { dg-error "invalid form of '#pragma omp atomic' before 'd'" "" { target c++ } .-1 } */
+ { r = d <= e; if (r) { d = f; } } /* { dg-error "expected '==', '<' or '>' comparison in 'if' condition" "" { target c } } */
+ #pragma omp atomic capture compare /* { dg-error "invalid form of '#pragma omp atomic' before 'd'" "" { target c++ } .-1 } */
+ { r = d > e; if (r) { d = f; } } /* { dg-error "expected '==', '<' or '>' comparison in 'if' condition" "" { target c } } */
+ #pragma omp atomic capture compare /* { dg-error "invalid form of '#pragma omp atomic' before 'd'" "" { target c++ } .-1 } */
+ { r = d < e; if (r) { d = f; } } /* { dg-error "expected '==', '<' or '>' comparison in 'if' condition" "" { target c } } */
+ #pragma omp atomic capture compare /* { dg-error "invalid form of '#pragma omp atomic' before 'd'" "" { target c++ } .-1 } */
+ { r = d != e; if (r) { d = f; } } /* { dg-error "expected '==', '<' or '>' comparison in 'if' condition" "" { target c } } */
+ #pragma omp atomic capture compare /* { dg-error "invalid form of '#pragma omp atomic' before 'd'" "" { target c++ } .-1 } */
+ { r = d + e; if (r) { d = f; } } /* { dg-error "expected '==', '<' or '>' comparison in 'if' condition" "" { target c } } */
+ #pragma omp atomic capture compare /* { dg-error "invalid form of '#pragma omp atomic' before 'd'" "" { target c++ } .-1 } */
{ r = d == e; if (r2) { d = f; } } /* { dg-error "invalid form of '#pragma omp atomic compare' before '\{' token" } */
#pragma omp atomic capture compare
if (d > e) { d = e; } /* { dg-error "expected '==' comparison in 'if' condition" } */
@@ -97,41 +97,46 @@ foo (int y, double e, long double f)
#pragma omp atomic compare
x ^= 5; /* { dg-error "expected '=' before '\\\^=' token" } */
#pragma omp atomic compare
- x = x + 3; /* { dg-error "invalid form of '#pragma omp atomic' before ';' token" } */
- #pragma omp atomic compare
- x = x - 5; /* { dg-error "invalid form of '#pragma omp atomic' before ';' token" } */
- #pragma omp atomic compare
- x = 2 * x; /* { dg-error "invalid form of '#pragma omp atomic' before ';' token" } */
- #pragma omp atomic compare
- x = 5 | x; /* { dg-error "invalid form of '#pragma omp atomic' before ';' token" } */
- #pragma omp atomic compare
- x = x & ~5; /* { dg-error "invalid form of '#pragma omp atomic' before ';' token" } */
- #pragma omp atomic compare
- x = x | 5; /* { dg-error "invalid form of '#pragma omp atomic' before ';' token" } */
- #pragma omp atomic compare
- x = x >= 5 ? 5 : x; /* { dg-error "invalid form of '#pragma omp atomic' before ';' token" } */
- #pragma omp atomic compare
- x = x <= 5 ? 5 : x; /* { dg-error "invalid form of '#pragma omp atomic' before ';' token" } */
- #pragma omp atomic compare
- x = x != 5 ? 7 : x; /* { dg-error "invalid form of '#pragma omp atomic' before ';' token" } */
- #pragma omp atomic compare
- x = 5 == x ? 7 : x; /* { dg-error "invalid form of '#pragma omp atomic' before ';' token" } */
- #pragma omp atomic compare
- x = x == 5 ? x : 7; /* { dg-error "invalid form of '#pragma omp atomic' before ';' token" } */
- #pragma omp atomic compare
- x = x == 5 ? 9 : 7; /* { dg-error "invalid form of '#pragma omp atomic' before ';' token" } */
- #pragma omp atomic compare
- x = x > 5 ? 6 : x; /* { dg-error "invalid form of '#pragma omp atomic' before ';' token" } */
- #pragma omp atomic compare
- x = x < 5 ? 6 : x; /* { dg-error "invalid form of '#pragma omp atomic' before ';' token" } */
- #pragma omp atomic compare
- x = x > 5 ? x : 6; /* { dg-error "invalid form of '#pragma omp atomic' before ';' token" } */
- #pragma omp atomic compare
- x = x < 5 ? x : 6; /* { dg-error "invalid form of '#pragma omp atomic' before ';' token" } */
- #pragma omp atomic capture
+ x = x + 3; /* { dg-error "invalid form of '#pragma omp atomic' before ';' token" "" { target c } } */
+ #pragma omp atomic compare /* { dg-error "invalid form of '#pragma omp atomic compare' before '\\\+' token" "" { target c++ } .-1 } */
+ x = x - 5; /* { dg-error "invalid form of '#pragma omp atomic' before ';' token" "" { target c } } */
+ #pragma omp atomic compare /* { dg-error "invalid form of '#pragma omp atomic compare' before '-' token" "" { target c++ } .-1 } */
+ x = 2 * x; /* { dg-error "invalid form of '#pragma omp atomic' before ';' token" "" { target c } } */
+ #pragma omp atomic compare /* { dg-error "invalid form of '#pragma omp atomic' before numeric constant" "" { target c++ } .-1 } */
+ x = 5 | x; /* { dg-error "invalid form of '#pragma omp atomic' before ';' token" "" { target c } } */
+ #pragma omp atomic compare /* { dg-error "invalid form of '#pragma omp atomic' before numeric constant" "" { target c++ } .-1 } */
+ x = x & ~5; /* { dg-error "invalid form of '#pragma omp atomic' before ';' token" "" { target c } } */
+ #pragma omp atomic compare /* { dg-error "invalid form of '#pragma omp atomic compare' before '\\\&' token" "" { target c++ } .-1 } */
+ x = x | 5; /* { dg-error "invalid form of '#pragma omp atomic' before ';' token" "" { target c } } */
+ #pragma omp atomic compare /* { dg-error "invalid form of '#pragma omp atomic compare' before '\\\|' token" "" { target c++ } .-1 } */
+ x = x >= 5 ? 5 : x; /* { dg-error "invalid form of '#pragma omp atomic' before ';' token" "" { target c } } */
+ #pragma omp atomic compare /* { dg-error "invalid operator for '#pragma omp atomic' before '>=' token" "" { target c++ } .-1 } */
+ x = x <= 5 ? 5 : x; /* { dg-error "invalid form of '#pragma omp atomic' before ';' token" "" { target c } } */
+ #pragma omp atomic compare /* { dg-error "invalid operator for '#pragma omp atomic' before '<=' token" "" { target c++ } .-1 } */
+ x = x != 5 ? 7 : x; /* { dg-error "invalid form of '#pragma omp atomic' before ';' token" "" { target c } } */
+ #pragma omp atomic compare /* { dg-error "invalid operator for '#pragma omp atomic' before '!=' token" "" { target c++ } .-1 } */
+ x = 5 == x ? 7 : x; /* { dg-error "invalid form of '#pragma omp atomic' before ';' token" "" { target c } } */
+ #pragma omp atomic compare /* { dg-error "invalid form of '#pragma omp atomic' before numeric constant" "" { target c++ } .-1 } */
+ x = x == 5 ? x : 7; /* { dg-error "invalid form of '#pragma omp atomic' before ';' token" "" { target c } } */
+ #pragma omp atomic compare /* { dg-error "invalid form of '#pragma omp atomic compare' before ';' token" "" { target c++ } .-1 } */
+ x = x == 5 ? 9 : 7; /* { dg-error "invalid form of '#pragma omp atomic' before ';' token" "" { target c } } */
+ #pragma omp atomic compare /* { dg-error "invalid form of '#pragma omp atomic compare' before ';' token" "" { target c++ } .-1 } */
+ x = x > 5 ? 6 : x; /* { dg-error "invalid form of '#pragma omp atomic' before ';' token" "" { target c } } */
+ #pragma omp atomic compare /* { dg-error "invalid form of '#pragma omp atomic compare' before ';' token" "" { target c++ } .-1 } */
+ x = x < 5 ? 6 : x; /* { dg-error "invalid form of '#pragma omp atomic' before ';' token" "" { target c } } */
+ #pragma omp atomic compare /* { dg-error "invalid form of '#pragma omp atomic compare' before ';' token" "" { target c++ } .-1 } */
+ x = x > 5 ? x : 6; /* { dg-error "invalid form of '#pragma omp atomic' before ';' token" "" { target c } } */
+ #pragma omp atomic compare /* { dg-error "invalid form of '#pragma omp atomic compare' before ';' token" "" { target c++ } .-1 } */
+ x = x < 5 ? x : 6; /* { dg-error "invalid form of '#pragma omp atomic' before ';' token" "" { target c } } */
+ #pragma omp atomic capture /* { dg-error "invalid form of '#pragma omp atomic compare' before ';' token" "" { target c++ } .-1 } */
r = x == 5; /* { dg-error "invalid operator for '#pragma omp atomic' before '==' token" } */
#pragma omp atomic capture compare
r = x == 5; /* { dg-error "expected '=' before '==' token" } */
#pragma omp atomic capture compare /* { dg-error "'#pragma omp atomic compare capture' with non-integral comparison result" } */
{ v = x == 5; if (v) { x = 6; } }
+ #pragma omp atomic compare capture
+ { r2 = x; x = y; } /* { dg-error "invalid form of '#pragma omp atomic' before ';' token" } */
+ #pragma omp atomic compare capture
+ { r2 = x; x = y == 7 ? 12 : y; } /* { dg-error "invalid form of '#pragma omp atomic' before ';' token" "" { target c } } */
+ /* { dg-error "invalid form of '#pragma omp atomic' before 'y'" "" { target c++ } .-1 } */
}
diff --git a/gcc/testsuite/g++.dg/gomp/atomic-20.C b/gcc/testsuite/g++.dg/gomp/atomic-20.C
new file mode 100644
index 0000000..cb7a37b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/gomp/atomic-20.C
@@ -0,0 +1,104 @@
+// { dg-do compile }
+
+int x, r, z;
+double d, v;
+long double ld;
+
+template <int N>
+void
+foo (int y, double e, long double f)
+{
+ #pragma omp atomic compare update seq_cst
+ x = x > y ? y : x;
+ #pragma omp atomic compare relaxed
+ d = e > d ? e : d;
+ #pragma omp atomic compare
+ d = f < d ? f : d;
+ #pragma omp atomic compare seq_cst fail(relaxed)
+ x = 12U < x ? 12U : x;
+ #pragma omp atomic compare
+ x = x == 7 ? 24 : x;
+ #pragma omp atomic compare
+ x = x == 123UL ? 256LL : x;
+ #pragma omp atomic compare
+ ld = ld == f ? f + 5.0L : ld;
+ #pragma omp atomic compare
+ if (x == 9) { x = 5; }
+ #pragma omp atomic compare
+ if (x > 5) { x = 5; }
+ #pragma omp atomic compare
+ if (7 > x) { x = 7; }
+ #pragma omp atomic compare update capture seq_cst fail(acquire)
+ v = d = f > d ? f : d;
+ #pragma omp atomic update capture compare
+ v = x = x < 24ULL ? 24ULL : x;
+ #pragma omp atomic compare, capture, update
+ v = x = x == e ? f : x;
+ #pragma omp atomic capture compare
+ { v = d; if (d > e) { d = e; } }
+ #pragma omp atomic compare capture
+ { if (e < d) { d = e; } v = d; }
+ #pragma omp atomic compare capture
+ { y = x; if (x == 42) { x = 7; } }
+ #pragma omp atomic capture compare weak
+ { if (x == 42) { x = 7; } y = x; }
+ #pragma omp atomic capture compare fail(seq_cst)
+ if (d == 8.0) { d = 16.0; } else { v = d; }
+ #pragma omp atomic capture compare
+ { r = x == 8; if (r) { x = 24; } }
+ #pragma omp atomic compare capture
+ { r = x == y; if (r) { x = y + 6; } else { z = x; } }
+}
+
+template <typename I, typename D, typename LD>
+void
+bar (I &x, I &r, I &z, D &d, D &v, LD &ld, I y, D e, LD f)
+{
+ #pragma omp atomic compare update seq_cst
+ x = x > y ? y : x;
+ #pragma omp atomic compare relaxed
+ d = e > d ? e : d;
+ #pragma omp atomic compare
+ d = f < d ? f : d;
+ #pragma omp atomic compare seq_cst fail(relaxed)
+ x = 12U < x ? 12U : x;
+ #pragma omp atomic compare
+ x = x == 7 ? 24 : x;
+ #pragma omp atomic compare
+ x = x == 123UL ? 256LL : x;
+ #pragma omp atomic compare
+ ld = ld == f ? f + 5.0L : ld;
+ #pragma omp atomic compare
+ if (x == 9) { x = 5; }
+ #pragma omp atomic compare
+ if (x > 5) { x = 5; }
+ #pragma omp atomic compare
+ if (7 > x) { x = 7; }
+ #pragma omp atomic compare update capture seq_cst fail(acquire)
+ v = d = f > d ? f : d;
+ #pragma omp atomic update capture compare
+ v = x = x < 24ULL ? 24ULL : x;
+ #pragma omp atomic compare, capture, update
+ v = x = x == e ? f : x;
+ #pragma omp atomic capture compare
+ { v = d; if (d > e) { d = e; } }
+ #pragma omp atomic compare capture
+ { if (e < d) { d = e; } v = d; }
+ #pragma omp atomic compare capture
+ { y = x; if (x == 42) { x = 7; } }
+ #pragma omp atomic capture compare weak
+ { if (x == 42) { x = 7; } y = x; }
+ #pragma omp atomic capture compare fail(seq_cst)
+ if (d == 8.0) { d = 16.0; } else { v = d; }
+ #pragma omp atomic capture compare
+ { r = x == 8; if (r) { x = 24; } }
+ #pragma omp atomic compare capture
+ { r = x == y; if (r) { x = y + 6; } else { z = x; } }
+}
+
+void
+baz (int y, double e, long double f)
+{
+ foo <0> (y, e, f);
+ bar (x, r, z, d, v, ld, y, e, f);
+}
diff --git a/gcc/testsuite/g++.dg/gomp/atomic-5.C b/gcc/testsuite/g++.dg/gomp/atomic-5.C
index 78f6344..e2fd591 100644
--- a/gcc/testsuite/g++.dg/gomp/atomic-5.C
+++ b/gcc/testsuite/g++.dg/gomp/atomic-5.C
@@ -23,7 +23,7 @@ void f1(void)
#pragma omp atomic
bar() += 1; /* { dg-error "lvalue required" } */
#pragma omp atomic a /* { dg-error "expected end of line" } */
- x++; /* { dg-error "expected 'read', 'write', 'update', 'capture', 'seq_cst', 'acq_rel', 'release', 'relaxed' or 'hint' clause" "" { target *-*-* } .-1 } */
+ x++; /* { dg-error "expected 'read', 'write', 'update', 'capture', 'compare', 'weak', 'fail', 'seq_cst', 'acq_rel', 'release', 'relaxed' or 'hint' clause" "" { target *-*-* } .-1 } */
#pragma omp atomic
; /* { dg-error "expected primary-expression" } */
#pragma omp atomic