/* 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);
  suppress_warning (*stmt_p);
  suppress_warning (TREE_OPERAND (*stmt_p, 1));
}

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

  /* consteval if has been verified not to have the then_/else_ blocks
     entered by gotos/case labels from elsewhere, and as then_ block
     can contain unfolded immediate function calls, we have to discard
     the then_ block regardless of whether else_ has side-effects or not.  */
  if (IF_STMT_CONSTEVAL_P (stmt))
    stmt = else_;
  else 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))
	      && !warning_suppressed_p (stmt, OPT_Wunused_value))
	    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, BUILT_IN_FRONTEND))
	    switch (DECL_FE_FUNCTION_CODE (decl))
	      {
	      case CP_BUILT_IN_IS_CONSTANT_EVALUATED:
		*expr_p = boolean_false_node;
		break;
	      case CP_BUILT_IN_SOURCE_LOCATION:
		*expr_p
		  = fold_builtin_source_location (EXPR_LOCATION (*expr_p));
		break;
	      case CP_BUILT_IN_IS_CORRESPONDING_MEMBER:
		*expr_p
		  = fold_builtin_is_corresponding_member
			(EXPR_LOCATION (*expr_p), call_expr_nargs (*expr_p),
			 &CALL_EXPR_ARG (*expr_p, 0));
		break;
	      case CP_BUILT_IN_IS_POINTER_INTERCONVERTIBLE_WITH_CLASS:
		*expr_p
		  = fold_builtin_is_pointer_inverconvertible_with_class
			(EXPR_LOCATION (*expr_p), call_expr_nargs (*expr_p),
			 &CALL_EXPR_ARG (*expr_p, 0));
		break;
	      default:
		break;
	      }
	}
      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;
  auto_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 (warning_suppressed_p (stmt /* What warning? */))
	  /* 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;
  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_PRIVATE
      && (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;
  bool last = OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE;
  if (!make_shared
      && CLASS_TYPE_P (inner_type)
      && cxx_omp_create_clause_info (c, inner_type, !first, first, last,
				     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:
	      x = constant_boolean_node (true, TREE_TYPE (x));
	      break;
	    case NE_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 (warn_nonnull_compare
		  && warning_suppressed_p (org_x, OPT_Wnonnull_compare))
		suppress_warning (x, OPT_Wnonnull_compare);
	    }
	  /* 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 (warn_nonnull_compare
		  && warning_suppressed_p (org_x, OPT_Wnonnull_compare))
		suppress_warning (x, OPT_Wnonnull_compare);
	    }
	  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;

	if (callee && fndecl_built_in_p (callee, BUILT_IN_FRONTEND))
	  {
	    switch (DECL_FE_FUNCTION_CODE (callee))
	      {
		/* Defer folding __builtin_is_constant_evaluated.  */
	      case CP_BUILT_IN_IS_CONSTANT_EVALUATED:
		break;
	      case CP_BUILT_IN_SOURCE_LOCATION:
		x = fold_builtin_source_location (EXPR_LOCATION (x));
		break;
	      case CP_BUILT_IN_IS_CORRESPONDING_MEMBER:
	        x = fold_builtin_is_corresponding_member
			(EXPR_LOCATION (x), call_expr_nargs (x),
			 &CALL_EXPR_ARG (x, 0));
		break;
	      case CP_BUILT_IN_IS_POINTER_INTERCONVERTIBLE_WITH_CLASS:
                x = fold_builtin_is_pointer_inverconvertible_with_class
			(EXPR_LOCATION (x), call_expr_nargs (x),
			 &CALL_EXPR_ARG (x, 0));
		break;
	      default:
		break;
	      }
	    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);
      copy_warning (x, 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"
