/* Report error messages, build initializers, and perform
   some front-end optimizations for C++ compiler.
   Copyright (C) 1987-2022 Free Software Foundation, Inc.
   Hacked by Michael Tiemann (tiemann@cygnus.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/>.  */


/* This file is part of the C++ front end.
   It contains routines to build C++ expressions given their operands,
   including computing the types of the result, C and C++ specific error
   checks, and some optimization.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "cp-tree.h"
#include "stor-layout.h"
#include "varasm.h"
#include "intl.h"
#include "gcc-rich-location.h"
#include "target.h"

static tree
process_init_constructor (tree type, tree init, int nested, int flags,
			  tsubst_flags_t complain);


/* Print an error message stemming from an attempt to use
   BASETYPE as a base class for TYPE.  */

tree
error_not_base_type (tree basetype, tree type)
{
  if (TREE_CODE (basetype) == FUNCTION_DECL)
    basetype = DECL_CONTEXT (basetype);
  error ("type %qT is not a base type for type %qT", basetype, type);
  return error_mark_node;
}

tree
binfo_or_else (tree base, tree type)
{
  tree binfo = lookup_base (type, base, ba_unique,
			    NULL, tf_warning_or_error);

  if (binfo == error_mark_node)
    return NULL_TREE;
  else if (!binfo)
    error_not_base_type (base, type);
  return binfo;
}

/* According to ARM $7.1.6, "A `const' object may be initialized, but its
   value may not be changed thereafter.  */

void
cxx_readonly_error (location_t loc, tree arg, enum lvalue_use errstring)
{
 
/* This macro is used to emit diagnostics to ensure that all format
   strings are complete sentences, visible to gettext and checked at
   compile time.  */
 
#define ERROR_FOR_ASSIGNMENT(LOC, AS, ASM, IN, DE, ARG)			\
  do {                                                                  \
    switch (errstring)                                                  \
      {                                                                 \
      case lv_assign:							\
	error_at (LOC, AS, ARG);					\
        break;                                                          \
      case lv_asm:							\
	error_at (LOC, ASM, ARG);					\
        break;                                                          \
      case lv_increment:						\
	error_at (LOC, IN, ARG);					\
        break;                                                          \
      case lv_decrement:                                                \
	error_at (LOC, DE, ARG);					\
        break;                                                          \
      default:                                                          \
        gcc_unreachable ();                                             \
      }                                                                 \
  } while (0)

  /* Handle C++-specific things first.  */

  if (VAR_P (arg)
      && DECL_LANG_SPECIFIC (arg)
      && DECL_IN_AGGR_P (arg)
      && !TREE_STATIC (arg))
    ERROR_FOR_ASSIGNMENT (loc,
			  G_("assignment of constant field %qD"),
			  G_("constant field %qD used as %<asm%> output"),
			  G_("increment of constant field %qD"),
			  G_("decrement of constant field %qD"),
			  arg);
  else if (INDIRECT_REF_P (arg)
	   && TYPE_REF_P (TREE_TYPE (TREE_OPERAND (arg, 0)))
	   && (VAR_P (TREE_OPERAND (arg, 0))
	       || TREE_CODE (TREE_OPERAND (arg, 0)) == PARM_DECL))
    ERROR_FOR_ASSIGNMENT (loc,
			  G_("assignment of read-only reference %qD"),
			  G_("read-only reference %qD used as %<asm%> output"),
			  G_("increment of read-only reference %qD"),
			  G_("decrement of read-only reference %qD"),
			  TREE_OPERAND (arg, 0));
  else
    readonly_error (loc, arg, errstring);
}

/* If TYPE has abstract virtual functions, issue an error about trying
   to create an object of that type.  DECL is the object declared, or
   NULL_TREE if the declaration is unavailable, in which case USE specifies
   the kind of invalid use.  Returns 1 if an error occurred; zero if
   all was well.  */

static int
abstract_virtuals_error (tree decl, tree type, abstract_class_use use,
			 tsubst_flags_t complain)
{
  vec<tree, va_gc> *pure;

  if (TREE_CODE (type) == ARRAY_TYPE)
    {
      decl = NULL_TREE;
      use = ACU_ARRAY;
      type = strip_array_types (type);
    }

  /* This function applies only to classes. Any other entity can never
     be abstract.  */
  if (!CLASS_TYPE_P (type))
    return 0;
  type = TYPE_MAIN_VARIANT (type);

#if 0
  /* Instantiation here seems to be required by the standard,
     but breaks e.g. boost::bind.  FIXME!  */
  /* In SFINAE, non-N3276 context, force instantiation.  */
  if (!(complain & (tf_error|tf_decltype)))
    complete_type (type);
#endif

  if (!TYPE_SIZE (type))
    /* TYPE is being defined, and during that time
       CLASSTYPE_PURE_VIRTUALS holds the inline friends.  */
    return 0;

  pure = CLASSTYPE_PURE_VIRTUALS (type);
  if (!pure)
    return 0;

  if (!(complain & tf_error))
    return 1;

  auto_diagnostic_group d;
  if (decl)
    {
      if (VAR_P (decl))
	error ("cannot declare variable %q+D to be of abstract "
	       "type %qT", decl, type);
      else if (TREE_CODE (decl) == PARM_DECL)
	{
	  if (DECL_NAME (decl))
	    error ("cannot declare parameter %q+D to be of abstract type %qT",
		   decl, type);
	  else
	    error ("cannot declare parameter to be of abstract type %qT",
		   type);
	}
      else if (TREE_CODE (decl) == FIELD_DECL)
	error ("cannot declare field %q+D to be of abstract type %qT",
	       decl, type);
      else if (TREE_CODE (decl) == FUNCTION_DECL
	       && TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE)
	error ("invalid abstract return type for member function %q+#D", decl);
      else if (TREE_CODE (decl) == FUNCTION_DECL)
	error ("invalid abstract return type for function %q+#D", decl);
      else if (identifier_p (decl))
	/* Here we do not have location information.  */
	error ("invalid abstract type %qT for %qE", type, decl);
      else
	error ("invalid abstract type for %q+D", decl);
    }
  else switch (use)
    {
    case ACU_ARRAY:
      error ("creating array of %qT, which is an abstract class type", type);
      break;
    case ACU_CAST:
      error ("invalid cast to abstract class type %qT", type);
      break;
    case ACU_NEW:
      error ("invalid new-expression of abstract class type %qT", type);
      break;
    case ACU_RETURN:
      error ("invalid abstract return type %qT", type);
      break;
    case ACU_PARM:
      error ("invalid abstract parameter type %qT", type);
      break;
    case ACU_THROW:
      error ("expression of abstract class type %qT cannot "
	     "be used in throw-expression", type);
      break;
    case ACU_CATCH:
      error ("cannot declare %<catch%> parameter to be of abstract "
	     "class type %qT", type);
      break;
    default:
      error ("cannot allocate an object of abstract type %qT", type);
    }

  /* Only go through this once.  */
  if (pure->length ())
    {
      unsigned ix;
      tree fn;

      inform (DECL_SOURCE_LOCATION (TYPE_MAIN_DECL (type)),
	      "  because the following virtual functions are pure within %qT:",
	      type);

      FOR_EACH_VEC_ELT (*pure, ix, fn)
	if (! DECL_CLONED_FUNCTION_P (fn)
	    || DECL_COMPLETE_DESTRUCTOR_P (fn))
	  inform (DECL_SOURCE_LOCATION (fn), "    %#qD", fn);

      /* Now truncate the vector.  This leaves it non-null, so we know
	 there are pure virtuals, but empty so we don't list them out
	 again.  */
      pure->truncate (0);
    }

  return 1;
}

int
abstract_virtuals_error (tree decl, tree type,
			 tsubst_flags_t complain /* = tf_warning_or_error */)
{
  return abstract_virtuals_error (decl, type, ACU_UNKNOWN, complain);
}

int
abstract_virtuals_error (abstract_class_use use, tree type,
			 tsubst_flags_t complain /* = tf_warning_or_error */)
{
  return abstract_virtuals_error (NULL_TREE, type, use, complain);
}


/* Print an inform about the declaration of the incomplete type TYPE.  */

void
cxx_incomplete_type_inform (const_tree type)
{
  if (!TYPE_MAIN_DECL (type))
    return;

  location_t loc = DECL_SOURCE_LOCATION (TYPE_MAIN_DECL (type));
  tree ptype = strip_top_quals (CONST_CAST_TREE (type));

  if (current_class_type
      && TYPE_BEING_DEFINED (current_class_type)
      && same_type_p (ptype, current_class_type))
    inform (loc, "definition of %q#T is not complete until "
	    "the closing brace", ptype);
  else if (!TYPE_TEMPLATE_INFO (ptype))
    inform (loc, "forward declaration of %q#T", ptype);
  else
    inform (loc, "declaration of %q#T", ptype);
}

/* Print an error message for invalid use of an incomplete type.
   VALUE is the expression that was used (or 0 if that isn't known)
   and TYPE is the type that was invalid.  DIAG_KIND indicates the
   type of diagnostic (see diagnostic.def).  */

void
cxx_incomplete_type_diagnostic (location_t loc, const_tree value,
				const_tree type, diagnostic_t diag_kind)
{
  bool is_decl = false, complained = false;

  gcc_assert (diag_kind == DK_WARNING 
	      || diag_kind == DK_PEDWARN 
	      || diag_kind == DK_ERROR);

  /* Avoid duplicate error message.  */
  if (TREE_CODE (type) == ERROR_MARK)
    return;

  if (value)
    {
      STRIP_ANY_LOCATION_WRAPPER (value);

      if (VAR_P (value)
	  || TREE_CODE (value) == PARM_DECL
	  || TREE_CODE (value) == FIELD_DECL)
	{
	  complained = emit_diagnostic (diag_kind, DECL_SOURCE_LOCATION (value), 0,
					"%qD has incomplete type", value);
	  is_decl = true;
	}
    }
 retry:
  /* We must print an error message.  Be clever about what it says.  */

  switch (TREE_CODE (type))
    {
    case RECORD_TYPE:
    case UNION_TYPE:
    case ENUMERAL_TYPE:
      if (!is_decl)
	complained = emit_diagnostic (diag_kind, loc, 0,
				      "invalid use of incomplete type %q#T",
				      type);
      if (complained)
	cxx_incomplete_type_inform (type);
      break;

    case VOID_TYPE:
      emit_diagnostic (diag_kind, loc, 0,
		       "invalid use of %qT", type);
      break;

    case ARRAY_TYPE:
      if (TYPE_DOMAIN (type))
	{
	  type = TREE_TYPE (type);
	  goto retry;
	}
      emit_diagnostic (diag_kind, loc, 0,
		       "invalid use of array with unspecified bounds");
      break;

    case OFFSET_TYPE:
    bad_member:
      {
	tree member = TREE_OPERAND (value, 1);
	if (is_overloaded_fn (member))
	  member = get_first_fn (member);

	if (DECL_FUNCTION_MEMBER_P (member)
	    && ! flag_ms_extensions)
	  {
	    gcc_rich_location richloc (loc);
	    /* If "member" has no arguments (other than "this"), then
	       add a fix-it hint.  */
	    if (type_num_arguments (TREE_TYPE (member)) == 1)
	      richloc.add_fixit_insert_after ("()");
	    emit_diagnostic (diag_kind, &richloc, 0,
			     "invalid use of member function %qD "
			     "(did you forget the %<()%> ?)", member);
	  }
	else
	  emit_diagnostic (diag_kind, loc, 0,
			   "invalid use of member %qD "
			   "(did you forget the %<&%> ?)", member);
      }
      break;

    case TEMPLATE_TYPE_PARM:
      if (is_auto (type))
	{
	  if (CLASS_PLACEHOLDER_TEMPLATE (type))
	    emit_diagnostic (diag_kind, loc, 0,
			     "invalid use of placeholder %qT", type);
	  else
	    emit_diagnostic (diag_kind, loc, 0,
			     "invalid use of %qT", type);
	}
      else
	emit_diagnostic (diag_kind, loc, 0,
			 "invalid use of template type parameter %qT", type);
      break;

    case BOUND_TEMPLATE_TEMPLATE_PARM:
      emit_diagnostic (diag_kind, loc, 0,
		       "invalid use of template template parameter %qT",
		       TYPE_NAME (type));
      break;

    case TYPE_PACK_EXPANSION:
      emit_diagnostic (diag_kind, loc, 0,
		       "invalid use of pack expansion %qT", type);
      break;

    case TYPENAME_TYPE:
    case DECLTYPE_TYPE:
      emit_diagnostic (diag_kind, loc, 0,
		       "invalid use of dependent type %qT", type);
      break;

    case LANG_TYPE:
      if (type == init_list_type_node)
	{
	  emit_diagnostic (diag_kind, loc, 0,
			   "invalid use of brace-enclosed initializer list");
	  break;
	}
      gcc_assert (type == unknown_type_node);
      if (value && TREE_CODE (value) == COMPONENT_REF)
	goto bad_member;
      else if (value && TREE_CODE (value) == ADDR_EXPR)
	emit_diagnostic (diag_kind, loc, 0,
			 "address of overloaded function with no contextual "
			 "type information");
      else if (value && TREE_CODE (value) == OVERLOAD)
	emit_diagnostic (diag_kind, loc, 0,
			 "overloaded function with no contextual type information");
      else
	emit_diagnostic (diag_kind, loc, 0,
			 "insufficient contextual information to determine type");
      break;

    default:
      gcc_unreachable ();
    }
}

/* Print an error message for invalid use of an incomplete type.
   VALUE is the expression that was used (or 0 if that isn't known)
   and TYPE is the type that was invalid.  */

void
cxx_incomplete_type_error (location_t loc, const_tree value, const_tree type)
{
  cxx_incomplete_type_diagnostic (loc, value, type, DK_ERROR);
}


/* We've just initialized subobject SUB; also insert a TARGET_EXPR with an
   EH-only cleanup for SUB.  Because of EH region nesting issues, we need to
   make the cleanup conditional on a flag that we will clear once the object is
   fully initialized, so push a new flag onto FLAGS.  */

static void
maybe_push_temp_cleanup (tree sub, vec<tree,va_gc> **flags)
{
  if (!flag_exceptions)
    return;
  if (tree cleanup
      = cxx_maybe_build_cleanup (sub, tf_warning_or_error))
    {
      tree tx = get_target_expr (boolean_true_node);
      tree flag = TARGET_EXPR_SLOT (tx);
      CLEANUP_EH_ONLY (tx) = true;
      TARGET_EXPR_CLEANUP (tx) = build3 (COND_EXPR, void_type_node,
					 flag, cleanup, void_node);
      add_stmt (tx);
      vec_safe_push (*flags, flag);
    }
}

/* The recursive part of split_nonconstant_init.  DEST is an lvalue
   expression to which INIT should be assigned.  INIT is a CONSTRUCTOR.
   Return true if the whole of the value was initialized by the
   generated statements.  */

static bool
split_nonconstant_init_1 (tree dest, tree init, bool last,
			  vec<tree,va_gc> **flags)
{
  unsigned HOST_WIDE_INT idx, tidx = HOST_WIDE_INT_M1U;
  tree field_index, value;
  tree type = TREE_TYPE (dest);
  tree inner_type = NULL;
  bool array_type_p = false;
  bool complete_p = true;
  HOST_WIDE_INT num_split_elts = 0;
  tree last_split_elt = NULL_TREE;

  switch (TREE_CODE (type))
    {
    case ARRAY_TYPE:
      inner_type = TREE_TYPE (type);
      array_type_p = true;
      if ((TREE_SIDE_EFFECTS (init)
	   && TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type))
	  || vla_type_p (type))
	{
	  if (!TYPE_DOMAIN (type)
	      && TREE_CODE (init) == CONSTRUCTOR
	      && CONSTRUCTOR_NELTS (init))
	    {
	      /* Flexible array.  */
	      cp_complete_array_type (&type, init, /*default*/true);
	      dest = build1 (VIEW_CONVERT_EXPR, type, dest);
	    }

	  /* For an array, we only need/want a single cleanup region rather
	     than one per element.  build_vec_init will handle it.  */
	  tree code = build_vec_init (dest, NULL_TREE, init, false, 1,
				      tf_warning_or_error, flags);
	  add_stmt (code);
	  return true;
	}
      /* FALLTHRU */

    case RECORD_TYPE:
    case UNION_TYPE:
    case QUAL_UNION_TYPE:
      FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (init), idx,
				field_index, value)
	{
	  /* The current implementation of this algorithm assumes that
	     the field was set for all the elements. This is usually done
	     by process_init_constructor.  */
	  gcc_assert (field_index);

	  if (!array_type_p)
	    inner_type = TREE_TYPE (field_index);

	  tree sub;
	  if (array_type_p)
	    sub = build4 (ARRAY_REF, inner_type, dest, field_index,
			  NULL_TREE, NULL_TREE);
	  else
	    sub = build3 (COMPONENT_REF, inner_type, dest, field_index,
			  NULL_TREE);

	  bool elt_last = last && idx == CONSTRUCTOR_NELTS (init) - 1;

	  /* We need to see sub-array TARGET_EXPR before cp_fold_r so we can
	     handle cleanup flags properly.  */
	  gcc_checking_assert (!target_expr_needs_replace (value));

	  if (TREE_CODE (value) == CONSTRUCTOR)
	    {
	      if (!split_nonconstant_init_1 (sub, value, elt_last, flags)
		      /* For flexible array member with initializer we
			 can't remove the initializer, because only the
			 initializer determines how many elements the
			 flexible array member has.  */
		  || (!array_type_p
		      && TREE_CODE (inner_type) == ARRAY_TYPE
		      && TYPE_DOMAIN (inner_type) == NULL
		      && TREE_CODE (TREE_TYPE (value)) == ARRAY_TYPE
		      && COMPLETE_TYPE_P (TREE_TYPE (value))
		      && !integer_zerop (TYPE_SIZE (TREE_TYPE (value)))
		      && elt_last
		      && TYPE_HAS_TRIVIAL_DESTRUCTOR
				(strip_array_types (inner_type))))
		complete_p = false;
	      else
		{
		  /* Mark element for removal.  */
		  last_split_elt = field_index;
		  CONSTRUCTOR_ELT (init, idx)->index = NULL_TREE;
		  if (idx < tidx)
		    tidx = idx;
		  num_split_elts++;
		}
	    }
	  else if (tree vi = get_vec_init_expr (value))
	    {
	      add_stmt (expand_vec_init_expr (sub, vi, tf_warning_or_error,
					      flags));

	      /* Mark element for removal.  */
	      last_split_elt = field_index;
	      CONSTRUCTOR_ELT (init, idx)->index = NULL_TREE;
	      if (idx < tidx)
		tidx = idx;
	      num_split_elts++;
	    }
	  else if (!initializer_constant_valid_p (value, inner_type))
	    {
	      tree code;

	      /* Push cleanups for any preceding members with constant
		 initialization.  */
	      if (CLASS_TYPE_P (type))
		for (tree prev = (last_split_elt ?
				  DECL_CHAIN (last_split_elt)
				  : TYPE_FIELDS (type));
		     ; prev = DECL_CHAIN (prev))
		  {
		    prev = next_aggregate_field (prev);
		    if (prev == field_index)
		      break;
		    tree ptype = TREE_TYPE (prev);
		    if (TYPE_P (ptype) && type_build_dtor_call (ptype))
		      {
			tree pcref = build3 (COMPONENT_REF, ptype, dest, prev,
					     NULL_TREE);
			maybe_push_temp_cleanup (pcref, flags);
		      }
		  }

	      /* Mark element for removal.  */
	      CONSTRUCTOR_ELT (init, idx)->index = NULL_TREE;
	      if (idx < tidx)
		tidx = idx;

	      if (TREE_CODE (field_index) == RANGE_EXPR)
		{
		  /* Use build_vec_init to initialize a range.  */
		  tree low = TREE_OPERAND (field_index, 0);
		  tree hi = TREE_OPERAND (field_index, 1);
		  sub = build4 (ARRAY_REF, inner_type, dest, low,
				NULL_TREE, NULL_TREE);
		  sub = cp_build_addr_expr (sub, tf_warning_or_error);
		  tree max = size_binop (MINUS_EXPR, hi, low);
		  code = build_vec_init (sub, max, value, false, 0,
					 tf_warning_or_error);
		  add_stmt (code);
		  if (tree_fits_shwi_p (max))
		    num_split_elts += tree_to_shwi (max);
		}
	      else
		{
		  /* We may need to add a copy constructor call if
		     the field has [[no_unique_address]].  */
		  if (unsafe_return_slot_p (sub))
		    {
		      /* But not if the initializer is an implicit ctor call
			 we just built in digest_init.  */
		      if (TREE_CODE (value) == TARGET_EXPR
			  && TARGET_EXPR_LIST_INIT_P (value)
			  && make_safe_copy_elision (sub, value))
			goto build_init;

		      tree name = (DECL_FIELD_IS_BASE (field_index)
				   ? base_ctor_identifier
				   : complete_ctor_identifier);
		      releasing_vec args = make_tree_vector_single (value);
		      code = build_special_member_call
			(sub, name, &args, inner_type,
			 LOOKUP_NORMAL, tf_warning_or_error);
		    }
		  else
		    {
		    build_init:
		      code = cp_build_init_expr (sub, value);
		    }
		  code = build_stmt (input_location, EXPR_STMT, code);
		  add_stmt (code);
		  if (!elt_last)
		    maybe_push_temp_cleanup (sub, flags);
		}

	      last_split_elt = field_index;
	      num_split_elts++;
	    }
	}
      if (num_split_elts == 1)
	CONSTRUCTOR_ELTS (init)->ordered_remove (tidx);
      else if (num_split_elts > 1)
	{
	  /* Perform the delayed ordered removal of non-constant elements
	     we split out.  */
	  for (idx = tidx; idx < CONSTRUCTOR_NELTS (init); ++idx)
	    if (CONSTRUCTOR_ELT (init, idx)->index == NULL_TREE)
	      ;
	    else
	      {
		*CONSTRUCTOR_ELT (init, tidx) = *CONSTRUCTOR_ELT (init, idx);
		++tidx;
	      }
	  vec_safe_truncate (CONSTRUCTOR_ELTS (init), tidx);
	}
      break;

    case VECTOR_TYPE:
      if (!initializer_constant_valid_p (init, type))
	{
	  tree code;
	  tree cons = copy_node (init);
	  CONSTRUCTOR_ELTS (init) = NULL;
	  code = build2 (MODIFY_EXPR, type, dest, cons);
	  code = build_stmt (input_location, EXPR_STMT, code);
	  add_stmt (code);
	  num_split_elts += CONSTRUCTOR_NELTS (init);
	}
      break;

    default:
      gcc_unreachable ();
    }

  /* The rest of the initializer is now a constant. */
  TREE_CONSTANT (init) = 1;
  TREE_SIDE_EFFECTS (init) = 0;

  /* We didn't split out anything.  */
  if (num_split_elts == 0)
    return false;

  return complete_p && complete_ctor_at_level_p (TREE_TYPE (init),
						 num_split_elts, inner_type);
}

/* A subroutine of store_init_value.  Splits non-constant static
   initializer INIT into a constant part and generates code to
   perform the non-constant part of the initialization to DEST.
   Returns the code for the runtime init.  */

tree
split_nonconstant_init (tree dest, tree init)
{
  tree code;

  if (TREE_CODE (init) == TARGET_EXPR)
    init = TARGET_EXPR_INITIAL (init);
  if (TREE_CODE (init) == CONSTRUCTOR)
    {
      /* Subobject initializers are not full-expressions.  */
      auto fe = (make_temp_override
		 (current_stmt_tree ()->stmts_are_full_exprs_p, 0));

      init = cp_fully_fold_init (init);
      code = push_stmt_list ();

      /* If the complete object is an array, build_vec_init's cleanup is
	 enough.  Otherwise, collect flags for disabling subobject
	 cleanups once the complete object is fully constructed.  */
      vec<tree, va_gc> *flags = nullptr;
      if (TREE_CODE (TREE_TYPE (dest)) != ARRAY_TYPE)
	flags = make_tree_vector ();

      if (split_nonconstant_init_1 (dest, init, true, &flags))
	init = NULL_TREE;

      for (tree f : flags)
	{
	  /* See maybe_push_temp_cleanup.  */
	  tree d = f;
	  tree i = boolean_false_node;
	  if (TREE_CODE (f) == TREE_LIST)
	    {
	      /* To disable a build_vec_init cleanup, set
		 iterator = maxindex.  */
	      d = TREE_PURPOSE (f);
	      i = TREE_VALUE (f);
	      ggc_free (f);
	    }
	  add_stmt (build2 (MODIFY_EXPR, TREE_TYPE (d), d, i));
	}
      release_tree_vector (flags);

      code = pop_stmt_list (code);
      if (VAR_P (dest) && !is_local_temp (dest))
	{
	  DECL_INITIAL (dest) = init;
	  TREE_READONLY (dest) = 0;
	}
      else if (init)
	{
	  tree ie = cp_build_init_expr (dest, init);
	  code = add_stmt_to_compound (ie, code);
	}
    }
  else if (TREE_CODE (init) == STRING_CST
	   && array_of_runtime_bound_p (TREE_TYPE (dest)))
    code = build_vec_init (dest, NULL_TREE, init, /*value-init*/false,
			   /*from array*/1, tf_warning_or_error);
  else
    code = cp_build_init_expr (dest, init);

  return code;
}

/* Perform appropriate conversions on the initial value of a variable,
   store it in the declaration DECL,
   and print any error messages that are appropriate.
   If the init is invalid, store an ERROR_MARK.

   C++: Note that INIT might be a TREE_LIST, which would mean that it is
   a base class initializer for some aggregate type, hopefully compatible
   with DECL.  If INIT is a single element, and DECL is an aggregate
   type, we silently convert INIT into a TREE_LIST, allowing a constructor
   to be called.

   If INIT is a TREE_LIST and there is no constructor, turn INIT
   into a CONSTRUCTOR and use standard initialization techniques.
   Perhaps a warning should be generated?

   Returns code to be executed if initialization could not be performed
   for static variable.  In that case, caller must emit the code.  */

tree
store_init_value (tree decl, tree init, vec<tree, va_gc>** cleanups, int flags)
{
  tree value, type;

  /* If variable's type was invalidly declared, just ignore it.  */

  type = TREE_TYPE (decl);
  if (TREE_CODE (type) == ERROR_MARK)
    return NULL_TREE;

  if (MAYBE_CLASS_TYPE_P (type))
    {
      if (TREE_CODE (init) == TREE_LIST)
	{
	  error ("constructor syntax used, but no constructor declared "
		 "for type %qT", type);
	  init = build_constructor_from_list (init_list_type_node, nreverse (init));
	}
    }

  /* End of special C++ code.  */

  if (flags & LOOKUP_ALREADY_DIGESTED)
    value = init;
  else
    {
      if (TREE_STATIC (decl))
	flags |= LOOKUP_ALLOW_FLEXARRAY_INIT;
      /* Digest the specified initializer into an expression.  */
      value = digest_init_flags (type, init, flags, tf_warning_or_error);
    }

  /* Look for braced array initializers for character arrays and
     recursively convert them into STRING_CSTs.  */
  value = braced_lists_to_strings (type, value);

  current_ref_temp_count = 0;
  value = extend_ref_init_temps (decl, value, cleanups);

  /* In C++11 constant expression is a semantic, not syntactic, property.
     In C++98, make sure that what we thought was a constant expression at
     template definition time is still constant and otherwise perform this
     as optimization, e.g. to fold SIZEOF_EXPRs in the initializer.  */
  if (decl_maybe_constant_var_p (decl) || TREE_STATIC (decl))
    {
      bool const_init;
      tree oldval = value;
      if (DECL_DECLARED_CONSTEXPR_P (decl)
	  || (DECL_IN_AGGR_P (decl)
	      && DECL_INITIALIZED_IN_CLASS_P (decl)))
	{
	  value = fold_non_dependent_expr (value, tf_warning_or_error,
					   /*manifestly_const_eval=*/true,
					   decl);
	  /* Diagnose a non-constant initializer for constexpr variable or
	     non-inline in-class-initialized static data member.  */
	  if (!require_constant_expression (value))
	    value = error_mark_node;
	  else if (processing_template_decl)
	    /* In a template we might not have done the necessary
	       transformations to make value actually constant,
	       e.g. extend_ref_init_temps.  */
	    value = maybe_constant_init (value, decl, true);
	  else
	    value = cxx_constant_init (value, decl);
	}
      else
	value = fold_non_dependent_init (value, tf_warning_or_error,
					 /*manifestly_const_eval=*/true, decl);
      if (TREE_CODE (value) == CONSTRUCTOR && cp_has_mutable_p (type))
	/* Poison this CONSTRUCTOR so it can't be copied to another
	   constexpr variable.  */
	CONSTRUCTOR_MUTABLE_POISON (value) = true;
      const_init = (reduced_constant_expression_p (value)
		    || error_operand_p (value));
      DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl) = const_init;
      /* FIXME setting TREE_CONSTANT on refs breaks the back end.  */
      if (!TYPE_REF_P (type))
	TREE_CONSTANT (decl) = const_init && decl_maybe_constant_var_p (decl);
      if (!const_init)
	{
	  /* [dcl.constinit]/2 "If a variable declared with the constinit
	     specifier has dynamic initialization, the program is
	     ill-formed."  */
	  if (DECL_DECLARED_CONSTINIT_P (decl))
	    {
	      error_at (location_of (decl),
			"%<constinit%> variable %qD does not have a constant "
			"initializer", decl);
	      if (require_constant_expression (value))
		cxx_constant_init (value, decl);
	      value = error_mark_node;
	    }
	  else
	    value = oldval;
	}
    }
  /* Don't fold initializers of automatic variables in constexpr functions,
     that might fold away something that needs to be diagnosed at constexpr
     evaluation time.  */
  if (!current_function_decl
      || !DECL_DECLARED_CONSTEXPR_P (current_function_decl)
      || TREE_STATIC (decl))
    value = cp_fully_fold_init (value);

  /* Handle aggregate NSDMI in non-constant initializers, too.  */
  value = replace_placeholders (value, decl);

  /* A COMPOUND_LITERAL_P CONSTRUCTOR is the syntactic form; by the time we get
     here it should have been digested into an actual value for the type.  */
  gcc_checking_assert (TREE_CODE (value) != CONSTRUCTOR
		       || processing_template_decl
		       || TREE_CODE (type) == VECTOR_TYPE
		       || !TREE_HAS_CONSTRUCTOR (value));

  /* If the initializer is not a constant, fill in DECL_INITIAL with
     the bits that are constant, and then return an expression that
     will perform the dynamic initialization.  */
  if (value != error_mark_node
      && !processing_template_decl
      && (TREE_SIDE_EFFECTS (value)
	  || vla_type_p (type)
	  || ! reduced_constant_expression_p (value)))
    return split_nonconstant_init (decl, value);

  /* DECL may change value; purge caches.  */
  clear_cv_and_fold_caches ();

  /* If the value is a constant, just put it in DECL_INITIAL.  If DECL
     is an automatic variable, the middle end will turn this into a
     dynamic initialization later.  */
  DECL_INITIAL (decl) = value;
  return NULL_TREE;
}


/* Give diagnostic about narrowing conversions within { }, or as part of
   a converted constant expression.  If CONST_ONLY, only check
   constants.  */

bool
check_narrowing (tree type, tree init, tsubst_flags_t complain,
		 bool const_only/*= false*/)
{
  tree ftype = unlowered_expr_type (init);
  bool ok = true;
  REAL_VALUE_TYPE d;

  if (((!warn_narrowing || !(complain & tf_warning))
       && cxx_dialect == cxx98)
      || !ARITHMETIC_TYPE_P (type)
      /* Don't emit bogus warnings with e.g. value-dependent trees.  */
      || instantiation_dependent_expression_p (init))
    return ok;

  if (BRACE_ENCLOSED_INITIALIZER_P (init)
      && TREE_CODE (type) == COMPLEX_TYPE)
    {
      tree elttype = TREE_TYPE (type);
      if (CONSTRUCTOR_NELTS (init) > 0)
        ok &= check_narrowing (elttype, CONSTRUCTOR_ELT (init, 0)->value,
			       complain);
      if (CONSTRUCTOR_NELTS (init) > 1)
	ok &= check_narrowing (elttype, CONSTRUCTOR_ELT (init, 1)->value,
			       complain);
      return ok;
    }

  /* Even non-dependent expressions can still have template
     codes like CAST_EXPR, so use *_non_dependent_expr to cope.  */
  init = fold_non_dependent_expr (init, complain, /*manifest*/true);
  if (init == error_mark_node)
    return ok;

  /* If we were asked to only check constants, return early.  */
  if (const_only && !TREE_CONSTANT (init))
    return ok;

  if (CP_INTEGRAL_TYPE_P (type)
      && TREE_CODE (ftype) == REAL_TYPE)
    ok = false;
  else if (INTEGRAL_OR_ENUMERATION_TYPE_P (ftype)
	   && CP_INTEGRAL_TYPE_P (type))
    {
      if (TREE_CODE (ftype) == ENUMERAL_TYPE)
	/* Check for narrowing based on the values of the enumeration. */
	ftype = ENUM_UNDERLYING_TYPE (ftype);
      if ((tree_int_cst_lt (TYPE_MAX_VALUE (type),
			    TYPE_MAX_VALUE (ftype))
	   || tree_int_cst_lt (TYPE_MIN_VALUE (ftype),
			       TYPE_MIN_VALUE (type)))
	  && (TREE_CODE (init) != INTEGER_CST
	      || !int_fits_type_p (init, type)))
	ok = false;
    }
  /* [dcl.init.list]#7.2: "from long double to double or float, or from
      double to float".  */
  else if (TREE_CODE (ftype) == REAL_TYPE
	   && TREE_CODE (type) == REAL_TYPE)
    {
      if ((extended_float_type_p (ftype) || extended_float_type_p (type))
	  ? /* "from a floating-point type T to another floating-point type
	       whose floating-point conversion rank is neither greater than
	       nor equal to that of T".
	       So, it is ok if
	       cp_compare_floating_point_conversion_ranks (ftype, type)
	       returns -2 (type has greater conversion rank than ftype)
	       or [-1..1] (type has equal conversion rank as ftype, possibly
	       different subrank.  Only do this if at least one of the
	       types is extended floating-point type, otherwise keep doing
	       what we did before (for the sake of non-standard
	       backend types).  */
	    cp_compare_floating_point_conversion_ranks (ftype, type) >= 2
	  : ((same_type_p (ftype, long_double_type_node)
	      && (same_type_p (type, double_type_node)
		  || same_type_p (type, float_type_node)))
	     || (same_type_p (ftype, double_type_node)
		 && same_type_p (type, float_type_node))
	     || (TYPE_PRECISION (type) < TYPE_PRECISION (ftype))))
	{
	  if (TREE_CODE (init) == REAL_CST)
	    {
	      /* Issue 703: Loss of precision is OK as long as the value is
		 within the representable range of the new type.  */
	      REAL_VALUE_TYPE r;
	      d = TREE_REAL_CST (init);
	      real_convert (&r, TYPE_MODE (type), &d);
	      if (real_isinf (&r))
		ok = false;
	    }
	  else
	    ok = false;
	}
    }
  else if (INTEGRAL_OR_ENUMERATION_TYPE_P (ftype)
	   && TREE_CODE (type) == REAL_TYPE)
    {
      ok = false;
      if (TREE_CODE (init) == INTEGER_CST)
	{
	  d = real_value_from_int_cst (0, init);
	  if (exact_real_truncate (TYPE_MODE (type), &d))
	    ok = true;
	}
    }
  else if (TREE_CODE (type) == BOOLEAN_TYPE
	   && (TYPE_PTR_P (ftype) || TYPE_PTRMEM_P (ftype)))
    /* C++20 P1957R2: converting from a pointer type or a pointer-to-member
       type to bool should be considered narrowing.  This is a DR so is not
       limited to C++20 only.  */
    ok = false;

  bool almost_ok = ok;
  if (!ok && !CONSTANT_CLASS_P (init) && (complain & tf_warning_or_error))
    {
      tree folded = cp_fully_fold (init);
      if (TREE_CONSTANT (folded) && check_narrowing (type, folded, tf_none))
	almost_ok = true;
    }

  if (!ok)
    {
      location_t loc = cp_expr_loc_or_input_loc (init);
      if (cxx_dialect == cxx98)
	{
	  if (complain & tf_warning)
	    warning_at (loc, OPT_Wnarrowing, "narrowing conversion of %qE "
			"from %qH to %qI is ill-formed in C++11",
			init, ftype, type);
	  ok = true;
	}
      else if (!CONSTANT_CLASS_P (init))
	{
	  if (complain & tf_warning_or_error)
	    {
	      auto_diagnostic_group d;
	      if ((!almost_ok || pedantic)
		  && pedwarn (loc, OPT_Wnarrowing,
			      "narrowing conversion of %qE from %qH to %qI",
			      init, ftype, type)
		  && almost_ok)
		inform (loc, " the expression has a constant value but is not "
			"a C++ constant-expression");
	      ok = true;
	    }
	}
      else if (complain & tf_error)
	{
	  int savederrorcount = errorcount;
	  global_dc->pedantic_errors = 1;
	  auto s = make_temp_override (global_dc->dc_warn_system_headers, true);
	  pedwarn (loc, OPT_Wnarrowing,
		   "narrowing conversion of %qE from %qH to %qI",
		   init, ftype, type);
	  if (errorcount == savederrorcount)
	    ok = true;
	  global_dc->pedantic_errors = flag_pedantic_errors;
	}
    }

  return ok;
}

/* True iff TYPE is a C++20 "ordinary" character type.  */

bool
ordinary_char_type_p (tree type)
{
  type = TYPE_MAIN_VARIANT (type);
  return (type == char_type_node
	  || type == signed_char_type_node
	  || type == unsigned_char_type_node);
}

/* True iff the string literal INIT has a type suitable for initializing array
   TYPE.  */

bool
array_string_literal_compatible_p (tree type, tree init)
{
  tree to_char_type = TYPE_MAIN_VARIANT (TREE_TYPE (type));
  tree from_char_type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (init)));

  if (to_char_type == from_char_type)
    return true;
  /* The array element type does not match the initializing string
     literal element type; this is only allowed when both types are
     ordinary character type.  There are no string literals of
     signed or unsigned char type in the language, but we can get
     them internally from converting braced-init-lists to
     STRING_CST.  */
  if (ordinary_char_type_p (to_char_type)
      && ordinary_char_type_p (from_char_type))
    return true;

  /* P2513 (C++20/C++23): "an array of char or unsigned char may
     be initialized by a UTF-8 string literal, or by such a string
     literal enclosed in braces."  */
  if (from_char_type == char8_type_node
      && (to_char_type == char_type_node
	  || to_char_type == unsigned_char_type_node))
    return true;

  return false;
}

/* Process the initializer INIT for a variable of type TYPE, emitting
   diagnostics for invalid initializers and converting the initializer as
   appropriate.

   For aggregate types, it assumes that reshape_init has already run, thus the
   initializer will have the right shape (brace elision has been undone).

   NESTED is non-zero iff we are being called for an element of a CONSTRUCTOR,
   2 iff the element of a CONSTRUCTOR is inside another CONSTRUCTOR.  */

static tree
digest_init_r (tree type, tree init, int nested, int flags,
	       tsubst_flags_t complain)
{
  enum tree_code code = TREE_CODE (type);

  if (error_operand_p (init))
    return error_mark_node;

  gcc_assert (init);

  /* We must strip the outermost array type when completing the type,
     because the its bounds might be incomplete at the moment.  */
  if (!complete_type_or_maybe_complain (code == ARRAY_TYPE
					? TREE_TYPE (type) : type, NULL_TREE,
					complain))
    return error_mark_node;

  location_t loc = cp_expr_loc_or_input_loc (init);

  tree stripped_init = init;

  if (BRACE_ENCLOSED_INITIALIZER_P (init)
      && CONSTRUCTOR_IS_PAREN_INIT (init))
    flags |= LOOKUP_AGGREGATE_PAREN_INIT;

  /* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue
     (g++.old-deja/g++.law/casts2.C).  */
  if (TREE_CODE (init) == NON_LVALUE_EXPR)
    stripped_init = TREE_OPERAND (init, 0);

  stripped_init = tree_strip_any_location_wrapper (stripped_init);

  /* Initialization of an array of chars from a string constant. The initializer
     can be optionally enclosed in braces, but reshape_init has already removed
     them if they were present.  */
  if (code == ARRAY_TYPE)
    {
      if (nested && !TYPE_DOMAIN (type))
	/* C++ flexible array members have a null domain.  */
	{
	  if (flags & LOOKUP_ALLOW_FLEXARRAY_INIT)
	    pedwarn (loc, OPT_Wpedantic,
		     "initialization of a flexible array member");
	  else
	    {
	      if (complain & tf_error)
		error_at (loc, "non-static initialization of"
			       " a flexible array member");
	      return error_mark_node;
	    }
	}

      tree typ1 = TYPE_MAIN_VARIANT (TREE_TYPE (type));
      if (char_type_p (typ1)
	  && TREE_CODE (stripped_init) == STRING_CST)
	{
	  if (!array_string_literal_compatible_p (type, init))
	    {
	      if (complain & tf_error)
		error_at (loc, "cannot initialize array of %qT from "
			  "a string literal with type array of %qT",
			  typ1,
			  TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (init))));
	      return error_mark_node;
	    }

	  if (nested == 2 && !TYPE_DOMAIN (type))
	    {
	      if (complain & tf_error)
		error_at (loc, "initialization of flexible array member "
			       "in a nested context");
	      return error_mark_node;
	    }

	  if (type != TREE_TYPE (init)
	      && !variably_modified_type_p (type, NULL_TREE))
	    {
	      init = copy_node (init);
	      TREE_TYPE (init) = type;
	      /* If we have a location wrapper, then also copy the wrapped
		 node, and update the copy's type.  */
	      if (location_wrapper_p (init))
		{
		  stripped_init = copy_node (stripped_init);
		  TREE_OPERAND (init, 0) = stripped_init;
		  TREE_TYPE (stripped_init) = type;
		}
	    }
	  if (TYPE_DOMAIN (type) && TREE_CONSTANT (TYPE_SIZE (type)))
	    {
	      /* Not a flexible array member.  */
	      int size = TREE_INT_CST_LOW (TYPE_SIZE (type));
	      size = (size + BITS_PER_UNIT - 1) / BITS_PER_UNIT;
	      /* In C it is ok to subtract 1 from the length of the string
		 because it's ok to ignore the terminating null char that is
		 counted in the length of the constant, but in C++ this would
		 be invalid.  */
	      if (size < TREE_STRING_LENGTH (stripped_init))
		{
		  permerror (loc, "initializer-string for %qT is too long",
			     type);

		  init = build_string (size,
				       TREE_STRING_POINTER (stripped_init));
		  TREE_TYPE (init) = type;
		}
	    }
	  return init;
	}
    }

  /* Handle scalar types (including conversions) and references.  */
  if ((code != COMPLEX_TYPE || BRACE_ENCLOSED_INITIALIZER_P (stripped_init))
      && (SCALAR_TYPE_P (type) || code == REFERENCE_TYPE))
    {
      /* Narrowing is OK when initializing an aggregate from
	 a parenthesized list.  */
      if (nested && !(flags & LOOKUP_AGGREGATE_PAREN_INIT))
	flags |= LOOKUP_NO_NARROWING;
      init = convert_for_initialization (0, type, init, flags,
					 ICR_INIT, NULL_TREE, 0,
					 complain);

      return init;
    }

  /* Come here only for aggregates: records, arrays, unions, complex numbers
     and vectors.  */
  gcc_assert (code == ARRAY_TYPE
	      || VECTOR_TYPE_P (type)
	      || code == RECORD_TYPE
	      || code == UNION_TYPE
	      || code == OPAQUE_TYPE
	      || code == COMPLEX_TYPE);

  /* "If T is a class type and the initializer list has a single
     element of type cv U, where U is T or a class derived from T,
     the object is initialized from that element."  */
  if (cxx_dialect >= cxx11
      && BRACE_ENCLOSED_INITIALIZER_P (stripped_init)
      && !CONSTRUCTOR_IS_DESIGNATED_INIT (stripped_init)
      && CONSTRUCTOR_NELTS (stripped_init) == 1
      && ((CLASS_TYPE_P (type) && !CLASSTYPE_NON_AGGREGATE (type))
	  || VECTOR_TYPE_P (type)))
    {
      tree elt = CONSTRUCTOR_ELT (stripped_init, 0)->value;
      if (reference_related_p (type, TREE_TYPE (elt)))
	{
	  /* In C++17, aggregates can have bases, thus participate in
	     aggregate initialization.  In the following case:

	       struct B { int c; };
	       struct D : B { };
	       D d{{D{{42}}}};

	    there's an extra set of braces, so the D temporary initializes
	    the first element of d, which is the B base subobject.  The base
	    of type B is copy-initialized from the D temporary, causing
	    object slicing.  */
	  tree field = next_aggregate_field (TYPE_FIELDS (type));
	  if (field && DECL_FIELD_IS_BASE (field))
	    {
	      if (warning_at (loc, 0, "initializing a base class of type %qT "
			      "results in object slicing", TREE_TYPE (field)))
		inform (loc, "remove %<{ }%> around initializer");
	    }
	  else if (flag_checking)
	    /* We should have fixed this in reshape_init.  */
	    gcc_unreachable ();
	}
    }

  if (SIMPLE_TARGET_EXPR_P (stripped_init))
    stripped_init = TARGET_EXPR_INITIAL (stripped_init);

  if (BRACE_ENCLOSED_INITIALIZER_P (stripped_init)
      && !TYPE_NON_AGGREGATE_CLASS (type))
    return process_init_constructor (type, stripped_init, nested, flags,
				     complain);
  else
    {
      if (COMPOUND_LITERAL_P (stripped_init) && code == ARRAY_TYPE)
	{
	  if (complain & tf_error)
	    error_at (loc, "cannot initialize aggregate of type %qT with "
		      "a compound literal", type);

	  return error_mark_node;
	}

      if (code == ARRAY_TYPE
	  && !BRACE_ENCLOSED_INITIALIZER_P (stripped_init))
	{
	  /* Allow the result of build_array_copy and of
	     build_value_init_noctor.  */
	  if ((TREE_CODE (stripped_init) == VEC_INIT_EXPR
	       || TREE_CODE (stripped_init) == CONSTRUCTOR)
	      && (same_type_ignoring_top_level_qualifiers_p
		  (type, TREE_TYPE (init))))
	    return init;

	  if (complain & tf_error)
	    error_at (loc, "array must be initialized with a brace-enclosed"
		      " initializer");
	  return error_mark_node;
	}

      return convert_for_initialization (NULL_TREE, type, init,
					 flags,
					 ICR_INIT, NULL_TREE, 0,
                                         complain);
    }
}

tree
digest_init (tree type, tree init, tsubst_flags_t complain)
{
  return digest_init_r (type, init, 0, LOOKUP_IMPLICIT, complain);
}

tree
digest_init_flags (tree type, tree init, int flags, tsubst_flags_t complain)
{
  return digest_init_r (type, init, 0, flags, complain);
}

/* Return true if SUBOB initializes the same object as FULL_EXPR.
   For instance:

     A a = A{};		      // initializer
     A a = (A{});	      // initializer
     A a = (1, A{});	      // initializer
     A a = true ? A{} : A{};  // initializer
     auto x = A{}.x;	      // temporary materialization
     auto x = foo(A{});	      // temporary materialization

   FULL_EXPR is the whole expression, SUBOB is its TARGET_EXPR subobject.  */

static bool
potential_prvalue_result_of (tree subob, tree full_expr)
{
  if (subob == full_expr)
    return true;
  else if (TREE_CODE (full_expr) == TARGET_EXPR)
    {
      tree init = TARGET_EXPR_INITIAL (full_expr);
      if (TREE_CODE (init) == COND_EXPR)
	return (potential_prvalue_result_of (subob, TREE_OPERAND (init, 1))
		|| potential_prvalue_result_of (subob, TREE_OPERAND (init, 2)));
      else if (TREE_CODE (init) == COMPOUND_EXPR)
	return potential_prvalue_result_of (subob, TREE_OPERAND (init, 1));
      /* ??? I don't know if this can be hit.  */
      else if (TREE_CODE (init) == PAREN_EXPR)
	{
	  gcc_checking_assert (false);
	  return potential_prvalue_result_of (subob, TREE_OPERAND (init, 0));
	}
    }
  return false;
}

/* Callback to replace PLACEHOLDER_EXPRs in a TARGET_EXPR (which isn't used
   in the context of guaranteed copy elision).  */

static tree
replace_placeholders_for_class_temp_r (tree *tp, int *, void *data)
{
  tree t = *tp;
  tree full_expr = *static_cast<tree *>(data);

  /* We're looking for a TARGET_EXPR nested in the whole expression.  */
  if (TREE_CODE (t) == TARGET_EXPR
      && !potential_prvalue_result_of (t, full_expr))
    {
      tree init = TARGET_EXPR_INITIAL (t);
      while (TREE_CODE (init) == COMPOUND_EXPR)
	init = TREE_OPERAND (init, 1);
      if (TREE_CODE (init) == CONSTRUCTOR
	  && CONSTRUCTOR_PLACEHOLDER_BOUNDARY (init))
	{
	  tree obj = TARGET_EXPR_SLOT (t);
	  replace_placeholders (init, obj);
	  /* We should have dealt with all PLACEHOLDER_EXPRs.  */
	  CONSTRUCTOR_PLACEHOLDER_BOUNDARY (init) = false;
	  gcc_checking_assert (!find_placeholders (init));
	}
    }

  return NULL_TREE;
}

/* Process the initializer INIT for an NSDMI DECL (a FIELD_DECL).  */
tree
digest_nsdmi_init (tree decl, tree init, tsubst_flags_t complain)
{
  gcc_assert (TREE_CODE (decl) == FIELD_DECL);

  tree type = TREE_TYPE (decl);
  if (DECL_BIT_FIELD_TYPE (decl))
    type = DECL_BIT_FIELD_TYPE (decl);
  int flags = LOOKUP_IMPLICIT;
  if (DIRECT_LIST_INIT_P (init))
    {
      flags = LOOKUP_NORMAL;
      complain |= tf_no_cleanup;
    }
  if (BRACE_ENCLOSED_INITIALIZER_P (init)
      && CP_AGGREGATE_TYPE_P (type))
    init = reshape_init (type, init, complain);
  init = digest_init_flags (type, init, flags, complain);
  set_target_expr_eliding (init);

  /* We may have temporary materialization in a NSDMI, if the initializer
     has something like A{} in it.  Digesting the {} could have introduced
     a PLACEHOLDER_EXPR referring to A.  Now that we've got a TARGET_EXPR,
     we have an object we can refer to.  The reason we bother doing this
     here is for code like

       struct A {
	 int x;
	 int y = x;
       };

       struct B {
	 int x = 0;
	 int y = A{x}.y; // #1
       };

     where in #1 we don't want to end up with two PLACEHOLDER_EXPRs for
     different types on the same level in a {} when lookup_placeholder
     wouldn't find a named object for the PLACEHOLDER_EXPR for A.  Note,
     temporary materialization does not occur when initializing an object
     from a prvalue of the same type, therefore we must not replace the
     placeholder with a temporary object so that it can be elided.  */
  cp_walk_tree (&init, replace_placeholders_for_class_temp_r, &init,
		nullptr);

  return init;
}

/* Set of flags used within process_init_constructor to describe the
   initializers.  */
#define PICFLAG_ERRONEOUS 1
#define PICFLAG_NOT_ALL_CONSTANT 2
#define PICFLAG_NOT_ALL_SIMPLE 4
#define PICFLAG_SIDE_EFFECTS 8
#define PICFLAG_VEC_INIT 16

/* Given an initializer INIT, return the flag (PICFLAG_*) which better
   describe it.  */

static int
picflag_from_initializer (tree init)
{
  if (init == error_mark_node)
    return PICFLAG_ERRONEOUS;
  else if (!TREE_CONSTANT (init))
    {
      if (TREE_SIDE_EFFECTS (init))
	return PICFLAG_SIDE_EFFECTS;
      else
	return PICFLAG_NOT_ALL_CONSTANT;
    }
  else if (!initializer_constant_valid_p (init, TREE_TYPE (init)))
    return PICFLAG_NOT_ALL_SIMPLE;
  return 0;
}

/* Adjust INIT for going into a CONSTRUCTOR.  */

static tree
massage_init_elt (tree type, tree init, int nested, int flags,
		  tsubst_flags_t complain)
{
  int new_flags = LOOKUP_IMPLICIT;
  if (flags & LOOKUP_ALLOW_FLEXARRAY_INIT)
    new_flags |= LOOKUP_ALLOW_FLEXARRAY_INIT;
  if (flags & LOOKUP_AGGREGATE_PAREN_INIT)
    new_flags |= LOOKUP_AGGREGATE_PAREN_INIT;
  init = digest_init_r (type, init, nested ? 2 : 1, new_flags, complain);
  /* When we defer constant folding within a statement, we may want to
     defer this folding as well.  Don't call this on CONSTRUCTORs because
     their elements have already been folded, and we must avoid folding
     the result of get_nsdmi.  */
  if (TREE_CODE (init) != CONSTRUCTOR)
    {
      tree t = fold_non_dependent_init (init, complain);
      if (TREE_CONSTANT (t))
	init = t;
      set_target_expr_eliding (init);
    }
  return init;
}

/* Subroutine of process_init_constructor, which will process an initializer
   INIT for an array or vector of type TYPE. Returns the flags (PICFLAG_*)
   which describe the initializers.  */

static int
process_init_constructor_array (tree type, tree init, int nested, int flags,
				tsubst_flags_t complain)
{
  unsigned HOST_WIDE_INT i, len = 0;
  int picflags = 0;
  bool unbounded = false;
  constructor_elt *ce;
  vec<constructor_elt, va_gc> *v = CONSTRUCTOR_ELTS (init);

  gcc_assert (TREE_CODE (type) == ARRAY_TYPE
	      || VECTOR_TYPE_P (type));

  if (TREE_CODE (type) == ARRAY_TYPE)
    {
      /* C++ flexible array members have a null domain.  */
      tree domain = TYPE_DOMAIN (type);
      if (domain && TREE_CONSTANT (TYPE_MAX_VALUE (domain)))
	len = wi::ext (wi::to_offset (TYPE_MAX_VALUE (domain))
                       - wi::to_offset (TYPE_MIN_VALUE (domain)) + 1,
		       TYPE_PRECISION (TREE_TYPE (domain)),
		       TYPE_SIGN (TREE_TYPE (domain))).to_uhwi ();
      else
	unbounded = true;  /* Take as many as there are.  */

      if (nested == 2 && !domain && !vec_safe_is_empty (v))
	{
	  if (complain & tf_error)
	    error_at (cp_expr_loc_or_input_loc (init),
		      "initialization of flexible array member "
		      "in a nested context");
	  return PICFLAG_ERRONEOUS;
	}
    }
  else
    /* Vectors are like simple fixed-size arrays.  */
    unbounded = !TYPE_VECTOR_SUBPARTS (type).is_constant (&len);

  /* There must not be more initializers than needed.  */
  if (!unbounded && vec_safe_length (v) > len)
    {
      if (complain & tf_error)
	error ("too many initializers for %qT", type);
      else
	return PICFLAG_ERRONEOUS;
    }

  FOR_EACH_VEC_SAFE_ELT (v, i, ce)
    {
      if (!ce->index)
	ce->index = size_int (i);
      else if (!check_array_designated_initializer (ce, i))
	ce->index = error_mark_node;
      gcc_assert (ce->value);
      ce->value
	= massage_init_elt (TREE_TYPE (type), ce->value, nested, flags,
			    complain);

      gcc_checking_assert
	(ce->value == error_mark_node
	 || (same_type_ignoring_top_level_qualifiers_p
	     (strip_array_types (TREE_TYPE (type)),
	      strip_array_types (TREE_TYPE (ce->value)))));

      picflags |= picflag_from_initializer (ce->value);
      /* Propagate CONSTRUCTOR_PLACEHOLDER_BOUNDARY to outer
	 CONSTRUCTOR.  */
      if (TREE_CODE (ce->value) == CONSTRUCTOR
	  && CONSTRUCTOR_PLACEHOLDER_BOUNDARY (ce->value))
	{
	  CONSTRUCTOR_PLACEHOLDER_BOUNDARY (init) = 1;
	  CONSTRUCTOR_PLACEHOLDER_BOUNDARY (ce->value) = 0;
	}
    }

  /* No more initializers. If the array is unbounded, we are done. Otherwise,
     we must add initializers ourselves.  */
  if (!unbounded)
    for (; i < len; ++i)
      {
	tree next;

	if (type_build_ctor_call (TREE_TYPE (type)))
	  {
	    /* If this type needs constructors run for default-initialization,
	       we can't rely on the back end to do it for us, so make the
	       initialization explicit by list-initializing from T{}.  */
	    next = build_constructor (init_list_type_node, NULL);
	    next = massage_init_elt (TREE_TYPE (type), next, nested, flags,
				     complain);
	    if (initializer_zerop (next))
	      /* The default zero-initialization is fine for us; don't
		 add anything to the CONSTRUCTOR.  */
	      next = NULL_TREE;
	  }
	else if (!zero_init_p (TREE_TYPE (type)))
	  next = build_zero_init (TREE_TYPE (type),
				  /*nelts=*/NULL_TREE,
				  /*static_storage_p=*/false);
	else
	  /* The default zero-initialization is fine for us; don't
	     add anything to the CONSTRUCTOR.  */
	  next = NULL_TREE;

	if (next)
	  {
	    if (next != error_mark_node
		&& ! seen_error () // Improves error-recovery on anew5.C.
		&& (initializer_constant_valid_p (next, TREE_TYPE (next))
		    != null_pointer_node))
	      {
		/* Use VEC_INIT_EXPR for non-constant initialization of
		   trailing elements with no explicit initializers.  */
		picflags |= PICFLAG_VEC_INIT;
		break;
	      }

	    picflags |= picflag_from_initializer (next);
	    /* Propagate CONSTRUCTOR_PLACEHOLDER_BOUNDARY to outer
	       CONSTRUCTOR.  */
	    if (TREE_CODE (next) == CONSTRUCTOR
		&& CONSTRUCTOR_PLACEHOLDER_BOUNDARY (next))
	      {
		CONSTRUCTOR_PLACEHOLDER_BOUNDARY (init) = 1;
		CONSTRUCTOR_PLACEHOLDER_BOUNDARY (next) = 0;
	      }
	    if (len > i+1)
	      {
		tree range = build2 (RANGE_EXPR, size_type_node,
				     build_int_cst (size_type_node, i),
				     build_int_cst (size_type_node, len - 1));
		CONSTRUCTOR_APPEND_ELT (v, range, next);
		break;
	      }
	    else
	      CONSTRUCTOR_APPEND_ELT (v, size_int (i), next);
	  }
	else
	  /* Don't bother checking all the other elements.  */
	  break;
      }

  CONSTRUCTOR_ELTS (init) = v;
  return picflags;
}

/* Subroutine of process_init_constructor, which will process an initializer
   INIT for a class of type TYPE. Returns the flags (PICFLAG_*) which describe
   the initializers.  */

static int
process_init_constructor_record (tree type, tree init, int nested, int flags,
				 tsubst_flags_t complain)
{
  vec<constructor_elt, va_gc> *v = NULL;
  tree field;
  int skipped = 0;

  gcc_assert (TREE_CODE (type) == RECORD_TYPE);
  gcc_assert (!CLASSTYPE_VBASECLASSES (type));
  gcc_assert (!TYPE_BINFO (type)
	      || cxx_dialect >= cxx17
	      || !BINFO_N_BASE_BINFOS (TYPE_BINFO (type)));
  gcc_assert (!TYPE_POLYMORPHIC_P (type));

 restart:
  int picflags = 0;
  unsigned HOST_WIDE_INT idx = 0;
  int designator_skip = -1;
  /* Generally, we will always have an index for each initializer (which is
     a FIELD_DECL, put by reshape_init), but compound literals don't go trough
     reshape_init. So we need to handle both cases.  */
  for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
    {
      tree next;

      if (TREE_CODE (field) != FIELD_DECL
	  || (DECL_ARTIFICIAL (field)
	      && !(cxx_dialect >= cxx17 && DECL_FIELD_IS_BASE (field))))
	continue;

      if (DECL_UNNAMED_BIT_FIELD (field))
	continue;

      /* If this is a bitfield, first convert to the declared type.  */
      tree fldtype = TREE_TYPE (field);
      if (DECL_BIT_FIELD_TYPE (field))
	fldtype = DECL_BIT_FIELD_TYPE (field);
      if (fldtype == error_mark_node)
	return PICFLAG_ERRONEOUS;

      next = NULL_TREE;
      if (idx < CONSTRUCTOR_NELTS (init))
	{
	  constructor_elt *ce = &(*CONSTRUCTOR_ELTS (init))[idx];
	  if (ce->index)
	    {
	      /* We can have either a FIELD_DECL or an IDENTIFIER_NODE. The
		 latter case can happen in templates where lookup has to be
		 deferred.  */
	      gcc_assert (TREE_CODE (ce->index) == FIELD_DECL
			  || identifier_p (ce->index));
	      if (ce->index == field || ce->index == DECL_NAME (field))
		next = ce->value;
	      else
		{
		  ce = NULL;
		  if (designator_skip == -1)
		    designator_skip = 1;
		}
	    }
	  else
	    {
	      designator_skip = 0;
	      next = ce->value;
	    }

	  if (ce)
	    {
	      gcc_assert (ce->value);
	      next = massage_init_elt (fldtype, next, nested, flags, complain);
	      /* We can't actually elide the temporary when initializing a
		 potentially-overlapping field from a function that returns by
		 value.  */
	      if (ce->index
		  && TREE_CODE (next) == TARGET_EXPR
		  && unsafe_copy_elision_p (ce->index, next))
		TARGET_EXPR_ELIDING_P (next) = false;
	      ++idx;
	    }
	}
      if (next == error_mark_node)
	/* We skip initializers for empty bases/fields, so skipping an invalid
	   one could make us accept invalid code.  */
	return PICFLAG_ERRONEOUS;
      else if (next)
	/* Already handled above.  */;
      else if (DECL_INITIAL (field))
	{
	  if (skipped > 0)
	    {
	      /* We're using an NSDMI past a field with implicit
	         zero-init.  Go back and make it explicit.  */
	      skipped = -1;
	      vec_safe_truncate (v, 0);
	      goto restart;
	    }
	  /* C++14 aggregate NSDMI.  */
	  next = get_nsdmi (field, /*ctor*/false, complain);
	  if (!CONSTRUCTOR_PLACEHOLDER_BOUNDARY (init)
	      && find_placeholders (next))
	    CONSTRUCTOR_PLACEHOLDER_BOUNDARY (init) = 1;
	}
      else if (type_build_ctor_call (fldtype))
	{
	  /* If this type needs constructors run for
	     default-initialization, we can't rely on the back end to do it
	     for us, so build up TARGET_EXPRs.  If the type in question is
	     a class, just build one up; if it's an array, recurse.  */
	  next = build_constructor (init_list_type_node, NULL);
	  next = massage_init_elt (fldtype, next, nested, flags, complain);
	  if (TREE_CODE (next) == TARGET_EXPR
	      && unsafe_copy_elision_p (field, next))
	    TARGET_EXPR_ELIDING_P (next) = false;

	  /* Warn when some struct elements are implicitly initialized.  */
	  if ((complain & tf_warning)
	      && !cp_unevaluated_operand
	      && !EMPTY_CONSTRUCTOR_P (init))
	    warning (OPT_Wmissing_field_initializers,
		     "missing initializer for member %qD", field);
	}
      else
	{
	  if (TYPE_REF_P (fldtype))
	    {
	      if (complain & tf_error)
		error ("member %qD is uninitialized reference", field);
	      else
		return PICFLAG_ERRONEOUS;
	    }
	  else if (CLASSTYPE_REF_FIELDS_NEED_INIT (fldtype))
	    {
	      if (complain & tf_error)
		error ("member %qD with uninitialized reference fields", field);
	      else
		return PICFLAG_ERRONEOUS;
	    }
	  /* Do nothing for flexible array members since they need not have any
	     elements.  Don't worry about 'skipped' because a flexarray has to
	     be the last field.  */
	  else if (TREE_CODE (fldtype) == ARRAY_TYPE && !TYPE_DOMAIN (fldtype))
	    continue;

	  /* Warn when some struct elements are implicitly initialized
	     to zero.  */
	  if ((complain & tf_warning)
	      && !cp_unevaluated_operand
	      && !EMPTY_CONSTRUCTOR_P (init))
	    warning (OPT_Wmissing_field_initializers,
		     "missing initializer for member %qD", field);

	  if (!zero_init_p (fldtype) || skipped < 0)
	    {
	      if (TYPE_REF_P (fldtype))
		next = build_zero_cst (fldtype);
	      else
		next = build_zero_init (fldtype, /*nelts=*/NULL_TREE,
					/*static_storage_p=*/false);
	    }
	  else
	    {
	      /* The default zero-initialization is fine for us; don't
		 add anything to the CONSTRUCTOR.  */
	      skipped = 1;
	      continue;
	    }
	}

      if (is_empty_field (field)
	  && !TREE_SIDE_EFFECTS (next))
	/* Don't add trivial initialization of an empty base/field to the
	   constructor, as they might not be ordered the way the back-end
	   expects.  */
	continue;

      /* If this is a bitfield, now convert to the lowered type.  */
      if (fldtype != TREE_TYPE (field))
	next = cp_convert_and_check (TREE_TYPE (field), next, complain);
      picflags |= picflag_from_initializer (next);
      /* Propagate CONSTRUCTOR_PLACEHOLDER_BOUNDARY to outer CONSTRUCTOR.  */
      if (TREE_CODE (next) == CONSTRUCTOR
	  && CONSTRUCTOR_PLACEHOLDER_BOUNDARY (next))
	{
	  CONSTRUCTOR_PLACEHOLDER_BOUNDARY (init) = 1;
	  CONSTRUCTOR_PLACEHOLDER_BOUNDARY (next) = 0;
	}
      CONSTRUCTOR_APPEND_ELT (v, field, next);
    }

  if (idx < CONSTRUCTOR_NELTS (init))
    {
      if (complain & tf_error)
	{
	  constructor_elt *ce = &(*CONSTRUCTOR_ELTS (init))[idx];
	  /* For better diagnostics, try to find out if it is really
	     the case of too many initializers or if designators are
	     in incorrect order.  */
	  if (designator_skip == 1 && ce->index)
	    {
	      gcc_assert (TREE_CODE (ce->index) == FIELD_DECL
			  || identifier_p (ce->index));
	      for (field = TYPE_FIELDS (type);
		   field; field = DECL_CHAIN (field))
		{
		  if (TREE_CODE (field) != FIELD_DECL
		      || (DECL_ARTIFICIAL (field)
			  && !(cxx_dialect >= cxx17
			       && DECL_FIELD_IS_BASE (field))))
		    continue;

		  if (DECL_UNNAMED_BIT_FIELD (field))
		    continue;

		  if (ce->index == field || ce->index == DECL_NAME (field))
		    break;
		}
	    }
	  if (field)
	    error ("designator order for field %qD does not match declaration "
		   "order in %qT", field, type);
	  else
	    error ("too many initializers for %qT", type);
	}
      else
	return PICFLAG_ERRONEOUS;
    }

  CONSTRUCTOR_ELTS (init) = v;
  return picflags;
}

/* Subroutine of process_init_constructor, which will process a single
   initializer INIT for a union of type TYPE. Returns the flags (PICFLAG_*)
   which describe the initializer.  */

static int
process_init_constructor_union (tree type, tree init, int nested, int flags,
				tsubst_flags_t complain)
{
  constructor_elt *ce;
  int len;

  /* If the initializer was empty, use the union's NSDMI if it has one.
     Otherwise use default zero initialization.  */
  if (vec_safe_is_empty (CONSTRUCTOR_ELTS (init)))
    {
      for (tree field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
	{
	  if (TREE_CODE (field) == FIELD_DECL
	      && DECL_INITIAL (field) != NULL_TREE)
	    {
	      tree val = get_nsdmi (field, /*in_ctor=*/false, complain);
	      if (!CONSTRUCTOR_PLACEHOLDER_BOUNDARY (init)
		  && find_placeholders (val))
		CONSTRUCTOR_PLACEHOLDER_BOUNDARY (init) = 1;
	      CONSTRUCTOR_APPEND_ELT (CONSTRUCTOR_ELTS (init), field, val);
	      break;
	    }
	}

      if (vec_safe_is_empty (CONSTRUCTOR_ELTS (init)))
	return 0;
    }

  len = CONSTRUCTOR_ELTS (init)->length ();
  if (len > 1)
    {
      if (!(complain & tf_error))
	return PICFLAG_ERRONEOUS;
      error ("too many initializers for %qT", type);
      CONSTRUCTOR_ELTS (init)->block_remove (1, len-1);
    }

  ce = &(*CONSTRUCTOR_ELTS (init))[0];

  /* If this element specifies a field, initialize via that field.  */
  if (ce->index)
    {
      if (TREE_CODE (ce->index) == FIELD_DECL)
	;
      else if (identifier_p (ce->index))
	{
	  /* This can happen within a cast, see g++.dg/opt/cse2.C.  */
	  tree name = ce->index;
	  tree field;
	  for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
	    if (DECL_NAME (field) == name)
	      break;
	  if (!field)
	    {
	      if (complain & tf_error)
		error ("no field %qD found in union being initialized",
		       field);
	      ce->value = error_mark_node;
	    }
	  ce->index = field;
	}
      else
	{
	  gcc_assert (TREE_CODE (ce->index) == INTEGER_CST
		      || TREE_CODE (ce->index) == RANGE_EXPR);
	  if (complain & tf_error)
	    error ("index value instead of field name in union initializer");
	  ce->value = error_mark_node;
	}
    }
  else
    {
      /* Find the first named field.  ANSI decided in September 1990
	 that only named fields count here.  */
      tree field = TYPE_FIELDS (type);
      while (field && (!DECL_NAME (field) || TREE_CODE (field) != FIELD_DECL))
	field = TREE_CHAIN (field);
      if (field == NULL_TREE)
	{
	  if (complain & tf_error)
	    error ("too many initializers for %qT", type);
	  ce->value = error_mark_node;
	}
      ce->index = field;
    }

  if (ce->value && ce->value != error_mark_node)
    ce->value = massage_init_elt (TREE_TYPE (ce->index), ce->value, nested,
				  flags, complain);

  /* Propagate CONSTRUCTOR_PLACEHOLDER_BOUNDARY to outer CONSTRUCTOR.  */
  if (ce->value
      && TREE_CODE (ce->value) == CONSTRUCTOR
      && CONSTRUCTOR_PLACEHOLDER_BOUNDARY (ce->value))
    {
      CONSTRUCTOR_PLACEHOLDER_BOUNDARY (init) = 1;
      CONSTRUCTOR_PLACEHOLDER_BOUNDARY (ce->value) = 0;
    }
  return picflag_from_initializer (ce->value);
}

/* Process INIT, a constructor for a variable of aggregate type TYPE. The
   constructor is a brace-enclosed initializer, and will be modified in-place.

   Each element is converted to the right type through digest_init, and
   missing initializers are added following the language rules (zero-padding,
   etc.).

   After the execution, the initializer will have TREE_CONSTANT if all elts are
   constant, and TREE_STATIC set if, in addition, all elts are simple enough
   constants that the assembler and linker can compute them.

   The function returns the initializer itself, or error_mark_node in case
   of error.  */

static tree
process_init_constructor (tree type, tree init, int nested, int flags,
			  tsubst_flags_t complain)
{
  int picflags;

  gcc_assert (BRACE_ENCLOSED_INITIALIZER_P (init));

  if (TREE_CODE (type) == ARRAY_TYPE || VECTOR_TYPE_P (type))
    picflags = process_init_constructor_array (type, init, nested, flags,
					       complain);
  else if (TREE_CODE (type) == RECORD_TYPE)
    picflags = process_init_constructor_record (type, init, nested, flags,
						complain);
  else if (TREE_CODE (type) == UNION_TYPE)
    picflags = process_init_constructor_union (type, init, nested, flags,
					       complain);
  else
    gcc_unreachable ();

  if (picflags & PICFLAG_ERRONEOUS)
    return error_mark_node;

  TREE_TYPE (init) = type;
  if (TREE_CODE (type) == ARRAY_TYPE && TYPE_DOMAIN (type) == NULL_TREE)
    cp_complete_array_type (&TREE_TYPE (init), init, /*do_default=*/0);
  if (picflags & PICFLAG_SIDE_EFFECTS)
    {
      TREE_CONSTANT (init) = false;
      TREE_SIDE_EFFECTS (init) = true;
    }
  else if (picflags & PICFLAG_NOT_ALL_CONSTANT)
    {
      /* Make sure TREE_CONSTANT isn't set from build_constructor.  */
      TREE_CONSTANT (init) = false;
      TREE_SIDE_EFFECTS (init) = false;
    }
  else
    {
      TREE_CONSTANT (init) = 1;
      TREE_SIDE_EFFECTS (init) = false;
      if (!(picflags & PICFLAG_NOT_ALL_SIMPLE))
	TREE_STATIC (init) = 1;
    }
  if (picflags & PICFLAG_VEC_INIT)
    {
      /* Defer default-initialization of array elements with no corresponding
	 initializer-clause until later so we can use a loop.  */
      TREE_TYPE (init) = init_list_type_node;
      init = build_vec_init_expr (type, init, complain);
      init = get_target_expr (init);
    }
  return init;
}

/* Given a structure or union value DATUM, construct and return
   the structure or union component which results from narrowing
   that value to the base specified in BASETYPE.  For example, given the
   hierarchy

   class L { int ii; };
   class A : L { ... };
   class B : L { ... };
   class C : A, B { ... };

   and the declaration

   C x;

   then the expression

   x.A::ii refers to the ii member of the L part of
   the A part of the C object named by X.  In this case,
   DATUM would be x, and BASETYPE would be A.

   I used to think that this was nonconformant, that the standard specified
   that first we look up ii in A, then convert x to an L& and pull out the
   ii part.  But in fact, it does say that we convert x to an A&; A here
   is known as the "naming class".  (jason 2000-12-19)

   BINFO_P points to a variable initialized either to NULL_TREE or to the
   binfo for the specific base subobject we want to convert to.  */

tree
build_scoped_ref (tree datum, tree basetype, tree* binfo_p)
{
  tree binfo;

  if (datum == error_mark_node)
    return error_mark_node;
  if (*binfo_p)
    binfo = *binfo_p;
  else
    binfo = lookup_base (TREE_TYPE (datum), basetype, ba_check,
			 NULL, tf_warning_or_error);

  if (!binfo || binfo == error_mark_node)
    {
      *binfo_p = NULL_TREE;
      if (!binfo)
	error_not_base_type (basetype, TREE_TYPE (datum));
      return error_mark_node;
    }

  *binfo_p = binfo;
  return build_base_path (PLUS_EXPR, datum, binfo, 1,
			  tf_warning_or_error);
}

/* Build a reference to an object specified by the C++ `->' operator.
   Usually this just involves dereferencing the object, but if the
   `->' operator is overloaded, then such overloads must be
   performed until an object which does not have the `->' operator
   overloaded is found.  An error is reported when circular pointer
   delegation is detected.  */

tree
build_x_arrow (location_t loc, tree expr, tsubst_flags_t complain)
{
  tree orig_expr = expr;
  tree type = TREE_TYPE (expr);
  tree last_rval = NULL_TREE;
  vec<tree, va_gc> *types_memoized = NULL;

  if (type == error_mark_node)
    return error_mark_node;

  if (processing_template_decl)
    {
      tree ttype = NULL_TREE;
      if (type && TYPE_PTR_P (type))
	ttype = TREE_TYPE (type);
      if (ttype && !dependent_scope_p (ttype))
	/* Pointer to current instantiation, don't treat as dependent.  */;
      else if (type_dependent_expression_p (expr))
	{
	  expr = build_min_nt_loc (loc, ARROW_EXPR, expr);
	  TREE_TYPE (expr) = ttype;
	  return expr;
	}
      expr = build_non_dependent_expr (expr);
    }

  if (MAYBE_CLASS_TYPE_P (type))
    {
      struct tinst_level *actual_inst = current_instantiation ();
      tree fn = NULL;

      while ((expr = build_new_op (loc, COMPONENT_REF,
				   LOOKUP_NORMAL, expr, NULL_TREE, NULL_TREE,
				   NULL_TREE, &fn, complain)))
	{
	  if (expr == error_mark_node)
	    return error_mark_node;

	  /* This provides a better instantiation backtrace in case of
	     error.  */
	  if (fn && DECL_USE_TEMPLATE (fn))
	    push_tinst_level_loc (fn, 
				  (current_instantiation () != actual_inst)
				  ? DECL_SOURCE_LOCATION (fn)
				  : input_location);
	  fn = NULL;

	  if (vec_member (TREE_TYPE (expr), types_memoized))
	    {
	      if (complain & tf_error)
		error ("circular pointer delegation detected");
	      return error_mark_node;
	    }

	  vec_safe_push (types_memoized, TREE_TYPE (expr));
	  last_rval = expr;
	}

      while (current_instantiation () != actual_inst)
	pop_tinst_level ();

      if (last_rval == NULL_TREE)
	{
	  if (complain & tf_error)
	    error ("base operand of %<->%> has non-pointer type %qT", type);
	  return error_mark_node;
	}

      if (TYPE_REF_P (TREE_TYPE (last_rval)))
	last_rval = convert_from_reference (last_rval);
    }
  else
    {
      last_rval = decay_conversion (expr, complain);
      if (last_rval == error_mark_node)
	return error_mark_node;
    }

  if (TYPE_PTR_P (TREE_TYPE (last_rval)))
    {
      if (processing_template_decl)
	{
	  expr = build_min (ARROW_EXPR, TREE_TYPE (TREE_TYPE (last_rval)),
			    orig_expr);
	  TREE_SIDE_EFFECTS (expr) = TREE_SIDE_EFFECTS (last_rval);
	  return expr;
	}

      return cp_build_indirect_ref (loc, last_rval, RO_ARROW, complain);
    }

  if (complain & tf_error)
    {
      if (types_memoized)
	error ("result of %<operator->()%> yields non-pointer result");
      else
	error ("base operand of %<->%> is not a pointer");
    }
  return error_mark_node;
}

/* Return an expression for "DATUM .* COMPONENT".  DATUM has not
   already been checked out to be of aggregate type.  */

tree
build_m_component_ref (tree datum, tree component, tsubst_flags_t complain)
{
  tree ptrmem_type;
  tree objtype;
  tree type;
  tree binfo;
  tree ctype;

  datum = mark_lvalue_use (datum);
  component = mark_rvalue_use (component);

  if (error_operand_p (datum) || error_operand_p (component))
    return error_mark_node;

  ptrmem_type = TREE_TYPE (component);
  if (!TYPE_PTRMEM_P (ptrmem_type))
    {
      if (complain & tf_error)
	error ("%qE cannot be used as a member pointer, since it is of "
	       "type %qT", component, ptrmem_type);
      return error_mark_node;
    }

  objtype = TYPE_MAIN_VARIANT (TREE_TYPE (datum));
  if (! MAYBE_CLASS_TYPE_P (objtype))
    {
      if (complain & tf_error)
	error ("cannot apply member pointer %qE to %qE, which is of "
	       "non-class type %qT", component, datum, objtype);
      return error_mark_node;
    }

  type = TYPE_PTRMEM_POINTED_TO_TYPE (ptrmem_type);
  ctype = complete_type (TYPE_PTRMEM_CLASS_TYPE (ptrmem_type));

  if (!COMPLETE_TYPE_P (ctype))
    {
      if (!same_type_p (ctype, objtype))
	goto mismatch;
      binfo = NULL;
    }
  else
    {
      binfo = lookup_base (objtype, ctype, ba_check, NULL, complain);

      if (!binfo)
	{
	mismatch:
	  if (complain & tf_error)
	    error ("pointer to member type %qT incompatible with object "
		   "type %qT", type, objtype);
	  return error_mark_node;
	}
      else if (binfo == error_mark_node)
	return error_mark_node;
    }

  if (TYPE_PTRDATAMEM_P (ptrmem_type))
    {
      bool is_lval = real_lvalue_p (datum);
      tree ptype;

      /* Compute the type of the field, as described in [expr.ref].
	 There's no such thing as a mutable pointer-to-member, so
	 things are not as complex as they are for references to
	 non-static data members.  */
      type = cp_build_qualified_type (type,
				      (cp_type_quals (type)
				       | cp_type_quals (TREE_TYPE (datum))));

      datum = build_address (datum);

      /* Convert object to the correct base.  */
      if (binfo)
	{
	  datum = build_base_path (PLUS_EXPR, datum, binfo, 1, complain);
	  if (datum == error_mark_node)
	    return error_mark_node;
	}

      /* Build an expression for "object + offset" where offset is the
	 value stored in the pointer-to-data-member.  */
      ptype = build_pointer_type (type);
      datum = fold_build_pointer_plus (fold_convert (ptype, datum), component);
      datum = cp_build_fold_indirect_ref (datum);
      if (datum == error_mark_node)
	return error_mark_node;

      /* If the object expression was an rvalue, return an rvalue.  */
      if (!is_lval)
	datum = move (datum);
      return datum;
    }
  else
    {
      /* 5.5/6: In a .* expression whose object expression is an rvalue, the
	 program is ill-formed if the second operand is a pointer to member
	 function with ref-qualifier & (for C++20: unless its cv-qualifier-seq
	 is const). In a .* expression whose object expression is an lvalue,
	 the program is ill-formed if the second operand is a pointer to member
	 function with ref-qualifier &&.  */
      if (FUNCTION_REF_QUALIFIED (type))
	{
	  bool lval = lvalue_p (datum);
	  if (lval && FUNCTION_RVALUE_QUALIFIED (type))
	    {
	      if (complain & tf_error)
		error ("pointer-to-member-function type %qT requires an rvalue",
		       ptrmem_type);
	      return error_mark_node;
	    }
	  else if (!lval && !FUNCTION_RVALUE_QUALIFIED (type))
	    {
	      if ((type_memfn_quals (type)
		   & (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE))
		  != TYPE_QUAL_CONST)
		{
		  if (complain & tf_error)
		    error ("pointer-to-member-function type %qT requires "
			   "an lvalue", ptrmem_type);
		  return error_mark_node;
		}
	      else if (cxx_dialect < cxx20)
		{
		  if (complain & tf_warning_or_error)
		    pedwarn (input_location, OPT_Wpedantic,
			     "pointer-to-member-function type %qT requires "
			     "an lvalue before C++20", ptrmem_type);
		  else
		    return error_mark_node;
		}
	    }
	}
      return build2 (OFFSET_REF, type, datum, component);
    }
}

/* Return a tree node for the expression TYPENAME '(' PARMS ')'.  */

static tree
build_functional_cast_1 (location_t loc, tree exp, tree parms,
			 tsubst_flags_t complain)
{
  /* This is either a call to a constructor,
     or a C cast in C++'s `functional' notation.  */

  /* The type to which we are casting.  */
  tree type;

  if (error_operand_p (exp) || parms == error_mark_node)
    return error_mark_node;

  if (TREE_CODE (exp) == TYPE_DECL)
    {
      type = TREE_TYPE (exp);

      if (DECL_ARTIFICIAL (exp))
	cp_handle_deprecated_or_unavailable (type);
    }
  else
    type = exp;

  /* We need to check this explicitly, since value-initialization of
     arrays is allowed in other situations.  */
  if (TREE_CODE (type) == ARRAY_TYPE)
    {
      if (complain & tf_error)
	error_at (loc, "functional cast to array type %qT", type);
      return error_mark_node;
    }

  if (tree anode = type_uses_auto (type))
    {
      tree init;
      if (CLASS_PLACEHOLDER_TEMPLATE (anode))
	init = parms;
      /* C++23 auto(x).  */
      else if (!AUTO_IS_DECLTYPE (anode)
	       && list_length (parms) == 1)
	{
	  init = TREE_VALUE (parms);
	  if (is_constrained_auto (anode))
	    {
	      if (complain & tf_error)
		error_at (loc, "%<auto(x)%> cannot be constrained");
	      return error_mark_node;
	    }
	  else if (cxx_dialect < cxx23)
	    pedwarn (loc, OPT_Wc__23_extensions,
		     "%<auto(x)%> only available with "
		     "%<-std=c++2b%> or %<-std=gnu++2b%>");
	}
      else
	{
	  if (complain & tf_error)
	    error_at (loc, "invalid use of %qT", anode);
	  return error_mark_node;
	}
      type = do_auto_deduction (type, init, anode, complain,
				adc_variable_type);
      if (type == error_mark_node)
	return error_mark_node;
    }

  if (processing_template_decl)
    {
      tree t;

      /* Diagnose this even in a template.  We could also try harder
	 to give all the usual errors when the type and args are
	 non-dependent...  */
      if (TYPE_REF_P (type) && !parms)
	{
	  if (complain & tf_error)
	    error_at (loc, "invalid value-initialization of reference type");
	  return error_mark_node;
	}

      t = build_min (CAST_EXPR, type, parms);
      /* We don't know if it will or will not have side effects.  */
      TREE_SIDE_EFFECTS (t) = 1;
      return t;
    }

  if (! MAYBE_CLASS_TYPE_P (type))
    {
      if (parms == NULL_TREE)
	{
	  if (VOID_TYPE_P (type))
	    return void_node;
	  return build_value_init (cv_unqualified (type), complain);
	}

      /* This must build a C cast.  */
      parms = build_x_compound_expr_from_list (parms, ELK_FUNC_CAST, complain);
      return cp_build_c_cast (loc, type, parms, complain);
    }

  /* Prepare to evaluate as a call to a constructor.  If this expression
     is actually used, for example,

     return X (arg1, arg2, ...);

     then the slot being initialized will be filled in.  */

  if (!complete_type_or_maybe_complain (type, NULL_TREE, complain))
    return error_mark_node;
  if (abstract_virtuals_error (ACU_CAST, type, complain))
    return error_mark_node;

  /* [expr.type.conv]

     If the expression list is a single-expression, the type
     conversion is equivalent (in definedness, and if defined in
     meaning) to the corresponding cast expression.  */
  if (parms && TREE_CHAIN (parms) == NULL_TREE)
    return cp_build_c_cast (loc, type, TREE_VALUE (parms), complain);

  /* [expr.type.conv]

     The expression T(), where T is a simple-type-specifier for a
     non-array complete object type or the (possibly cv-qualified)
     void type, creates an rvalue of the specified type, which is
     value-initialized.  */

  if (parms == NULL_TREE)
    {
      exp = build_value_init (type, complain);
      exp = get_target_expr (exp, complain);
      return exp;
    }

  /* Call the constructor.  */
  releasing_vec parmvec;
  for (; parms != NULL_TREE; parms = TREE_CHAIN (parms))
    vec_safe_push (parmvec, TREE_VALUE (parms));
  exp = build_special_member_call (NULL_TREE, complete_ctor_identifier,
				   &parmvec, type, LOOKUP_NORMAL, complain);

  if (exp == error_mark_node)
    return error_mark_node;

  return build_cplus_new (type, exp, complain);
}

tree
build_functional_cast (location_t loc, tree exp, tree parms,
		       tsubst_flags_t complain)
{
  tree result = build_functional_cast_1 (loc, exp, parms, complain);
  protected_set_expr_location (result, loc);
  return result;  
}


/* Add new exception specifier SPEC, to the LIST we currently have.
   If it's already in LIST then do nothing.
   Moan if it's bad and we're allowed to. COMPLAIN < 0 means we
   know what we're doing.  */

tree
add_exception_specifier (tree list, tree spec, tsubst_flags_t complain)
{
  bool ok;
  tree core = spec;
  bool is_ptr;
  diagnostic_t diag_type = DK_UNSPECIFIED; /* none */

  if (spec == error_mark_node)
    return list;

  gcc_assert (spec && (!list || TREE_VALUE (list)));

  /* [except.spec] 1, type in an exception specifier shall not be
     incomplete, or pointer or ref to incomplete other than pointer
     to cv void.  */
  is_ptr = TYPE_PTR_P (core);
  if (is_ptr || TYPE_REF_P (core))
    core = TREE_TYPE (core);
  if (complain < 0)
    ok = true;
  else if (VOID_TYPE_P (core))
    ok = is_ptr;
  else if (TREE_CODE (core) == TEMPLATE_TYPE_PARM)
    ok = true;
  else if (processing_template_decl)
    ok = true;
  else if (!verify_type_context (input_location, TCTX_EXCEPTIONS, core,
				 !(complain & tf_error)))
    return error_mark_node;
  else
    {
      ok = true;
      /* 15.4/1 says that types in an exception specifier must be complete,
	 but it seems more reasonable to only require this on definitions
	 and calls.  So just give a pedwarn at this point; we will give an
	 error later if we hit one of those two cases.  */
      if (!COMPLETE_TYPE_P (complete_type (core)))
	diag_type = DK_PEDWARN; /* pedwarn */
    }

  if (ok)
    {
      tree probe;

      for (probe = list; probe; probe = TREE_CHAIN (probe))
	if (same_type_p (TREE_VALUE (probe), spec))
	  break;
      if (!probe)
	list = tree_cons (NULL_TREE, spec, list);
    }
  else
    diag_type = DK_ERROR; /* error */

  if (diag_type != DK_UNSPECIFIED
      && (complain & tf_warning_or_error))
    cxx_incomplete_type_diagnostic (NULL_TREE, core, diag_type);

  return list;
}

/* Like nothrow_spec_p, but don't abort on deferred noexcept.  */

static bool
nothrow_spec_p_uninst (const_tree spec)
{
  if (DEFERRED_NOEXCEPT_SPEC_P (spec))
    return false;
  return nothrow_spec_p (spec);
}

/* Combine the two exceptions specifier lists LIST and ADD, and return
   their union.  */

tree
merge_exception_specifiers (tree list, tree add)
{
  tree noex, orig_list;

  if (list == error_mark_node || add == error_mark_node)
    return error_mark_node;

  /* No exception-specifier or noexcept(false) are less strict than
     anything else.  Prefer the newer variant (LIST).  */
  if (!list || list == noexcept_false_spec)
    return list;
  else if (!add || add == noexcept_false_spec)
    return add;

  /* noexcept(true) and throw() are stricter than anything else.
     As above, prefer the more recent one (LIST).  */
  if (nothrow_spec_p_uninst (add))
    return list;

  /* Two implicit noexcept specs (e.g. on a destructor) are equivalent.  */
  if (UNEVALUATED_NOEXCEPT_SPEC_P (add)
      && UNEVALUATED_NOEXCEPT_SPEC_P (list))
    return list;
  /* We should have instantiated other deferred noexcept specs by now.  */
  gcc_assert (!DEFERRED_NOEXCEPT_SPEC_P (add));

  if (nothrow_spec_p_uninst (list))
    return add;
  noex = TREE_PURPOSE (list);
  gcc_checking_assert (!TREE_PURPOSE (add)
		       || errorcount || !flag_exceptions
		       || cp_tree_equal (noex, TREE_PURPOSE (add)));

  /* Combine the dynamic-exception-specifiers, if any.  */
  orig_list = list;
  for (; add && TREE_VALUE (add); add = TREE_CHAIN (add))
    {
      tree spec = TREE_VALUE (add);
      tree probe;

      for (probe = orig_list; probe && TREE_VALUE (probe);
	   probe = TREE_CHAIN (probe))
	if (same_type_p (TREE_VALUE (probe), spec))
	  break;
      if (!probe)
	{
	  spec = build_tree_list (NULL_TREE, spec);
	  TREE_CHAIN (spec) = list;
	  list = spec;
	}
    }

  /* Keep the noexcept-specifier at the beginning of the list.  */
  if (noex != TREE_PURPOSE (list))
    list = tree_cons (noex, TREE_VALUE (list), TREE_CHAIN (list));

  return list;
}

/* Subroutine of build_call.  Ensure that each of the types in the
   exception specification is complete.  Technically, 15.4/1 says that
   they need to be complete when we see a declaration of the function,
   but we should be able to get away with only requiring this when the
   function is defined or called.  See also add_exception_specifier.  */

void
require_complete_eh_spec_types (tree fntype, tree decl)
{
  tree raises;
  /* Don't complain about calls to op new.  */
  if (decl && DECL_ARTIFICIAL (decl))
    return;
  for (raises = TYPE_RAISES_EXCEPTIONS (fntype); raises;
       raises = TREE_CHAIN (raises))
    {
      tree type = TREE_VALUE (raises);
      if (type && !COMPLETE_TYPE_P (type))
	{
	  if (decl)
	    error
	      ("call to function %qD which throws incomplete type %q#T",
	       decl, type);
	  else
	    error ("call to function which throws incomplete type %q#T",
		   decl);
	}
    }
}

/* Record that any TARGET_EXPR in T are going to be elided in
   cp_gimplify_init_expr (or sooner).  */

void
set_target_expr_eliding (tree t)
{
  if (!t)
    return;
  switch (TREE_CODE (t))
    {
    case TARGET_EXPR:
      TARGET_EXPR_ELIDING_P (t) = true;
      break;
    case COMPOUND_EXPR:
      set_target_expr_eliding (TREE_OPERAND (t, 1));
      break;
    case COND_EXPR:
      set_target_expr_eliding (TREE_OPERAND (t, 1));
      set_target_expr_eliding (TREE_OPERAND (t, 2));
      break;

    default:
      break;
    }
}

/* Call the above in the process of building an INIT_EXPR.  */

tree
cp_build_init_expr (location_t loc, tree target, tree init)
{
  set_target_expr_eliding (init);
  tree ie = build2_loc (loc, INIT_EXPR, TREE_TYPE (target),
			target, init);
  TREE_SIDE_EFFECTS (ie) = true;
  return ie;
}
