re PR c/67495 (#pragma omp atomic ICEs)
authorJakub Jelinek <jakub@redhat.com>
Wed, 9 Sep 2015 07:23:11 +0000 (09:23 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Wed, 9 Sep 2015 07:23:11 +0000 (09:23 +0200)
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

gcc/c/ChangeLog
gcc/c/c-parser.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/gomp/pr67495.c [new file with mode: 0644]

index a61df71ae8e90c1bc78b67b5050419bbc29341ec..dadec059618e166473b4d4d1e0eda30111d398d5 100644 (file)
@@ -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
index 11a2b0f9731c186032f5fc7e06c1a2f7b27b4be7..86ccbe7730c5fe91bab3db8f273c84e795dcd9c5 100644 (file)
@@ -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)
     {
index 15c503f43f30287821bcdafa89f1611e0fc7af89..4afb642ac93c9a78db13e277c8e6e04b881c090b 100644 (file)
@@ -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 (file)
index 0000000..1011a26
--- /dev/null
@@ -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" } */
+}