Hi! #pragma omp atomic write RHS can be arbitrary expression (not mentioning the LHS), so it is wrong to parse it just as unary expression. Fixed thusly, tested on x86_64-linux, committed to gomp-3_1-branch.
2011-04-27 Jakub Jelinek <ja...@redhat.com> * c-parser.c (c_parser_omp_atomic): Parse #pragma omp write RHS using c_parser_expression instead of c_parser_unary_expression. * parser.c (cp_parser_omp_atomic): Parse #pragma omp write RHS using cp_parser_expression instead of cp_parser_unary_expression. * testsuite/libgomp.c/atomic-13.c: New test. * testsuite/libgomp.c++/atomic-6.C: New test. * testsuite/libgomp.c++/atomic-7.C: New test. --- gcc/c-parser.c.jj 2011-04-20 18:31:25.000000000 +0200 +++ gcc/c-parser.c 2011-04-27 17:02:46.000000000 +0200 @@ -9095,7 +9095,10 @@ c_parser_omp_atomic (location_t loc, c_p loc = c_parser_peek_token (parser)->location; if (!c_parser_require (parser, CPP_EQ, "expected %<=%>")) goto saw_error; - lhs = c_parser_unary_expression (parser).value; + if (code == NOP_EXPR) + lhs = c_parser_expression (parser).value; + else + lhs = c_parser_unary_expression (parser).value; lhs = c_fully_fold (lhs, false, NULL); if (lhs == error_mark_node) goto saw_error; --- gcc/cp/parser.c.jj 2011-04-26 18:55:38.000000000 +0200 +++ gcc/cp/parser.c 2011-04-27 17:25:06.000000000 +0200 @@ -24108,8 +24108,11 @@ cp_parser_omp_atomic (cp_parser *parser, goto saw_error; if (!cp_parser_require (parser, CPP_EQ, RT_EQ)) goto saw_error; - lhs = cp_parser_unary_expression (parser, /*address_p=*/false, - /*cast_p=*/false, NULL); + if (code == NOP_EXPR) + lhs = cp_parser_expression (parser, /*cast_p=*/false, NULL); + else + lhs = cp_parser_unary_expression (parser, /*address_p=*/false, + /*cast_p=*/false, NULL); if (lhs == error_mark_node) goto saw_error; if (code == NOP_EXPR) --- libgomp/testsuite/libgomp.c/atomic-13.c.jj 2011-04-27 17:17:17.000000000 +0200 +++ libgomp/testsuite/libgomp.c/atomic-13.c 2011-04-27 17:20:18.000000000 +0200 @@ -0,0 +1,59 @@ +/* { dg-do run } */ + +extern void abort (void); +long long l, m; +int i, j; + +void +foo (void) +{ + #pragma omp atomic read + i = l; + #pragma omp atomic read + m = j; + if (i != 77 || m != 88) + abort (); + #pragma omp atomic write + l = 1 + i + 6 * 1; + #pragma omp atomic write + j = 170 - 170 + m + 1 * 7; + #pragma omp atomic capture + i = l += 4; + #pragma omp atomic capture + m = j += 4; + if (i != 88 || m != 99) + abort (); + #pragma omp atomic capture + { + i = l; + l += 4; + } + #pragma omp atomic capture + { + m = j; + j += 4; + } + if (i != 88 || m != 99) + abort (); + #pragma omp atomic capture + { + l += 4; + i = l; + } + #pragma omp atomic capture + { + j += 4; + m = j; + } + if (i != 96 || m != 107) + abort (); +} + +int +main () +{ + l = 77; + j = 88; + foo (); + return 0; +} --- libgomp/testsuite/libgomp.c++/atomic-6.C.jj 2011-04-27 17:19:46.000000000 +0200 +++ libgomp/testsuite/libgomp.c++/atomic-6.C 2011-04-27 17:21:03.000000000 +0200 @@ -0,0 +1,58 @@ +// { dg-do run } + +extern "C" void abort (void); +long long l, m; +int i, j; + +void +foo (void) +{ + #pragma omp atomic read + i = l; + #pragma omp atomic read + m = j; + if (i != 77 || m != 88) + abort (); + #pragma omp atomic write + l = 1 + i + 6 * 1; + #pragma omp atomic write + j = 170 - 170 + m + 1 * 7; + #pragma omp atomic capture + i = l += 4; + #pragma omp atomic capture + m = j += 4; + if (i != 88 || m != 99) + abort (); + #pragma omp atomic capture + { + i = l; + l += 4; + } + #pragma omp atomic capture + { + m = j; + j += 4; + } + if (i != 88 || m != 99) + abort (); + #pragma omp atomic capture + { + l += 4; + i = l; + } + #pragma omp atomic capture + { + j += 4; + m = j; + } + if (i != 96 || m != 107) + abort (); +} + +int +main () +{ + l = 77; + j = 88; + foo (); +} --- libgomp/testsuite/libgomp.c++/atomic-7.C.jj 2011-04-27 17:21:11.000000000 +0200 +++ libgomp/testsuite/libgomp.c++/atomic-7.C 2011-04-27 17:21:58.000000000 +0200 @@ -0,0 +1,63 @@ +// { dg-do run } + +extern "C" void abort (void); + +template <typename S, typename T> +void +foo (void) +{ + extern S l, m; + extern T i, j; + + #pragma omp atomic read + i = l; + #pragma omp atomic read + m = j; + if (i != 77 || m != 88) + abort (); + #pragma omp atomic write + l = 1 + i + 6 * 1; + #pragma omp atomic write + j = 170 - 170 + m + 1 * 7; + #pragma omp atomic capture + i = l += 4; + #pragma omp atomic capture + m = j += 4; + if (i != 88 || m != 99) + abort (); + #pragma omp atomic capture + { + i = l; + l += 4; + } + #pragma omp atomic capture + { + m = j; + j += 4; + } + if (i != 88 || m != 99) + abort (); + #pragma omp atomic capture + { + l += 4; + i = l; + } + #pragma omp atomic capture + { + j += 4; + m = j; + } + if (i != 96 || m != 107) + abort (); +} + +long long l, m; +int i, j; + +int +main () +{ + l = 77; + j = 88; + foo <long long, int> (); +} Jakub