Commit f4b189d5 by Jakub Jelinek Committed by Jakub Jelinek

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
parent 04e49571
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> 2015-09-04 Marek Polacek <polacek@redhat.com>
PR sanitizer/67279 PR sanitizer/67279
......
...@@ -12422,6 +12422,7 @@ c_parser_omp_atomic (location_t loc, c_parser *parser) ...@@ -12422,6 +12422,7 @@ c_parser_omp_atomic (location_t loc, c_parser *parser)
bool structured_block = false; bool structured_block = false;
bool swapped = false; bool swapped = false;
bool seq_cst = false; bool seq_cst = false;
bool non_lvalue_p;
if (c_parser_next_token_is (parser, CPP_NAME)) if (c_parser_next_token_is (parser, CPP_NAME))
{ {
...@@ -12475,20 +12476,33 @@ c_parser_omp_atomic (location_t loc, c_parser *parser) ...@@ -12475,20 +12476,33 @@ c_parser_omp_atomic (location_t loc, c_parser *parser)
{ {
case OMP_ATOMIC_READ: case OMP_ATOMIC_READ:
case NOP_EXPR: /* atomic write */ 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); v = c_fully_fold (v, false, NULL);
if (v == error_mark_node) if (v == error_mark_node)
goto saw_error; goto saw_error;
if (non_lvalue_p)
v = non_lvalue (v);
loc = c_parser_peek_token (parser)->location; loc = c_parser_peek_token (parser)->location;
if (!c_parser_require (parser, CPP_EQ, "expected %<=%>")) if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
goto saw_error; goto saw_error;
if (code == NOP_EXPR) 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 else
lhs = c_parser_unary_expression (parser).value; {
lhs = c_fully_fold (lhs, false, NULL); lhs = c_parser_cast_expression (parser, NULL).value;
if (lhs == error_mark_node) non_lvalue_p = !lvalue_p (lhs);
goto saw_error; 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) if (code == NOP_EXPR)
{ {
/* atomic write is represented by OMP_ATOMIC with 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) ...@@ -12507,10 +12521,13 @@ c_parser_omp_atomic (location_t loc, c_parser *parser)
} }
else 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); v = c_fully_fold (v, false, NULL);
if (v == error_mark_node) if (v == error_mark_node)
goto saw_error; goto saw_error;
if (non_lvalue_p)
v = non_lvalue (v);
if (!c_parser_require (parser, CPP_EQ, "expected %<=%>")) if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
goto saw_error; goto saw_error;
} }
...@@ -12523,7 +12540,7 @@ c_parser_omp_atomic (location_t loc, c_parser *parser) ...@@ -12523,7 +12540,7 @@ c_parser_omp_atomic (location_t loc, c_parser *parser)
old or new x should be captured. */ old or new x should be captured. */
restart: restart:
eloc = c_parser_peek_token (parser)->location; eloc = c_parser_peek_token (parser)->location;
expr = c_parser_unary_expression (parser); expr = c_parser_cast_expression (parser, NULL);
lhs = expr.value; lhs = expr.value;
expr = default_function_array_conversion (eloc, expr); expr = default_function_array_conversion (eloc, expr);
unfolded_lhs = expr.value; unfolded_lhs = expr.value;
...@@ -12616,6 +12633,8 @@ restart: ...@@ -12616,6 +12633,8 @@ restart:
} }
/* FALLTHRU */ /* FALLTHRU */
default: default:
if (!lvalue_p (unfolded_lhs))
lhs = non_lvalue (lhs);
switch (c_parser_peek_token (parser)->type) switch (c_parser_peek_token (parser)->type)
{ {
case CPP_MULT_EQ: case CPP_MULT_EQ:
...@@ -12730,20 +12749,25 @@ stmt_done: ...@@ -12730,20 +12749,25 @@ stmt_done:
{ {
if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>")) if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
goto saw_error; 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); v = c_fully_fold (v, false, NULL);
if (v == error_mark_node) if (v == error_mark_node)
goto saw_error; goto saw_error;
if (non_lvalue_p)
v = non_lvalue (v);
if (!c_parser_require (parser, CPP_EQ, "expected %<=%>")) if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
goto saw_error; goto saw_error;
eloc = c_parser_peek_token (parser)->location; eloc = c_parser_peek_token (parser)->location;
expr = c_parser_unary_expression (parser); expr = c_parser_cast_expression (parser, NULL);
lhs1 = expr.value; lhs1 = expr.value;
expr = default_function_array_read_conversion (eloc, expr); expr = default_function_array_read_conversion (eloc, expr);
unfolded_lhs1 = expr.value; unfolded_lhs1 = expr.value;
lhs1 = c_fully_fold (lhs1, false, NULL); lhs1 = c_fully_fold (lhs1, false, NULL);
if (lhs1 == error_mark_node) if (lhs1 == error_mark_node)
goto saw_error; goto saw_error;
if (!lvalue_p (unfolded_lhs1))
lhs1 = non_lvalue (lhs1);
} }
if (structured_block) if (structured_block)
{ {
......
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> 2015-09-09 Aditya Kumar <hiraditya@msn.com>
Sebastian Pop <s.pop@samsung.com> Sebastian Pop <s.pop@samsung.com>
......
/* 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" } */
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment