/* C++-specific tree lowering bits; see also c-gimplify.c and gimple.c.

   Copyright (C) 2002-2020 Free Software Foundation, Inc.
   Contributed by Jason Merrill <jason@redhat.com>

This file is part of GCC.

GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3, or (at your option) any later
version.

GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
for more details.

You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "target.h"
#include "basic-block.h"
#include "cp-tree.h"
#include "gimple.h"
#include "predict.h"
#include "stor-layout.h"
#include "tree-iterator.h"
#include "gimplify.h"
#include "c-family/c-ubsan.h"
#include "stringpool.h"
#include "attribs.h"
#include "asan.h"
#include "gcc-rich-location.h"
#include "memmodel.h"
#include "tm_p.h"
#include "output.h"
#include "file-prefix-map.h"
#include "cgraph.h"
#include "omp-general.h"

/* Forward declarations.  */

static tree cp_genericize_r (tree *, int *, void *);
static tree cp_fold_r (tree *, int *, void *);
static void cp_genericize_tree (tree*, bool);
static tree cp_fold (tree);

/* Local declarations.  */

enum bc_t { bc_break = 0, bc_continue = 1 };

/* Stack of labels which are targets for "break" or "continue",
   linked through TREE_CHAIN.  */
static tree bc_label[2];

/* Begin a scope which can be exited by a break or continue statement.  BC
   indicates which.

   Just creates a label with location LOCATION and pushes it into the current
   context.  */

static tree
begin_bc_block (enum bc_t bc, location_t location)
{
  tree label = create_artificial_label (location);
  DECL_CHAIN (label) = bc_label[bc];
  bc_label[bc] = label;
  if (bc == bc_break)
    LABEL_DECL_BREAK (label) = true;
  else
    LABEL_DECL_CONTINUE (label) = true;
  return label;
}

/* Finish a scope which can be exited by a break or continue statement.
   LABEL was returned from the most recent call to begin_bc_block.  BLOCK is
   an expression for the contents of the scope.

   If we saw a break (or continue) in the scope, append a LABEL_EXPR to
   BLOCK.  Otherwise, just forget the label.  */

static void
finish_bc_block (tree *block, enum bc_t bc, tree label)
{
  gcc_assert (label == bc_label[bc]);

  if (TREE_USED (label))
    append_to_statement_list (build1 (LABEL_EXPR, void_type_node, label),
			      block);

  bc_label[bc] = DECL_CHAIN (label);
  DECL_CHAIN (label) = NULL_TREE;
}

/* Get the LABEL_EXPR to represent a break or continue statement
   in the current block scope.  BC indicates which.  */

static tree
get_bc_label (enum bc_t bc)
{
  tree label = bc_label[bc];

  /* Mark the label used for finish_bc_block.  */
  TREE_USED (label) = 1;
  return label;
}

/* Genericize a TRY_BLOCK.  */

static void
genericize_try_block (tree *stmt_p)
{
  tree body = TRY_STMTS (*stmt_p);
  tree cleanup = TRY_HANDLERS (*stmt_p);

  *stmt_p = build2 (TRY_CATCH_EXPR, void_type_node, body, cleanup);
}

/* Genericize a HANDLER by converting to a CATCH_EXPR.  */

static void
genericize_catch_block (tree *stmt_p)
{
  tree type = HANDLER_TYPE (*stmt_p);
  tree body = HANDLER_BODY (*stmt_p);

  /* FIXME should the caught type go in TREE_TYPE?  */
  *stmt_p = build2 (CATCH_EXPR, void_type_node, type, body);
}

/* A terser interface for building a representation of an exception
   specification.  */

static tree
build_gimple_eh_filter_tree (tree body, tree allowed, tree failure)
{
  tree t;

  /* FIXME should the allowed types go in TREE_TYPE?  */
  t = build2 (EH_FILTER_EXPR, void_type_node, allowed, NULL_TREE);
  append_to_statement_list (failure, &EH_FILTER_FAILURE (t));

  t = build2 (TRY_CATCH_EXPR, void_type_node, NULL_TREE, t);
  append_to_statement_list (body, &TREE_OPERAND (t, 0));

  return t;
}

/* Genericize an EH_SPEC_BLOCK by converting it to a
   TRY_CATCH_EXPR/EH_FILTER_EXPR pair.  */

static void
genericize_eh_spec_block (tree *stmt_p)
{
  tree body = EH_SPEC_STMTS (*stmt_p);
  tree allowed = EH_SPEC_RAISES (*stmt_p);
  tree failure = build_call_n (call_unexpected_fn, 1, build_exc_ptr ());

  *stmt_p = build_gimple_eh_filter_tree (body, allowed, failure);
  TREE_NO_WARNING (*stmt_p) = true;
  TREE_NO_WARNING (TREE_OPERAND (*stmt_p, 1)) = true;
}

/* Return the first non-compound statement in STMT.  */

tree
first_stmt (tree stmt)
{
  switch (TREE_CODE (stmt))
    {
    case STATEMENT_LIST:
      if (tree_statement_list_node *p = STATEMENT_LIST_HEAD (stmt))
	return first_stmt (p->stmt);
      return void_node;

    case BIND_EXPR:
      return first_stmt (BIND_EXPR_BODY (stmt));

    default:
      return stmt;
    }
}

/* Genericize an IF_STMT by turning it into a COND_EXPR.  */

static void
genericize_if_stmt (tree *stmt_p)
{
  tree stmt, cond, then_, else_;
  location_t locus = EXPR_LOCATION (*stmt_p);

  stmt = *stmt_p;
  cond = IF_COND (stmt);
  then_ = THEN_CLAUSE (stmt);
  else_ = ELSE_CLAUSE (stmt);

  if (then_ && else_)
    {
      tree ft = first_stmt (then_);
      tree fe = first_stmt (else_);
      br_predictor pr;
      if (TREE_CODE (ft) == PREDICT_EXPR
	  && TREE_CODE (fe) == PREDICT_EXPR
	  && (pr = PREDICT_EXPR_PREDICTOR (ft)) == PREDICT_EXPR_PREDICTOR (fe)
	  && (pr == PRED_HOT_LABEL || pr == PRED_COLD_LABEL))
	{
	  gcc_rich_location richloc (EXPR_LOC_OR_LOC (ft, locus));
	  richloc.add_range (EXPR_LOC_OR_LOC (fe, locus));
	  warning_at (&richloc, OPT_Wattributes,
		      "both branches of %<if%> statement marked as %qs",
		      pr == PRED_HOT_LABEL ? "likely" : "unlikely");
	}
    }

  if (!then_)
    then_ = build_empty_stmt (locus);
  if (!else_)
    else_ = build_empty_stmt (locus);

  if (integer_nonzerop (cond) && !TREE_SIDE_EFFECTS (else_))
    stmt = then_;
  else if (integer_zerop (cond) && !TREE_SIDE_EFFECTS (then_))
    stmt = else_;
  else
    stmt = build3 (COND_EXPR, void_type_node, cond, then_, else_);
  protected_set_expr_location_if_unset (stmt, locus);
  *stmt_p = stmt;
}

/* Build a generic representation of one of the C loop forms.  COND is the
   loop condition or NULL_TREE.  BODY is the (possibly compound) statement
   controlled by the loop.  INCR is the increment expression of a for-loop,
   or NULL_TREE.  COND_IS_FIRST indicates whether the condition is
   evaluated before the loop body as in while and for loops, or after the
   loop body as in do-while loops.  */

static void
genericize_cp_loop (tree *stmt_p, location_t start_locus, tree cond, tree body,
		    tree incr, bool cond_is_first, int *walk_subtrees,
		    void *data)
{
  tree blab, clab;
  tree exit = NULL;
  tree stmt_list = NULL;
  tree debug_begin = NULL;

  protected_set_expr_location_if_unset (incr, start_locus);

  cp_walk_tree (&cond, cp_genericize_r, data, NULL);
  cp_walk_tree (&incr, cp_genericize_r, data, NULL);

  blab = begin_bc_block (bc_break, start_locus);
  clab = begin_bc_block (bc_continue, start_locus);

  cp_walk_tree (&body, cp_genericize_r, data, NULL);
  *walk_subtrees = 0;

  if (MAY_HAVE_DEBUG_MARKER_STMTS
      && (!cond || !integer_zerop (cond)))
    {
      debug_begin = build0 (DEBUG_BEGIN_STMT, void_type_node);
      SET_EXPR_LOCATION (debug_begin, cp_expr_loc_or_loc (cond, start_locus));
    }

  if (cond && TREE_CODE (cond) != INTEGER_CST)
    {
      /* If COND is constant, don't bother building an exit.  If it's false,
	 we won't build a loop.  If it's true, any exits are in the body.  */
      location_t cloc = cp_expr_loc_or_loc (cond, start_locus);
      exit = build1_loc (cloc, GOTO_EXPR, void_type_node,
			 get_bc_label (bc_break));
      exit = fold_build3_loc (cloc, COND_EXPR, void_type_node, cond,
			      build_empty_stmt (cloc), exit);
    }

  if (exit && cond_is_first)
    {
      append_to_statement_list (debug_begin, &stmt_list);
      debug_begin = NULL_TREE;
      append_to_statement_list (exit, &stmt_list);
    }
  append_to_statement_list (body, &stmt_list);
  finish_bc_block (&stmt_list, bc_continue, clab);
  if (incr)
    {
      if (MAY_HAVE_DEBUG_MARKER_STMTS)
	{
	  tree d = build0 (DEBUG_BEGIN_STMT, void_type_node);
	  SET_EXPR_LOCATION (d, cp_expr_loc_or_loc (incr, start_locus));
	  append_to_statement_list (d, &stmt_list);
	}
      append_to_statement_list (incr, &stmt_list);
    }
  append_to_statement_list (debug_begin, &stmt_list);
  if (exit && !cond_is_first)
    append_to_statement_list (exit, &stmt_list);

  if (!stmt_list)
    stmt_list = build_empty_stmt (start_locus);

  tree loop;
  if (cond && integer_zerop (cond))
    {
      if (cond_is_first)
	loop = fold_build3_loc (start_locus, COND_EXPR,
				void_type_node, cond, stmt_list,
				build_empty_stmt (start_locus));
      else
	loop = stmt_list;
    }
  else
    {
      location_t loc = start_locus;
      if (!cond || integer_nonzerop (cond))
	loc = EXPR_LOCATION (expr_first (body));
      if (loc == UNKNOWN_LOCATION)
	loc = start_locus;
      loop = build1_loc (loc, LOOP_EXPR, void_type_node, stmt_list);
    }

  stmt_list = NULL;
  append_to_statement_list (loop, &stmt_list);
  finish_bc_block (&stmt_list, bc_break, blab);
  if (!stmt_list)
    stmt_list = build_empty_stmt (start_locus);

  *stmt_p = stmt_list;
}

/* Genericize a FOR_STMT node *STMT_P.  */

static void
genericize_for_stmt (tree *stmt_p, int *walk_subtrees, void *data)
{
  tree stmt = *stmt_p;
  tree expr = NULL;
  tree loop;
  tree init = FOR_INIT_STMT (stmt);

  if (init)
    {
      cp_walk_tree (&init, cp_genericize_r, data, NULL);
      append_to_statement_list (init, &expr);
    }

  genericize_cp_loop (&loop, EXPR_LOCATION (stmt), FOR_COND (stmt),
		      FOR_BODY (stmt), FOR_EXPR (stmt), 1, walk_subtrees, data);
  append_to_statement_list (loop, &expr);
  if (expr == NULL_TREE)
    expr = loop;
  *stmt_p = expr;
}

/* Genericize a WHILE_STMT node *STMT_P.  */

static void
genericize_while_stmt (tree *stmt_p, int *walk_subtrees, void *data)
{
  tree stmt = *stmt_p;
  genericize_cp_loop (stmt_p, EXPR_LOCATION (stmt), WHILE_COND (stmt),
		      WHILE_BODY (stmt), NULL_TREE, 1, walk_subtrees, data);
}

/* Genericize a DO_STMT node *STMT_P.  */

static void
genericize_do_stmt (tree *stmt_p, int *walk_subtrees, void *data)
{
  tree stmt = *stmt_p;
  genericize_cp_loop (stmt_p, EXPR_LOCATION (stmt), DO_COND (stmt),
		      DO_BODY (stmt), NULL_TREE, 0, walk_subtrees, data);
}

/* Genericize a SWITCH_STMT node *STMT_P by turning it into a SWITCH_EXPR.  */

static void
genericize_switch_stmt (tree *stmt_p, int *walk_subtrees, void *data)
{
  tree stmt = *stmt_p;
  tree break_block, body, cond, type;
  location_t stmt_locus = EXPR_LOCATION (stmt);

  body = SWITCH_STMT_BODY (stmt);
  if (!body)
    body = build_empty_stmt (stmt_locus);
  cond = SWITCH_STMT_COND (stmt);
  type = SWITCH_STMT_TYPE (stmt);

  cp_walk_tree (&cond, cp_genericize_r, data, NULL);

  break_block = begin_bc_block (bc_break, stmt_locus);

  cp_walk_tree (&body, cp_genericize_r, data, NULL);
  cp_walk_tree (&type, cp_genericize_r, data, NULL);
  *walk_subtrees = 0;

  if (TREE_USED (break_block))
    SWITCH_BREAK_LABEL_P (break_block) = 1;
  finish_bc_block (&body, bc_break, break_block);
  *stmt_p = build2_loc (stmt_locus, SWITCH_EXPR, type, cond, body);
  SWITCH_ALL_CASES_P (*stmt_p) = SWITCH_STMT_ALL_CASES_P (stmt);
  gcc_checking_assert (!SWITCH_STMT_NO_BREAK_P (stmt)
		       || !TREE_USED (break_block));
}

/* Genericize a CONTINUE_STMT node *STMT_P.  */

static void
genericize_continue_stmt (tree *stmt_p)
{
  tree stmt_list = NULL;
  tree pred = build_predict_expr (PRED_CONTINUE, NOT_TAKEN);
  tree label = get_bc_label (bc_continue);
  location_t location = EXPR_LOCATION (*stmt_p);
  tree jump = build1_loc (location, GOTO_EXPR, void_type_node, label);
  append_to_statement_list_force (pred, &stmt_list);
  append_to_statement_list (jump, &stmt_list);
  *stmt_p = stmt_list;
}

/* Genericize a BREAK_STMT node *STMT_P.  */

static void
genericize_break_stmt (tree *stmt_p)
{
  tree label = get_bc_label (bc_break);
  location_t location = EXPR_LOCATION (*stmt_p);
  *stmt_p = build1_loc (location, GOTO_EXPR, void_type_node, label);
}

/* Genericize a OMP_FOR node *STMT_P.  */

static void
genericize_omp_for_stmt (tree *stmt_p, int *walk_subtrees, void *data)
{
  tree stmt = *stmt_p;
  location_t locus = EXPR_LOCATION (stmt);
  tree clab = begin_bc_block (bc_continue, locus);

  cp_walk_tree (&OMP_FOR_BODY (stmt), cp_genericize_r, data, NULL);
  if (TREE_CODE (stmt) != OMP_TASKLOOP)
    cp_walk_tree (&OMP_FOR_CLAUSES (stmt), cp_genericize_r, data, NULL);
  cp_walk_tree (&OMP_FOR_INIT (stmt), cp_genericize_r, data, NULL);
  cp_walk_tree (&OMP_FOR_COND (stmt), cp_genericize_r, data, NULL);
  cp_walk_tree (&OMP_FOR_INCR (stmt), cp_genericize_r, data, NULL);
  cp_walk_tree (&OMP_FOR_PRE_BODY (stmt), cp_genericize_r, data, NULL);
  *walk_subtrees = 0;

  finish_bc_block (&OMP_FOR_BODY (stmt), bc_continue, clab);
}

/* Hook into the middle of gimplifying an OMP_FOR node.  */

static enum gimplify_status
cp_gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
{
  tree for_stmt = *expr_p;
  gimple_seq seq = NULL;

  /* Protect ourselves from recursion.  */
  if (OMP_FOR_GIMPLIFYING_P (for_stmt))
    return GS_UNHANDLED;
  OMP_FOR_GIMPLIFYING_P (for_stmt) = 1;

  gimplify_and_add (for_stmt, &seq);
  gimple_seq_add_seq (pre_p, seq);

  OMP_FOR_GIMPLIFYING_P (for_stmt) = 0;

  return GS_ALL_DONE;
}

/*  Gimplify an EXPR_STMT node.  */

static void
gimplify_expr_stmt (tree *stmt_p)
{
  tree stmt = EXPR_STMT_EXPR (*stmt_p);

  if (stmt == error_mark_node)
    stmt = NULL;

  /* Gimplification of a statement expression will nullify the
     statement if all its side effects are moved to *PRE_P and *POST_P.

     In this case we will not want to emit the gimplified statement.
     However, we may still want to emit a warning, so we do that before
     gimplification.  */
  if (stmt && warn_unused_value)
    {
      if (!TREE_SIDE_EFFECTS (stmt))
	{
	  if (!IS_EMPTY_STMT (stmt)
	      && !VOID_TYPE_P (TREE_TYPE (stmt))
	      && !TREE_NO_WARNING (stmt))
	    warning (OPT_Wunused_value, "statement with no effect");
	}
      else
	warn_if_unused_value (stmt, input_location);
    }

  if (stmt == NULL_TREE)
    stmt = alloc_stmt_list ();

  *stmt_p = stmt;
}

/* Gimplify initialization from an AGGR_INIT_EXPR.  */

static void
cp_gimplify_init_expr (tree *expr_p)
{
  tree from = TREE_OPERAND (*expr_p, 1);
  tree to = TREE_OPERAND (*expr_p, 0);
  tree t;

  /* What about code that pulls out the temp and uses it elsewhere?  I
     think that such code never uses the TARGET_EXPR as an initializer.  If
     I'm wrong, we'll abort because the temp won't have any RTL.  In that
     case, I guess we'll need to replace references somehow.  */
  if (TREE_CODE (from) == TARGET_EXPR && TARGET_EXPR_INITIAL (from))
    from = TARGET_EXPR_INITIAL (from);

  /* Look through any COMPOUND_EXPRs, since build_compound_expr pushes them
     inside the TARGET_EXPR.  */
  for (t = from; t; )
    {
      tree sub = TREE_CODE (t) == COMPOUND_EXPR ? TREE_OPERAND (t, 0) : t;

      /* If we are initializing from an AGGR_INIT_EXPR, drop the INIT_EXPR and
	 replace the slot operand with our target.

	 Should we add a target parm to gimplify_expr instead?  No, as in this
	 case we want to replace the INIT_EXPR.  */
      if (TREE_CODE (sub) == AGGR_INIT_EXPR
	  || TREE_CODE (sub) == VEC_INIT_EXPR)
	{
	  if (TREE_CODE (sub) == AGGR_INIT_EXPR)
	    AGGR_INIT_EXPR_SLOT (sub) = to;
	  else
	    VEC_INIT_EXPR_SLOT (sub) = to;
	  *expr_p = from;

	  /* The initialization is now a side-effect, so the container can
	     become void.  */
	  if (from != sub)
	    TREE_TYPE (from) = void_type_node;
	}

      /* Handle aggregate NSDMI.  */
      replace_placeholders (sub, to);

      if (t == sub)
	break;
      else
	t = TREE_OPERAND (t, 1);
    }

}

/* Gimplify a MUST_NOT_THROW_EXPR.  */

static enum gimplify_status
gimplify_must_not_throw_expr (tree *expr_p, gimple_seq *pre_p)
{
  tree stmt = *expr_p;
  tree temp = voidify_wrapper_expr (stmt, NULL);
  tree body = TREE_OPERAND (stmt, 0);
  gimple_seq try_ = NULL;
  gimple_seq catch_ = NULL;
  gimple *mnt;

  gimplify_and_add (body, &try_);
  mnt = gimple_build_eh_must_not_throw (terminate_fn);
  gimple_seq_add_stmt_without_update (&catch_, mnt);
  mnt = gimple_build_try (try_, catch_, GIMPLE_TRY_CATCH);

  gimple_seq_add_stmt_without_update (pre_p, mnt);
  if (temp)
    {
      *expr_p = temp;
      return GS_OK;
    }

  *expr_p = NULL;
  return GS_ALL_DONE;
}

/* Return TRUE if an operand (OP) of a given TYPE being copied is
   really just an empty class copy.

   Check that the operand has a simple form so that TARGET_EXPRs and
   non-empty CONSTRUCTORs get reduced properly, and we leave the
   return slot optimization alone because it isn't a copy.  */

bool
simple_empty_class_p (tree type, tree op, tree_code code)
{
  if (TREE_CODE (op) == COMPOUND_EXPR)
    return simple_empty_class_p (type, TREE_OPERAND (op, 1), code);
  if (SIMPLE_TARGET_EXPR_P (op)
      && TYPE_HAS_TRIVIAL_DESTRUCTOR (type))
    /* The TARGET_EXPR is itself a simple copy, look through it.  */
    return simple_empty_class_p (type, TARGET_EXPR_INITIAL (op), code);
  return
    (TREE_CODE (op) == EMPTY_CLASS_EXPR
     || code == MODIFY_EXPR
     || is_gimple_lvalue (op)
     || INDIRECT_REF_P (op)
     || (TREE_CODE (op) == CONSTRUCTOR
	 && CONSTRUCTOR_NELTS (op) == 0)
     || (TREE_CODE (op) == CALL_EXPR
	 && !CALL_EXPR_RETURN_SLOT_OPT (op)))
    && !TREE_CLOBBER_P (op)
    && is_really_empty_class (type, /*ignore_vptr*/true);
}

/* Returns true if evaluating E as an lvalue has side-effects;
   specifically, a volatile lvalue has TREE_SIDE_EFFECTS, but it doesn't really
   have side-effects until there is a read or write through it.  */

static bool
lvalue_has_side_effects (tree e)
{
  if (!TREE_SIDE_EFFECTS (e))
    return false;
  while (handled_component_p (e))
    {
      if (TREE_CODE (e) == ARRAY_REF
	  && TREE_SIDE_EFFECTS (TREE_OPERAND (e, 1)))
	return true;
      e = TREE_OPERAND (e, 0);
    }
  if (DECL_P (e))
    /* Just naming a variable has no side-effects.  */
    return false;
  else if (INDIRECT_REF_P (e))
    /* Similarly, indirection has no side-effects.  */
    return TREE_SIDE_EFFECTS (TREE_OPERAND (e, 0));
  else
    /* For anything else, trust TREE_SIDE_EFFECTS.  */
    return TREE_SIDE_EFFECTS (e);
}

/* Gimplify *EXPR_P as rvalue into an expression that can't be modified
   by expressions with side-effects in other operands.  */

static enum gimplify_status
gimplify_to_rvalue (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
		    bool (*gimple_test_f) (tree))
{
  enum gimplify_status t
    = gimplify_expr (expr_p, pre_p, post_p, gimple_test_f, fb_rvalue);
  if (t == GS_ERROR)
    return GS_ERROR;
  else if (is_gimple_variable (*expr_p) && TREE_CODE (*expr_p) != SSA_NAME)
    *expr_p = get_initialized_tmp_var (*expr_p, pre_p);
  return t;
}

/* Do C++-specific gimplification.  Args are as for gimplify_expr.  */

int
cp_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
{
  int saved_stmts_are_full_exprs_p = 0;
  location_t loc = cp_expr_loc_or_input_loc (*expr_p);
  enum tree_code code = TREE_CODE (*expr_p);
  enum gimplify_status ret;

  if (STATEMENT_CODE_P (code))
    {
      saved_stmts_are_full_exprs_p = stmts_are_full_exprs_p ();
      current_stmt_tree ()->stmts_are_full_exprs_p
	= STMT_IS_FULL_EXPR_P (*expr_p);
    }

  switch (code)
    {
    case AGGR_INIT_EXPR:
      simplify_aggr_init_expr (expr_p);
      ret = GS_OK;
      break;

    case VEC_INIT_EXPR:
      {
	location_t loc = input_location;
	tree init = VEC_INIT_EXPR_INIT (*expr_p);
	int from_array = (init && TREE_CODE (TREE_TYPE (init)) == ARRAY_TYPE);
	gcc_assert (EXPR_HAS_LOCATION (*expr_p));
	input_location = EXPR_LOCATION (*expr_p);
	*expr_p = build_vec_init (VEC_INIT_EXPR_SLOT (*expr_p), NULL_TREE,
				  init, VEC_INIT_EXPR_VALUE_INIT (*expr_p),
				  from_array,
				  tf_warning_or_error);
	hash_set<tree> pset;
	cp_walk_tree (expr_p, cp_fold_r, &pset, NULL);
	cp_genericize_tree (expr_p, false);
	copy_if_shared (expr_p);
	ret = GS_OK;
	input_location = loc;
      }
      break;

    case THROW_EXPR:
      /* FIXME communicate throw type to back end, probably by moving
	 THROW_EXPR into ../tree.def.  */
      *expr_p = TREE_OPERAND (*expr_p, 0);
      ret = GS_OK;
      break;

    case MUST_NOT_THROW_EXPR:
      ret = gimplify_must_not_throw_expr (expr_p, pre_p);
      break;

      /* We used to do this for MODIFY_EXPR as well, but that's unsafe; the
	 LHS of an assignment might also be involved in the RHS, as in bug
	 25979.  */
    case INIT_EXPR:
      cp_gimplify_init_expr (expr_p);
      if (TREE_CODE (*expr_p) != INIT_EXPR)
	return GS_OK;
      /* Fall through.  */
    case MODIFY_EXPR:
    modify_expr_case:
      {
	/* If the back end isn't clever enough to know that the lhs and rhs
	   types are the same, add an explicit conversion.  */
	tree op0 = TREE_OPERAND (*expr_p, 0);
	tree op1 = TREE_OPERAND (*expr_p, 1);

	if (!error_operand_p (op0)
	    && !error_operand_p (op1)
	    && (TYPE_STRUCTURAL_EQUALITY_P (TREE_TYPE (op0))
		|| TYPE_STRUCTURAL_EQUALITY_P (TREE_TYPE (op1)))
	    && !useless_type_conversion_p (TREE_TYPE (op1), TREE_TYPE (op0)))
	  TREE_OPERAND (*expr_p, 1) = build1 (VIEW_CONVERT_EXPR,
					      TREE_TYPE (op0), op1);

	else if (simple_empty_class_p (TREE_TYPE (op0), op1, code))
	  {
	    while (TREE_CODE (op1) == TARGET_EXPR)
	      /* We're disconnecting the initializer from its target,
		 don't create a temporary.  */
	      op1 = TARGET_EXPR_INITIAL (op1);

	    /* Remove any copies of empty classes.  Also drop volatile
	       variables on the RHS to avoid infinite recursion from
	       gimplify_expr trying to load the value.  */
	    if (TREE_SIDE_EFFECTS (op1))
	      {
		if (TREE_THIS_VOLATILE (op1)
		    && (REFERENCE_CLASS_P (op1) || DECL_P (op1)))
		  op1 = build_fold_addr_expr (op1);

		gimplify_and_add (op1, pre_p);
	      }
	    gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
			   is_gimple_lvalue, fb_lvalue);
	    *expr_p = TREE_OPERAND (*expr_p, 0);
	    if (code == RETURN_EXPR && REFERENCE_CLASS_P (*expr_p))
	      /* Avoid 'return *<retval>;'  */
	      *expr_p = TREE_OPERAND (*expr_p, 0);
	  }
	/* P0145 says that the RHS is sequenced before the LHS.
	   gimplify_modify_expr gimplifies the RHS before the LHS, but that
	   isn't quite strong enough in two cases:

	   1) gimplify.c wants to leave a CALL_EXPR on the RHS, which would
	   mean it's evaluated after the LHS.

	   2) the value calculation of the RHS is also sequenced before the
	   LHS, so for scalar assignment we need to preevaluate if the
	   RHS could be affected by LHS side-effects even if it has no
	   side-effects of its own.  We don't need this for classes because
	   class assignment takes its RHS by reference.  */
       else if (flag_strong_eval_order > 1
                && TREE_CODE (*expr_p) == MODIFY_EXPR
                && lvalue_has_side_effects (op0)
		&& (TREE_CODE (op1) == CALL_EXPR
		    || (SCALAR_TYPE_P (TREE_TYPE (op1))
			&& !TREE_CONSTANT (op1))))
	 TREE_OPERAND (*expr_p, 1) = get_initialized_tmp_var (op1, pre_p);
      }
      ret = GS_OK;
      break;

    case EMPTY_CLASS_EXPR:
      /* We create an empty CONSTRUCTOR with RECORD_TYPE.  */
      *expr_p = build_constructor (TREE_TYPE (*expr_p), NULL);
      ret = GS_OK;
      break;

    case BASELINK:
      *expr_p = BASELINK_FUNCTIONS (*expr_p);
      ret = GS_OK;
      break;

    case TRY_BLOCK:
      genericize_try_block (expr_p);
      ret = GS_OK;
      break;

    case HANDLER:
      genericize_catch_block (expr_p);
      ret = GS_OK;
      break;

    case EH_SPEC_BLOCK:
      genericize_eh_spec_block (expr_p);
      ret = GS_OK;
      break;

    case USING_STMT:
      gcc_unreachable ();

    case FOR_STMT:
    case WHILE_STMT:
    case DO_STMT:
    case SWITCH_STMT:
    case CONTINUE_STMT:
    case BREAK_STMT:
      gcc_unreachable ();

    case OMP_FOR:
    case OMP_SIMD:
    case OMP_DISTRIBUTE:
    case OMP_LOOP:
    case OMP_TASKLOOP:
      ret = cp_gimplify_omp_for (expr_p, pre_p);
      break;

    case EXPR_STMT:
      gimplify_expr_stmt (expr_p);
      ret = GS_OK;
      break;

    case UNARY_PLUS_EXPR:
      {
	tree arg = TREE_OPERAND (*expr_p, 0);
	tree type = TREE_TYPE (*expr_p);
	*expr_p = (TREE_TYPE (arg) != type) ? fold_convert (type, arg)
					    : arg;
	ret = GS_OK;
      }
      break;

    case CALL_EXPR:
      ret = GS_OK;
      if (flag_strong_eval_order == 2
	  && CALL_EXPR_FN (*expr_p)
	  && !CALL_EXPR_OPERATOR_SYNTAX (*expr_p)
	  && cp_get_callee_fndecl_nofold (*expr_p) == NULL_TREE)
	{
	  tree fnptrtype = TREE_TYPE (CALL_EXPR_FN (*expr_p));
	  enum gimplify_status t
	    = gimplify_to_rvalue (&CALL_EXPR_FN (*expr_p), pre_p, NULL,
				  is_gimple_call_addr);
	  if (t == GS_ERROR)
	    ret = GS_ERROR;
	  /* GIMPLE considers most pointer conversion useless, but for
	     calls we actually care about the exact function pointer type.  */
	  else if (TREE_TYPE (CALL_EXPR_FN (*expr_p)) != fnptrtype)
	    CALL_EXPR_FN (*expr_p)
	      = build1 (NOP_EXPR, fnptrtype, CALL_EXPR_FN (*expr_p));
	}
      if (!CALL_EXPR_FN (*expr_p))
	/* Internal function call.  */;
      else if (CALL_EXPR_REVERSE_ARGS (*expr_p))
	{
	  /* This is a call to a (compound) assignment operator that used
	     the operator syntax; gimplify the RHS first.  */
	  gcc_assert (call_expr_nargs (*expr_p) == 2);
	  gcc_assert (!CALL_EXPR_ORDERED_ARGS (*expr_p));
	  enum gimplify_status t
	    = gimplify_arg (&CALL_EXPR_ARG (*expr_p, 1), pre_p, loc);
	  if (t == GS_ERROR)
	    ret = GS_ERROR;
	}
      else if (CALL_EXPR_ORDERED_ARGS (*expr_p))
	{
	  /* Leave the last argument for gimplify_call_expr, to avoid problems
	     with __builtin_va_arg_pack().  */
	  int nargs = call_expr_nargs (*expr_p) - 1;
	  for (int i = 0; i < nargs; ++i)
	    {
	      enum gimplify_status t
		= gimplify_arg (&CALL_EXPR_ARG (*expr_p, i), pre_p, loc);
	      if (t == GS_ERROR)
		ret = GS_ERROR;
	    }
	}
      else if (flag_strong_eval_order
	       && !CALL_EXPR_OPERATOR_SYNTAX (*expr_p))
	{
	  /* If flag_strong_eval_order, evaluate the object argument first.  */
	  tree fntype = TREE_TYPE (CALL_EXPR_FN (*expr_p));
	  if (INDIRECT_TYPE_P (fntype))
	    fntype = TREE_TYPE (fntype);
	  if (TREE_CODE (fntype) == METHOD_TYPE)
	    {
	      enum gimplify_status t
		= gimplify_arg (&CALL_EXPR_ARG (*expr_p, 0), pre_p, loc);
	      if (t == GS_ERROR)
		ret = GS_ERROR;
	    }
	}
      if (ret != GS_ERROR)
	{
	  tree decl = cp_get_callee_fndecl_nofold (*expr_p);
	  if (decl
	      && fndecl_built_in_p (decl, CP_BUILT_IN_IS_CONSTANT_EVALUATED,
				    BUILT_IN_FRONTEND))
	    *expr_p = boolean_false_node;
	  else if (decl
		   && fndecl_built_in_p (decl, CP_BUILT_IN_SOURCE_LOCATION,
					 BUILT_IN_FRONTEND))
	    *expr_p = fold_builtin_source_location (EXPR_LOCATION (*expr_p));
	}
      break;

    case TARGET_EXPR:
      /* A TARGET_EXPR that expresses direct-initialization should have been
	 elided by cp_gimplify_init_expr.  */
      gcc_checking_assert (!TARGET_EXPR_DIRECT_INIT_P (*expr_p));
      ret = GS_UNHANDLED;
      break;

    case RETURN_EXPR:
      if (TREE_OPERAND (*expr_p, 0)
	  && (TREE_CODE (TREE_OPERAND (*expr_p, 0)) == INIT_EXPR
	      || TREE_CODE (TREE_OPERAND (*expr_p, 0)) == MODIFY_EXPR))
	{
	  expr_p = &TREE_OPERAND (*expr_p, 0);
	  /* Avoid going through the INIT_EXPR case, which can
	     degrade INIT_EXPRs into AGGR_INIT_EXPRs.  */
	  goto modify_expr_case;
	}
      /* Fall through.  */

    default:
      ret = (enum gimplify_status) c_gimplify_expr (expr_p, pre_p, post_p);
      break;
    }

  /* Restore saved state.  */
  if (STATEMENT_CODE_P (code))
    current_stmt_tree ()->stmts_are_full_exprs_p
      = saved_stmts_are_full_exprs_p;

  return ret;
}

static inline bool
is_invisiref_parm (const_tree t)
{
  return ((TREE_CODE (t) == PARM_DECL || TREE_CODE (t) == RESULT_DECL)
	  && DECL_BY_REFERENCE (t));
}

/* Return true if the uid in both int tree maps are equal.  */

bool
cxx_int_tree_map_hasher::equal (cxx_int_tree_map *a, cxx_int_tree_map *b)
{
  return (a->uid == b->uid);
}

/* Hash a UID in a cxx_int_tree_map.  */

unsigned int
cxx_int_tree_map_hasher::hash (cxx_int_tree_map *item)
{
  return item->uid;
}

/* A stable comparison routine for use with splay trees and DECLs.  */

static int
splay_tree_compare_decl_uid (splay_tree_key xa, splay_tree_key xb)
{
  tree a = (tree) xa;
  tree b = (tree) xb;

  return DECL_UID (a) - DECL_UID (b);
}

/* OpenMP context during genericization.  */

struct cp_genericize_omp_taskreg
{
  bool is_parallel;
  bool default_shared;
  struct cp_genericize_omp_taskreg *outer;
  splay_tree variables;
};

/* Return true if genericization should try to determine if
   DECL is firstprivate or shared within task regions.  */

static bool
omp_var_to_track (tree decl)
{
  tree type = TREE_TYPE (decl);
  if (is_invisiref_parm (decl))
    type = TREE_TYPE (type);
  else if (TYPE_REF_P (type))
    type = TREE_TYPE (type);
  while (TREE_CODE (type) == ARRAY_TYPE)
    type = TREE_TYPE (type);
  if (type == error_mark_node || !CLASS_TYPE_P (type))
    return false;
  if (VAR_P (decl) && CP_DECL_THREAD_LOCAL_P (decl))
    return false;
  if (cxx_omp_predetermined_sharing (decl) != OMP_CLAUSE_DEFAULT_UNSPECIFIED)
    return false;
  return true;
}

/* Note DECL use in OpenMP region OMP_CTX during genericization.  */

static void
omp_cxx_notice_variable (struct cp_genericize_omp_taskreg *omp_ctx, tree decl)
{
  splay_tree_node n = splay_tree_lookup (omp_ctx->variables,
					 (splay_tree_key) decl);
  if (n == NULL)
    {
      int flags = OMP_CLAUSE_DEFAULT_SHARED;
      if (omp_ctx->outer)
	omp_cxx_notice_variable (omp_ctx->outer, decl);
      if (!omp_ctx->default_shared)
	{
	  struct cp_genericize_omp_taskreg *octx;

	  for (octx = omp_ctx->outer; octx; octx = octx->outer)
	    {
	      n = splay_tree_lookup (octx->variables, (splay_tree_key) decl);
	      if (n && n->value != OMP_CLAUSE_DEFAULT_SHARED)
		{
		  flags = OMP_CLAUSE_DEFAULT_FIRSTPRIVATE;
		  break;
		}
	      if (octx->is_parallel)
		break;
	    }
	  if (octx == NULL
	      && (TREE_CODE (decl) == PARM_DECL
		  || (!(TREE_STATIC (decl) || DECL_EXTERNAL (decl))
		      && DECL_CONTEXT (decl) == current_function_decl)))
	    flags = OMP_CLAUSE_DEFAULT_FIRSTPRIVATE;
	  if (flags == OMP_CLAUSE_DEFAULT_FIRSTPRIVATE)
	    {
	      /* DECL is implicitly determined firstprivate in
		 the current task construct.  Ensure copy ctor and
		 dtor are instantiated, because during gimplification
		 it will be already too late.  */
	      tree type = TREE_TYPE (decl);
	      if (is_invisiref_parm (decl))
		type = TREE_TYPE (type);
	      else if (TYPE_REF_P (type))
		type = TREE_TYPE (type);
	      while (TREE_CODE (type) == ARRAY_TYPE)
		type = TREE_TYPE (type);
	      get_copy_ctor (type, tf_none);
	      get_dtor (type, tf_none);
	    }
	}
      splay_tree_insert (omp_ctx->variables, (splay_tree_key) decl, flags);
    }
}

/* Genericization context.  */

struct cp_genericize_data
{
  hash_set<tree> *p_set;
  vec<tree> bind_expr_stack;
  struct cp_genericize_omp_taskreg *omp_ctx;
  tree try_block;
  bool no_sanitize_p;
  bool handle_invisiref_parm_p;
};

/* Perform any pre-gimplification folding of C++ front end trees to
   GENERIC.
   Note:  The folding of none-omp cases is something to move into
     the middle-end.  As for now we have most foldings only on GENERIC
     in fold-const, we need to perform this before transformation to
     GIMPLE-form.  */

static tree
cp_fold_r (tree *stmt_p, int *walk_subtrees, void *data)
{
  tree stmt;
  enum tree_code code;

  *stmt_p = stmt = cp_fold (*stmt_p);

  if (((hash_set<tree> *) data)->add (stmt))
    {
      /* Don't walk subtrees of stmts we've already walked once, otherwise
	 we can have exponential complexity with e.g. lots of nested
	 SAVE_EXPRs or TARGET_EXPRs.  cp_fold uses a cache and will return
	 always the same tree, which the first time cp_fold_r has been
	 called on it had the subtrees walked.  */
      *walk_subtrees = 0;
      return NULL;
    }

  code = TREE_CODE (stmt);
  if (code == OMP_FOR || code == OMP_SIMD || code == OMP_DISTRIBUTE
      || code == OMP_LOOP || code == OMP_TASKLOOP || code == OACC_LOOP)
    {
      tree x;
      int i, n;

      cp_walk_tree (&OMP_FOR_BODY (stmt), cp_fold_r, data, NULL);
      cp_walk_tree (&OMP_FOR_CLAUSES (stmt), cp_fold_r, data, NULL);
      cp_walk_tree (&OMP_FOR_INIT (stmt), cp_fold_r, data, NULL);
      x = OMP_FOR_COND (stmt);
      if (x && TREE_CODE_CLASS (TREE_CODE (x)) == tcc_comparison)
	{
	  cp_walk_tree (&TREE_OPERAND (x, 0), cp_fold_r, data, NULL);
	  cp_walk_tree (&TREE_OPERAND (x, 1), cp_fold_r, data, NULL);
	}
      else if (x && TREE_CODE (x) == TREE_VEC)
	{
	  n = TREE_VEC_LENGTH (x);
	  for (i = 0; i < n; i++)
	    {
	      tree o = TREE_VEC_ELT (x, i);
	      if (o && TREE_CODE_CLASS (TREE_CODE (o)) == tcc_comparison)
		cp_walk_tree (&TREE_OPERAND (o, 1), cp_fold_r, data, NULL);
	    }
	}
      x = OMP_FOR_INCR (stmt);
      if (x && TREE_CODE (x) == TREE_VEC)
	{
	  n = TREE_VEC_LENGTH (x);
	  for (i = 0; i < n; i++)
	    {
	      tree o = TREE_VEC_ELT (x, i);
	      if (o && TREE_CODE (o) == MODIFY_EXPR)
		o = TREE_OPERAND (o, 1);
	      if (o && (TREE_CODE (o) == PLUS_EXPR || TREE_CODE (o) == MINUS_EXPR
			|| TREE_CODE (o) == POINTER_PLUS_EXPR))
		{
		  cp_walk_tree (&TREE_OPERAND (o, 0), cp_fold_r, data, NULL);
		  cp_walk_tree (&TREE_OPERAND (o, 1), cp_fold_r, data, NULL);
		}
	    }
	}
      cp_walk_tree (&OMP_FOR_PRE_BODY (stmt), cp_fold_r, data, NULL);
      *walk_subtrees = 0;
    }

  return NULL;
}

/* Fold ALL the trees!  FIXME we should be able to remove this, but
   apparently that still causes optimization regressions.  */

void
cp_fold_function (tree fndecl)
{
  hash_set<tree> pset;
  cp_walk_tree (&DECL_SAVED_TREE (fndecl), cp_fold_r, &pset, NULL);
}

/* Turn SPACESHIP_EXPR EXPR into GENERIC.  */

static tree genericize_spaceship (tree expr)
{
  iloc_sentinel s (cp_expr_location (expr));
  tree type = TREE_TYPE (expr);
  tree op0 = TREE_OPERAND (expr, 0);
  tree op1 = TREE_OPERAND (expr, 1);
  return genericize_spaceship (type, op0, op1);
}

/* If EXPR involves an anonymous VLA type, prepend a DECL_EXPR for that type
   to trigger gimplify_type_sizes; otherwise a cast to pointer-to-VLA confuses
   the middle-end (c++/88256).  If EXPR is a DECL, use add_stmt and return
   NULL_TREE; otherwise return a COMPOUND_STMT of the DECL_EXPR and EXPR.  */

tree
predeclare_vla (tree expr)
{
  tree type = TREE_TYPE (expr);
  if (type == error_mark_node)
    return expr;
  if (is_typedef_decl (expr))
    type = DECL_ORIGINAL_TYPE (expr);

  /* We need to strip pointers for gimplify_type_sizes.  */
  tree vla = type;
  while (POINTER_TYPE_P (vla))
    {
      if (TYPE_NAME (vla))
	return expr;
      vla = TREE_TYPE (vla);
    }
  if (vla == type || TYPE_NAME (vla)
      || !variably_modified_type_p (vla, NULL_TREE))
    return expr;

  tree decl = build_decl (input_location, TYPE_DECL, NULL_TREE, vla);
  DECL_ARTIFICIAL (decl) = 1;
  TYPE_NAME (vla) = decl;
  tree dexp = build_stmt (input_location, DECL_EXPR, decl);
  if (DECL_P (expr))
    {
      add_stmt (dexp);
      return NULL_TREE;
    }
  else
    {
      expr = build2 (COMPOUND_EXPR, type, dexp, expr);
      return expr;
    }
}

/* Perform any pre-gimplification lowering of C++ front end trees to
   GENERIC.  */

static tree
cp_genericize_r (tree *stmt_p, int *walk_subtrees, void *data)
{
  tree stmt = *stmt_p;
  struct cp_genericize_data *wtd = (struct cp_genericize_data *) data;
  hash_set<tree> *p_set = wtd->p_set;

  /* If in an OpenMP context, note var uses.  */
  if (__builtin_expect (wtd->omp_ctx != NULL, 0)
      && (VAR_P (stmt)
	  || TREE_CODE (stmt) == PARM_DECL
	  || TREE_CODE (stmt) == RESULT_DECL)
      && omp_var_to_track (stmt))
    omp_cxx_notice_variable (wtd->omp_ctx, stmt);

  /* Don't dereference parms in a thunk, pass the references through. */
  if ((TREE_CODE (stmt) == CALL_EXPR && CALL_FROM_THUNK_P (stmt))
      || (TREE_CODE (stmt) == AGGR_INIT_EXPR && AGGR_INIT_FROM_THUNK_P (stmt)))
    {
      *walk_subtrees = 0;
      return NULL;
    }

  /* Dereference invisible reference parms.  */
  if (wtd->handle_invisiref_parm_p && is_invisiref_parm (stmt))
    {
      *stmt_p = convert_from_reference (stmt);
      p_set->add (*stmt_p);
      *walk_subtrees = 0;
      return NULL;
    }

  /* Map block scope extern declarations to visible declarations with the
     same name and type in outer scopes if any.  */
  if (cp_function_chain->extern_decl_map
      && VAR_OR_FUNCTION_DECL_P (stmt)
      && DECL_EXTERNAL (stmt))
    {
      struct cxx_int_tree_map *h, in;
      in.uid = DECL_UID (stmt);
      h = cp_function_chain->extern_decl_map->find_with_hash (&in, in.uid);
      if (h)
	{
	  *stmt_p = h->to;
	  TREE_USED (h->to) |= TREE_USED (stmt);
	  *walk_subtrees = 0;
	  return NULL;
	}
    }

  if (TREE_CODE (stmt) == INTEGER_CST
      && TYPE_REF_P (TREE_TYPE (stmt))
      && (flag_sanitize & (SANITIZE_NULL | SANITIZE_ALIGNMENT))
      && !wtd->no_sanitize_p)
    {
      ubsan_maybe_instrument_reference (stmt_p);
      if (*stmt_p != stmt)
	{
	  *walk_subtrees = 0;
	  return NULL_TREE;
	}
    }

  /* Other than invisiref parms, don't walk the same tree twice.  */
  if (p_set->contains (stmt))
    {
      *walk_subtrees = 0;
      return NULL_TREE;
    }

  switch (TREE_CODE (stmt))
    {
    case ADDR_EXPR:
      if (is_invisiref_parm (TREE_OPERAND (stmt, 0)))
	{
	  /* If in an OpenMP context, note var uses.  */
	  if (__builtin_expect (wtd->omp_ctx != NULL, 0)
	      && omp_var_to_track (TREE_OPERAND (stmt, 0)))
	    omp_cxx_notice_variable (wtd->omp_ctx, TREE_OPERAND (stmt, 0));
	  *stmt_p = fold_convert (TREE_TYPE (stmt), TREE_OPERAND (stmt, 0));
	  *walk_subtrees = 0;
	}
      break;

    case RETURN_EXPR:
      if (TREE_OPERAND (stmt, 0) && is_invisiref_parm (TREE_OPERAND (stmt, 0)))
	/* Don't dereference an invisiref RESULT_DECL inside a RETURN_EXPR.  */
	*walk_subtrees = 0;
      break;

    case OMP_CLAUSE:
      switch (OMP_CLAUSE_CODE (stmt))
	{
	case OMP_CLAUSE_LASTPRIVATE:
	  /* Don't dereference an invisiref in OpenMP clauses.  */
	  if (is_invisiref_parm (OMP_CLAUSE_DECL (stmt)))
	    {
	      *walk_subtrees = 0;
	      if (OMP_CLAUSE_LASTPRIVATE_STMT (stmt))
		cp_walk_tree (&OMP_CLAUSE_LASTPRIVATE_STMT (stmt),
			      cp_genericize_r, data, NULL);
	    }
	  break;
	case OMP_CLAUSE_PRIVATE:
	  /* Don't dereference an invisiref in OpenMP clauses.  */
	  if (is_invisiref_parm (OMP_CLAUSE_DECL (stmt)))
	    *walk_subtrees = 0;
	  else if (wtd->omp_ctx != NULL)
	    {
	      /* Private clause doesn't cause any references to the
		 var in outer contexts, avoid calling
		 omp_cxx_notice_variable for it.  */
	      struct cp_genericize_omp_taskreg *old = wtd->omp_ctx;
	      wtd->omp_ctx = NULL;
	      cp_walk_tree (&OMP_CLAUSE_DECL (stmt), cp_genericize_r,
			    data, NULL);
	      wtd->omp_ctx = old;
	      *walk_subtrees = 0;
	    }
	  break;
	case OMP_CLAUSE_SHARED:
	case OMP_CLAUSE_FIRSTPRIVATE:
	case OMP_CLAUSE_COPYIN:
	case OMP_CLAUSE_COPYPRIVATE:
	case OMP_CLAUSE_INCLUSIVE:
	case OMP_CLAUSE_EXCLUSIVE:
	  /* Don't dereference an invisiref in OpenMP clauses.  */
	  if (is_invisiref_parm (OMP_CLAUSE_DECL (stmt)))
	    *walk_subtrees = 0;
	  break;
	case OMP_CLAUSE_REDUCTION:
	case OMP_CLAUSE_IN_REDUCTION:
	case OMP_CLAUSE_TASK_REDUCTION:
	  /* Don't dereference an invisiref in reduction clause's
	     OMP_CLAUSE_DECL either.  OMP_CLAUSE_REDUCTION_{INIT,MERGE}
	     still needs to be genericized.  */
	  if (is_invisiref_parm (OMP_CLAUSE_DECL (stmt)))
	    {
	      *walk_subtrees = 0;
	      if (OMP_CLAUSE_REDUCTION_INIT (stmt))
		cp_walk_tree (&OMP_CLAUSE_REDUCTION_INIT (stmt),
			      cp_genericize_r, data, NULL);
	      if (OMP_CLAUSE_REDUCTION_MERGE (stmt))
		cp_walk_tree (&OMP_CLAUSE_REDUCTION_MERGE (stmt),
			      cp_genericize_r, data, NULL);
	    }
	  break;
	default:
	  break;
	}
      break;

    /* Due to the way voidify_wrapper_expr is written, we don't get a chance
       to lower this construct before scanning it, so we need to lower these
       before doing anything else.  */
    case CLEANUP_STMT:
      *stmt_p = build2_loc (EXPR_LOCATION (stmt),
			    CLEANUP_EH_ONLY (stmt) ? TRY_CATCH_EXPR
						   : TRY_FINALLY_EXPR,
			    void_type_node,
			    CLEANUP_BODY (stmt),
			    CLEANUP_EXPR (stmt));
      break;

    case IF_STMT:
      genericize_if_stmt (stmt_p);
      /* *stmt_p has changed, tail recurse to handle it again.  */
      return cp_genericize_r (stmt_p, walk_subtrees, data);

    /* COND_EXPR might have incompatible types in branches if one or both
       arms are bitfields.  Fix it up now.  */
    case COND_EXPR:
      {
	tree type_left
	  = (TREE_OPERAND (stmt, 1)
	     ? is_bitfield_expr_with_lowered_type (TREE_OPERAND (stmt, 1))
	     : NULL_TREE);
	tree type_right
	  = (TREE_OPERAND (stmt, 2)
	     ? is_bitfield_expr_with_lowered_type (TREE_OPERAND (stmt, 2))
	     : NULL_TREE);
	if (type_left
	    && !useless_type_conversion_p (TREE_TYPE (stmt),
					   TREE_TYPE (TREE_OPERAND (stmt, 1))))
	  {
	    TREE_OPERAND (stmt, 1)
	      = fold_convert (type_left, TREE_OPERAND (stmt, 1));
	    gcc_assert (useless_type_conversion_p (TREE_TYPE (stmt),
						   type_left));
	  }
	if (type_right
	    && !useless_type_conversion_p (TREE_TYPE (stmt),
					   TREE_TYPE (TREE_OPERAND (stmt, 2))))
	  {
	    TREE_OPERAND (stmt, 2)
	      = fold_convert (type_right, TREE_OPERAND (stmt, 2));
	    gcc_assert (useless_type_conversion_p (TREE_TYPE (stmt),
						   type_right));
	  }
      }
      break;

    case BIND_EXPR:
      if (__builtin_expect (wtd->omp_ctx != NULL, 0))
	{
	  tree decl;
	  for (decl = BIND_EXPR_VARS (stmt); decl; decl = DECL_CHAIN (decl))
	    if (VAR_P (decl)
		&& !DECL_EXTERNAL (decl)
		&& omp_var_to_track (decl))
	      {
		splay_tree_node n
		  = splay_tree_lookup (wtd->omp_ctx->variables,
				       (splay_tree_key) decl);
		if (n == NULL)
		  splay_tree_insert (wtd->omp_ctx->variables,
				     (splay_tree_key) decl,
				     TREE_STATIC (decl)
				     ? OMP_CLAUSE_DEFAULT_SHARED
				     : OMP_CLAUSE_DEFAULT_PRIVATE);
	      }
	}
      if (sanitize_flags_p (SANITIZE_NULL | SANITIZE_ALIGNMENT | SANITIZE_VPTR))
	{
	  /* The point here is to not sanitize static initializers.  */
	  bool no_sanitize_p = wtd->no_sanitize_p;
	  wtd->no_sanitize_p = true;
	  for (tree decl = BIND_EXPR_VARS (stmt);
	       decl;
	       decl = DECL_CHAIN (decl))
	    if (VAR_P (decl)
		&& TREE_STATIC (decl)
		&& DECL_INITIAL (decl))
	      cp_walk_tree (&DECL_INITIAL (decl), cp_genericize_r, data, NULL);
	  wtd->no_sanitize_p = no_sanitize_p;
	}
      wtd->bind_expr_stack.safe_push (stmt);
      cp_walk_tree (&BIND_EXPR_BODY (stmt),
		    cp_genericize_r, data, NULL);
      wtd->bind_expr_stack.pop ();
      break;

    case USING_STMT:
      {
	tree block = NULL_TREE;

	/* Get the innermost inclosing GIMPLE_BIND that has a non NULL
	   BLOCK, and append an IMPORTED_DECL to its
	   BLOCK_VARS chained list.  */
	if (wtd->bind_expr_stack.exists ())
	  {
	    int i;
	    for (i = wtd->bind_expr_stack.length () - 1; i >= 0; i--)
	      if ((block = BIND_EXPR_BLOCK (wtd->bind_expr_stack[i])))
		break;
	  }
	if (block)
	  {
	    tree decl = TREE_OPERAND (stmt, 0);
	    gcc_assert (decl);

	    if (undeduced_auto_decl (decl))
	      /* Omit from the GENERIC, the back-end can't handle it.  */;
	    else
	      {
		tree using_directive = make_node (IMPORTED_DECL);
		TREE_TYPE (using_directive) = void_type_node;
		DECL_CONTEXT (using_directive) = current_function_decl;

		IMPORTED_DECL_ASSOCIATED_DECL (using_directive) = decl;
		DECL_CHAIN (using_directive) = BLOCK_VARS (block);
		BLOCK_VARS (block) = using_directive;
	      }
	  }
	/* The USING_STMT won't appear in GENERIC.  */
	*stmt_p = build1 (NOP_EXPR, void_type_node, integer_zero_node);
	*walk_subtrees = 0;
      }
      break;

    case DECL_EXPR:
      if (TREE_CODE (DECL_EXPR_DECL (stmt)) == USING_DECL)
	{
	  /* Using decls inside DECL_EXPRs are just dropped on the floor.  */
	  *stmt_p = build1 (NOP_EXPR, void_type_node, integer_zero_node);
	  *walk_subtrees = 0;
	}
      else
	{
	  tree d = DECL_EXPR_DECL (stmt);
	  if (VAR_P (d))
	    gcc_assert (CP_DECL_THREAD_LOCAL_P (d) == DECL_THREAD_LOCAL_P (d));
	}
      break;

    case OMP_PARALLEL:
    case OMP_TASK:
    case OMP_TASKLOOP:
      {
	struct cp_genericize_omp_taskreg omp_ctx;
	tree c, decl;
	splay_tree_node n;

	*walk_subtrees = 0;
	cp_walk_tree (&OMP_CLAUSES (stmt), cp_genericize_r, data, NULL);
	omp_ctx.is_parallel = TREE_CODE (stmt) == OMP_PARALLEL;
	omp_ctx.default_shared = omp_ctx.is_parallel;
	omp_ctx.outer = wtd->omp_ctx;
	omp_ctx.variables = splay_tree_new (splay_tree_compare_decl_uid, 0, 0);
	wtd->omp_ctx = &omp_ctx;
	for (c = OMP_CLAUSES (stmt); c; c = OMP_CLAUSE_CHAIN (c))
	  switch (OMP_CLAUSE_CODE (c))
	    {
	    case OMP_CLAUSE_SHARED:
	    case OMP_CLAUSE_PRIVATE:
	    case OMP_CLAUSE_FIRSTPRIVATE:
	    case OMP_CLAUSE_LASTPRIVATE:
	      decl = OMP_CLAUSE_DECL (c);
	      if (decl == error_mark_node || !omp_var_to_track (decl))
		break;
	      n = splay_tree_lookup (omp_ctx.variables, (splay_tree_key) decl);
	      if (n != NULL)
		break;
	      splay_tree_insert (omp_ctx.variables, (splay_tree_key) decl,
				 OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
				 ? OMP_CLAUSE_DEFAULT_SHARED
				 : OMP_CLAUSE_DEFAULT_PRIVATE);
	      if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_PRIVATE && omp_ctx.outer)
		omp_cxx_notice_variable (omp_ctx.outer, decl);
	      break;
	    case OMP_CLAUSE_DEFAULT:
	      if (OMP_CLAUSE_DEFAULT_KIND (c) == OMP_CLAUSE_DEFAULT_SHARED)
		omp_ctx.default_shared = true;
	    default:
	      break;
	    }
	if (TREE_CODE (stmt) == OMP_TASKLOOP)
	  genericize_omp_for_stmt (stmt_p, walk_subtrees, data);
	else
	  cp_walk_tree (&OMP_BODY (stmt), cp_genericize_r, data, NULL);
	wtd->omp_ctx = omp_ctx.outer;
	splay_tree_delete (omp_ctx.variables);
      }
      break;

    case OMP_TARGET:
      cfun->has_omp_target = true;
      break;

    case TRY_BLOCK:
      {
        *walk_subtrees = 0;
        tree try_block = wtd->try_block;
        wtd->try_block = stmt;
        cp_walk_tree (&TRY_STMTS (stmt), cp_genericize_r, data, NULL);
        wtd->try_block = try_block;
        cp_walk_tree (&TRY_HANDLERS (stmt), cp_genericize_r, data, NULL);
      }
      break;

    case MUST_NOT_THROW_EXPR:
      /* MUST_NOT_THROW_COND might be something else with TM.  */
      if (MUST_NOT_THROW_COND (stmt) == NULL_TREE)
	{
	  *walk_subtrees = 0;
	  tree try_block = wtd->try_block;
	  wtd->try_block = stmt;
	  cp_walk_tree (&TREE_OPERAND (stmt, 0), cp_genericize_r, data, NULL);
	  wtd->try_block = try_block;
	}
      break;

    case THROW_EXPR:
      {
	location_t loc = location_of (stmt);
	if (TREE_NO_WARNING (stmt))
	  /* Never mind.  */;
	else if (wtd->try_block)
	  {
	    if (TREE_CODE (wtd->try_block) == MUST_NOT_THROW_EXPR)
	      {
		auto_diagnostic_group d;
		if (warning_at (loc, OPT_Wterminate,
				"%<throw%> will always call %<terminate%>")
		    && cxx_dialect >= cxx11
		    && DECL_DESTRUCTOR_P (current_function_decl))
		  inform (loc, "in C++11 destructors default to %<noexcept%>");
	      }
	  }
	else
	  {
	    if (warn_cxx11_compat && cxx_dialect < cxx11
		&& DECL_DESTRUCTOR_P (current_function_decl)
		&& (TYPE_RAISES_EXCEPTIONS (TREE_TYPE (current_function_decl))
		    == NULL_TREE)
		&& (get_defaulted_eh_spec (current_function_decl)
		    == empty_except_spec))
	      warning_at (loc, OPT_Wc__11_compat,
			  "in C++11 this %<throw%> will call %<terminate%> "
			  "because destructors default to %<noexcept%>");
	  }
      }
      break;

    case CONVERT_EXPR:
      gcc_assert (!CONVERT_EXPR_VBASE_PATH (stmt));
      break;

    case FOR_STMT:
      genericize_for_stmt (stmt_p, walk_subtrees, data);
      break;

    case WHILE_STMT:
      genericize_while_stmt (stmt_p, walk_subtrees, data);
      break;

    case DO_STMT:
      genericize_do_stmt (stmt_p, walk_subtrees, data);
      break;

    case SWITCH_STMT:
      genericize_switch_stmt (stmt_p, walk_subtrees, data);
      break;

    case CONTINUE_STMT:
      genericize_continue_stmt (stmt_p);
      break;

    case BREAK_STMT:
      genericize_break_stmt (stmt_p);
      break;

    case SPACESHIP_EXPR:
      *stmt_p = genericize_spaceship (*stmt_p);
      break;

    case OMP_DISTRIBUTE:
      /* Need to explicitly instantiate copy ctors on class iterators of
	 composite distribute parallel for.  */
      if (OMP_FOR_INIT (*stmt_p) == NULL_TREE)
	{
	  tree *data[4] = { NULL, NULL, NULL, NULL };
	  tree inner = walk_tree (&OMP_FOR_BODY (*stmt_p),
				  find_combined_omp_for, data, NULL);
	  if (inner != NULL_TREE
	      && TREE_CODE (inner) == OMP_FOR)
	    {
	      for (int i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (inner)); i++)
		if (OMP_FOR_ORIG_DECLS (inner)
		    && TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner),
				  i)) == TREE_LIST
		    && TREE_PURPOSE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner),
				     i)))
		  {
		    tree orig = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner), i);
		    /* Class iterators aren't allowed on OMP_SIMD, so the only
		       case we need to solve is distribute parallel for.  */
		    gcc_assert (TREE_CODE (inner) == OMP_FOR
				&& data[1]);
		    tree orig_decl = TREE_PURPOSE (orig);
		    tree c, cl = NULL_TREE;
		    for (c = OMP_FOR_CLAUSES (inner);
			 c; c = OMP_CLAUSE_CHAIN (c))
		      if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_PRIVATE
			   || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE)
			  && OMP_CLAUSE_DECL (c) == orig_decl)
			{
			  cl = c;
			  break;
			}
		    if (cl == NULL_TREE)
		      {
			for (c = OMP_PARALLEL_CLAUSES (*data[1]);
			     c; c = OMP_CLAUSE_CHAIN (c))
			  if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_PRIVATE
			      && OMP_CLAUSE_DECL (c) == orig_decl)
			    {
			      cl = c;
			      break;
			    }
		      }
		    if (cl)
		      {
			orig_decl = require_complete_type (orig_decl);
			tree inner_type = TREE_TYPE (orig_decl);
			if (orig_decl == error_mark_node)
			  continue;
			if (TYPE_REF_P (TREE_TYPE (orig_decl)))
			  inner_type = TREE_TYPE (inner_type);

			while (TREE_CODE (inner_type) == ARRAY_TYPE)
			  inner_type = TREE_TYPE (inner_type);
			get_copy_ctor (inner_type, tf_warning_or_error);
		      }
		}
	    }
	}
      /* FALLTHRU */
    case OMP_FOR:
    case OMP_SIMD:
    case OMP_LOOP:
    case OACC_LOOP:
      genericize_omp_for_stmt (stmt_p, walk_subtrees, data);
      break;

    case PTRMEM_CST:
      /* By the time we get here we're handing off to the back end, so we don't
	 need or want to preserve PTRMEM_CST anymore.  */
      *stmt_p = cplus_expand_constant (stmt);
      *walk_subtrees = 0;
      break;

    case MEM_REF:
      /* For MEM_REF, make sure not to sanitize the second operand even
	 if it has reference type.  It is just an offset with a type
	 holding other information.  There is no other processing we
	 need to do for INTEGER_CSTs, so just ignore the second argument
	 unconditionally.  */
      cp_walk_tree (&TREE_OPERAND (stmt, 0), cp_genericize_r, data, NULL);
      *walk_subtrees = 0;
      break;

    case NOP_EXPR:
      *stmt_p = predeclare_vla (*stmt_p);
      if (!wtd->no_sanitize_p
	  && sanitize_flags_p (SANITIZE_NULL | SANITIZE_ALIGNMENT)
	  && TYPE_REF_P (TREE_TYPE (stmt)))
	ubsan_maybe_instrument_reference (stmt_p);
      break;

    case CALL_EXPR:
      /* Evaluate function concept checks instead of treating them as
	 normal functions.  */
      if (concept_check_p (stmt))
	{
	  *stmt_p = evaluate_concept_check (stmt, tf_warning_or_error);
	  * walk_subtrees = 0;
	  break;
	}

      if (!wtd->no_sanitize_p
	  && sanitize_flags_p ((SANITIZE_NULL
				| SANITIZE_ALIGNMENT | SANITIZE_VPTR)))
	{
	  tree fn = CALL_EXPR_FN (stmt);
	  if (fn != NULL_TREE
	      && !error_operand_p (fn)
	      && INDIRECT_TYPE_P (TREE_TYPE (fn))
	      && TREE_CODE (TREE_TYPE (TREE_TYPE (fn))) == METHOD_TYPE)
	    {
	      bool is_ctor
		= TREE_CODE (fn) == ADDR_EXPR
		  && TREE_CODE (TREE_OPERAND (fn, 0)) == FUNCTION_DECL
		  && DECL_CONSTRUCTOR_P (TREE_OPERAND (fn, 0));
	      if (sanitize_flags_p (SANITIZE_NULL | SANITIZE_ALIGNMENT))
		ubsan_maybe_instrument_member_call (stmt, is_ctor);
	      if (sanitize_flags_p (SANITIZE_VPTR) && !is_ctor)
		cp_ubsan_maybe_instrument_member_call (stmt);
	    }
	  else if (fn == NULL_TREE
		   && CALL_EXPR_IFN (stmt) == IFN_UBSAN_NULL
		   && TREE_CODE (CALL_EXPR_ARG (stmt, 0)) == INTEGER_CST
		   && TYPE_REF_P (TREE_TYPE (CALL_EXPR_ARG (stmt, 0))))
	    *walk_subtrees = 0;
	}
      /* Fall through.  */
    case AGGR_INIT_EXPR:
      /* For calls to a multi-versioned function, overload resolution
	 returns the function with the highest target priority, that is,
	 the version that will checked for dispatching first.  If this
	 version is inlinable, a direct call to this version can be made
	 otherwise the call should go through the dispatcher.  */
      {
	tree fn = cp_get_callee_fndecl_nofold (stmt);
	if (fn && DECL_FUNCTION_VERSIONED (fn)
	    && (current_function_decl == NULL
		|| !targetm.target_option.can_inline_p (current_function_decl,
							fn)))
	  if (tree dis = get_function_version_dispatcher (fn))
	    {
	      mark_versions_used (dis);
	      dis = build_address (dis);
	      if (TREE_CODE (stmt) == CALL_EXPR)
		CALL_EXPR_FN (stmt) = dis;
	      else
		AGGR_INIT_EXPR_FN (stmt) = dis;
	    }
      }
      break;

    case TARGET_EXPR:
      if (TARGET_EXPR_INITIAL (stmt)
	  && TREE_CODE (TARGET_EXPR_INITIAL (stmt)) == CONSTRUCTOR
	  && CONSTRUCTOR_PLACEHOLDER_BOUNDARY (TARGET_EXPR_INITIAL (stmt)))
	TARGET_EXPR_NO_ELIDE (stmt) = 1;
      break;

    case REQUIRES_EXPR:
      /* Emit the value of the requires-expression.  */
      *stmt_p = constant_boolean_node (constraints_satisfied_p (stmt),
				       boolean_type_node);
      *walk_subtrees = 0;
      break;

    case TEMPLATE_ID_EXPR:
      gcc_assert (concept_check_p (stmt));
      /* Emit the value of the concept check.  */
      *stmt_p = evaluate_concept_check (stmt, tf_warning_or_error);
      walk_subtrees = 0;
      break;

    case STATEMENT_LIST:
      if (TREE_SIDE_EFFECTS (stmt))
	{
	  tree_stmt_iterator i;
	  int nondebug_stmts = 0;
	  bool clear_side_effects = true;
	  /* Genericization can clear TREE_SIDE_EFFECTS, e.g. when
	     transforming an IF_STMT into COND_EXPR.  If such stmt
	     appears in a STATEMENT_LIST that contains only that
	     stmt and some DEBUG_BEGIN_STMTs, without -g where the
	     STATEMENT_LIST wouldn't be present at all the resulting
	     expression wouldn't have TREE_SIDE_EFFECTS set, so make sure
	     to clear it even on the STATEMENT_LIST in such cases.  */
	  for (i = tsi_start (stmt); !tsi_end_p (i); tsi_next (&i))
	    {
	      tree t = tsi_stmt (i);
	      if (TREE_CODE (t) != DEBUG_BEGIN_STMT && nondebug_stmts < 2)
		nondebug_stmts++;
	      cp_walk_tree (tsi_stmt_ptr (i), cp_genericize_r, data, NULL);
	      if (TREE_CODE (t) != DEBUG_BEGIN_STMT
		  && (nondebug_stmts > 1 || TREE_SIDE_EFFECTS (tsi_stmt (i))))
		clear_side_effects = false;
	    }
	  if (clear_side_effects)
	    TREE_SIDE_EFFECTS (stmt) = 0;
	  *walk_subtrees = 0;
	}
      break;

    default:
      if (IS_TYPE_OR_DECL_P (stmt))
	*walk_subtrees = 0;
      break;
    }

  p_set->add (*stmt_p);

  return NULL;
}

/* Lower C++ front end trees to GENERIC in T_P.  */

static void
cp_genericize_tree (tree* t_p, bool handle_invisiref_parm_p)
{
  struct cp_genericize_data wtd;

  wtd.p_set = new hash_set<tree>;
  wtd.bind_expr_stack.create (0);
  wtd.omp_ctx = NULL;
  wtd.try_block = NULL_TREE;
  wtd.no_sanitize_p = false;
  wtd.handle_invisiref_parm_p = handle_invisiref_parm_p;
  cp_walk_tree (t_p, cp_genericize_r, &wtd, NULL);
  delete wtd.p_set;
  wtd.bind_expr_stack.release ();
  if (sanitize_flags_p (SANITIZE_VPTR))
    cp_ubsan_instrument_member_accesses (t_p);
}

/* If a function that should end with a return in non-void
   function doesn't obviously end with return, add ubsan
   instrumentation code to verify it at runtime.  If -fsanitize=return
   is not enabled, instrument __builtin_unreachable.  */

static void
cp_maybe_instrument_return (tree fndecl)
{
  if (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (fndecl)))
      || DECL_CONSTRUCTOR_P (fndecl)
      || DECL_DESTRUCTOR_P (fndecl)
      || !targetm.warn_func_return (fndecl))
    return;

  if (!sanitize_flags_p (SANITIZE_RETURN, fndecl)
      /* Don't add __builtin_unreachable () if not optimizing, it will not
	 improve any optimizations in that case, just break UB code.
	 Don't add it if -fsanitize=unreachable -fno-sanitize=return either,
	 UBSan covers this with ubsan_instrument_return above where sufficient
	 information is provided, while the __builtin_unreachable () below
	 if return sanitization is disabled will just result in hard to
	 understand runtime error without location.  */
      && (!optimize
	  || sanitize_flags_p (SANITIZE_UNREACHABLE, fndecl)))
    return;

  tree t = DECL_SAVED_TREE (fndecl);
  while (t)
    {
      switch (TREE_CODE (t))
	{
	case BIND_EXPR:
	  t = BIND_EXPR_BODY (t);
	  continue;
	case TRY_FINALLY_EXPR:
	case CLEANUP_POINT_EXPR:
	  t = TREE_OPERAND (t, 0);
	  continue;
	case STATEMENT_LIST:
	  {
	    tree_stmt_iterator i = tsi_last (t);
	    while (!tsi_end_p (i))
	      {
		tree p = tsi_stmt (i);
		if (TREE_CODE (p) != DEBUG_BEGIN_STMT)
		  break;
		tsi_prev (&i);
	      }
	    if (!tsi_end_p (i))
	      {
		t = tsi_stmt (i);
		continue;
	      }
	  }
	  break;
	case RETURN_EXPR:
	  return;
	default:
	  break;
	}
      break;
    }
  if (t == NULL_TREE)
    return;
  tree *p = &DECL_SAVED_TREE (fndecl);
  if (TREE_CODE (*p) == BIND_EXPR)
    p = &BIND_EXPR_BODY (*p);

  location_t loc = DECL_SOURCE_LOCATION (fndecl);
  if (sanitize_flags_p (SANITIZE_RETURN, fndecl))
    t = ubsan_instrument_return (loc);
  else
    {
      tree fndecl = builtin_decl_explicit (BUILT_IN_UNREACHABLE);
      t = build_call_expr_loc (BUILTINS_LOCATION, fndecl, 0);
    }

  append_to_statement_list (t, p);
}

void
cp_genericize (tree fndecl)
{
  tree t;

  /* Fix up the types of parms passed by invisible reference.  */
  for (t = DECL_ARGUMENTS (fndecl); t; t = DECL_CHAIN (t))
    if (TREE_ADDRESSABLE (TREE_TYPE (t)))
      {
	/* If a function's arguments are copied to create a thunk,
	   then DECL_BY_REFERENCE will be set -- but the type of the
	   argument will be a pointer type, so we will never get
	   here.  */
	gcc_assert (!DECL_BY_REFERENCE (t));
	gcc_assert (DECL_ARG_TYPE (t) != TREE_TYPE (t));
	TREE_TYPE (t) = DECL_ARG_TYPE (t);
	DECL_BY_REFERENCE (t) = 1;
	TREE_ADDRESSABLE (t) = 0;
	relayout_decl (t);
      }

  /* Do the same for the return value.  */
  if (TREE_ADDRESSABLE (TREE_TYPE (DECL_RESULT (fndecl))))
    {
      t = DECL_RESULT (fndecl);
      TREE_TYPE (t) = build_reference_type (TREE_TYPE (t));
      DECL_BY_REFERENCE (t) = 1;
      TREE_ADDRESSABLE (t) = 0;
      relayout_decl (t);
      if (DECL_NAME (t))
	{
	  /* Adjust DECL_VALUE_EXPR of the original var.  */
	  tree outer = outer_curly_brace_block (current_function_decl);
	  tree var;

	  if (outer)
	    for (var = BLOCK_VARS (outer); var; var = DECL_CHAIN (var))
	      if (VAR_P (var)
		  && DECL_NAME (t) == DECL_NAME (var)
		  && DECL_HAS_VALUE_EXPR_P (var)
		  && DECL_VALUE_EXPR (var) == t)
		{
		  tree val = convert_from_reference (t);
		  SET_DECL_VALUE_EXPR (var, val);
		  break;
		}
	}
    }

  /* If we're a clone, the body is already GIMPLE.  */
  if (DECL_CLONED_FUNCTION_P (fndecl))
    return;

  /* Allow cp_genericize calls to be nested.  */
  tree save_bc_label[2];
  save_bc_label[bc_break] = bc_label[bc_break];
  save_bc_label[bc_continue] = bc_label[bc_continue];
  bc_label[bc_break] = NULL_TREE;
  bc_label[bc_continue] = NULL_TREE;

  /* We do want to see every occurrence of the parms, so we can't just use
     walk_tree's hash functionality.  */
  cp_genericize_tree (&DECL_SAVED_TREE (fndecl), true);

  cp_maybe_instrument_return (fndecl);

  /* Do everything else.  */
  c_genericize (fndecl);

  gcc_assert (bc_label[bc_break] == NULL);
  gcc_assert (bc_label[bc_continue] == NULL);
  bc_label[bc_break] = save_bc_label[bc_break];
  bc_label[bc_continue] = save_bc_label[bc_continue];
}

/* Build code to apply FN to each member of ARG1 and ARG2.  FN may be
   NULL if there is in fact nothing to do.  ARG2 may be null if FN
   actually only takes one argument.  */

static tree
cxx_omp_clause_apply_fn (tree fn, tree arg1, tree arg2)
{
  tree defparm, parm, t;
  int i = 0;
  int nargs;
  tree *argarray;

  if (fn == NULL)
    return NULL;

  nargs = list_length (DECL_ARGUMENTS (fn));
  argarray = XALLOCAVEC (tree, nargs);

  defparm = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (fn)));
  if (arg2)
    defparm = TREE_CHAIN (defparm);

  bool is_method = TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE;
  if (TREE_CODE (TREE_TYPE (arg1)) == ARRAY_TYPE)
    {
      tree inner_type = TREE_TYPE (arg1);
      tree start1, end1, p1;
      tree start2 = NULL, p2 = NULL;
      tree ret = NULL, lab;

      start1 = arg1;
      start2 = arg2;
      do
	{
	  inner_type = TREE_TYPE (inner_type);
	  start1 = build4 (ARRAY_REF, inner_type, start1,
			   size_zero_node, NULL, NULL);
	  if (arg2)
	    start2 = build4 (ARRAY_REF, inner_type, start2,
			     size_zero_node, NULL, NULL);
	}
      while (TREE_CODE (inner_type) == ARRAY_TYPE);
      start1 = build_fold_addr_expr_loc (input_location, start1);
      if (arg2)
	start2 = build_fold_addr_expr_loc (input_location, start2);

      end1 = TYPE_SIZE_UNIT (TREE_TYPE (arg1));
      end1 = fold_build_pointer_plus (start1, end1);

      p1 = create_tmp_var (TREE_TYPE (start1));
      t = build2 (MODIFY_EXPR, TREE_TYPE (p1), p1, start1);
      append_to_statement_list (t, &ret);

      if (arg2)
	{
	  p2 = create_tmp_var (TREE_TYPE (start2));
	  t = build2 (MODIFY_EXPR, TREE_TYPE (p2), p2, start2);
	  append_to_statement_list (t, &ret);
	}

      lab = create_artificial_label (input_location);
      t = build1 (LABEL_EXPR, void_type_node, lab);
      append_to_statement_list (t, &ret);

      argarray[i++] = p1;
      if (arg2)
	argarray[i++] = p2;
      /* Handle default arguments.  */
      for (parm = defparm; parm && parm != void_list_node;
	   parm = TREE_CHAIN (parm), i++)
	argarray[i] = convert_default_arg (TREE_VALUE (parm),
					   TREE_PURPOSE (parm), fn,
					   i - is_method, tf_warning_or_error);
      t = build_call_a (fn, i, argarray);
      t = fold_convert (void_type_node, t);
      t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
      append_to_statement_list (t, &ret);

      t = fold_build_pointer_plus (p1, TYPE_SIZE_UNIT (inner_type));
      t = build2 (MODIFY_EXPR, TREE_TYPE (p1), p1, t);
      append_to_statement_list (t, &ret);

      if (arg2)
	{
	  t = fold_build_pointer_plus (p2, TYPE_SIZE_UNIT (inner_type));
	  t = build2 (MODIFY_EXPR, TREE_TYPE (p2), p2, t);
	  append_to_statement_list (t, &ret);
	}

      t = build2 (NE_EXPR, boolean_type_node, p1, end1);
      t = build3 (COND_EXPR, void_type_node, t, build_and_jump (&lab), NULL);
      append_to_statement_list (t, &ret);

      return ret;
    }
  else
    {
      argarray[i++] = build_fold_addr_expr_loc (input_location, arg1);
      if (arg2)
	argarray[i++] = build_fold_addr_expr_loc (input_location, arg2);
      /* Handle default arguments.  */
      for (parm = defparm; parm && parm != void_list_node;
	   parm = TREE_CHAIN (parm), i++)
	argarray[i] = convert_default_arg (TREE_VALUE (parm),
					   TREE_PURPOSE (parm), fn,
					   i - is_method, tf_warning_or_error);
      t = build_call_a (fn, i, argarray);
      t = fold_convert (void_type_node, t);
      return fold_build_cleanup_point_expr (TREE_TYPE (t), t);
    }
}

/* Return code to initialize DECL with its default constructor, or
   NULL if there's nothing to do.  */

tree
cxx_omp_clause_default_ctor (tree clause, tree decl, tree /*outer*/)
{
  tree info = CP_OMP_CLAUSE_INFO (clause);
  tree ret = NULL;

  if (info)
    ret = cxx_omp_clause_apply_fn (TREE_VEC_ELT (info, 0), decl, NULL);

  return ret;
}

/* Return code to initialize DST with a copy constructor from SRC.  */

tree
cxx_omp_clause_copy_ctor (tree clause, tree dst, tree src)
{
  tree info = CP_OMP_CLAUSE_INFO (clause);
  tree ret = NULL;

  if (info)
    ret = cxx_omp_clause_apply_fn (TREE_VEC_ELT (info, 0), dst, src);
  if (ret == NULL)
    ret = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);

  return ret;
}

/* Similarly, except use an assignment operator instead.  */

tree
cxx_omp_clause_assign_op (tree clause, tree dst, tree src)
{
  tree info = CP_OMP_CLAUSE_INFO (clause);
  tree ret = NULL;

  if (info)
    ret = cxx_omp_clause_apply_fn (TREE_VEC_ELT (info, 2), dst, src);
  if (ret == NULL)
    ret = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);

  return ret;
}

/* Return code to destroy DECL.  */

tree
cxx_omp_clause_dtor (tree clause, tree decl)
{
  tree info = CP_OMP_CLAUSE_INFO (clause);
  tree ret = NULL;

  if (info)
    ret = cxx_omp_clause_apply_fn (TREE_VEC_ELT (info, 1), decl, NULL);

  return ret;
}

/* True if OpenMP should privatize what this DECL points to rather
   than the DECL itself.  */

bool
cxx_omp_privatize_by_reference (const_tree decl)
{
  return (TYPE_REF_P (TREE_TYPE (decl))
	  || is_invisiref_parm (decl));
}

/* Return true if DECL is const qualified var having no mutable member.  */
bool
cxx_omp_const_qual_no_mutable (tree decl)
{
  tree type = TREE_TYPE (decl);
  if (TYPE_REF_P (type))
    {
      if (!is_invisiref_parm (decl))
	return false;
      type = TREE_TYPE (type);

      if (TREE_CODE (decl) == RESULT_DECL && DECL_NAME (decl))
	{
	  /* NVR doesn't preserve const qualification of the
	     variable's type.  */
	  tree outer = outer_curly_brace_block (current_function_decl);
	  tree var;

	  if (outer)
	    for (var = BLOCK_VARS (outer); var; var = DECL_CHAIN (var))
	      if (VAR_P (var)
		  && DECL_NAME (decl) == DECL_NAME (var)
		  && (TYPE_MAIN_VARIANT (type)
		      == TYPE_MAIN_VARIANT (TREE_TYPE (var))))
		{
		  if (TYPE_READONLY (TREE_TYPE (var)))
		    type = TREE_TYPE (var);
		  break;
		}
	}
    }

  if (type == error_mark_node)
    return false;

  /* Variables with const-qualified type having no mutable member
     are predetermined shared.  */
  if (TYPE_READONLY (type) && !cp_has_mutable_p (type))
    return true;

  return false;
}

/* OMP_CLAUSE_DEFAULT_UNSPECIFIED unless OpenMP sharing attribute
   of DECL is predetermined.  */

enum omp_clause_default_kind
cxx_omp_predetermined_sharing_1 (tree decl)
{
  /* Static data members are predetermined shared.  */
  if (TREE_STATIC (decl))
    {
      tree ctx = CP_DECL_CONTEXT (decl);
      if (TYPE_P (ctx) && MAYBE_CLASS_TYPE_P (ctx))
	return OMP_CLAUSE_DEFAULT_SHARED;

      if (c_omp_predefined_variable (decl))
	return OMP_CLAUSE_DEFAULT_SHARED;
    }

  /* this may not be specified in data-sharing clauses, still we need
     to predetermined it firstprivate.  */
  if (decl == current_class_ptr)
    return OMP_CLAUSE_DEFAULT_FIRSTPRIVATE;

  return OMP_CLAUSE_DEFAULT_UNSPECIFIED;
}

/* Likewise, but also include the artificial vars.  We don't want to
   disallow the artificial vars being mentioned in explicit clauses,
   as we use artificial vars e.g. for loop constructs with random
   access iterators other than pointers, but during gimplification
   we want to treat them as predetermined.  */

enum omp_clause_default_kind
cxx_omp_predetermined_sharing (tree decl)
{
  enum omp_clause_default_kind ret = cxx_omp_predetermined_sharing_1 (decl);
  if (ret != OMP_CLAUSE_DEFAULT_UNSPECIFIED)
    return ret;

  /* Predetermine artificial variables holding integral values, those
     are usually result of gimplify_one_sizepos or SAVE_EXPR
     gimplification.  */
  if (VAR_P (decl)
      && DECL_ARTIFICIAL (decl)
      && INTEGRAL_TYPE_P (TREE_TYPE (decl))
      && !(DECL_LANG_SPECIFIC (decl)
	   && DECL_OMP_PRIVATIZED_MEMBER (decl)))
    return OMP_CLAUSE_DEFAULT_SHARED;

  /* Similarly for typeinfo symbols.  */
  if (VAR_P (decl) && DECL_ARTIFICIAL (decl) && DECL_TINFO_P (decl))
    return OMP_CLAUSE_DEFAULT_SHARED;

  return OMP_CLAUSE_DEFAULT_UNSPECIFIED;
}

enum omp_clause_defaultmap_kind
cxx_omp_predetermined_mapping (tree decl)
{
  /* Predetermine artificial variables holding integral values, those
     are usually result of gimplify_one_sizepos or SAVE_EXPR
     gimplification.  */
  if (VAR_P (decl)
      && DECL_ARTIFICIAL (decl)
      && INTEGRAL_TYPE_P (TREE_TYPE (decl))
      && !(DECL_LANG_SPECIFIC (decl)
	   && DECL_OMP_PRIVATIZED_MEMBER (decl)))
    return OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE;

  if (c_omp_predefined_variable (decl))
    return OMP_CLAUSE_DEFAULTMAP_TO;

  return OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED;
}

/* Finalize an implicitly determined clause.  */

void
cxx_omp_finish_clause (tree c, gimple_seq *)
{
  tree decl, inner_type;
  bool make_shared = false;

  if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_FIRSTPRIVATE
      && (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_LASTPRIVATE
	  || !OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c)))
    return;

  decl = OMP_CLAUSE_DECL (c);
  decl = require_complete_type (decl);
  inner_type = TREE_TYPE (decl);
  if (decl == error_mark_node)
    make_shared = true;
  else if (TYPE_REF_P (TREE_TYPE (decl)))
    inner_type = TREE_TYPE (inner_type);

  /* We're interested in the base element, not arrays.  */
  while (TREE_CODE (inner_type) == ARRAY_TYPE)
    inner_type = TREE_TYPE (inner_type);

  /* Check for special function availability by building a call to one.
     Save the results, because later we won't be in the right context
     for making these queries.  */
  bool first = OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE;
  if (!make_shared
      && CLASS_TYPE_P (inner_type)
      && cxx_omp_create_clause_info (c, inner_type, !first, first, !first,
				     true))
    make_shared = true;

  if (make_shared)
    {
      OMP_CLAUSE_CODE (c) = OMP_CLAUSE_SHARED;
      OMP_CLAUSE_SHARED_FIRSTPRIVATE (c) = 0;
      OMP_CLAUSE_SHARED_READONLY (c) = 0;
    }
}

/* Return true if DECL's DECL_VALUE_EXPR (if any) should be
   disregarded in OpenMP construct, because it is going to be
   remapped during OpenMP lowering.  SHARED is true if DECL
   is going to be shared, false if it is going to be privatized.  */

bool
cxx_omp_disregard_value_expr (tree decl, bool shared)
{
  if (shared)
    return false;
  if (VAR_P (decl)
      && DECL_HAS_VALUE_EXPR_P (decl)
      && DECL_ARTIFICIAL (decl)
      && DECL_LANG_SPECIFIC (decl)
      && DECL_OMP_PRIVATIZED_MEMBER (decl))
    return true;
  if (VAR_P (decl) && DECL_CONTEXT (decl) && is_capture_proxy (decl))
    return true;
  return false;
}

/* Fold expression X which is used as an rvalue if RVAL is true.  */

tree
cp_fold_maybe_rvalue (tree x, bool rval)
{
  while (true)
    {
      x = cp_fold (x);
      if (rval)
	x = mark_rvalue_use (x);
      if (rval && DECL_P (x)
	  && !TYPE_REF_P (TREE_TYPE (x)))
	{
	  tree v = decl_constant_value (x);
	  if (v != x && v != error_mark_node)
	    {
	      x = v;
	      continue;
	    }
	}
      break;
    }
  return x;
}

/* Fold expression X which is used as an rvalue.  */

tree
cp_fold_rvalue (tree x)
{
  return cp_fold_maybe_rvalue (x, true);
}

/* Perform folding on expression X.  */

tree
cp_fully_fold (tree x)
{
  if (processing_template_decl)
    return x;
  /* FIXME cp_fold ought to be a superset of maybe_constant_value so we don't
     have to call both.  */
  if (cxx_dialect >= cxx11)
    {
      x = maybe_constant_value (x);
      /* Sometimes we are given a CONSTRUCTOR but the call above wraps it into
	 a TARGET_EXPR; undo that here.  */
      if (TREE_CODE (x) == TARGET_EXPR)
	x = TARGET_EXPR_INITIAL (x);
      else if (TREE_CODE (x) == VIEW_CONVERT_EXPR
	       && TREE_CODE (TREE_OPERAND (x, 0)) == CONSTRUCTOR
	       && TREE_TYPE (TREE_OPERAND (x, 0)) == TREE_TYPE (x))
	x = TREE_OPERAND (x, 0);
    }
  return cp_fold_rvalue (x);
}

/* Likewise, but also fold recursively, which cp_fully_fold doesn't perform
   in some cases.  */

tree
cp_fully_fold_init (tree x)
{
  if (processing_template_decl)
    return x;
  x = cp_fully_fold (x);
  hash_set<tree> pset;
  cp_walk_tree (&x, cp_fold_r, &pset, NULL);
  return x;
}

/* c-common interface to cp_fold.  If IN_INIT, this is in a static initializer
   and certain changes are made to the folding done.  Or should be (FIXME).  We
   never touch maybe_const, as it is only used for the C front-end
   C_MAYBE_CONST_EXPR.  */

tree
c_fully_fold (tree x, bool /*in_init*/, bool */*maybe_const*/, bool lval)
{
  return cp_fold_maybe_rvalue (x, !lval);
}

static GTY((deletable)) hash_map<tree, tree> *fold_cache;

/* Dispose of the whole FOLD_CACHE.  */

void
clear_fold_cache (void)
{
  if (fold_cache != NULL)
    fold_cache->empty ();
}

/*  This function tries to fold an expression X.
    To avoid combinatorial explosion, folding results are kept in fold_cache.
    If X is invalid, we don't fold at all.
    For performance reasons we don't cache expressions representing a
    declaration or constant.
    Function returns X or its folded variant.  */

static tree
cp_fold (tree x)
{
  tree op0, op1, op2, op3;
  tree org_x = x, r = NULL_TREE;
  enum tree_code code;
  location_t loc;
  bool rval_ops = true;

  if (!x || x == error_mark_node)
    return x;

  if (EXPR_P (x) && (!TREE_TYPE (x) || TREE_TYPE (x) == error_mark_node))
    return x;

  /* Don't bother to cache DECLs or constants.  */
  if (DECL_P (x) || CONSTANT_CLASS_P (x))
    return x;

  if (fold_cache == NULL)
    fold_cache = hash_map<tree, tree>::create_ggc (101);

  if (tree *cached = fold_cache->get (x))
    return *cached;

  uid_sensitive_constexpr_evaluation_checker c;

  code = TREE_CODE (x);
  switch (code)
    {
    case CLEANUP_POINT_EXPR:
      /* Strip CLEANUP_POINT_EXPR if the expression doesn't have side
	 effects.  */
      r = cp_fold_rvalue (TREE_OPERAND (x, 0));
      if (!TREE_SIDE_EFFECTS (r))
	x = r;
      break;

    case SIZEOF_EXPR:
      x = fold_sizeof_expr (x);
      break;

    case VIEW_CONVERT_EXPR:
      rval_ops = false;
      /* FALLTHRU */
    case CONVERT_EXPR:
    case NOP_EXPR:
    case NON_LVALUE_EXPR:

      if (VOID_TYPE_P (TREE_TYPE (x)))
	{
	  /* This is just to make sure we don't end up with casts to
	     void from error_mark_node.  If we just return x, then
	     cp_fold_r might fold the operand into error_mark_node and
	     leave the conversion in the IR.  STRIP_USELESS_TYPE_CONVERSION
	     during gimplification doesn't like such casts.
	     Don't create a new tree if op0 != TREE_OPERAND (x, 0), the
	     folding of the operand should be in the caches and if in cp_fold_r
	     it will modify it in place.  */
	  op0 = cp_fold (TREE_OPERAND (x, 0));
	  if (op0 == error_mark_node)
	    x = error_mark_node;
	  break;
	}

      loc = EXPR_LOCATION (x);
      op0 = cp_fold_maybe_rvalue (TREE_OPERAND (x, 0), rval_ops);

      if (code == CONVERT_EXPR
	  && SCALAR_TYPE_P (TREE_TYPE (x))
	  && op0 != void_node)
	/* During parsing we used convert_to_*_nofold; re-convert now using the
	   folding variants, since fold() doesn't do those transformations.  */
	x = fold (convert (TREE_TYPE (x), op0));
      else if (op0 != TREE_OPERAND (x, 0))
	{
	  if (op0 == error_mark_node)
	    x = error_mark_node;
	  else
	    x = fold_build1_loc (loc, code, TREE_TYPE (x), op0);
	}
      else
	x = fold (x);

      /* Conversion of an out-of-range value has implementation-defined
	 behavior; the language considers it different from arithmetic
	 overflow, which is undefined.  */
      if (TREE_CODE (op0) == INTEGER_CST
	  && TREE_OVERFLOW_P (x) && !TREE_OVERFLOW_P (op0))
	TREE_OVERFLOW (x) = false;

      break;

    case INDIRECT_REF:
      /* We don't need the decltype(auto) obfuscation anymore.  */
      if (REF_PARENTHESIZED_P (x))
	{
	  tree p = maybe_undo_parenthesized_ref (x);
	  return cp_fold (p);
	}
      goto unary;

    case ADDR_EXPR:
      loc = EXPR_LOCATION (x);
      op0 = cp_fold_maybe_rvalue (TREE_OPERAND (x, 0), false);

      /* Cope with user tricks that amount to offsetof.  */
      if (op0 != error_mark_node
	  && !FUNC_OR_METHOD_TYPE_P (TREE_TYPE (op0)))
	{
	  tree val = get_base_address (op0);
	  if (val
	      && INDIRECT_REF_P (val)
	      && COMPLETE_TYPE_P (TREE_TYPE (val))
	      && TREE_CONSTANT (TREE_OPERAND (val, 0)))
	    {
	      val = TREE_OPERAND (val, 0);
	      STRIP_NOPS (val);
	      val = maybe_constant_value (val);
	      if (TREE_CODE (val) == INTEGER_CST)
		return fold_offsetof (op0, TREE_TYPE (x));
	    }
	}
      goto finish_unary;

    case REALPART_EXPR:
    case IMAGPART_EXPR:
      rval_ops = false;
      /* FALLTHRU */
    case CONJ_EXPR:
    case FIX_TRUNC_EXPR:
    case FLOAT_EXPR:
    case NEGATE_EXPR:
    case ABS_EXPR:
    case ABSU_EXPR:
    case BIT_NOT_EXPR:
    case TRUTH_NOT_EXPR:
    case FIXED_CONVERT_EXPR:
    unary:

      loc = EXPR_LOCATION (x);
      op0 = cp_fold_maybe_rvalue (TREE_OPERAND (x, 0), rval_ops);

    finish_unary:
      if (op0 != TREE_OPERAND (x, 0))
	{
	  if (op0 == error_mark_node)
	    x = error_mark_node;
	  else
	    {
	      x = fold_build1_loc (loc, code, TREE_TYPE (x), op0);
	      if (code == INDIRECT_REF
		  && (INDIRECT_REF_P (x) || TREE_CODE (x) == MEM_REF))
		{
		  TREE_READONLY (x) = TREE_READONLY (org_x);
		  TREE_SIDE_EFFECTS (x) = TREE_SIDE_EFFECTS (org_x);
		  TREE_THIS_VOLATILE (x) = TREE_THIS_VOLATILE (org_x);
		}
	    }
	}
      else
	x = fold (x);

      gcc_assert (TREE_CODE (x) != COND_EXPR
		  || !VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (x, 0))));
      break;

    case UNARY_PLUS_EXPR:
      op0 = cp_fold_rvalue (TREE_OPERAND (x, 0));
      if (op0 == error_mark_node)
	x = error_mark_node;
      else
	x = fold_convert (TREE_TYPE (x), op0);
      break;

    case POSTDECREMENT_EXPR:
    case POSTINCREMENT_EXPR:
    case INIT_EXPR:
    case PREDECREMENT_EXPR:
    case PREINCREMENT_EXPR:
    case COMPOUND_EXPR:
    case MODIFY_EXPR:
      rval_ops = false;
      /* FALLTHRU */
    case POINTER_PLUS_EXPR:
    case PLUS_EXPR:
    case POINTER_DIFF_EXPR:
    case MINUS_EXPR:
    case MULT_EXPR:
    case TRUNC_DIV_EXPR:
    case CEIL_DIV_EXPR:
    case FLOOR_DIV_EXPR:
    case ROUND_DIV_EXPR:
    case TRUNC_MOD_EXPR:
    case CEIL_MOD_EXPR:
    case ROUND_MOD_EXPR:
    case RDIV_EXPR:
    case EXACT_DIV_EXPR:
    case MIN_EXPR:
    case MAX_EXPR:
    case LSHIFT_EXPR:
    case RSHIFT_EXPR:
    case LROTATE_EXPR:
    case RROTATE_EXPR:
    case BIT_AND_EXPR:
    case BIT_IOR_EXPR:
    case BIT_XOR_EXPR:
    case TRUTH_AND_EXPR:
    case TRUTH_ANDIF_EXPR:
    case TRUTH_OR_EXPR:
    case TRUTH_ORIF_EXPR:
    case TRUTH_XOR_EXPR:
    case LT_EXPR: case LE_EXPR:
    case GT_EXPR: case GE_EXPR:
    case EQ_EXPR: case NE_EXPR:
    case UNORDERED_EXPR: case ORDERED_EXPR:
    case UNLT_EXPR: case UNLE_EXPR:
    case UNGT_EXPR: case UNGE_EXPR:
    case UNEQ_EXPR: case LTGT_EXPR:
    case RANGE_EXPR: case COMPLEX_EXPR:

      loc = EXPR_LOCATION (x);
      op0 = cp_fold_maybe_rvalue (TREE_OPERAND (x, 0), rval_ops);
      op1 = cp_fold_rvalue (TREE_OPERAND (x, 1));

      if (op0 != TREE_OPERAND (x, 0) || op1 != TREE_OPERAND (x, 1))
	{
	  if (op0 == error_mark_node || op1 == error_mark_node)
	    x = error_mark_node;
	  else
	    x = fold_build2_loc (loc, code, TREE_TYPE (x), op0, op1);
	}
      else
	x = fold (x);

      /* This is only needed for -Wnonnull-compare and only if
	 TREE_NO_WARNING (org_x), but to avoid that option affecting code
	 generation, we do it always.  */
      if (COMPARISON_CLASS_P (org_x))
	{
	  if (x == error_mark_node || TREE_CODE (x) == INTEGER_CST)
	    ;
	  else if (COMPARISON_CLASS_P (x))
	    {
	      if (TREE_NO_WARNING (org_x) && warn_nonnull_compare)
		TREE_NO_WARNING (x) = 1;
	    }
	  /* Otherwise give up on optimizing these, let GIMPLE folders
	     optimize those later on.  */
	  else if (op0 != TREE_OPERAND (org_x, 0)
		   || op1 != TREE_OPERAND (org_x, 1))
	    {
	      x = build2_loc (loc, code, TREE_TYPE (org_x), op0, op1);
	      if (TREE_NO_WARNING (org_x) && warn_nonnull_compare)
		TREE_NO_WARNING (x) = 1;
	    }
	  else
	    x = org_x;
	}

      break;

    case VEC_COND_EXPR:
    case COND_EXPR:
      loc = EXPR_LOCATION (x);
      op0 = cp_fold_rvalue (TREE_OPERAND (x, 0));
      op1 = cp_fold (TREE_OPERAND (x, 1));
      op2 = cp_fold (TREE_OPERAND (x, 2));

      if (TREE_CODE (TREE_TYPE (x)) == BOOLEAN_TYPE)
	{
	  warning_sentinel s (warn_int_in_bool_context);
	  if (!VOID_TYPE_P (TREE_TYPE (op1)))
	    op1 = cp_truthvalue_conversion (op1, tf_warning_or_error);
	  if (!VOID_TYPE_P (TREE_TYPE (op2)))
	    op2 = cp_truthvalue_conversion (op2, tf_warning_or_error);
	}
      else if (VOID_TYPE_P (TREE_TYPE (x)))
	{
	  if (TREE_CODE (op0) == INTEGER_CST)
	    {
	      /* If the condition is constant, fold can fold away
		 the COND_EXPR.  If some statement-level uses of COND_EXPR
		 have one of the branches NULL, avoid folding crash.  */
	      if (!op1)
		op1 = build_empty_stmt (loc);
	      if (!op2)
		op2 = build_empty_stmt (loc);
	    }
	  else
	    {
	      /* Otherwise, don't bother folding a void condition, since
		 it can't produce a constant value.  */
	      if (op0 != TREE_OPERAND (x, 0)
		  || op1 != TREE_OPERAND (x, 1)
		  || op2 != TREE_OPERAND (x, 2))
		x = build3_loc (loc, code, TREE_TYPE (x), op0, op1, op2);
	      break;
	    }
	}

      if (op0 != TREE_OPERAND (x, 0)
	  || op1 != TREE_OPERAND (x, 1)
	  || op2 != TREE_OPERAND (x, 2))
	{
	  if (op0 == error_mark_node
	      || op1 == error_mark_node
	      || op2 == error_mark_node)
	    x = error_mark_node;
	  else
	    x = fold_build3_loc (loc, code, TREE_TYPE (x), op0, op1, op2);
	}
      else
	x = fold (x);

      /* A COND_EXPR might have incompatible types in branches if one or both
	 arms are bitfields.  If folding exposed such a branch, fix it up.  */
      if (TREE_CODE (x) != code
	  && x != error_mark_node
	  && !useless_type_conversion_p (TREE_TYPE (org_x), TREE_TYPE (x)))
	x = fold_convert (TREE_TYPE (org_x), x);

      break;

    case CALL_EXPR:
      {
	int sv = optimize, nw = sv;
	tree callee = get_callee_fndecl (x);

	/* Some built-in function calls will be evaluated at compile-time in
	   fold ().  Set optimize to 1 when folding __builtin_constant_p inside
	   a constexpr function so that fold_builtin_1 doesn't fold it to 0.  */
	if (callee && fndecl_built_in_p (callee) && !optimize
	    && DECL_IS_BUILTIN_CONSTANT_P (callee)
	    && current_function_decl
	    && DECL_DECLARED_CONSTEXPR_P (current_function_decl))
	  nw = 1;

	/* Defer folding __builtin_is_constant_evaluated.  */
	if (callee
	    && fndecl_built_in_p (callee, CP_BUILT_IN_IS_CONSTANT_EVALUATED,
				  BUILT_IN_FRONTEND))
	  break;

	if (callee
	    && fndecl_built_in_p (callee, CP_BUILT_IN_SOURCE_LOCATION,
				  BUILT_IN_FRONTEND))
	  {
	    x = fold_builtin_source_location (EXPR_LOCATION (x));
	    break;
	  }

	bool changed = false;
	int m = call_expr_nargs (x);
	for (int i = 0; i < m; i++)
	  {
	    r = cp_fold (CALL_EXPR_ARG (x, i));
	    if (r != CALL_EXPR_ARG (x, i))
	      {
		if (r == error_mark_node)
		  {
		    x = error_mark_node;
		    break;
		  }
		if (!changed)
		  x = copy_node (x);
		CALL_EXPR_ARG (x, i) = r;
		changed = true;
	      }
	  }
	if (x == error_mark_node)
	  break;

	optimize = nw;
	r = fold (x);
	optimize = sv;

	if (TREE_CODE (r) != CALL_EXPR)
	  {
	    x = cp_fold (r);
	    break;
	  }

	optimize = nw;

	/* Invoke maybe_constant_value for functions declared
	   constexpr and not called with AGGR_INIT_EXPRs.
	   TODO:
	   Do constexpr expansion of expressions where the call itself is not
	   constant, but the call followed by an INDIRECT_REF is.  */
	if (callee && DECL_DECLARED_CONSTEXPR_P (callee)
	    && !flag_no_inline)
	  r = maybe_constant_value (x);
	optimize = sv;

        if (TREE_CODE (r) != CALL_EXPR)
	  {
	    if (DECL_CONSTRUCTOR_P (callee))
	      {
		loc = EXPR_LOCATION (x);
		tree s = build_fold_indirect_ref_loc (loc,
						      CALL_EXPR_ARG (x, 0));
		r = build2_loc (loc, INIT_EXPR, TREE_TYPE (s), s, r);
	      }
	    x = r;
	    break;
	  }

	break;
      }

    case CONSTRUCTOR:
      {
	unsigned i;
	constructor_elt *p;
	vec<constructor_elt, va_gc> *elts = CONSTRUCTOR_ELTS (x);
	vec<constructor_elt, va_gc> *nelts = NULL;
	FOR_EACH_VEC_SAFE_ELT (elts, i, p)
	  {
	    tree op = cp_fold (p->value);
	    if (op != p->value)
	      {
		if (op == error_mark_node)
		  {
		    x = error_mark_node;
		    vec_free (nelts);
		    break;
		  }
		if (nelts == NULL)
		  nelts = elts->copy ();
		(*nelts)[i].value = op;
	      }
	  }
	if (nelts)
	  {
	    x = build_constructor (TREE_TYPE (x), nelts);
	    CONSTRUCTOR_PLACEHOLDER_BOUNDARY (x)
	      = CONSTRUCTOR_PLACEHOLDER_BOUNDARY (org_x);
	  }
	if (VECTOR_TYPE_P (TREE_TYPE (x)))
	  x = fold (x);
	break;
      }
    case TREE_VEC:
      {
	bool changed = false;
	int n = TREE_VEC_LENGTH (x);

	for (int i = 0; i < n; i++)
	  {
	    tree op = cp_fold (TREE_VEC_ELT (x, i));
	    if (op != TREE_VEC_ELT (x, i))
	      {
		if (!changed)
		  x = copy_node (x);
		TREE_VEC_ELT (x, i) = op;
		changed = true;
	      }
	  }
      }

      break;

    case ARRAY_REF:
    case ARRAY_RANGE_REF:

      loc = EXPR_LOCATION (x);
      op0 = cp_fold (TREE_OPERAND (x, 0));
      op1 = cp_fold (TREE_OPERAND (x, 1));
      op2 = cp_fold (TREE_OPERAND (x, 2));
      op3 = cp_fold (TREE_OPERAND (x, 3));

      if (op0 != TREE_OPERAND (x, 0)
	  || op1 != TREE_OPERAND (x, 1)
	  || op2 != TREE_OPERAND (x, 2)
	  || op3 != TREE_OPERAND (x, 3))
	{
	  if (op0 == error_mark_node
	      || op1 == error_mark_node
	      || op2 == error_mark_node
	      || op3 == error_mark_node)
	    x = error_mark_node;
	  else
	    {
	      x = build4_loc (loc, code, TREE_TYPE (x), op0, op1, op2, op3);
	      TREE_READONLY (x) = TREE_READONLY (org_x);
	      TREE_SIDE_EFFECTS (x) = TREE_SIDE_EFFECTS (org_x);
	      TREE_THIS_VOLATILE (x) = TREE_THIS_VOLATILE (org_x);
	    }
	}

      x = fold (x);
      break;

    case SAVE_EXPR:
      /* A SAVE_EXPR might contain e.g. (0 * i) + (0 * j), which, after
	 folding, evaluates to an invariant.  In that case no need to wrap
	 this folded tree with a SAVE_EXPR.  */
      r = cp_fold (TREE_OPERAND (x, 0));
      if (tree_invariant_p (r))
	x = r;
      break;

    default:
      return org_x;
    }

  if (EXPR_P (x) && TREE_CODE (x) == code)
    {
      TREE_THIS_VOLATILE (x) = TREE_THIS_VOLATILE (org_x);
      TREE_NO_WARNING (x) = TREE_NO_WARNING (org_x);
    }

  if (!c.evaluation_restricted_p ())
    {
      fold_cache->put (org_x, x);
      /* Prevent that we try to fold an already folded result again.  */
      if (x != org_x)
	fold_cache->put (x, x);
    }

  return x;
}

/* Look up either "hot" or "cold" in attribute list LIST.  */

tree
lookup_hotness_attribute (tree list)
{
  for (; list; list = TREE_CHAIN (list))
    {
      tree name = get_attribute_name (list);
      if (is_attribute_p ("hot", name)
	  || is_attribute_p ("cold", name)
	  || is_attribute_p ("likely", name)
	  || is_attribute_p ("unlikely", name))
	break;
    }
  return list;
}

/* Remove both "hot" and "cold" attributes from LIST.  */

static tree
remove_hotness_attribute (tree list)
{
  list = remove_attribute ("hot", list);
  list = remove_attribute ("cold", list);
  list = remove_attribute ("likely", list);
  list = remove_attribute ("unlikely", list);
  return list;
}

/* If [[likely]] or [[unlikely]] appear on this statement, turn it into a
   PREDICT_EXPR.  */

tree
process_stmt_hotness_attribute (tree std_attrs, location_t attrs_loc)
{
  if (std_attrs == error_mark_node)
    return std_attrs;
  if (tree attr = lookup_hotness_attribute (std_attrs))
    {
      tree name = get_attribute_name (attr);
      bool hot = (is_attribute_p ("hot", name)
		  || is_attribute_p ("likely", name));
      tree pred = build_predict_expr (hot ? PRED_HOT_LABEL : PRED_COLD_LABEL,
				      hot ? TAKEN : NOT_TAKEN);
      SET_EXPR_LOCATION (pred, attrs_loc);
      add_stmt (pred);
      if (tree other = lookup_hotness_attribute (TREE_CHAIN (attr)))
	warning (OPT_Wattributes, "ignoring attribute %qE after earlier %qE",
		 get_attribute_name (other), name);
      std_attrs = remove_hotness_attribute (std_attrs);
    }
  return std_attrs;
}

/* Helper of fold_builtin_source_location, return the
   std::source_location::__impl type after performing verification
   on it.  LOC is used for reporting any errors.  */

static tree
get_source_location_impl_type (location_t loc)
{
  tree name = get_identifier ("source_location");
  tree decl = lookup_qualified_name (std_node, name);
  if (TREE_CODE (decl) != TYPE_DECL)
    {
      auto_diagnostic_group d;
      if (decl == error_mark_node || TREE_CODE (decl) == TREE_LIST)
	qualified_name_lookup_error (std_node, name, decl, loc);
      else
	error_at (loc, "%qD is not a type", decl);
      return error_mark_node;
    }
  name = get_identifier ("__impl");
  tree type = TREE_TYPE (decl);
  decl = lookup_qualified_name (type, name);
  if (TREE_CODE (decl) != TYPE_DECL)
    {
      auto_diagnostic_group d;
      if (decl == error_mark_node || TREE_CODE (decl) == TREE_LIST)
	qualified_name_lookup_error (type, name, decl, loc);
      else
	error_at (loc, "%qD is not a type", decl);
      return error_mark_node;
    }
  type = TREE_TYPE (decl);
  if (TREE_CODE (type) != RECORD_TYPE)
    {
      error_at (loc, "%qD is not a class type", decl);
      return error_mark_node;
    }

  int cnt = 0;
  for (tree field = TYPE_FIELDS (type);
       (field = next_initializable_field (field)) != NULL_TREE;
       field = DECL_CHAIN (field))
    {
      if (DECL_NAME (field) != NULL_TREE)
	{
	  const char *n = IDENTIFIER_POINTER (DECL_NAME (field));
	  if (strcmp (n, "_M_file_name") == 0
	      || strcmp (n, "_M_function_name") == 0)
	    {
	      if (TREE_TYPE (field) != const_string_type_node)
		{
		  error_at (loc, "%qD does not have %<const char *%> type",
			    field);
		  return error_mark_node;
		}
	      cnt++;
	      continue;
	    }
	  else if (strcmp (n, "_M_line") == 0 || strcmp (n, "_M_column") == 0)
	    {
	      if (TREE_CODE (TREE_TYPE (field)) != INTEGER_TYPE)
		{
		  error_at (loc, "%qD does not have integral type", field);
		  return error_mark_node;
		}
	      cnt++;
	      continue;
	    }
	}
      cnt = 0;
      break;
    }
  if (cnt != 4)
    {
      error_at (loc, "%<std::source_location::__impl%> does not contain only "
		     "non-static data members %<_M_file_name%>, "
		     "%<_M_function_name%>, %<_M_line%> and %<_M_column%>");
      return error_mark_node;
    }
  return build_qualified_type (type, TYPE_QUAL_CONST);
}

/* Type for source_location_table hash_set.  */
struct GTY((for_user)) source_location_table_entry {
  location_t loc;
  unsigned uid;
  tree var;
};

/* Traits class for function start hash maps below.  */

struct source_location_table_entry_hash
  : ggc_remove <source_location_table_entry>
{
  typedef source_location_table_entry value_type;
  typedef source_location_table_entry compare_type;

  static hashval_t
  hash (const source_location_table_entry &ref)
  {
    inchash::hash hstate (0);
    hstate.add_int (ref.loc);
    hstate.add_int (ref.uid);
    return hstate.end ();
  }

  static bool
  equal (const source_location_table_entry &ref1,
	 const source_location_table_entry &ref2)
  {
    return ref1.loc == ref2.loc && ref1.uid == ref2.uid;
  }

  static void
  mark_deleted (source_location_table_entry &ref)
  {
    ref.loc = UNKNOWN_LOCATION;
    ref.uid = -1U;
    ref.var = NULL_TREE;
  }

  static const bool empty_zero_p = true;

  static void
  mark_empty (source_location_table_entry &ref)
  {
    ref.loc = UNKNOWN_LOCATION;
    ref.uid = 0;
    ref.var = NULL_TREE;
  }

  static bool
  is_deleted (const source_location_table_entry &ref)
  {
    return (ref.loc == UNKNOWN_LOCATION
	    && ref.uid == -1U
	    && ref.var == NULL_TREE);
  }

  static bool
  is_empty (const source_location_table_entry &ref)
  {
    return (ref.loc == UNKNOWN_LOCATION
	    && ref.uid == 0
	    && ref.var == NULL_TREE);
  }
};

static GTY(()) hash_table <source_location_table_entry_hash>
  *source_location_table;
static GTY(()) unsigned int source_location_id;

/* Fold __builtin_source_location () call.  LOC is the location
   of the call.  */

tree
fold_builtin_source_location (location_t loc)
{
  if (source_location_impl == NULL_TREE)
    {
      auto_diagnostic_group d;
      source_location_impl = get_source_location_impl_type (loc);
      if (source_location_impl == error_mark_node)
	inform (loc, "evaluating %qs", "__builtin_source_location");
    }
  if (source_location_impl == error_mark_node)
    return build_zero_cst (const_ptr_type_node);
  if (source_location_table == NULL)
    source_location_table
      = hash_table <source_location_table_entry_hash>::create_ggc (64);
  const line_map_ordinary *map;
  source_location_table_entry entry;
  entry.loc
    = linemap_resolve_location (line_table, loc, LRK_MACRO_EXPANSION_POINT,
				&map);
  entry.uid = current_function_decl ? DECL_UID (current_function_decl) : -1;
  entry.var = error_mark_node;
  source_location_table_entry *entryp
    = source_location_table->find_slot (entry, INSERT);
  tree var;
  if (entryp->var)
    var = entryp->var;
  else
    {
      char tmp_name[32];
      ASM_GENERATE_INTERNAL_LABEL (tmp_name, "Lsrc_loc", source_location_id++);
      var = build_decl (loc, VAR_DECL, get_identifier (tmp_name),
			source_location_impl);
      TREE_STATIC (var) = 1;
      TREE_PUBLIC (var) = 0;
      DECL_ARTIFICIAL (var) = 1;
      DECL_IGNORED_P (var) = 1;
      DECL_EXTERNAL (var) = 0;
      DECL_DECLARED_CONSTEXPR_P (var) = 1;
      DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (var) = 1;
      layout_decl (var, 0);

      vec<constructor_elt, va_gc> *v = NULL;
      vec_alloc (v, 4);
      for (tree field = TYPE_FIELDS (source_location_impl);
	   (field = next_initializable_field (field)) != NULL_TREE;
	   field = DECL_CHAIN (field))
	{
	  const char *n = IDENTIFIER_POINTER (DECL_NAME (field));
	  tree val = NULL_TREE;
	  if (strcmp (n, "_M_file_name") == 0)
	    {
	      if (const char *fname = LOCATION_FILE (loc))
		{
		  fname = remap_macro_filename (fname);
		  val = build_string_literal (strlen (fname) + 1, fname);
		}
	      else
		val = build_string_literal (1, "");
	    }
	  else if (strcmp (n, "_M_function_name") == 0)
	    {
	      const char *name = "";

	      if (current_function_decl)
		name = cxx_printable_name (current_function_decl, 0);

	      val = build_string_literal (strlen (name) + 1, name);
	    }
	  else if (strcmp (n, "_M_line") == 0)
	    val = build_int_cst (TREE_TYPE (field), LOCATION_LINE (loc));
	  else if (strcmp (n, "_M_column") == 0)
	    val = build_int_cst (TREE_TYPE (field), LOCATION_COLUMN (loc));
	  else
	    gcc_unreachable ();
	  CONSTRUCTOR_APPEND_ELT (v, field, val);
	}

      tree ctor = build_constructor (source_location_impl, v);
      TREE_CONSTANT (ctor) = 1;
      TREE_STATIC (ctor) = 1;
      DECL_INITIAL (var) = ctor;
      varpool_node::finalize_decl (var);
      *entryp = entry;
      entryp->var = var;
    }

  return build_fold_addr_expr_with_type_loc (loc, var, const_ptr_type_node);
}

#include "gt-cp-cp-gimplify.h"
