Hi! This patch fixes atomic capture with structure block and pre/post inc/decrement and adds tests for it (these forms weren't in the 3.1 draft and were parsed by mistake before and for x++; v = x; and x--; v = x; it actually ICEd).
I haven't added the x = x binop expr forms yet for neither atomic update nor atomic capture, because the new standard is fuzzy about those late additions and I'm waiting for clarifications on openmp.org/forum/. 2011-07-12 Jakub Jelinek <ja...@redhat.com> * c-parser.c (c_parser_omp_atomic): Fix handling of #pragma omp atomic capture { x++; v = x; } and #pragma omp atomic capture { x--; v = x; }. * parser.c (cp_parser_omp_atomic): Fix handling of #pragma omp atomic capture { x++; v = x; } and #pragma omp atomic capture { x--; v = x; }. * testsuite/libgomp.c/atomic-11.c: Add new tests. * testsuite/libgomp.c/atomic-12.c: Likewise. * testsuite/libgomp.c++/atomic-2.C: Likewise. * testsuite/libgomp.c++/atomic-3.C: Likewise. * testsuite/libgomp.c++/atomic-4.C: Likewise. * testsuite/libgomp.c++/atomic-5.C: Likewise. --- gcc/c-parser.c.jj 2011-07-11 17:48:18.000000000 +0200 +++ gcc/c-parser.c 2011-07-12 13:10:57.000000000 +0200 @@ -9157,7 +9157,7 @@ c_parser_omp_structured_block (c_parser capture-stmt: v = x binop= expr | v = x++ | v = ++x | v = x-- | v = --x capture-block: - { v = x; x binop= expr; } | { x binop= expr; v = x; } + { v = x; expression-stmt; } | { expression-stmt; v = x; } where x and v are lvalue expressions with scalar type. @@ -9253,7 +9253,7 @@ restart: return; case POSTINCREMENT_EXPR: - if (code == OMP_ATOMIC_CAPTURE_NEW) + if (code == OMP_ATOMIC_CAPTURE_NEW && !structured_block) code = OMP_ATOMIC_CAPTURE_OLD; /* FALLTHROUGH */ case PREINCREMENT_EXPR: @@ -9263,7 +9263,7 @@ restart: break; case POSTDECREMENT_EXPR: - if (code == OMP_ATOMIC_CAPTURE_NEW) + if (code == OMP_ATOMIC_CAPTURE_NEW && !structured_block) code = OMP_ATOMIC_CAPTURE_OLD; /* FALLTHROUGH */ case PREDECREMENT_EXPR: @@ -9295,6 +9295,7 @@ restart: lhs = TREE_OPERAND (lhs, 0); opcode = NOP_EXPR; if (code == OMP_ATOMIC_CAPTURE_NEW + && !structured_block && TREE_CODE (orig_lhs) == COMPOUND_EXPR) code = OMP_ATOMIC_CAPTURE_OLD; break; @@ -9308,6 +9309,7 @@ restart: lhs = TREE_OPERAND (lhs, 0); opcode = NOP_EXPR; if (code == OMP_ATOMIC_CAPTURE_NEW + && !structured_block && TREE_CODE (orig_lhs) == COMPOUND_EXPR) code = OMP_ATOMIC_CAPTURE_OLD; break; --- gcc/cp/parser.c.jj 2011-07-11 17:43:43.000000000 +0200 +++ gcc/cp/parser.c 2011-07-12 13:48:18.000000000 +0200 @@ -24219,7 +24219,7 @@ cp_parser_omp_structured_block (cp_parse capture-stmt: v = x binop= expr | v = x++ | v = ++x | v = x-- | v = --x capture-block: - { v = x; x binop= expr; } | { x binop= expr; v = x; } + { v = x; expression-stmt; } | { expression-stmt; v = x; } where x and v are lvalue expressions with scalar type. */ @@ -24307,7 +24307,7 @@ restart: goto saw_error; case POSTINCREMENT_EXPR: - if (code == OMP_ATOMIC_CAPTURE_NEW) + if (code == OMP_ATOMIC_CAPTURE_NEW && !structured_block) code = OMP_ATOMIC_CAPTURE_OLD; /* FALLTHROUGH */ case PREINCREMENT_EXPR: @@ -24317,7 +24317,7 @@ restart: break; case POSTDECREMENT_EXPR: - if (code == OMP_ATOMIC_CAPTURE_NEW) + if (code == OMP_ATOMIC_CAPTURE_NEW && !structured_block) code = OMP_ATOMIC_CAPTURE_OLD; /* FALLTHROUGH */ case PREDECREMENT_EXPR: @@ -24349,6 +24349,7 @@ restart: lhs = TREE_OPERAND (lhs, 0); opcode = NOP_EXPR; if (code == OMP_ATOMIC_CAPTURE_NEW + && !structured_block && TREE_CODE (orig_lhs) == COMPOUND_EXPR) code = OMP_ATOMIC_CAPTURE_OLD; break; --- libgomp/testsuite/libgomp.c/atomic-11.c.jj 2011-04-20 18:31:25.000000000 +0200 +++ libgomp/testsuite/libgomp.c/atomic-11.c 2011-07-12 14:05:32.000000000 +0200 @@ -60,6 +60,50 @@ main (void) v = x; if (v != 62) abort (); + #pragma omp atomic capture + { v = x; x++; } + if (v != 62) + abort (); + #pragma omp atomic capture + { v = x; ++x; } + if (v != 63) + abort (); + #pragma omp atomic capture + { + ++x; + v = x; + } + if (v != 65) + abort (); +#pragma omp atomic capture +{x++;v=x;}if (v != 66) + abort (); + #pragma omp atomic read + v = x; + if (v != 66) + abort (); + #pragma omp atomic capture + { v = x; x--; } + if (v != 66) + abort (); + #pragma omp atomic capture + { v = x; --x; } + if (v != 65) + abort (); + #pragma omp atomic capture + { + --x; + v = x; + } + if (v != 63) + abort (); + #pragma omp atomic capture + { x--; v = x; } if (v != 62) + abort (); + #pragma omp atomic read + v = x; + if (v != 62) + abort (); #pragma omp atomic write y = 17.5f; #pragma omp atomic read --- libgomp/testsuite/libgomp.c/atomic-12.c.jj 2011-04-20 18:31:25.000000000 +0200 +++ libgomp/testsuite/libgomp.c/atomic-12.c 2011-07-12 14:13:24.000000000 +0200 @@ -1,7 +1,7 @@ /* { dg-do run } */ extern void abort (void); -_Bool v, x1, x2, x3, x4, x5, x6, x7, x8; +_Bool v, x1, x2, x3, x4, x5, x6; void foo (void) @@ -32,6 +32,59 @@ foo (void) abort (); } +void +bar (void) +{ + #pragma omp atomic write + x1 = 0; + #pragma omp atomic write + x2 = 0; + #pragma omp atomic write + x3 = 1; + #pragma omp atomic write + x4 = 1; + #pragma omp atomic capture + { ++x1; v = x1; } + if (!v) + abort (); + #pragma omp atomic capture + { v = x2; x2++; } + if (v) + abort (); + #pragma omp atomic capture + { --x3; v = x3; } + if (v) + abort (); + #pragma omp atomic capture + { v = x4; x4--; } + if (!v) + abort (); + #pragma omp atomic write + x1 = 0; + #pragma omp atomic write + x2 = 0; + #pragma omp atomic write + x3 = 1; + #pragma omp atomic write + x4 = 1; + #pragma omp atomic capture + { x1++; v = x1; } + if (!v) + abort (); + #pragma omp atomic capture + { v = x2; ++x2; } + if (v) + abort (); + #pragma omp atomic capture + { x3--; v = x3; } + if (v) + abort (); + #pragma omp atomic capture + { v = x4; --x4; } + if (!v) + abort (); +} + int main () { @@ -40,5 +93,6 @@ main () #pragma omp atomic write x4 = 1; foo (); + bar (); return 0; } --- libgomp/testsuite/libgomp.c++/atomic-2.C.jj 2011-04-26 18:53:21.000000000 +0200 +++ libgomp/testsuite/libgomp.c++/atomic-2.C 2011-07-12 14:21:12.000000000 +0200 @@ -60,6 +60,50 @@ main (void) v = x; if (v != 62) abort (); + #pragma omp atomic capture + { v = x; x++; } + if (v != 62) + abort (); + #pragma omp atomic capture + { v = x; ++x; } + if (v != 63) + abort (); + #pragma omp atomic capture + { + ++x; + v = x; + } + if (v != 65) + abort (); +#pragma omp atomic capture +{x++;v=x;}if (v != 66) + abort (); + #pragma omp atomic read + v = x; + if (v != 66) + abort (); + #pragma omp atomic capture + { v = x; x--; } + if (v != 66) + abort (); + #pragma omp atomic capture + { v = x; --x; } + if (v != 65) + abort (); + #pragma omp atomic capture + { + --x; + v = x; + } + if (v != 63) + abort (); + #pragma omp atomic capture + { x--; v = x; } if (v != 62) + abort (); + #pragma omp atomic read + v = x; + if (v != 62) + abort (); #pragma omp atomic write y = 17.5f; #pragma omp atomic read --- libgomp/testsuite/libgomp.c++/atomic-3.C.jj 2011-04-27 09:57:02.000000000 +0200 +++ libgomp/testsuite/libgomp.c++/atomic-3.C 2011-07-12 14:19:12.000000000 +0200 @@ -4,7 +4,7 @@ extern "C" void abort (void); bool v, x1, x2, x3, x4, x5, x6; void -foo (void) +foo () { #pragma omp atomic capture v = ++x1; @@ -32,6 +32,35 @@ foo (void) abort (); } +void +bar () +{ + #pragma omp atomic write + x1 = false; + #pragma omp atomic write + x2 = false; + #pragma omp atomic capture + { ++x1; v = x1; } + if (!v) + abort (); + #pragma omp atomic capture + { v = x2; x2++; } + if (v) + abort (); + #pragma omp atomic write + x1 = false; + #pragma omp atomic write + x2 = false; + #pragma omp atomic capture + { x1++; v = x1; } + if (!v) + abort (); + #pragma omp atomic capture + { v = x2; ++x2; } + if (v) + abort (); +} + int main () { @@ -40,5 +69,6 @@ main () #pragma omp atomic write x4 = true; foo (); + bar (); return 0; } --- libgomp/testsuite/libgomp.c++/atomic-4.C.jj 2011-04-26 19:05:45.000000000 +0200 +++ libgomp/testsuite/libgomp.c++/atomic-4.C 2011-07-12 14:21:42.000000000 +0200 @@ -60,6 +60,50 @@ foo (void) v = x; if (v != 62) abort (); + #pragma omp atomic capture + { v = x; x++; } + if (v != 62) + abort (); + #pragma omp atomic capture + { v = x; ++x; } + if (v != 63) + abort (); + #pragma omp atomic capture + { + ++x; + v = x; + } + if (v != 65) + abort (); +#pragma omp atomic capture +{x++;v=x;}if (v != 66) + abort (); + #pragma omp atomic read + v = x; + if (v != 66) + abort (); + #pragma omp atomic capture + { v = x; x--; } + if (v != 66) + abort (); + #pragma omp atomic capture + { v = x; --x; } + if (v != 65) + abort (); + #pragma omp atomic capture + { + --x; + v = x; + } + if (v != 63) + abort (); + #pragma omp atomic capture + { x--; v = x; } if (v != 62) + abort (); + #pragma omp atomic read + v = x; + if (v != 62) + abort (); #pragma omp atomic write y = 17.5f; #pragma omp atomic read --- libgomp/testsuite/libgomp.c++/atomic-5.C.jj 2011-04-27 09:56:50.000000000 +0200 +++ libgomp/testsuite/libgomp.c++/atomic-5.C 2011-07-12 14:20:09.000000000 +0200 @@ -4,7 +4,7 @@ extern "C" void abort (void); template <typename T> void -foo (void) +foo () { extern T v, x1, x2, x3, x4, x5, x6; #pragma omp atomic capture @@ -33,6 +33,37 @@ foo (void) abort (); } +template <typename T> +void +bar () +{ + extern T v, x1, x2; + #pragma omp atomic write + x1 = false; + #pragma omp atomic write + x2 = false; + #pragma omp atomic capture + { ++x1; v = x1; } + if (!v) + abort (); + #pragma omp atomic capture + { v = x2; x2++; } + if (v) + abort (); + #pragma omp atomic write + x1 = false; + #pragma omp atomic write + x2 = false; + #pragma omp atomic capture + { x1++; v = x1; } + if (!v) + abort (); + #pragma omp atomic capture + { v = x2; ++x2; } + if (v) + abort (); +} + bool v, x1, x2, x3, x4, x5, x6; int @@ -43,5 +74,6 @@ main () #pragma omp atomic write x4 = true; foo <bool> (); + bar <bool> (); return 0; } Jakub