openmp: Fix C ICE on OpenMP atomics
authorJakub Jelinek <jakub@redhat.com>
Tue, 24 Nov 2020 08:04:28 +0000 (09:04 +0100)
committerJakub Jelinek <jakub@redhat.com>
Tue, 24 Nov 2020 08:04:28 +0000 (09:04 +0100)
c_parser_binary_expression was using build2 to create a temporary holder
for binary expression that c_parser_atomic and c_finish_omp_atomic can then
handle.  The latter performs then all the needed checking.

Unfortunately, build2 performs some checking too, e.g. PLUS_EXPR vs.
POINTER_PLUS_EXPR or matching types of the arguments, nothing we can guarantee
at the parsing time.  So we need something like C++ build_min_nt*.  This
patch implements that inline.

2020-11-24  Jakub Jelinek  <jakub@redhat.com>

PR c/97958
* c-parser.c (c_parser_binary_expression): For omp atomic binary
expressions, use make_node instead of build2 to avoid checking build2
performs.

* c-c++-common/gomp/pr97958.c: New test.

gcc/c/c-parser.c
gcc/testsuite/c-c++-common/gomp/pr97958.c [new file with mode: 0644]

index 7540a15d65d6f7eb82e11e3188da212de7bf08d8..d86098a6de7f65ad620f648f0e9f79d2a6adfe79 100644 (file)
@@ -7865,9 +7865,13 @@ c_parser_binary_expression (c_parser *parser, struct c_expr *after,
        && stack[1].expr.value != error_mark_node                             \
        && (c_tree_equal (stack[0].expr.value, omp_atomic_lhs)                \
            || c_tree_equal (stack[1].expr.value, omp_atomic_lhs)))           \
-      stack[0].expr.value                                                    \
-       = build2 (stack[1].op, TREE_TYPE (stack[0].expr.value),               \
-                 stack[0].expr.value, stack[1].expr.value);                  \
+      {                                                                              \
+       tree t = make_node (stack[1].op);                                     \
+       TREE_TYPE (t) = TREE_TYPE (stack[0].expr.value);                      \
+       TREE_OPERAND (t, 0) = stack[0].expr.value;                            \
+       TREE_OPERAND (t, 1) = stack[1].expr.value;                            \
+       stack[0].expr.value = t;                                              \
+      }                                                                              \
     else                                                                     \
       stack[sp - 1].expr = parser_build_binary_op (stack[sp].loc,            \
                                                   stack[sp].op,              \
diff --git a/gcc/testsuite/c-c++-common/gomp/pr97958.c b/gcc/testsuite/c-c++-common/gomp/pr97958.c
new file mode 100644 (file)
index 0000000..5a6de02
--- /dev/null
@@ -0,0 +1,17 @@
+/* PR c/97958 */
+
+int *p;
+
+void
+foo (void)
+{
+  #pragma omp atomic
+  p = p + 1;
+}
+
+void
+bar (void)
+{
+  #pragma omp atomic   /* { dg-error "invalid expression type for '#pragma omp atomic'" } */
+  bar = bar + 1;
+}