diff gcc/cp/semantics.c @ 131:84e7813d76e9

gcc-8.2
author mir3636
date Thu, 25 Oct 2018 07:37:49 +0900
parents 04ced10e8804
children 1830386684a0
line wrap: on
line diff
--- a/gcc/cp/semantics.c	Fri Oct 27 22:46:09 2017 +0900
+++ b/gcc/cp/semantics.c	Thu Oct 25 07:37:49 2018 +0900
@@ -3,7 +3,7 @@
    building RTL.  These routines are used both during actual parsing
    and during the instantiation of template functions.
 
-   Copyright (C) 1998-2017 Free Software Foundation, Inc.
+   Copyright (C) 1998-2018 Free Software Foundation, Inc.
    Written by Mark Mitchell (mmitchell@usa.net) based on code found
    formerly in parse.y and pt.c.
 
@@ -410,8 +410,6 @@
 {
   if (!processing_template_decl && stmts_are_full_exprs_p ())
     expr = fold_build_cleanup_point_expr (TREE_TYPE (expr), expr);
-  else
-    expr = do_dependent_capture (expr);
   return expr;
 }
 
@@ -425,8 +423,6 @@
 {
   if (!processing_template_decl && stmts_are_full_exprs_p ())
     expr = fold_build_cleanup_point_expr (void_type_node, expr);
-  else
-    expr = do_dependent_capture (expr);
   return expr;
 }
 
@@ -618,10 +614,6 @@
     TREE_USED (destination) = 1;
   else
     {
-      if (check_no_cilk (destination,
-	 "Cilk array notation cannot be used as a computed goto expression",
-	 "%<_Cilk_spawn%> statement cannot be used as a computed goto expression"))
-	destination = error_mark_node;
       destination = mark_rvalue_use (destination);
       if (!processing_template_decl)
 	{
@@ -633,8 +625,6 @@
 	    = fold_build_cleanup_point_expr (TREE_TYPE (destination),
 					     destination);
 	}
-      else
-	destination = do_dependent_capture (destination);
     }
 
   check_goto (destination);
@@ -656,7 +646,7 @@
 
   /* Wait until we instantiate templates before doing conversion.  */
   if (processing_template_decl)
-    return do_dependent_capture (cond);
+    return cond;
 
   if (warn_sequence_point)
     verify_sequence_points (cond);
@@ -668,7 +658,7 @@
       && !TREE_NO_WARNING (cond)
       && warn_parentheses)
     {
-      warning_at (EXPR_LOC_OR_LOC (cond, input_location), OPT_Wparentheses,
+      warning_at (cp_expr_loc_or_loc (cond, input_location), OPT_Wparentheses,
 		  "suggest parentheses around assignment used as truth value");
       TREE_NO_WARNING (cond) = 1;
     }
@@ -741,8 +731,12 @@
 {
   cond = maybe_convert_cond (cond);
   if (IF_STMT_CONSTEXPR_P (if_stmt)
-      && is_constant_expression (cond)
-      && !value_dependent_expression_p (cond))
+      && !type_dependent_expression_p (cond)
+      && require_constant_expression (cond)
+      && !instantiation_dependent_expression_p (cond)
+      /* Wait until instantiation time, since only then COND has been
+	 converted to bool.  */
+      && TYPE_MAIN_VARIANT (TREE_TYPE (cond)) == boolean_type_node)
     {
       cond = instantiate_non_dependent_expr (cond);
       cond = cxx_constant_value (cond, NULL_TREE);
@@ -808,21 +802,27 @@
    WHILE_STMT.  */
 
 void
-finish_while_stmt_cond (tree cond, tree while_stmt, bool ivdep)
-{
-  if (check_no_cilk (cond,
-      "Cilk array notation cannot be used as a condition for while statement",
-      "%<_Cilk_spawn%> statement cannot be used as a condition for while statement"))
-    cond = error_mark_node;
+finish_while_stmt_cond (tree cond, tree while_stmt, bool ivdep,
+			unsigned short unroll)
+{
   cond = maybe_convert_cond (cond);
   finish_cond (&WHILE_COND (while_stmt), cond);
   begin_maybe_infinite_loop (cond);
   if (ivdep && cond != error_mark_node)
-    WHILE_COND (while_stmt) = build2 (ANNOTATE_EXPR,
+    WHILE_COND (while_stmt) = build3 (ANNOTATE_EXPR,
 				      TREE_TYPE (WHILE_COND (while_stmt)),
 				      WHILE_COND (while_stmt),
 				      build_int_cst (integer_type_node,
-						     annot_expr_ivdep_kind));
+						     annot_expr_ivdep_kind),
+				      integer_zero_node);
+  if (unroll && cond != error_mark_node)
+    WHILE_COND (while_stmt) = build3 (ANNOTATE_EXPR,
+				      TREE_TYPE (WHILE_COND (while_stmt)),
+				      WHILE_COND (while_stmt),
+				      build_int_cst (integer_type_node,
+						     annot_expr_unroll_kind),
+				      build_int_cst (integer_type_node,
+						     unroll));
   simplify_loop_decl_cond (&WHILE_COND (while_stmt), WHILE_BODY (while_stmt));
 }
 
@@ -867,17 +867,18 @@
    COND is as indicated.  */
 
 void
-finish_do_stmt (tree cond, tree do_stmt, bool ivdep)
-{
-  if (check_no_cilk (cond,
-  "Cilk array notation cannot be used as a condition for a do-while statement",
-  "%<_Cilk_spawn%> statement cannot be used as a condition for a do-while statement"))
-    cond = error_mark_node;
+finish_do_stmt (tree cond, tree do_stmt, bool ivdep, unsigned short unroll)
+{
   cond = maybe_convert_cond (cond);
   end_maybe_infinite_loop (cond);
   if (ivdep && cond != error_mark_node)
-    cond = build2 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
-		   build_int_cst (integer_type_node, annot_expr_ivdep_kind));
+    cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
+		   build_int_cst (integer_type_node, annot_expr_ivdep_kind),
+		   integer_zero_node);
+  if (unroll && cond != error_mark_node)
+    cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
+		   build_int_cst (integer_type_node, annot_expr_unroll_kind),
+		   build_int_cst (integer_type_node, unroll));
   DO_COND (do_stmt) = cond;
 }
 
@@ -933,9 +934,7 @@
 tree
 begin_for_scope (tree *init)
 {
-  tree scope = NULL_TREE;
-  if (flag_new_for_scope > 0)
-    scope = do_pushlevel (sk_for);
+  tree scope = do_pushlevel (sk_for);
 
   if (processing_template_decl)
     *init = push_stmt_list ();
@@ -959,10 +958,10 @@
 
   if (scope == NULL_TREE)
     {
-      gcc_assert (!init || !(flag_new_for_scope > 0));
-      if (!init)
-	scope = begin_for_scope (&init);
-    }
+      gcc_assert (!init);
+      scope = begin_for_scope (&init);
+    }
+
   FOR_INIT_STMT (r) = init;
   FOR_SCOPE (r) = scope;
 
@@ -986,21 +985,26 @@
    FOR_STMT.  */
 
 void
-finish_for_cond (tree cond, tree for_stmt, bool ivdep)
-{
-  if (check_no_cilk (cond,
-	 "Cilk array notation cannot be used in a condition for a for-loop",
-	 "%<_Cilk_spawn%> statement cannot be used in a condition for a for-loop"))
-    cond = error_mark_node;
+finish_for_cond (tree cond, tree for_stmt, bool ivdep, unsigned short unroll)
+{
   cond = maybe_convert_cond (cond);
   finish_cond (&FOR_COND (for_stmt), cond);
   begin_maybe_infinite_loop (cond);
   if (ivdep && cond != error_mark_node)
-    FOR_COND (for_stmt) = build2 (ANNOTATE_EXPR,
+    FOR_COND (for_stmt) = build3 (ANNOTATE_EXPR,
 				  TREE_TYPE (FOR_COND (for_stmt)),
 				  FOR_COND (for_stmt),
 				  build_int_cst (integer_type_node,
-						 annot_expr_ivdep_kind));
+						 annot_expr_ivdep_kind),
+				  integer_zero_node);
+  if (unroll && cond != error_mark_node)
+    FOR_COND (for_stmt) = build3 (ANNOTATE_EXPR,
+				  TREE_TYPE (FOR_COND (for_stmt)),
+				  FOR_COND (for_stmt),
+				  build_int_cst (integer_type_node,
+						 annot_expr_unroll_kind),
+				  build_int_cst (integer_type_node,
+						 unroll));
   simplify_loop_decl_cond (&FOR_COND (for_stmt), FOR_BODY (for_stmt));
 }
 
@@ -1051,16 +1055,40 @@
     FOR_BODY (for_stmt) = do_poplevel (FOR_BODY (for_stmt));
 
   /* Pop the scope for the body of the loop.  */
-  if (flag_new_for_scope > 0)
-    {
-      tree scope;
-      tree *scope_ptr = (TREE_CODE (for_stmt) == RANGE_FOR_STMT
-			 ? &RANGE_FOR_SCOPE (for_stmt)
-			 : &FOR_SCOPE (for_stmt));
-      scope = *scope_ptr;
-      *scope_ptr = NULL;
-      add_stmt (do_poplevel (scope));
-    }
+  tree *scope_ptr = (TREE_CODE (for_stmt) == RANGE_FOR_STMT
+		     ? &RANGE_FOR_SCOPE (for_stmt)
+		     : &FOR_SCOPE (for_stmt));
+  tree scope = *scope_ptr;
+  *scope_ptr = NULL;
+
+  /* During parsing of the body, range for uses "__for_{range,begin,end} "
+     decl names to make those unaccessible by code in the body.
+     Change it to ones with underscore instead of space, so that it can
+     be inspected in the debugger.  */
+  tree range_for_decl[3] = { NULL_TREE, NULL_TREE, NULL_TREE };
+  gcc_assert (CPTI_FOR_BEGIN__IDENTIFIER == CPTI_FOR_RANGE__IDENTIFIER + 1
+	      && CPTI_FOR_END__IDENTIFIER == CPTI_FOR_RANGE__IDENTIFIER + 2
+	      && CPTI_FOR_RANGE_IDENTIFIER == CPTI_FOR_RANGE__IDENTIFIER + 3
+	      && CPTI_FOR_BEGIN_IDENTIFIER == CPTI_FOR_BEGIN__IDENTIFIER + 3
+	      && CPTI_FOR_END_IDENTIFIER == CPTI_FOR_END__IDENTIFIER + 3);
+  for (int i = 0; i < 3; i++)
+    {
+      tree id = cp_global_trees[CPTI_FOR_RANGE__IDENTIFIER + i];
+      if (IDENTIFIER_BINDING (id)
+	  && IDENTIFIER_BINDING (id)->scope == current_binding_level)
+	{
+	  range_for_decl[i] = IDENTIFIER_BINDING (id)->value;
+	  gcc_assert (VAR_P (range_for_decl[i])
+		      && DECL_ARTIFICIAL (range_for_decl[i]));
+	}
+    }
+
+  add_stmt (do_poplevel (scope));
+
+  for (int i = 0; i < 3; i++)
+    if (range_for_decl[i])
+      DECL_NAME (range_for_decl[i])
+	= cp_global_trees[CPTI_FOR_RANGE_IDENTIFIER + i];
 }
 
 /* Begin a range-for-statement.  Returns a new RANGE_FOR_STMT.
@@ -1071,36 +1099,34 @@
 tree
 begin_range_for_stmt (tree scope, tree init)
 {
-  tree r;
-
   begin_maybe_infinite_loop (boolean_false_node);
 
-  r = build_stmt (input_location, RANGE_FOR_STMT,
-		  NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE);
+  tree r = build_stmt (input_location, RANGE_FOR_STMT, NULL_TREE, NULL_TREE,
+		       NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE);
 
   if (scope == NULL_TREE)
     {
-      gcc_assert (!init || !(flag_new_for_scope > 0));
-      if (!init)
-	scope = begin_for_scope (&init);
-    }
-
-  /* RANGE_FOR_STMTs do not use nor save the init tree, so we
-     pop it now.  */
-  if (init)
-    pop_stmt_list (init);
+      gcc_assert (!init);
+      scope = begin_for_scope (&init);
+    }
+
+  /* Since C++20, RANGE_FOR_STMTs can use the init tree, so save it.  */
+  RANGE_FOR_INIT_STMT (r) = init;
   RANGE_FOR_SCOPE (r) = scope;
 
   return r;
 }
 
 /* Finish the head of a range-based for statement, which may
-   be given by RANGE_FOR_STMT. DECL must be the declaration
+   be given by RANGE_FOR_STMT.  DECL must be the declaration
    and EXPR must be the loop expression. */
 
 void
 finish_range_for_decl (tree range_for_stmt, tree decl, tree expr)
 {
+  if (processing_template_decl)
+    RANGE_FOR_INIT_STMT (range_for_stmt)
+      = pop_stmt_list (RANGE_FOR_INIT_STMT (range_for_stmt));
   RANGE_FOR_DECL (range_for_stmt) = decl;
   RANGE_FOR_EXPR (range_for_stmt) = expr;
   add_stmt (range_for_stmt);
@@ -1121,6 +1147,7 @@
      understand.  */
   if (!block_may_fallthru (cur_stmt_list))
     return void_node;
+  note_break_stmt ();
   return add_stmt (build_stmt (input_location, BREAK_STMT));
 }
 
@@ -1155,11 +1182,6 @@
 {
   tree orig_type = NULL;
 
-  if (check_no_cilk (cond,
-	"Cilk array notation cannot be used as a condition for switch statement",
-	"%<_Cilk_spawn%> statement cannot be used as a condition for switch statement"))
-    cond = error_mark_node;
-
   if (!processing_template_decl)
     {
       /* Convert the condition to an integer or enumeration type.  */
@@ -1341,7 +1363,7 @@
       if (warn_catch_value
 	  && type != NULL_TREE
 	  && type != error_mark_node
-	  && TREE_CODE (TREE_TYPE (decl)) != REFERENCE_TYPE)
+	  && !TYPE_REF_P (TREE_TYPE (decl)))
 	{
 	  tree orig_type = TREE_TYPE (decl);
 	  if (CLASS_TYPE_P (orig_type))
@@ -1511,7 +1533,22 @@
 		     effectively const.  */
 		  || (CLASS_TYPE_P (TREE_TYPE (operand))
 		      && C_TYPE_FIELDS_READONLY (TREE_TYPE (operand)))))
-	    cxx_readonly_error (operand, lv_asm);
+	    cxx_readonly_error (input_location, operand, lv_asm);
+
+	  tree *op = &operand;
+	  while (TREE_CODE (*op) == COMPOUND_EXPR)
+	    op = &TREE_OPERAND (*op, 1);
+	  switch (TREE_CODE (*op))
+	    {
+	    case PREINCREMENT_EXPR:
+	    case PREDECREMENT_EXPR:
+	    case MODIFY_EXPR:
+	      *op = genericize_compound_lvalue (*op);
+	      op = &TREE_OPERAND (*op, 1);
+	      break;
+	    default:
+	      break;
+	    }
 
 	  constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (t)));
 	  oconstraints[i] = constraint;
@@ -1521,7 +1558,7 @@
 	    {
 	      /* If the operand is going to end up in memory,
 		 mark it addressable.  */
-	      if (!allows_reg && !cxx_mark_addressable (operand))
+	      if (!allows_reg && !cxx_mark_addressable (*op))
 		operand = error_mark_node;
 	    }
 	  else
@@ -1563,7 +1600,23 @@
 		  /* Strip the nops as we allow this case.  FIXME, this really
 		     should be rejected or made deprecated.  */
 		  STRIP_NOPS (operand);
-		  if (!cxx_mark_addressable (operand))
+
+		  tree *op = &operand;
+		  while (TREE_CODE (*op) == COMPOUND_EXPR)
+		    op = &TREE_OPERAND (*op, 1);
+		  switch (TREE_CODE (*op))
+		    {
+		    case PREINCREMENT_EXPR:
+		    case PREDECREMENT_EXPR:
+		    case MODIFY_EXPR:
+		      *op = genericize_compound_lvalue (*op);
+		      op = &TREE_OPERAND (*op, 1);
+		      break;
+		    default:
+		      break;
+		    }
+
+		  if (!cxx_mark_addressable (*op))
 		    operand = error_mark_node;
 		}
 	      else if (!allows_reg && !allows_mem)
@@ -1694,25 +1747,12 @@
   if (TREE_CODE (expr) == COMPONENT_REF
       || TREE_CODE (expr) == SCOPE_REF)
     REF_PARENTHESIZED_P (expr) = true;
-  else if (type_dependent_expression_p (expr))
+  else if (processing_template_decl)
     expr = build1 (PAREN_EXPR, TREE_TYPE (expr), expr);
-  else if (VAR_P (expr) && DECL_HARD_REGISTER (expr))
-    /* We can't bind a hard register variable to a reference.  */;
   else
     {
-      cp_lvalue_kind kind = lvalue_kind (expr);
-      if ((kind & ~clk_class) != clk_none)
-	{
-	  tree type = unlowered_expr_type (expr);
-	  bool rval = !!(kind & clk_rvalueref);
-	  type = cp_build_reference_type (type, rval);
-	  /* This inhibits warnings in, eg, cxx_mark_addressable
-	     (c++/60955).  */
-	  warning_sentinel s (extra_warnings);
-	  expr = build_static_cast (type, expr, tf_error);
-	  if (expr != error_mark_node)
-	    REF_PARENTHESIZED_P (expr) = true;
-	}
+      expr = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (expr), expr);
+      REF_PARENTHESIZED_P (expr) = true;
     }
 
   return expr;
@@ -1725,9 +1765,10 @@
 tree
 maybe_undo_parenthesized_ref (tree t)
 {
-  if (cxx_dialect >= cxx14
-      && INDIRECT_REF_P (t)
-      && REF_PARENTHESIZED_P (t))
+  if (cxx_dialect < cxx14)
+    return t;
+
+  if (INDIRECT_REF_P (t) && REF_PARENTHESIZED_P (t))
     {
       t = TREE_OPERAND (t, 0);
       while (TREE_CODE (t) == NON_LVALUE_EXPR
@@ -1738,6 +1779,11 @@
 		  || TREE_CODE (t) == STATIC_CAST_EXPR);
       t = TREE_OPERAND (t, 0);
     }
+  else if (TREE_CODE (t) == PAREN_EXPR)
+    t = TREE_OPERAND (t, 0);
+  else if (TREE_CODE (t) == VIEW_CONVERT_EXPR
+	   && REF_PARENTHESIZED_P (t))
+    t = TREE_OPERAND (t, 0);
 
   return t;
 }
@@ -1808,7 +1854,7 @@
     {
       tree type = TREE_TYPE (decl);
 
-      if (TREE_CODE (type) == REFERENCE_TYPE)
+      if (TYPE_REF_P (type))
 	/* Quals on the object don't matter.  */;
       else if (PACK_EXPANSION_P (type))
 	/* Don't bother trying to represent this.  */
@@ -2003,12 +2049,12 @@
   if (template_p)
     {
       if (TREE_CODE (expr) == UNBOUND_CLASS_TEMPLATE)
-	/* cp_parser_lookup_name thought we were looking for a type,
-	   but we're actually looking for a declaration.  */
-	expr = build_qualified_name (/*type*/NULL_TREE,
-				     TYPE_CONTEXT (expr),
-				     TYPE_IDENTIFIER (expr),
-				     /*template_p*/true);
+	{
+	  /* cp_parser_lookup_name thought we were looking for a type,
+	     but we're actually looking for a declaration.  */
+	  qualifying_class = TYPE_CONTEXT (expr);
+	  expr = TYPE_IDENTIFIER (expr);
+	}
       else
 	check_template_keyword (expr);
     }
@@ -2025,7 +2071,8 @@
     }
 
   /* No need to check access within an enum.  */
-  if (TREE_CODE (qualifying_class) == ENUMERAL_TYPE)
+  if (TREE_CODE (qualifying_class) == ENUMERAL_TYPE
+      && TREE_CODE (expr) != IDENTIFIER_NODE)
     return expr;
 
   /* Within the scope of a class, turn references to non-static
@@ -2070,6 +2117,8 @@
 	 non-type template argument handling.  */
       if (processing_template_decl
 	  && (!currently_open_class (qualifying_class)
+	      || TREE_CODE (expr) == IDENTIFIER_NODE
+	      || TREE_CODE (expr) == TEMPLATE_ID_EXPR
 	      || TREE_CODE (expr) == BIT_NOT_EXPR))
 	expr = build_qualified_name (TREE_TYPE (expr),
 				     qualifying_class, expr,
@@ -2112,7 +2161,14 @@
     {
       tree type = TREE_TYPE (expr);
 
-      if (processing_template_decl)
+      if (type && type_unknown_p (type))
+	{
+	  error ("a statement expression is an insufficient context"
+		 " for overload resolution");
+	  TREE_TYPE (stmt_expr) = error_mark_node;
+	  return error_mark_node;
+	}
+      else if (processing_template_decl)
 	{
 	  expr = build_stmt (input_location, EXPR_STMT, expr);
 	  expr = add_stmt (expr);
@@ -2288,6 +2344,11 @@
 	  else
 	    fn = identifier;
 	}
+      else if (TREE_CODE (fn) == OVERLOAD && processing_template_decl)
+	/* FIXME: We shouldn't really need to mark the lookup here, as
+	   resolving the (non-dependent) call should save the single
+	   function we resolve to.  Related to PR c++/83529.  */
+	lookup_keep (fn);
     }
 
   if (fn && template_id && fn != error_mark_node)
@@ -2313,7 +2374,7 @@
 {
   tree result;
   tree orig_fn;
-  vec<tree, va_gc> *orig_args = NULL;
+  vec<tree, va_gc> *orig_args = *args;
 
   if (fn == error_mark_node)
     return error_mark_node;
@@ -2345,13 +2406,10 @@
 	  || any_type_dependent_arguments_p (*args))
 	{
 	  result = build_min_nt_call_vec (orig_fn, *args);
-	  SET_EXPR_LOCATION (result, EXPR_LOC_OR_LOC (fn, input_location));
+	  SET_EXPR_LOCATION (result, cp_expr_loc_or_loc (fn, input_location));
 	  KOENIG_LOOKUP_P (result) = koenig_p;
 	  if (is_overloaded_fn (fn))
-	    {
-	      fn = get_fns (fn);
-	      lookup_keep (fn, true);
-	    }
+	    fn = get_fns (fn);
 
 	  if (cfun)
 	    {
@@ -2487,6 +2545,21 @@
 		 sizeof_arg, same_type_ignoring_top_level_qualifiers_p);
 	    }
 
+	  if ((complain & tf_warning)
+	      && TREE_CODE (fn) == FUNCTION_DECL
+	      && fndecl_built_in_p (fn, BUILT_IN_MEMSET)
+	      && vec_safe_length (*args) == 3
+	      && !any_type_dependent_arguments_p (*args))
+	    {
+	      tree arg0 = (*orig_args)[0];
+	      tree arg1 = (*orig_args)[1];
+	      tree arg2 = (*orig_args)[2];
+	      int literal_mask = ((literal_integer_zerop (arg1) << 1)
+				  | (literal_integer_zerop (arg2) << 2));
+	      arg2 = instantiate_non_dependent_expr (arg2);
+	      warn_for_memset (input_location, arg0, arg2, literal_mask);
+	    }
+
 	  /* A call to a namespace-scope function.  */
 	  result = build_new_function_call (fn, args, complain);
 	}
@@ -2522,10 +2595,6 @@
       result = convert_from_reference (result);
     }
 
-  /* Free or retain OVERLOADs from lookup.  */
-  if (is_overloaded_fn (orig_fn))
-    lookup_keep (get_fns (orig_fn), processing_template_decl);
-
   return result;
 }
 
@@ -2658,13 +2727,14 @@
   /* TODO: build_x_unary_op doesn't always honor the location.  */
   result.set_location (combined_loc);
 
-  tree result_ovl, expr_ovl;
+  if (result == error_mark_node)
+    return result;
 
   if (!(complain & tf_warning))
     return result;
 
-  result_ovl = result;
-  expr_ovl = expr;
+  tree result_ovl = result;
+  tree expr_ovl = expr;
 
   if (!processing_template_decl)
     expr_ovl = cp_fully_fold (expr_ovl);
@@ -2694,12 +2764,15 @@
   if (type == error_mark_node)
     return error_mark_node;
 
-  if (TREE_CODE (type) == REFERENCE_TYPE)
+  if (TYPE_REF_P (type))
     {
       compound_literal
 	= finish_compound_literal (TREE_TYPE (type), compound_literal,
 				   complain, fcl_context);
-      return cp_build_c_cast (type, compound_literal, complain);
+      /* The prvalue is then used to direct-initialize the reference.  */
+      tree r = (perform_implicit_conversion_flags
+		(type, compound_literal, complain, LOOKUP_NORMAL));
+      return convert_from_reference (r);
     }
 
   if (!TYPE_OBJ_P (type))
@@ -3291,10 +3364,14 @@
 }
 
 /* DECL satisfies outer_automatic_var_p.  Possibly complain about it or
-   rewrite it for lambda capture.  */
+   rewrite it for lambda capture.
+
+   If ODR_USE is true, we're being called from mark_use, and we complain about
+   use of constant variables.  If ODR_USE is false, we're being called for the
+   id-expression, and we do lambda capture.  */
 
 tree
-process_outer_var_ref (tree decl, tsubst_flags_t complain, bool force_use)
+process_outer_var_ref (tree decl, tsubst_flags_t complain, bool odr_use)
 {
   if (cp_unevaluated_operand)
     /* It's not a use (3.2) if we're in an unevaluated context.  */
@@ -3315,12 +3392,6 @@
   if (parsing_nsdmi ())
     containing_function = NULL_TREE;
 
-  /* Core issue 696: Only an odr-use of an outer automatic variable causes a
-     capture (or error), and a constant variable can decay to a prvalue
-     constant without odr-use.  So don't capture yet.  */
-  if (decl_constant_var_p (decl) && !force_use)
-    return decl;
-
   if (containing_function && LAMBDA_FUNCTION_P (containing_function))
     {
       /* Check whether we've already built a proxy.  */
@@ -3336,7 +3407,7 @@
 	    return d;
 	  else
 	    /* We need to capture an outer proxy.  */
-	    return process_outer_var_ref (d, complain, force_use);
+	    return process_outer_var_ref (d, complain, odr_use);
 	}
     }
 
@@ -3382,12 +3453,19 @@
 	error ("cannot capture member %qD of anonymous union", decl);
       return error_mark_node;
     }
-  if (context == containing_function)
+  /* Do lambda capture when processing the id-expression, not when
+     odr-using a variable.  */
+  if (!odr_use && context == containing_function)
     {
       decl = add_default_capture (lambda_stack,
 				  /*id=*/DECL_NAME (decl),
 				  initializer);
     }
+  /* Only an odr-use of an outer automatic variable causes an
+     error, and a constant variable can decay to a prvalue
+     constant without odr-use.  So don't complain yet.  */
+  else if (!odr_use && decl_constant_var_p (decl))
+    return decl;
   else if (lambda_expr)
     {
       if (complain & tf_error)
@@ -3399,7 +3477,7 @@
 	    inform (location_of (closure),
 		    "the lambda has no capture-default");
 	  else if (TYPE_CLASS_SCOPE_P (closure))
-	    inform (0, "lambda in local class %q+T cannot "
+	    inform (UNKNOWN_LOCATION, "lambda in local class %q+T cannot "
 		    "capture variables from the enclosing context",
 		    TYPE_CONTEXT (closure));
 	  inform (DECL_SOURCE_LOCATION (decl), "%q#D declared here", decl);
@@ -3511,11 +3589,6 @@
 	  else
 	    decl = id_expression;
 	}
-      /* If DECL is a variable that would be out of scope under
-	 ANSI/ISO rules, but in scope in the ARM, name lookup
-	 will succeed.  Issue a diagnostic here.  */
-      else
-	decl = check_for_out_of_scope_variable (decl);
 
       /* Remember that the name was used in the definition of
 	 the current class so that we can check later to see if
@@ -3837,49 +3910,36 @@
 }
 
 /* Implement the __direct_bases keyword: Return the direct base classes
-   of type */
+   of type.  */
 
 tree
-calculate_direct_bases (tree type)
-{
-  vec<tree, va_gc> *vector = make_tree_vector();
-  tree bases_vec = NULL_TREE;
-  vec<tree, va_gc> *base_binfos;
+calculate_direct_bases (tree type, tsubst_flags_t complain)
+{
+  if (!complete_type_or_maybe_complain (type, NULL_TREE, complain)
+      || !NON_UNION_CLASS_TYPE_P (type))
+    return make_tree_vec (0);
+
+  vec<tree, va_gc> *vector = make_tree_vector ();
+  vec<tree, va_gc> *base_binfos = BINFO_BASE_BINFOS (TYPE_BINFO (type));
   tree binfo;
   unsigned i;
 
-  complete_type (type);
-
-  if (!NON_UNION_CLASS_TYPE_P (type))
-    return make_tree_vec (0);
-
-  base_binfos = BINFO_BASE_BINFOS (TYPE_BINFO (type));
-
   /* Virtual bases are initialized first */
   for (i = 0; base_binfos->iterate (i, &binfo); i++)
-    {
-      if (BINFO_VIRTUAL_P (binfo))
-       {
-         vec_safe_push (vector, binfo);
-       }
-    }
+    if (BINFO_VIRTUAL_P (binfo))
+      vec_safe_push (vector, binfo);
 
   /* Now non-virtuals */
   for (i = 0; base_binfos->iterate (i, &binfo); i++)
-    {
-      if (!BINFO_VIRTUAL_P (binfo))
-       {
-         vec_safe_push (vector, binfo);
-       }
-    }
-
-
-  bases_vec = make_tree_vec (vector->length ());
+    if (!BINFO_VIRTUAL_P (binfo))
+      vec_safe_push (vector, binfo);
+
+  tree bases_vec = make_tree_vec (vector->length ());
 
   for (i = 0; i < vector->length (); ++i)
-    {
-      TREE_VEC_ELT (bases_vec, i) = BINFO_TYPE ((*vector)[i]);
-    }
+    TREE_VEC_ELT (bases_vec, i) = BINFO_TYPE ((*vector)[i]);
+
+  release_tree_vector (vector);
   return bases_vec;
 }
 
@@ -3901,9 +3961,7 @@
 {
   vec<tree, va_gc> **data = ((vec<tree, va_gc> **) data_);
   if (!BINFO_VIRTUAL_P (binfo))
-    {
-      vec_safe_push (*data, BINFO_TYPE (binfo));
-    }
+    vec_safe_push (*data, BINFO_TYPE (binfo));
   return NULL_TREE;
 }
 
@@ -3911,7 +3969,7 @@
 static vec<tree, va_gc> *
 calculate_bases_helper (tree type)
 {
-  vec<tree, va_gc> *vector = make_tree_vector();
+  vec<tree, va_gc> *vector = make_tree_vector ();
 
   /* Now add non-virtual base classes in order of construction */
   if (TYPE_BINFO (type))
@@ -3921,26 +3979,25 @@
 }
 
 tree
-calculate_bases (tree type)
-{
-  vec<tree, va_gc> *vector = make_tree_vector();
+calculate_bases (tree type, tsubst_flags_t complain)
+{
+  if (!complete_type_or_maybe_complain (type, NULL_TREE, complain)
+      || !NON_UNION_CLASS_TYPE_P (type))
+    return make_tree_vec (0);
+
+  vec<tree, va_gc> *vector = make_tree_vector ();
   tree bases_vec = NULL_TREE;
   unsigned i;
   vec<tree, va_gc> *vbases;
   vec<tree, va_gc> *nonvbases;
   tree binfo;
 
-  complete_type (type);
-
-  if (!NON_UNION_CLASS_TYPE_P (type))
-    return make_tree_vec (0);
-
   /* First go through virtual base classes */
   for (vbases = CLASSTYPE_VBASECLASSES (type), i = 0;
        vec_safe_iterate (vbases, i, &binfo); i++)
     {
-      vec<tree, va_gc> *vbase_bases;
-      vbase_bases = calculate_bases_helper (BINFO_TYPE (binfo));
+      vec<tree, va_gc> *vbase_bases
+	= calculate_bases_helper (BINFO_TYPE (binfo));
       vec_safe_splice (vector, vbase_bases);
       release_tree_vector (vbase_bases);
     }
@@ -3954,7 +4011,7 @@
   if (vector->length () > 1)
     {
       /* Last element is entire class, so don't copy */
-      bases_vec = make_tree_vec (vector->length() - 1);
+      bases_vec = make_tree_vec (vector->length () - 1);
 
       for (i = 0; i < vector->length () - 1; ++i)
 	TREE_VEC_ELT (bases_vec, i) = (*vector)[i];
@@ -4011,17 +4068,22 @@
       || TREE_CODE (TREE_TYPE (expr)) == METHOD_TYPE
       || TREE_TYPE (expr) == unknown_type_node)
     {
-      if (INDIRECT_REF_P (expr))
-	error ("second operand of %<offsetof%> is neither a single "
-	       "identifier nor a sequence of member accesses and "
-	       "array references");
+      while (TREE_CODE (expr) == COMPONENT_REF
+	     || TREE_CODE (expr) == COMPOUND_EXPR)
+	expr = TREE_OPERAND (expr, 1);
+
+      if (DECL_P (expr))
+	{
+	  error ("cannot apply %<offsetof%> to member function %qD", expr);
+	  inform (DECL_SOURCE_LOCATION (expr), "declared here");
+	}
       else
-	{
-	  if (TREE_CODE (expr) == COMPONENT_REF
-	      || TREE_CODE (expr) == COMPOUND_EXPR)
-	    expr = TREE_OPERAND (expr, 1);
-	  error ("cannot apply %<offsetof%> to member function %qD", expr);
-	}
+	error ("cannot apply %<offsetof%> to member function");
+      return error_mark_node;
+    }
+  if (TREE_CODE (expr) == CONST_DECL)
+    {
+      error ("cannot apply %<offsetof%> to an enumerator %qD", expr);
       return error_mark_node;
     }
   if (REFERENCE_REF_P (expr))
@@ -4032,9 +4094,9 @@
       && CLASS_TYPE_P (TREE_TYPE (TREE_TYPE (object_ptr)))
       && CLASSTYPE_NON_STD_LAYOUT (TREE_TYPE (TREE_TYPE (object_ptr)))
       && cp_unevaluated_operand == 0)
-    pedwarn (loc, OPT_Winvalid_offsetof,
-	     "offsetof within non-standard-layout type %qT is undefined",
-	     TREE_TYPE (TREE_TYPE (object_ptr)));
+    warning_at (loc, OPT_Winvalid_offsetof, "offsetof within "
+		"non-standard-layout type %qT is conditionally-supported",
+		TREE_TYPE (TREE_TYPE (object_ptr)));
   return fold_offsetof (expr);
 }
 
@@ -4078,8 +4140,6 @@
     = CALL_EXPR_OPERATOR_SYNTAX (aggr_init_expr);
   CALL_EXPR_ORDERED_ARGS (call_expr) = CALL_EXPR_ORDERED_ARGS (aggr_init_expr);
   CALL_EXPR_REVERSE_ARGS (call_expr) = CALL_EXPR_REVERSE_ARGS (aggr_init_expr);
-  /* Preserve CILK_SPAWN flag.  */
-  EXPR_CILK_SPAWN (call_expr) = EXPR_CILK_SPAWN (aggr_init_expr);
 
   if (style == ctor)
     {
@@ -4390,7 +4450,7 @@
       && DECL_OMP_PRIVATIZED_MEMBER (decl))
     {
       tree f = DECL_VALUE_EXPR (decl);
-      if (TREE_CODE (f) == INDIRECT_REF)
+      if (INDIRECT_REF_P (f))
 	f = TREE_OPERAND (f, 0);
       if (TREE_CODE (f) == COMPONENT_REF)
 	{
@@ -4443,9 +4503,9 @@
     return error_mark_node;
   if (!omp_private_member_map && !shared)
     omp_private_member_map = new hash_map<tree, tree>;
-  if (TREE_CODE (TREE_TYPE (t)) == REFERENCE_TYPE)
-    {
-      gcc_assert (TREE_CODE (m) == INDIRECT_REF);
+  if (TYPE_REF_P (TREE_TYPE (t)))
+    {
+      gcc_assert (INDIRECT_REF_P (m));
       m = TREE_OPERAND (m, 0);
     }
   tree vb = NULL_TREE;
@@ -4761,7 +4821,7 @@
 	    }
 	}
     }
-  else if (TREE_CODE (type) == POINTER_TYPE)
+  else if (TYPE_PTR_P (type))
     {
       if (length == NULL_TREE)
 	{
@@ -4975,8 +5035,8 @@
 		eltype = TREE_TYPE (eltype);
 	      tree type = build_array_type (eltype, index_type);
 	      tree ptype = build_pointer_type (eltype);
-	      if (TREE_CODE (TREE_TYPE (t)) == REFERENCE_TYPE
-		  && POINTER_TYPE_P (TREE_TYPE (TREE_TYPE (t))))
+	      if (TYPE_REF_P (TREE_TYPE (t))
+		  && INDIRECT_TYPE_P (TREE_TYPE (TREE_TYPE (t))))
 		t = convert_from_reference (t);
 	      else if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
 		t = build_fold_addr_expr (t);
@@ -5051,7 +5111,7 @@
 				ptrdiff_type_node, t);
 	  tree ptr = OMP_CLAUSE_DECL (c2);
 	  ptr = convert_from_reference (ptr);
-	  if (!POINTER_TYPE_P (TREE_TYPE (ptr)))
+	  if (!INDIRECT_TYPE_P (TREE_TYPE (ptr)))
 	    ptr = build_fold_addr_expr (ptr);
 	  t = fold_build2_loc (OMP_CLAUSE_LOCATION (c), MINUS_EXPR,
 			       ptrdiff_type_node, t,
@@ -5062,8 +5122,8 @@
 	  OMP_CLAUSE_CHAIN (c) = c2;
 	  ptr = OMP_CLAUSE_DECL (c2);
 	  if (OMP_CLAUSE_MAP_KIND (c2) != GOMP_MAP_FIRSTPRIVATE_POINTER
-	      && TREE_CODE (TREE_TYPE (ptr)) == REFERENCE_TYPE
-	      && POINTER_TYPE_P (TREE_TYPE (TREE_TYPE (ptr))))
+	      && TYPE_REF_P (TREE_TYPE (ptr))
+	      && INDIRECT_TYPE_P (TREE_TYPE (TREE_TYPE (ptr))))
 	    {
 	      tree c3 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
 					  OMP_CLAUSE_MAP);
@@ -5099,7 +5159,7 @@
     case BIT_IOR_EXPR:
     case TRUTH_ANDIF_EXPR:
     case TRUTH_ORIF_EXPR:
-      reduction_id = cp_operator_id (reduction_code);
+      reduction_id = ovl_op_identifier (false, reduction_code);
       break;
     case MIN_EXPR:
       p = "min";
@@ -5329,7 +5389,7 @@
 cp_check_omp_declare_reduction (tree udr)
 {
   tree type = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (udr)));
-  gcc_assert (TREE_CODE (type) == REFERENCE_TYPE);
+  gcc_assert (TYPE_REF_P (type));
   type = TREE_TYPE (type);
   int i;
   location_t loc = DECL_SOURCE_LOCATION (udr);
@@ -5380,7 +5440,7 @@
 		     "%<#pragma omp declare reduction%>", type);
       return;
     }
-  else if (TREE_CODE (type) == REFERENCE_TYPE)
+  else if (TYPE_REF_P (type))
     {
       error_at (loc, "reference type %qT in %<#pragma omp declare reduction%>",
 		type);
@@ -5489,7 +5549,7 @@
   tree type = TREE_TYPE (t);
   if (TREE_CODE (t) == MEM_REF)
     type = TREE_TYPE (type);
-  if (TREE_CODE (type) == REFERENCE_TYPE)
+  if (TYPE_REF_P (type))
     type = TREE_TYPE (type);
   if (TREE_CODE (type) == ARRAY_TYPE)
     {
@@ -5572,7 +5632,11 @@
       return false;
     }
   else if (processing_template_decl)
-    return false;
+    {
+      if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c) == error_mark_node)
+	return true;
+      return false;
+    }
 
   tree id = OMP_CLAUSE_REDUCTION_PLACEHOLDER (c);
 
@@ -5625,8 +5689,7 @@
 	      if (TREE_ADDRESSABLE (DECL_EXPR_DECL (stmts[0])))
 		cxx_mark_addressable (placeholder);
 	      if (TREE_ADDRESSABLE (DECL_EXPR_DECL (stmts[1]))
-		  && TREE_CODE (TREE_TYPE (OMP_CLAUSE_DECL (c)))
-		     != REFERENCE_TYPE)
+		  && !TYPE_REF_P (TREE_TYPE (OMP_CLAUSE_DECL (c))))
 		cxx_mark_addressable (decl_placeholder ? decl_placeholder
 				      : OMP_CLAUSE_DECL (c));
 	      tree omp_out = placeholder;
@@ -5744,8 +5807,7 @@
 	if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
 	    && integer_zerop (OMP_CLAUSE_DECL (c))
 	    && OMP_CLAUSE_LINEAR_STEP (c)
-	    && TREE_CODE (TREE_TYPE (OMP_CLAUSE_LINEAR_STEP (c)))
-	       == POINTER_TYPE)
+	    && TYPE_PTR_P (TREE_TYPE (OMP_CLAUSE_LINEAR_STEP (c))))
 	  {
 	    tree s = OMP_CLAUSE_LINEAR_STEP (c);
 	    s = fold_convert_loc (OMP_CLAUSE_LOCATION (c), sizetype, s);
@@ -5774,7 +5836,7 @@
   for (; t; t = TREE_CHAIN (t))
     {
       tree decl = TREE_VALUE (t);
-      if (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE)
+      if (TYPE_PTR_P (TREE_TYPE (decl)))
 	{
 	  tree offset = TREE_PURPOSE (t);
 	  bool neg = wi::neg_p (wi::to_wide (offset));
@@ -5863,7 +5925,7 @@
 		  if (TREE_CODE (t) == POINTER_PLUS_EXPR)
 		    t = TREE_OPERAND (t, 0);
 		  if (TREE_CODE (t) == ADDR_EXPR
-		      || TREE_CODE (t) == INDIRECT_REF)
+		      || INDIRECT_REF_P (t))
 		    t = TREE_OPERAND (t, 0);
 		}
 	      tree n = omp_clause_decl_field (t);
@@ -5897,7 +5959,7 @@
 	      tree type = TREE_TYPE (t);
 	      if ((OMP_CLAUSE_LINEAR_KIND (c) == OMP_CLAUSE_LINEAR_REF
 		   || OMP_CLAUSE_LINEAR_KIND (c) == OMP_CLAUSE_LINEAR_UVAL)
-		  && TREE_CODE (type) != REFERENCE_TYPE)
+		  && !TYPE_REF_P (type))
 		{
 		  error ("linear clause with %qs modifier applied to "
 			 "non-reference variable with %qT type",
@@ -5906,25 +5968,12 @@
 		  remove = true;
 		  break;
 		}
-	      if (TREE_CODE (type) == REFERENCE_TYPE)
+	      if (TYPE_REF_P (type))
 		type = TREE_TYPE (type);
-	      if (ort == C_ORT_CILK)
+	      if (OMP_CLAUSE_LINEAR_KIND (c) != OMP_CLAUSE_LINEAR_REF)
 		{
 		  if (!INTEGRAL_TYPE_P (type)
-		      && !SCALAR_FLOAT_TYPE_P (type)
-		      && TREE_CODE (type) != POINTER_TYPE)
-		    {
-		      error ("linear clause applied to non-integral, "
-			     "non-floating, non-pointer variable with %qT type",
-			     TREE_TYPE (t));
-		      remove = true;
-		      break;
-		    }
-		}
-	      else if (OMP_CLAUSE_LINEAR_KIND (c) != OMP_CLAUSE_LINEAR_REF)
-		{
-		  if (!INTEGRAL_TYPE_P (type)
-		      && TREE_CODE (type) != POINTER_TYPE)
+		      && !TYPE_PTR_P (type))
 		    {
 		      error ("linear clause applied to non-integral non-pointer"
 			     " variable with %qT type", TREE_TYPE (t));
@@ -5945,7 +5994,7 @@
 		   && !INTEGRAL_TYPE_P (TREE_TYPE (t))
 		   && (ort != C_ORT_OMP_DECLARE_SIMD
 		       || TREE_CODE (t) != PARM_DECL
-		       || TREE_CODE (TREE_TYPE (t)) != REFERENCE_TYPE
+		       || !TYPE_REF_P (TREE_TYPE (t))
 		       || !INTEGRAL_TYPE_P (TREE_TYPE (TREE_TYPE (t)))))
 	    {
 	      error ("linear step expression must be integral");
@@ -5978,7 +6027,7 @@
 		    }
 		  t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
 		  tree type = TREE_TYPE (OMP_CLAUSE_DECL (c));
-		  if (TREE_CODE (type) == REFERENCE_TYPE)
+		  if (TYPE_REF_P (type))
 		    type = TREE_TYPE (type);
 		  if (OMP_CLAUSE_LINEAR_KIND (c) == OMP_CLAUSE_LINEAR_REF)
 		    {
@@ -5996,7 +6045,7 @@
 			  break;
 			}
 		    }
-		  else if (TREE_CODE (type) == POINTER_TYPE
+		  else if (TYPE_PTR_P (type)
 			   /* Can't multiply the step yet if *this
 			      is still incomplete type.  */
 			   && (ort != C_ORT_OMP_DECLARE_SIMD
@@ -6345,8 +6394,6 @@
 	  else if (t == error_mark_node)
 	    remove = true;
 	  else if (!type_dependent_expression_p (t)
-		   && (OMP_CLAUSE_SCHEDULE_KIND (c)
-		       != OMP_CLAUSE_SCHEDULE_CILKFOR)
 		   && !INTEGRAL_TYPE_P (TREE_TYPE (t)))
 	    {
 	      error ("schedule chunk size expression must be integral");
@@ -6357,27 +6404,14 @@
 	      t = mark_rvalue_use (t);
 	      if (!processing_template_decl)
 		{
-		  if (OMP_CLAUSE_SCHEDULE_KIND (c)
-		      == OMP_CLAUSE_SCHEDULE_CILKFOR)
-		    {
-		      t = convert_to_integer (long_integer_type_node, t);
-		      if (t == error_mark_node)
-			{
-			  remove = true;
-			  break;
-			}
-		    }
-		  else
-		    {
-		      t = maybe_constant_value (t);
-		      if (TREE_CODE (t) == INTEGER_CST
-			  && tree_int_cst_sgn (t) != 1)
-			{
-			  warning_at (OMP_CLAUSE_LOCATION (c), 0,
-				      "chunk size value must be positive");
-			  t = integer_one_node;
-			}
-		    }
+		  t = maybe_constant_value (t);
+		  if (TREE_CODE (t) == INTEGER_CST
+		      && tree_int_cst_sgn (t) != 1)
+		  {
+		    warning_at (OMP_CLAUSE_LOCATION (c), 0,
+			      "chunk size value must be positive");
+		    t = integer_one_node;
+		  }
 		  t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
 		}
 	      OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (c) = t;
@@ -6535,10 +6569,10 @@
 	      remove = true;
 	    }
 	  else if (!type_dependent_expression_p (t)
-		   && TREE_CODE (TREE_TYPE (t)) != POINTER_TYPE
+		   && !TYPE_PTR_P (TREE_TYPE (t))
 		   && TREE_CODE (TREE_TYPE (t)) != ARRAY_TYPE
-		   && (TREE_CODE (TREE_TYPE (t)) != REFERENCE_TYPE
-		       || (!POINTER_TYPE_P (TREE_TYPE (TREE_TYPE (t)))
+		   && (!TYPE_REF_P (TREE_TYPE (t))
+		       || (!INDIRECT_TYPE_P (TREE_TYPE (TREE_TYPE (t)))
 			   && (TREE_CODE (TREE_TYPE (TREE_TYPE (t)))
 			       != ARRAY_TYPE))))
 	    {
@@ -6767,7 +6801,7 @@
 	      break;
 	    }
 	  else if (!processing_template_decl
-		   && TREE_CODE (TREE_TYPE (t)) != REFERENCE_TYPE
+		   && !TYPE_REF_P (TREE_TYPE (t))
 		   && (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_MAP
 		       || (OMP_CLAUSE_MAP_KIND (c)
 			   != GOMP_MAP_FIRSTPRIVATE_POINTER))
@@ -6779,8 +6813,7 @@
 			     == GOMP_MAP_FIRSTPRIVATE_POINTER)))
 		   && t == OMP_CLAUSE_DECL (c)
 		   && !type_dependent_expression_p (t)
-		   && !cp_omp_mappable_type ((TREE_CODE (TREE_TYPE (t))
-					      == REFERENCE_TYPE)
+		   && !cp_omp_mappable_type (TYPE_REF_P (TREE_TYPE (t))
 					     ? TREE_TYPE (TREE_TYPE (t))
 					     : TREE_TYPE (t)))
 	    {
@@ -6792,7 +6825,7 @@
 	  else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
 		   && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FORCE_DEVICEPTR
 		   && !type_dependent_expression_p (t)
-		   && !POINTER_TYPE_P (TREE_TYPE (t)))
+		   && !INDIRECT_TYPE_P (TREE_TYPE (t)))
 	    {
 	      error ("%qD is not a pointer variable", t);
 	      remove = true;
@@ -6846,8 +6879,8 @@
 	handle_map_references:
 	  if (!remove
 	      && !processing_template_decl
-	      && (ort & C_ORT_OMP_DECLARE_SIMD) == C_ORT_OMP
-	      && TREE_CODE (TREE_TYPE (OMP_CLAUSE_DECL (c))) == REFERENCE_TYPE)
+	      && ort != C_ORT_DECLARE_SIMD
+	      && TYPE_REF_P (TREE_TYPE (OMP_CLAUSE_DECL (c))))
 	    {
 	      t = OMP_CLAUSE_DECL (c);
 	      if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_MAP)
@@ -7045,10 +7078,10 @@
 	  if (!type_dependent_expression_p (t))
 	    {
 	      tree type = TREE_TYPE (t);
-	      if (TREE_CODE (type) != POINTER_TYPE
+	      if (!TYPE_PTR_P (type)
 		  && TREE_CODE (type) != ARRAY_TYPE
-		  && (TREE_CODE (type) != REFERENCE_TYPE
-		      || (TREE_CODE (TREE_TYPE (type)) != POINTER_TYPE
+		  && (!TYPE_REF_P (type)
+		      || (!TYPE_PTR_P (TREE_TYPE (type))
 			  && TREE_CODE (TREE_TYPE (type)) != ARRAY_TYPE)))
 		{
 		  error_at (OMP_CLAUSE_LOCATION (c),
@@ -7074,10 +7107,11 @@
 	case OMP_CLAUSE_THREADS:
 	case OMP_CLAUSE_SIMD:
 	case OMP_CLAUSE_DEFAULTMAP:
-	case OMP_CLAUSE__CILK_FOR_COUNT_:
 	case OMP_CLAUSE_AUTO:
 	case OMP_CLAUSE_INDEPENDENT:
 	case OMP_CLAUSE_SEQ:
+	case OMP_CLAUSE_IF_PRESENT:
+	case OMP_CLAUSE_FINALIZE:
 	  break;
 
 	case OMP_CLAUSE_TILE:
@@ -7290,7 +7324,7 @@
 	  t = require_complete_type (t);
 	  if (t == error_mark_node)
 	    remove = true;
-	  else if (TREE_CODE (TREE_TYPE (t)) == REFERENCE_TYPE
+	  else if (TYPE_REF_P (TREE_TYPE (t))
 		   && !complete_type_or_else (TREE_TYPE (TREE_TYPE (t)), t))
 	    remove = true;
 	}
@@ -7300,7 +7334,7 @@
 
 	  if (VAR_P (t) && CP_DECL_THREAD_LOCAL_P (t))
 	    share_name = "threadprivate";
-	  else switch (cxx_omp_predetermined_sharing (t))
+	  else switch (cxx_omp_predetermined_sharing_1 (t))
 	    {
 	    case OMP_CLAUSE_DEFAULT_UNSPECIFIED:
 	      break;
@@ -7331,7 +7365,7 @@
       if ((need_complete_type
 	   || need_copy_assignment
 	   || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION)
-	  && TREE_CODE (inner_type) == REFERENCE_TYPE)
+	  && TYPE_REF_P (inner_type))
 	inner_type = TREE_TYPE (inner_type);
       while (TREE_CODE (inner_type) == ARRAY_TYPE)
 	inner_type = TREE_TYPE (inner_type);
@@ -7674,7 +7708,7 @@
 handle_omp_for_class_iterator (int i, location_t locus, enum tree_code code,
 			       tree declv, tree orig_declv, tree initv,
 			       tree condv, tree incrv, tree *body,
-			       tree *pre_body, tree &clauses, tree *lastp,
+			       tree *pre_body, tree &clauses,
 			       int collapse, int ordered)
 {
   tree diff, iter_init, iter_incr = NULL, last;
@@ -7978,7 +8012,8 @@
   TREE_VEC_ELT (initv, i) = init;
   TREE_VEC_ELT (condv, i) = cond;
   TREE_VEC_ELT (incrv, i) = incr;
-  *lastp = last;
+  TREE_VEC_ELT (orig_declv, i)
+    = tree_cons (TREE_VEC_ELT (orig_declv, i), last, NULL_TREE);
 
   return false;
 }
@@ -7996,8 +8031,7 @@
 		tree body, tree pre_body, vec<tree> *orig_inits, tree clauses)
 {
   tree omp_for = NULL, orig_incr = NULL;
-  tree decl = NULL, init, cond, incr, orig_decl = NULL_TREE, block = NULL_TREE;
-  tree last = NULL_TREE;
+  tree decl = NULL, init, cond, incr;
   location_t elocus;
   int i;
   int collapse = 1;
@@ -8162,11 +8196,9 @@
 				"iteration variable %qE", decl);
 	      return NULL;
 	    }
-	  if (code == CILK_FOR && i == 0)
-	    orig_decl = decl;
 	  if (handle_omp_for_class_iterator (i, locus, code, declv, orig_declv,
 					     initv, condv, incrv, &body,
-					     &pre_body, clauses, &last,
+					     &pre_body, clauses,
 					     collapse, ordered))
 	    return NULL;
 	  continue;
@@ -8221,9 +8253,6 @@
   if (IS_EMPTY_STMT (pre_body))
     pre_body = NULL;
 
-  if (code == CILK_FOR && !processing_template_decl)
-    block = push_stmt_list ();
-
   omp_for = c_finish_omp_for (locus, code, declv, orig_declv, initv, condv,
 			      incrv, body, pre_body);
 
@@ -8233,8 +8262,6 @@
 
   if (omp_for == NULL)
     {
-      if (block)
-	pop_stmt_list (block);
       return NULL;
     }
 
@@ -8293,14 +8320,14 @@
 	    case POSTINCREMENT_EXPR:
 	      /* c_omp_for_incr_canonicalize_ptr() should have been
 		 called to massage things appropriately.  */
-	      gcc_assert (!POINTER_TYPE_P (TREE_TYPE (decl)));
+	      gcc_assert (!INDIRECT_TYPE_P (TREE_TYPE (decl)));
 	      OMP_CLAUSE_LINEAR_STEP (c) = build_int_cst (TREE_TYPE (decl), 1);
 	      break;
 	    case PREDECREMENT_EXPR:
 	    case POSTDECREMENT_EXPR:
 	      /* c_omp_for_incr_canonicalize_ptr() should have been
 		 called to massage things appropriately.  */
-	      gcc_assert (!POINTER_TYPE_P (TREE_TYPE (decl)));
+	      gcc_assert (!INDIRECT_TYPE_P (TREE_TYPE (decl)));
 	      OMP_CLAUSE_LINEAR_STEP (c)
 		= build_int_cst (TREE_TYPE (decl), -1);
 	      break;
@@ -8324,7 +8351,7 @@
 		  gcc_unreachable ();
 		}
 	      stept = TREE_TYPE (decl);
-	      if (POINTER_TYPE_P (stept))
+	      if (INDIRECT_TYPE_P (stept))
 		stept = sizetype;
 	      step = fold_convert (stept, step);
 	      if (TREE_CODE (incr) == MINUS_EXPR)
@@ -8336,115 +8363,6 @@
 	    }
 	}
 
-  if (block)
-    {
-      tree omp_par = make_node (OMP_PARALLEL);
-      TREE_TYPE (omp_par) = void_type_node;
-      OMP_PARALLEL_CLAUSES (omp_par) = NULL_TREE;
-      tree bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, NULL);
-      TREE_SIDE_EFFECTS (bind) = 1;
-      BIND_EXPR_BODY (bind) = pop_stmt_list (block);
-      OMP_PARALLEL_BODY (omp_par) = bind;
-      if (OMP_FOR_PRE_BODY (omp_for))
-	{
-	  add_stmt (OMP_FOR_PRE_BODY (omp_for));
-	  OMP_FOR_PRE_BODY (omp_for) = NULL_TREE;
-	}
-      init = TREE_VEC_ELT (OMP_FOR_INIT (omp_for), 0);
-      decl = TREE_OPERAND (init, 0);
-      cond = TREE_VEC_ELT (OMP_FOR_COND (omp_for), 0);
-      incr = TREE_VEC_ELT (OMP_FOR_INCR (omp_for), 0);
-      tree t = TREE_OPERAND (cond, 1), c, clauses, *pc;
-      clauses = OMP_FOR_CLAUSES (omp_for);
-      OMP_FOR_CLAUSES (omp_for) = NULL_TREE;
-      for (pc = &clauses; *pc; )
-	if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_SCHEDULE)
-	  {
-	    gcc_assert (OMP_FOR_CLAUSES (omp_for) == NULL_TREE);
-	    OMP_FOR_CLAUSES (omp_for) = *pc;
-	    *pc = OMP_CLAUSE_CHAIN (*pc);
-	    OMP_CLAUSE_CHAIN (OMP_FOR_CLAUSES (omp_for)) = NULL_TREE;
-	  }
-	else
-	  {
-	    gcc_assert (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_FIRSTPRIVATE);
-	    pc = &OMP_CLAUSE_CHAIN (*pc);
-	  }
-      if (TREE_CODE (t) != INTEGER_CST)
-	{
-	  TREE_OPERAND (cond, 1) = get_temp_regvar (TREE_TYPE (t), t);
-	  c = build_omp_clause (input_location, OMP_CLAUSE_FIRSTPRIVATE);
-	  OMP_CLAUSE_DECL (c) = TREE_OPERAND (cond, 1);
-	  OMP_CLAUSE_CHAIN (c) = clauses;
-	  clauses = c;
-	}
-      if (TREE_CODE (incr) == MODIFY_EXPR)
-	{
-	  t = TREE_OPERAND (TREE_OPERAND (incr, 1), 1);
-	  if (TREE_CODE (t) != INTEGER_CST)
-	    {
-	      TREE_OPERAND (TREE_OPERAND (incr, 1), 1)
-		= get_temp_regvar (TREE_TYPE (t), t);
-	      c = build_omp_clause (input_location, OMP_CLAUSE_FIRSTPRIVATE);
-	      OMP_CLAUSE_DECL (c) = TREE_OPERAND (TREE_OPERAND (incr, 1), 1);
-	      OMP_CLAUSE_CHAIN (c) = clauses;
-	      clauses = c;
-	    }
-	}
-      t = TREE_OPERAND (init, 1);
-      if (TREE_CODE (t) != INTEGER_CST)
-	{
-	  TREE_OPERAND (init, 1) = get_temp_regvar (TREE_TYPE (t), t);
-	  c = build_omp_clause (input_location, OMP_CLAUSE_FIRSTPRIVATE);
-	  OMP_CLAUSE_DECL (c) = TREE_OPERAND (init, 1);
-	  OMP_CLAUSE_CHAIN (c) = clauses;
-	  clauses = c;
-	}
-      if (orig_decl && orig_decl != decl)
-	{
-	  c = build_omp_clause (input_location, OMP_CLAUSE_FIRSTPRIVATE);
-	  OMP_CLAUSE_DECL (c) = orig_decl;
-	  OMP_CLAUSE_CHAIN (c) = clauses;
-	  clauses = c;
-	}
-      if (last)
-	{
-	  c = build_omp_clause (input_location, OMP_CLAUSE_FIRSTPRIVATE);
-	  OMP_CLAUSE_DECL (c) = last;
-	  OMP_CLAUSE_CHAIN (c) = clauses;
-	  clauses = c;
-	}
-      c = build_omp_clause (input_location, OMP_CLAUSE_PRIVATE);
-      OMP_CLAUSE_DECL (c) = decl;
-      OMP_CLAUSE_CHAIN (c) = clauses;
-      clauses = c;
-      c = build_omp_clause (input_location, OMP_CLAUSE__CILK_FOR_COUNT_);
-      OMP_CLAUSE_OPERAND (c, 0)
-	= cilk_for_number_of_iterations (omp_for);
-      OMP_CLAUSE_CHAIN (c) = clauses;
-      OMP_PARALLEL_CLAUSES (omp_par) = finish_omp_clauses (c, C_ORT_CILK);
-      add_stmt (omp_par);
-      return omp_par;
-    }
-  else if (code == CILK_FOR && processing_template_decl)
-    {
-      tree c, clauses = OMP_FOR_CLAUSES (omp_for);
-      if (orig_decl && orig_decl != decl)
-	{
-	  c = build_omp_clause (input_location, OMP_CLAUSE_FIRSTPRIVATE);
-	  OMP_CLAUSE_DECL (c) = orig_decl;
-	  OMP_CLAUSE_CHAIN (c) = clauses;
-	  clauses = c;
-	}
-      if (last)
-	{
-	  c = build_omp_clause (input_location, OMP_CLAUSE_FIRSTPRIVATE);
-	  OMP_CLAUSE_DECL (c) = last;
-	  OMP_CLAUSE_CHAIN (c) = clauses;
-	  clauses = c;
-	}
-      OMP_FOR_CLAUSES (omp_for) = clauses;
-    }
   return omp_for;
 }
 
@@ -8752,6 +8670,8 @@
 finish_static_assert (tree condition, tree message, location_t location, 
                       bool member_p)
 {
+  tsubst_flags_t complain = tf_warning_or_error;
+
   if (message == NULL_TREE
       || message == error_mark_node
       || condition == NULL_TREE
@@ -8761,8 +8681,7 @@
   if (check_for_bare_parameter_packs (condition))
     condition = error_mark_node;
 
-  if (type_dependent_expression_p (condition) 
-      || value_dependent_expression_p (condition))
+  if (instantiation_dependent_expression_p (condition))
     {
       /* We're in a template; build a STATIC_ASSERT and put it in
          the right place. */
@@ -8784,9 +8703,9 @@
     }
 
   /* Fold the expression and convert it to a boolean value. */
-  condition = instantiate_non_dependent_expr (condition);
-  condition = cp_convert (boolean_type_node, condition, tf_warning_or_error);
-  condition = maybe_constant_value (condition);
+  condition = perform_implicit_conversion_flags (boolean_type_node, condition,
+						 complain, LOOKUP_NORMAL);
+  condition = fold_non_dependent_expr (condition, complain);
 
   if (TREE_CODE (condition) == INTEGER_CST && !integer_zerop (condition))
     /* Do nothing; the condition is satisfied. */
@@ -8812,7 +8731,7 @@
       else if (condition && condition != error_mark_node)
 	{
 	  error ("non-constant condition for static assertion");
-	  if (require_potential_rvalue_constant_expression (condition))
+	  if (require_rvalue_constant_expression (condition))
 	    cxx_constant_value (condition);
 	}
       input_location = saved_loc;
@@ -8996,7 +8915,7 @@
 	     decltype(e) is defined as T&; if an xvalue, T&&; otherwise, T. */
 	  cp_lvalue_kind clk = lvalue_kind (expr);
 	  type = unlowered_expr_type (expr);
-	  gcc_assert (TREE_CODE (type) != REFERENCE_TYPE);
+	  gcc_assert (!TYPE_REF_P (type));
 
 	  /* For vector types, pick a non-opaque variant.  */
 	  if (VECTOR_TYPE_P (type))
@@ -9020,8 +8939,7 @@
   tree fns = NULL_TREE;
 
   if (assign_p || TYPE_HAS_COPY_CTOR (type))
-    fns = get_class_binding (type,
-			     assign_p ? cp_assignment_operator_id (NOP_EXPR)
+    fns = get_class_binding (type, assign_p ? assign_op_identifier
 			     : ctor_identifier);
 
   bool saw_copy = false;
@@ -9377,14 +9295,14 @@
 
       case CPLD_COPY:
 	type = TREE_TYPE (decl);
-	if (TREE_CODE (type) == REFERENCE_TYPE
+	if (TYPE_REF_P (type)
 	    && TREE_CODE (TREE_TYPE (type)) != FUNCTION_TYPE)
 	  type = TREE_TYPE (type);
 	break;
 
       case CPLD_REFERENCE:
 	type = TREE_TYPE (decl);
-	if (TREE_CODE (type) != REFERENCE_TYPE)
+	if (!TYPE_REF_P (type))
 	  type = build_reference_type (TREE_TYPE (decl));
 	break;
 
@@ -9392,7 +9310,7 @@
 	gcc_unreachable ();
       }
 
-  if (TREE_CODE (type) != REFERENCE_TYPE)
+  if (!TYPE_REF_P (type))
     {
       if (!LAMBDA_EXPR_MUTABLE_P (lam))
 	type = cp_build_qualified_type (type, (cp_type_quals (type)
@@ -9482,7 +9400,7 @@
   if (error_operand_p (arg))
     return error_mark_node;
   if (!type_dependent_expression_p (arg)
-      && TREE_CODE (TREE_TYPE (arg)) != POINTER_TYPE)
+      && !TYPE_PTR_P (TREE_TYPE (arg)))
     {
       error_at (loc, "non-pointer argument to %<__builtin_launder%>");
       return error_mark_node;