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

   Copyright (C) 2002-2021 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);

/* 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;
}

/* 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);

  if (TREE_CODE (op) == PARM_DECL
      && TREE_ADDRESSABLE (TREE_TYPE (op)))
    {
      tree fn = DECL_CONTEXT (op);
      if (DECL_THUNK_P (fn)
	  || lambda_static_thunk_p (fn))
	/* In a thunk, we pass through invisible reference parms, so this isn't
	   actually a copy.  */
	return false;
    }

  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 PTRMEM_CST:
      *expr_p = cplus_expand_constant (*expr_p);
      if (TREE_CODE (*expr_p) == PTRMEM_CST)
	ret = GS_ERROR;
      else
	ret = GS_OK;
      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));
}

/* 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 (input_location, 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_lambda_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 (VAR_OR_FUNCTION_DECL_P (stmt) && DECL_LOCAL_DECL_P (stmt))
    if (tree alias = DECL_LOCAL_DECL_ALIAS (stmt))
      {
	if (alias != error_mark_node)
	  {
	    *stmt_p = alias;
	    TREE_USED (alias) |= 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)
	  c_genericize_control_stmt (stmt_p, walk_subtrees, data,
				     cp_genericize_r, cp_walk_subtrees);
	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 SPACESHIP_EXPR:
      *stmt_p = genericize_spaceship (*stmt_p);
      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);
	  * walk_subtrees = 0;
	  break;
	}

      if (tree fndecl = cp_get_callee_fndecl_nofold (stmt))
	if (DECL_IMMEDIATE_FUNCTION_P (fndecl))
	  {
	    gcc_assert (source_location_current_p (fndecl));
	    *stmt_p = cxx_constant_value (stmt);
	    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 TEMPLATE_ID_EXPR:
      gcc_assert (concept_check_p (stmt));
      /* Emit the value of the concept check.  */
      *stmt_p = evaluate_concept_check (stmt);
      walk_subtrees = 0;
      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 FOR_STMT:
    case WHILE_STMT:
    case DO_STMT:
    case SWITCH_STMT:
    case CONTINUE_STMT:
    case BREAK_STMT:
    case OMP_FOR:
    case OMP_SIMD:
    case OMP_LOOP:
    case OACC_LOOP:
    case STATEMENT_LIST:
      /* These cases are handled by shared code.  */
      c_genericize_control_stmt (stmt_p, walk_subtrees, data,
				 cp_genericize_r, cp_walk_subtrees);
      break;

    case BIT_CAST_EXPR:
      *stmt_p = build1_loc (EXPR_LOCATION (stmt), VIEW_CONVERT_EXPR,
			    TREE_TYPE (stmt), TREE_OPERAND (stmt, 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.  */
  bc_state_t save_state;
  save_bc_state (&save_state);

  /* 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);
  restore_bc_state (&save_state);
}

/* 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 *, bool /* openacc */)
{
  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));

      /* decltype(nullptr) has only one value, so optimize away all comparisons
	 with that type right away, keeping them in the IL causes troubles for
	 various optimizations.  */
      if (COMPARISON_CLASS_P (org_x)
	  && TREE_CODE (TREE_TYPE (op0)) == NULLPTR_TYPE
	  && TREE_CODE (TREE_TYPE (op1)) == NULLPTR_TYPE)
	{
	  switch (code)
	    {
	    case EQ_EXPR:
	    case LE_EXPR:
	    case GE_EXPR:
	      x = constant_boolean_node (true, TREE_TYPE (x));
	      break;
	    case NE_EXPR:
	    case LT_EXPR:
	    case GT_EXPR:
	      x = constant_boolean_node (false, TREE_TYPE (x));
	      break;
	    default:
	      gcc_unreachable ();
	    }
	  return omit_two_operands_loc (loc, TREE_TYPE (x), x,
					op0, op1);
	}

      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;

    case REQUIRES_EXPR:
      x = evaluate_requires_expr (x);
      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 void
  pch_nx (source_location_table_entry &p)
  {
    extern void gt_pch_nx (source_location_table_entry &);
    gt_pch_nx (p);
  }

  static void
  pch_nx (source_location_table_entry &p, gt_pointer_operator op, void *cookie)
  {
    extern void gt_pch_nx (source_location_table_entry *, gt_pointer_operator,
			   void *);
    gt_pch_nx (&p, op, cookie);
  }
};

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, 2);

	      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"
