Hi!

When cp_parser_binary_expression is called with no_toplevel_fold_p
(only for OpenMP parsing), it might create a binary op tree with
error_mark_node as one of the operands, which the rest of the FE
isn't prepared to handle.

This arranges to return error_mark_node instead.

Bootstrapped/regtested on x86_64-linux and i686-linux, committed to trunk.

2018-02-19  Jakub Jelinek  <ja...@redhat.com>

        PR c++/84448
        * parser.c (cp_parser_binary_expression): For no_toplevel_fold_p, if
        either operand is error_mark_node, set current.lhs to that instead of
        creating a binary op with error_mark_node operands.

        * g++.dg/gomp/pr84448.C: New test.

--- gcc/cp/parser.c.jj  2018-02-13 21:21:37.565978250 +0100
+++ gcc/cp/parser.c     2018-02-19 16:14:34.994863674 +0100
@@ -9331,12 +9331,18 @@ cp_parser_binary_expression (cp_parser*
          && lookahead_prec <= current.prec
          && sp == stack)
        {
-         current.lhs
-           = build_min (current.tree_type,
-                        TREE_CODE_CLASS (current.tree_type) == tcc_comparison
-                        ? boolean_type_node : TREE_TYPE (current.lhs),
-                        current.lhs.get_value (), rhs.get_value ());
-         SET_EXPR_LOCATION (current.lhs, combined_loc);
+         if (current.lhs == error_mark_node || rhs == error_mark_node)
+           current.lhs = error_mark_node;
+         else
+           {
+             current.lhs
+               = build_min (current.tree_type,
+                            TREE_CODE_CLASS (current.tree_type)
+                            == tcc_comparison
+                            ? boolean_type_node : TREE_TYPE (current.lhs),
+                            current.lhs.get_value (), rhs.get_value ());
+             SET_EXPR_LOCATION (current.lhs, combined_loc);
+           }
        }
       else
         {
--- gcc/testsuite/g++.dg/gomp/pr84448.C.jj      2018-02-19 16:19:09.614928616 
+0100
+++ gcc/testsuite/g++.dg/gomp/pr84448.C 2018-02-19 16:20:36.703967955 +0100
@@ -0,0 +1,17 @@
+// PR c++/84448
+// { dg-do compile }
+
+struct A
+{
+  operator int () const;
+  A& operator += (int);
+  A& operator ++ ();
+};
+
+void
+foo (A a, A b)
+{
+  #pragma omp for
+  for (A i = a; i <=; ++i)     // { dg-error "expected primary-expression 
before" }
+    ;                          // { dg-error "invalid controlling predicate" 
"" { target *-*-* } .-1 }
+}

        Jakub

Reply via email to