aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2015-09-09 09:23:11 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2015-09-09 09:23:11 +0200
commitf4b189d53bbc5def47c17cdc04c1c7fd291f29b1 (patch)
tree5f941573079243b9c93eaa04c1a90288a8a88bf5 /gcc
parent04e49571a086621e33261b8e25b35a577195f2d6 (diff)
downloadgcc-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/ChangeLog7
-rw-r--r--gcc/c/c-parser.c44
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/gomp/pr67495.c38
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" } */
+}