[committed] Fix OpenMP parsing error-recovery (PR c++/84448)

Message ID 20180219191848.GU5867@tucnak
State New
Headers show
Series
  • [committed] Fix OpenMP parsing error-recovery (PR c++/84448)
Related show

Commit Message

Jakub Jelinek Feb. 19, 2018, 7:18 p.m.
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  <jakub@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.


	Jakub

Patch

--- 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 }
+}