diff options
author | Jakub Jelinek <jakub@redhat.com> | 2015-09-09 09:23:11 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2015-09-09 09:23:11 +0200 |
commit | f4b189d53bbc5def47c17cdc04c1c7fd291f29b1 (patch) | |
tree | 5f941573079243b9c93eaa04c1a90288a8a88bf5 /gcc | |
parent | 04e49571a086621e33261b8e25b35a577195f2d6 (diff) | |
download | gcc-f4b189d53bbc5def47c17cdc04c1c7fd291f29b1.zip gcc-f4b189d53bbc5def47c17cdc04c1c7fd291f29b1.tar.gz gcc-f4b189d53bbc5def47c17cdc04c1c7fd291f29b1.tar.bz2 |
re PR c/67495 (#pragma omp atomic ICEs)
PR c/67495
* c-parser.c (c_parser_omp_atomic): Use c_parser_cast_expression
instead of c_parser_unary_expression. If the result is !lvalue_p,
wrap the result of c_fully_fold into NON_LVALUE_EXPR.
* gcc.dg/gomp/pr67495.c: New test.
From-SVN: r227576
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/c/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/c/c-parser.c | 44 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/gomp/pr67495.c | 38 |
4 files changed, 84 insertions, 10 deletions
diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index a61df71..dadec05 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,10 @@ +2015-09-09 Jakub Jelinek <jakub@redhat.com> + + PR c/67495 + * c-parser.c (c_parser_omp_atomic): Use c_parser_cast_expression + instead of c_parser_unary_expression. If the result is !lvalue_p, + wrap the result of c_fully_fold into NON_LVALUE_EXPR. + 2015-09-04 Marek Polacek <polacek@redhat.com> PR sanitizer/67279 diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c index 11a2b0f..86ccbe7 100644 --- a/gcc/c/c-parser.c +++ b/gcc/c/c-parser.c @@ -12422,6 +12422,7 @@ c_parser_omp_atomic (location_t loc, c_parser *parser) bool structured_block = false; bool swapped = false; bool seq_cst = false; + bool non_lvalue_p; if (c_parser_next_token_is (parser, CPP_NAME)) { @@ -12475,20 +12476,33 @@ c_parser_omp_atomic (location_t loc, c_parser *parser) { case OMP_ATOMIC_READ: case NOP_EXPR: /* atomic write */ - v = c_parser_unary_expression (parser).value; + v = c_parser_cast_expression (parser, NULL).value; + non_lvalue_p = !lvalue_p (v); v = c_fully_fold (v, false, NULL); if (v == error_mark_node) goto saw_error; + if (non_lvalue_p) + v = non_lvalue (v); loc = c_parser_peek_token (parser)->location; if (!c_parser_require (parser, CPP_EQ, "expected %<=%>")) goto saw_error; if (code == NOP_EXPR) - lhs = c_parser_expression (parser).value; + { + lhs = c_parser_expression (parser).value; + lhs = c_fully_fold (lhs, false, NULL); + if (lhs == error_mark_node) + goto saw_error; + } else - lhs = c_parser_unary_expression (parser).value; - lhs = c_fully_fold (lhs, false, NULL); - if (lhs == error_mark_node) - goto saw_error; + { + lhs = c_parser_cast_expression (parser, NULL).value; + non_lvalue_p = !lvalue_p (lhs); + lhs = c_fully_fold (lhs, false, NULL); + if (lhs == error_mark_node) + goto saw_error; + if (non_lvalue_p) + lhs = non_lvalue (lhs); + } if (code == NOP_EXPR) { /* atomic write is represented by OMP_ATOMIC with NOP_EXPR @@ -12507,10 +12521,13 @@ c_parser_omp_atomic (location_t loc, c_parser *parser) } else { - v = c_parser_unary_expression (parser).value; + v = c_parser_cast_expression (parser, NULL).value; + non_lvalue_p = !lvalue_p (v); v = c_fully_fold (v, false, NULL); if (v == error_mark_node) goto saw_error; + if (non_lvalue_p) + v = non_lvalue (v); if (!c_parser_require (parser, CPP_EQ, "expected %<=%>")) goto saw_error; } @@ -12523,7 +12540,7 @@ c_parser_omp_atomic (location_t loc, c_parser *parser) old or new x should be captured. */ restart: eloc = c_parser_peek_token (parser)->location; - expr = c_parser_unary_expression (parser); + expr = c_parser_cast_expression (parser, NULL); lhs = expr.value; expr = default_function_array_conversion (eloc, expr); unfolded_lhs = expr.value; @@ -12616,6 +12633,8 @@ restart: } /* FALLTHRU */ default: + if (!lvalue_p (unfolded_lhs)) + lhs = non_lvalue (lhs); switch (c_parser_peek_token (parser)->type) { case CPP_MULT_EQ: @@ -12730,20 +12749,25 @@ stmt_done: { if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>")) goto saw_error; - v = c_parser_unary_expression (parser).value; + v = c_parser_cast_expression (parser, NULL).value; + non_lvalue_p = !lvalue_p (v); v = c_fully_fold (v, false, NULL); if (v == error_mark_node) goto saw_error; + if (non_lvalue_p) + v = non_lvalue (v); if (!c_parser_require (parser, CPP_EQ, "expected %<=%>")) goto saw_error; eloc = c_parser_peek_token (parser)->location; - expr = c_parser_unary_expression (parser); + expr = c_parser_cast_expression (parser, NULL); lhs1 = expr.value; expr = default_function_array_read_conversion (eloc, expr); unfolded_lhs1 = expr.value; lhs1 = c_fully_fold (lhs1, false, NULL); if (lhs1 == error_mark_node) goto saw_error; + if (!lvalue_p (unfolded_lhs1)) + lhs1 = non_lvalue (lhs1); } if (structured_block) { diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 15c503f..4afb642 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2015-09-09 Jakub Jelinek <jakub@redhat.com> + + PR c/67495 + * gcc.dg/gomp/pr67495.c: New test. + 2015-09-09 Aditya Kumar <hiraditya@msn.com> Sebastian Pop <s.pop@samsung.com> diff --git a/gcc/testsuite/gcc.dg/gomp/pr67495.c b/gcc/testsuite/gcc.dg/gomp/pr67495.c new file mode 100644 index 0000000..1011a26 --- /dev/null +++ b/gcc/testsuite/gcc.dg/gomp/pr67495.c @@ -0,0 +1,38 @@ +/* PR c/67495 */ +/* { dg-do compile } */ +/* { dg-options "-fopenmp" } */ + +int a, b, c; + +void +foo (void) +{ +#pragma omp atomic capture + a = (float)a + b; /* { dg-error "invalid operator" } */ +#pragma omp atomic read + (float) a = b; /* { dg-error "lvalue required" } */ +#pragma omp atomic write + (float) a = b; /* { dg-error "lvalue required" } */ +#pragma omp atomic read + a = (float) b; /* { dg-error "lvalue required" } */ +#pragma omp atomic capture + (float) a = b += c; /* { dg-error "lvalue required" } */ +#pragma omp atomic capture + { a += b; (float) c = a; } /* { dg-error "lvalue required" } */ +#pragma omp atomic capture + { a += b; c = (float) a; } /* { dg-error "uses two different expressions for memory" } */ +#pragma omp atomic capture + a = (int)a + b; /* { dg-error "invalid operator" } */ +#pragma omp atomic read + (int) a = b; /* { dg-error "lvalue required" } */ +#pragma omp atomic write + (int) a = b; /* { dg-error "lvalue required" } */ +#pragma omp atomic read + a = (int) b; /* { dg-error "lvalue required" } */ +#pragma omp atomic capture + (int) a = b += c; /* { dg-error "lvalue required" } */ +#pragma omp atomic capture + { a += b; (int) c = a; } /* { dg-error "lvalue required" } */ +#pragma omp atomic capture + { a += b; c = (int) a; } /* { dg-error "lvalue required" } */ +} |