/* Handle the hair of processing (but not expanding) inline functions.
   Also manage function and variable name overloading.
   Copyright (C) 1987-2022 Free Software Foundation, Inc.
   Contributed 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/>.  */


/* Handle method declarations.  */
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "target.h"
#include "cp-tree.h"
#include "stringpool.h"
#include "cgraph.h"
#include "varasm.h"
#include "toplev.h"
#include "intl.h"
#include "common/common-target.h"

static void do_build_copy_assign (tree);
static void do_build_copy_constructor (tree);
static tree make_alias_for_thunk (tree);

/* Called once to initialize method.cc.  */

void
init_method (void)
{
  init_mangle ();
}

/* Return a this or result adjusting thunk to FUNCTION.  THIS_ADJUSTING
   indicates whether it is a this or result adjusting thunk.
   FIXED_OFFSET and VIRTUAL_OFFSET indicate how to do the adjustment
   (see thunk_adjust).  VIRTUAL_OFFSET can be NULL, but FIXED_OFFSET
   never is.  VIRTUAL_OFFSET is the /index/ into the vtable for this
   adjusting thunks, we scale it to a byte offset. For covariant
   thunks VIRTUAL_OFFSET is the virtual binfo.  You must post process
   the returned thunk with finish_thunk.  */

tree
make_thunk (tree function, bool this_adjusting,
	    tree fixed_offset, tree virtual_offset)
{
  HOST_WIDE_INT d;
  tree thunk;

  gcc_assert (TREE_CODE (function) == FUNCTION_DECL);
  /* We can have this thunks to covariant thunks, but not vice versa.  */
  gcc_assert (!DECL_THIS_THUNK_P (function));
  gcc_assert (!DECL_RESULT_THUNK_P (function) || this_adjusting);

  /* Scale the VIRTUAL_OFFSET to be in terms of bytes.  */
  if (this_adjusting && virtual_offset)
    virtual_offset
      = size_binop (MULT_EXPR,
		    virtual_offset,
		    convert (ssizetype,
			     TYPE_SIZE_UNIT (vtable_entry_type)));

  d = tree_to_shwi (fixed_offset);

  /* See if we already have the thunk in question.  For this_adjusting
     thunks VIRTUAL_OFFSET will be an INTEGER_CST, for covariant thunks it
     will be a BINFO.  */
  for (thunk = DECL_THUNKS (function); thunk; thunk = DECL_CHAIN (thunk))
    if (DECL_THIS_THUNK_P (thunk) == this_adjusting
	&& THUNK_FIXED_OFFSET (thunk) == d
	&& !virtual_offset == !THUNK_VIRTUAL_OFFSET (thunk)
	&& (!virtual_offset
	    || (this_adjusting
		? tree_int_cst_equal (THUNK_VIRTUAL_OFFSET (thunk),
				      virtual_offset)
		: THUNK_VIRTUAL_OFFSET (thunk) == virtual_offset)))
      return thunk;

  /* All thunks must be created before FUNCTION is actually emitted;
     the ABI requires that all thunks be emitted together with the
     function to which they transfer control.  */
  gcc_assert (!TREE_ASM_WRITTEN (function));
  /* Likewise, we can only be adding thunks to a function declared in
     the class currently being laid out.  */
  gcc_assert (TYPE_SIZE (DECL_CONTEXT (function))
	      && TYPE_BEING_DEFINED (DECL_CONTEXT (function)));

  thunk = build_decl (DECL_SOURCE_LOCATION (function),
		      FUNCTION_DECL, NULL_TREE, TREE_TYPE (function));
  DECL_LANG_SPECIFIC (thunk) = DECL_LANG_SPECIFIC (function);
  cxx_dup_lang_specific_decl (thunk);
  DECL_VIRTUAL_P (thunk) = true;
  SET_DECL_THUNKS (thunk, NULL_TREE);

  DECL_CONTEXT (thunk) = DECL_CONTEXT (function);
  TREE_READONLY (thunk) = TREE_READONLY (function);
  TREE_THIS_VOLATILE (thunk) = TREE_THIS_VOLATILE (function);
  TREE_PUBLIC (thunk) = TREE_PUBLIC (function);
  SET_DECL_THUNK_P (thunk, this_adjusting);
  THUNK_TARGET (thunk) = function;
  THUNK_FIXED_OFFSET (thunk) = d;
  THUNK_VIRTUAL_OFFSET (thunk) = virtual_offset;
  THUNK_ALIAS (thunk) = NULL_TREE;

  DECL_INTERFACE_KNOWN (thunk) = 1;
  DECL_NOT_REALLY_EXTERN (thunk) = 1;
  DECL_COMDAT (thunk) = DECL_COMDAT (function);
  DECL_SAVED_AUTO_RETURN_TYPE (thunk) = NULL;
  /* The thunk itself is not a constructor or destructor, even if
     the thing it is thunking to is.  */
  DECL_CXX_DESTRUCTOR_P (thunk) = 0;
  DECL_CXX_CONSTRUCTOR_P (thunk) = 0;
  DECL_EXTERNAL (thunk) = 1;
  DECL_ARTIFICIAL (thunk) = 1;
  /* The THUNK is not a pending inline, even if the FUNCTION is.  */
  DECL_PENDING_INLINE_P (thunk) = 0;
  DECL_DECLARED_INLINE_P (thunk) = 0;
  /* Nor is it a template instantiation.  */
  DECL_USE_TEMPLATE (thunk) = 0;
  DECL_TEMPLATE_INFO (thunk) = NULL;

  /* Add it to the list of thunks associated with FUNCTION.  */
  DECL_CHAIN (thunk) = DECL_THUNKS (function);
  SET_DECL_THUNKS (function, thunk);

  return thunk;
}

/* Finish THUNK, a thunk decl.  */

void
finish_thunk (tree thunk)
{
  tree function, name;
  tree fixed_offset = ssize_int (THUNK_FIXED_OFFSET (thunk));
  tree virtual_offset = THUNK_VIRTUAL_OFFSET (thunk);

  gcc_assert (!DECL_NAME (thunk) && DECL_THUNK_P (thunk));
  if (virtual_offset && DECL_RESULT_THUNK_P (thunk))
    virtual_offset = BINFO_VPTR_FIELD (virtual_offset);
  function = THUNK_TARGET (thunk);
  name = mangle_thunk (function, DECL_THIS_THUNK_P (thunk),
		       fixed_offset, virtual_offset, thunk);

  /* We can end up with declarations of (logically) different
     covariant thunks, that do identical adjustments.  The two thunks
     will be adjusting between within different hierarchies, which
     happen to have the same layout.  We must nullify one of them to
     refer to the other.  */
  if (DECL_RESULT_THUNK_P (thunk))
    {
      tree cov_probe;

      for (cov_probe = DECL_THUNKS (function);
	   cov_probe; cov_probe = DECL_CHAIN (cov_probe))
	if (DECL_NAME (cov_probe) == name)
	  {
	    gcc_assert (!DECL_THUNKS (thunk));
	    THUNK_ALIAS (thunk) = (THUNK_ALIAS (cov_probe)
				   ? THUNK_ALIAS (cov_probe) : cov_probe);
	    break;
	  }
    }

  DECL_NAME (thunk) = name;
  SET_DECL_ASSEMBLER_NAME (thunk, name);
}

static GTY (()) int thunk_labelno;

/* Create a static alias to target.  */

tree
make_alias_for (tree target, tree newid)
{
  tree alias = build_decl (DECL_SOURCE_LOCATION (target),
			   TREE_CODE (target), newid, TREE_TYPE (target));
  DECL_LANG_SPECIFIC (alias) = DECL_LANG_SPECIFIC (target);
  cxx_dup_lang_specific_decl (alias);
  DECL_CONTEXT (alias) = DECL_CONTEXT (target);
  TREE_READONLY (alias) = TREE_READONLY (target);
  TREE_THIS_VOLATILE (alias) = TREE_THIS_VOLATILE (target);
  TREE_PUBLIC (alias) = 0;
  DECL_INTERFACE_KNOWN (alias) = 1;
  if (DECL_LANG_SPECIFIC (alias))
    {
      DECL_NOT_REALLY_EXTERN (alias) = 1;
      DECL_USE_TEMPLATE (alias) = 0;
      DECL_TEMPLATE_INFO (alias) = NULL;
    }
  DECL_EXTERNAL (alias) = 0;
  DECL_ARTIFICIAL (alias) = 1;
  DECL_TEMPLATE_INSTANTIATED (alias) = 0;
  if (TREE_CODE (alias) == FUNCTION_DECL)
    {
      DECL_SAVED_AUTO_RETURN_TYPE (alias) = NULL;
      DECL_CXX_DESTRUCTOR_P (alias) = 0;
      DECL_CXX_CONSTRUCTOR_P (alias) = 0;
      DECL_PENDING_INLINE_P (alias) = 0;
      DECL_DECLARED_INLINE_P (alias) = 0;
      DECL_INITIAL (alias) = error_mark_node;
      DECL_ARGUMENTS (alias) = copy_list (DECL_ARGUMENTS (target));
    }
  else
    TREE_STATIC (alias) = 1;
  TREE_ADDRESSABLE (alias) = 1;
  TREE_USED (alias) = 1;
  SET_DECL_ASSEMBLER_NAME (alias, DECL_NAME (alias));
  return alias;
}

static tree
make_alias_for_thunk (tree function)
{
  tree alias;
  char buf[256];

  targetm.asm_out.generate_internal_label (buf, "LTHUNK", thunk_labelno);
  thunk_labelno++;

  alias = make_alias_for (function, get_identifier (buf));

  if (!flag_syntax_only)
    {
      struct cgraph_node *funcn, *aliasn;
      funcn = cgraph_node::get (function);
      gcc_checking_assert (funcn);
      aliasn = cgraph_node::create_same_body_alias (alias, function);
      DECL_ASSEMBLER_NAME (function);
      gcc_assert (aliasn != NULL);
    }

  return alias;
}

/* Emit the definition of a C++ multiple inheritance or covariant
   return vtable thunk.  If EMIT_P is nonzero, the thunk is emitted
   immediately.  */

void
use_thunk (tree thunk_fndecl, bool emit_p)
{
  tree a, t, function, alias;
  tree virtual_offset;
  HOST_WIDE_INT fixed_offset, virtual_value;
  bool this_adjusting = DECL_THIS_THUNK_P (thunk_fndecl);
  struct cgraph_node *funcn, *thunk_node;

  /* We should have called finish_thunk to give it a name.  */
  gcc_assert (DECL_NAME (thunk_fndecl));

  /* We should never be using an alias, always refer to the
     aliased thunk.  */
  gcc_assert (!THUNK_ALIAS (thunk_fndecl));

  if (TREE_ASM_WRITTEN (thunk_fndecl))
    return;

  function = THUNK_TARGET (thunk_fndecl);
  if (DECL_RESULT (thunk_fndecl))
    /* We already turned this thunk into an ordinary function.
       There's no need to process this thunk again.  */
    return;

  if (DECL_THUNK_P (function))
    /* The target is itself a thunk, process it now.  */
    use_thunk (function, emit_p);

  /* Thunks are always addressable; they only appear in vtables.  */
  TREE_ADDRESSABLE (thunk_fndecl) = 1;

  /* Figure out what function is being thunked to.  It's referenced in
     this translation unit.  */
  TREE_ADDRESSABLE (function) = 1;
  mark_used (function);
  if (!emit_p)
    return;

  if (TARGET_USE_LOCAL_THUNK_ALIAS_P (function))
   alias = make_alias_for_thunk (function);
  else
   alias = function;

  fixed_offset = THUNK_FIXED_OFFSET (thunk_fndecl);
  virtual_offset = THUNK_VIRTUAL_OFFSET (thunk_fndecl);

  if (virtual_offset)
    {
      if (!this_adjusting)
	virtual_offset = BINFO_VPTR_FIELD (virtual_offset);
      virtual_value = tree_to_shwi (virtual_offset);
      gcc_assert (virtual_value);
    }
  else
    virtual_value = 0;

  /* And, if we need to emit the thunk, it's used.  */
  mark_used (thunk_fndecl);
  /* This thunk is actually defined.  */
  DECL_EXTERNAL (thunk_fndecl) = 0;
  /* The linkage of the function may have changed.  FIXME in linkage
     rewrite.  */
  gcc_assert (DECL_INTERFACE_KNOWN (function));
  TREE_PUBLIC (thunk_fndecl) = TREE_PUBLIC (function);
  DECL_VISIBILITY (thunk_fndecl) = DECL_VISIBILITY (function);
  DECL_VISIBILITY_SPECIFIED (thunk_fndecl)
    = DECL_VISIBILITY_SPECIFIED (function);
  DECL_COMDAT (thunk_fndecl) = DECL_COMDAT (function);
  DECL_WEAK (thunk_fndecl) = DECL_WEAK (function);

  if (flag_syntax_only)
    {
      TREE_ASM_WRITTEN (thunk_fndecl) = 1;
      return;
    }

  push_to_top_level ();

  if (TARGET_USE_LOCAL_THUNK_ALIAS_P (function)
      && targetm_common.have_named_sections)
    {
      tree fn = function;
      struct symtab_node *symbol;

      if ((symbol = symtab_node::get (function))
	  && symbol->alias)
	{
	  if (symbol->analyzed)
	    fn = symtab_node::get (function)->ultimate_alias_target ()->decl;
	  else
	    fn = symtab_node::get (function)->alias_target;
	}
      resolve_unique_section (fn, 0, flag_function_sections);

      if (DECL_SECTION_NAME (fn) != NULL && DECL_ONE_ONLY (fn))
	{
	  resolve_unique_section (thunk_fndecl, 0, flag_function_sections);

	  /* Output the thunk into the same section as function.  */
	  set_decl_section_name (thunk_fndecl, fn);
	  symtab_node::get (thunk_fndecl)->implicit_section
	    = symtab_node::get (fn)->implicit_section;
	}
    }

  /* Set up cloned argument trees for the thunk.  */
  t = NULL_TREE;
  for (a = DECL_ARGUMENTS (function); a; a = DECL_CHAIN (a))
    {
      tree x = copy_node (a);
      DECL_CHAIN (x) = t;
      DECL_CONTEXT (x) = thunk_fndecl;
      SET_DECL_RTL (x, NULL);
      DECL_HAS_VALUE_EXPR_P (x) = 0;
      TREE_ADDRESSABLE (x) = 0;
      t = x;
    }
  a = nreverse (t);
  DECL_ARGUMENTS (thunk_fndecl) = a;
  TREE_ASM_WRITTEN (thunk_fndecl) = 1;
  funcn = cgraph_node::get (function);
  gcc_checking_assert (funcn);
  thunk_node = funcn->create_thunk (thunk_fndecl, function,
				    this_adjusting, fixed_offset, virtual_value,
				    0, virtual_offset, alias);
  if (DECL_ONE_ONLY (function))
    thunk_node->add_to_same_comdat_group (funcn);

  pop_from_top_level ();
}

/* Code for synthesizing methods which have default semantics defined.  */

/* True iff CTYPE has a trivial SFK.  */

static bool
type_has_trivial_fn (tree ctype, special_function_kind sfk)
{
  switch (sfk)
    {
    case sfk_constructor:
      return !TYPE_HAS_COMPLEX_DFLT (ctype);
    case sfk_copy_constructor:
      return !TYPE_HAS_COMPLEX_COPY_CTOR (ctype);
    case sfk_move_constructor:
      return !TYPE_HAS_COMPLEX_MOVE_CTOR (ctype);
    case sfk_copy_assignment:
      return !TYPE_HAS_COMPLEX_COPY_ASSIGN (ctype);
    case sfk_move_assignment:
      return !TYPE_HAS_COMPLEX_MOVE_ASSIGN (ctype);
    case sfk_destructor:
    case sfk_virtual_destructor:
      return !TYPE_HAS_NONTRIVIAL_DESTRUCTOR (ctype);
    case sfk_inheriting_constructor:
    case sfk_comparison:
      return false;
    default:
      gcc_unreachable ();
    }
}

/* Note that CTYPE has a non-trivial SFK even though we previously thought
   it was trivial.  */

static void
type_set_nontrivial_flag (tree ctype, special_function_kind sfk)
{
  switch (sfk)
    {
    case sfk_constructor:
      TYPE_HAS_COMPLEX_DFLT (ctype) = true;
      return;
    case sfk_copy_constructor:
      TYPE_HAS_COMPLEX_COPY_CTOR (ctype) = true;
      return;
    case sfk_move_constructor:
      TYPE_HAS_COMPLEX_MOVE_CTOR (ctype) = true;
      return;
    case sfk_copy_assignment:
      TYPE_HAS_COMPLEX_COPY_ASSIGN (ctype) = true;
      return;
    case sfk_move_assignment:
      TYPE_HAS_COMPLEX_MOVE_ASSIGN (ctype) = true;
      return;
    case sfk_destructor:
      TYPE_HAS_NONTRIVIAL_DESTRUCTOR (ctype) = true;
      return;
    case sfk_inheriting_constructor:
    default:
      gcc_unreachable ();
    }
}

/* True iff FN is a trivial defaulted member function ([cd]tor, op=).  */

bool
trivial_fn_p (tree fn)
{
  if (TREE_CODE (fn) == TEMPLATE_DECL)
    return false;
  if (!DECL_DEFAULTED_FN (fn))
    return false;

  /* If fn is a clone, get the primary variant.  */
  if (tree prim = DECL_CLONED_FUNCTION (fn))
    fn = prim;
  return type_has_trivial_fn (DECL_CONTEXT (fn), special_function_p (fn));
}

/* PARM is a PARM_DECL for a function which we want to forward to another
   function without changing its value category, a la std::forward.  */

tree
forward_parm (tree parm)
{
  tree exp = convert_from_reference (parm);
  tree type = TREE_TYPE (parm);
  if (DECL_PACK_P (parm))
    type = PACK_EXPANSION_PATTERN (type);
  if (!TYPE_REF_P (type))
    type = cp_build_reference_type (type, /*rval=*/true);
  warning_sentinel w (warn_useless_cast);
  exp = build_static_cast (input_location, type, exp,
			   tf_warning_or_error);
  if (DECL_PACK_P (parm))
    exp = make_pack_expansion (exp);
  return exp;
}

/* Strip all inheriting constructors, if any, to return the original
   constructor from a (possibly indirect) base class.  */

tree
strip_inheriting_ctors (tree dfn)
{
  if (!flag_new_inheriting_ctors)
    return dfn;
  tree fn = dfn;
  while (tree inh = DECL_INHERITED_CTOR (fn))
    fn = OVL_FIRST (inh);

  if (TREE_CODE (fn) == TEMPLATE_DECL
      && TREE_CODE (dfn) == FUNCTION_DECL)
    fn = DECL_TEMPLATE_RESULT (fn);
  return fn;
}

/* Find the binfo for the base subobject of BINFO being initialized by
   inherited constructor FNDECL (a member of a direct base of BINFO).  */

static tree inherited_ctor_binfo (tree, tree);
static tree
inherited_ctor_binfo_1 (tree binfo, tree fndecl)
{
  tree base = DECL_CONTEXT (fndecl);
  tree base_binfo;
  for (int i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
    if (BINFO_TYPE (base_binfo) == base)
      return inherited_ctor_binfo (base_binfo, fndecl);

  gcc_unreachable();
}

/* Find the binfo for the base subobject of BINFO being initialized by
   inheriting constructor FNDECL (a member of BINFO), or BINFO if FNDECL is not
   an inheriting constructor.  */

static tree
inherited_ctor_binfo (tree binfo, tree fndecl)
{
  tree inh = DECL_INHERITED_CTOR (fndecl);
  if (!inh)
    return binfo;

  tree results = NULL_TREE;
  for (ovl_iterator iter (inh); iter; ++iter)
    {
      tree one = inherited_ctor_binfo_1 (binfo, *iter);
      if (!results)
	results = one;
      else if (one != results)
	results = tree_cons (NULL_TREE, one, results);
    }
  return results;
}

/* Find the binfo for the base subobject being initialized by inheriting
   constructor FNDECL, or NULL_TREE if FNDECL is not an inheriting
   constructor.  */

tree
inherited_ctor_binfo (tree fndecl)
{
  if (!DECL_INHERITED_CTOR (fndecl))
    return NULL_TREE;
  tree binfo = TYPE_BINFO (DECL_CONTEXT (fndecl));
  return inherited_ctor_binfo (binfo, fndecl);
}


/* True if we should omit all user-declared parameters from a base
   construtor built from complete constructor FN.
   That's when the ctor is inherited from a virtual base.  */

bool
base_ctor_omit_inherited_parms (tree comp_ctor)
{
  gcc_checking_assert (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (comp_ctor));

  if (!flag_new_inheriting_ctors)
    /* We only optimize away the parameters in the new model.  */
    return false;

  if (!CLASSTYPE_VBASECLASSES (DECL_CONTEXT (comp_ctor)))
    return false;

  if (FUNCTION_FIRST_USER_PARMTYPE (comp_ctor) == void_list_node)
    /* No user-declared parameters to omit.  */
    return false;

  for (tree binfo = inherited_ctor_binfo (comp_ctor);
       binfo;
       binfo = BINFO_INHERITANCE_CHAIN (binfo))
    if (BINFO_VIRTUAL_P (binfo))
      return true;

  return false;
}


/* True if we should omit all user-declared parameters from constructor FN,
   because it is a base clone of a ctor inherited from a virtual base.  */

bool
ctor_omit_inherited_parms (tree fn)
{
  gcc_checking_assert (TREE_CODE (fn) == FUNCTION_DECL);

  if (!DECL_BASE_CONSTRUCTOR_P (fn))
    return false;

  return base_ctor_omit_inherited_parms (DECL_CLONED_FUNCTION (fn));
}

/* True iff constructor(s) INH inherited into BINFO initializes INIT_BINFO.
   This can be true for multiple virtual bases as well as one direct
   non-virtual base.  */

static bool
binfo_inherited_from (tree binfo, tree init_binfo, tree inh)
{
  /* inh is an OVERLOAD if we inherited the same constructor along
     multiple paths, check all of them.  */
  for (ovl_iterator iter (inh); iter; ++iter)
    {
      tree fn = *iter;
      tree base = DECL_CONTEXT (fn);
      tree base_binfo = NULL_TREE;
      for (int i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
	if (BINFO_TYPE (base_binfo) == base)
	  break;
      if (base_binfo == init_binfo
	  || (flag_new_inheriting_ctors
	      && binfo_inherited_from (base_binfo, init_binfo,
				       DECL_INHERITED_CTOR (fn))))
	return true;
    }
  return false;
}

/* Subroutine of do_build_copy_constructor: Add a mem-initializer for BINFO
   given the parameter or parameters PARM, possibly inherited constructor
   base INH, or move flag MOVE_P.  */

static tree
add_one_base_init (tree binfo, tree parm, bool move_p, tree inh,
		   tree member_init_list)
{
  tree init;
  if (inh)
    {
      /* An inheriting constructor only has a mem-initializer for
	 the base it inherits from.  */
      if (!binfo_inherited_from (TYPE_BINFO (current_class_type), binfo, inh))
	return member_init_list;

      tree *p = &init;
      init = NULL_TREE;
      for (; parm; parm = DECL_CHAIN (parm))
	{
	  tree exp = forward_parm (parm);
	  *p = build_tree_list (NULL_TREE, exp);
	  p = &TREE_CHAIN (*p);
	}
    }
  else
    {
      init = build_base_path (PLUS_EXPR, parm, binfo, 1,
			      tf_warning_or_error);
      if (move_p)
	init = move (init);
      init = build_tree_list (NULL_TREE, init);
    }
  return tree_cons (binfo, init, member_init_list);
}

/* Generate code for default X(X&) or X(X&&) constructor or an inheriting
   constructor.  */

static void
do_build_copy_constructor (tree fndecl)
{
  tree parm = FUNCTION_FIRST_USER_PARM (fndecl);
  bool move_p = DECL_MOVE_CONSTRUCTOR_P (fndecl);
  bool trivial = trivial_fn_p (fndecl);
  tree inh = DECL_INHERITED_CTOR (fndecl);

  if (!inh)
    parm = convert_from_reference (parm);

  if (trivial)
    {
      if (is_empty_class (current_class_type))
	/* Don't copy the padding byte; it might not have been allocated
	   if *this is a base subobject.  */;
      else if (tree_int_cst_equal (TYPE_SIZE (current_class_type),
				   CLASSTYPE_SIZE (current_class_type)))
	{
	  tree t = cp_build_init_expr (current_class_ref, parm);
	  finish_expr_stmt (t);
	}
      else
	{
	  /* We must only copy the non-tail padding parts.  */
	  tree base_size = CLASSTYPE_SIZE_UNIT (current_class_type);
	  base_size = size_binop (MINUS_EXPR, base_size, size_int (1));
	  tree array_type = build_array_type (unsigned_char_type_node,
					      build_index_type (base_size));
	  tree alias_set = build_int_cst (TREE_TYPE (current_class_ptr), 0);
	  tree lhs = build2 (MEM_REF, array_type,
			     current_class_ptr, alias_set);
	  tree rhs = build2 (MEM_REF, array_type,
			     TREE_OPERAND (parm, 0), alias_set);
	  tree t = cp_build_init_expr (lhs, rhs);
	  finish_expr_stmt (t);
	}
    }
  else
    {
      tree member_init_list = NULL_TREE;
      int i;
      tree binfo, base_binfo;
      vec<tree, va_gc> *vbases;

      /* Initialize all the base-classes with the parameter converted
	 to their type so that we get their copy constructor and not
	 another constructor that takes current_class_type.  We must
	 deal with the binfo's directly as a direct base might be
	 inaccessible due to ambiguity.  */
      for (vbases = CLASSTYPE_VBASECLASSES (current_class_type), i = 0;
	   vec_safe_iterate (vbases, i, &binfo); i++)
	{
	  member_init_list = add_one_base_init (binfo, parm, move_p, inh,
						member_init_list);
	}

      for (binfo = TYPE_BINFO (current_class_type), i = 0;
	   BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
	{
	  if (BINFO_VIRTUAL_P (base_binfo))
	    continue;
	  member_init_list = add_one_base_init (base_binfo, parm, move_p,
						inh, member_init_list);
	}

      if (!inh)
	{
	  int cvquals = cp_type_quals (TREE_TYPE (parm));

	  for (tree fields = TYPE_FIELDS (current_class_type);
	       fields; fields = DECL_CHAIN (fields))
	    {
	      tree field = fields;
	      tree expr_type;

	      if (TREE_CODE (field) != FIELD_DECL)
		continue;

	      expr_type = TREE_TYPE (field);
	      if (DECL_NAME (field))
		{
		  if (VFIELD_NAME_P (DECL_NAME (field)))
		    continue;
		}
	      else if (ANON_AGGR_TYPE_P (expr_type) && TYPE_FIELDS (expr_type))
		/* Just use the field; anonymous types can't have
		   nontrivial copy ctors or assignment ops or this
		   function would be deleted.  */;
	      else
		continue;

	      /* Compute the type of "init->field".  If the copy-constructor
		 parameter is, for example, "const S&", and the type of
		 the field is "T", then the type will usually be "const
		 T".  (There are no cv-qualified variants of reference
		 types.)  */
	      if (!TYPE_REF_P (expr_type))
		{
		  int quals = cvquals;

		  if (DECL_MUTABLE_P (field))
		    quals &= ~TYPE_QUAL_CONST;
		  quals |= cp_type_quals (expr_type);
		  expr_type = cp_build_qualified_type (expr_type, quals);
		}

	      tree init = build3 (COMPONENT_REF, expr_type, parm, field, NULL_TREE);
	      if (move_p && !TYPE_REF_P (expr_type)
		  /* 'move' breaks bit-fields, and has no effect for scalars.  */
		  && !scalarish_type_p (expr_type))
		init = move (init);
	      init = build_tree_list (NULL_TREE, init);

	      member_init_list = tree_cons (field, init, member_init_list);
	    }
	}

      finish_mem_initializers (member_init_list);
    }
}

static void
do_build_copy_assign (tree fndecl)
{
  tree parm = DECL_CHAIN (DECL_ARGUMENTS (fndecl));
  tree compound_stmt;
  bool move_p = move_fn_p (fndecl);
  bool trivial = trivial_fn_p (fndecl);
  int flags = LOOKUP_NORMAL | LOOKUP_NONVIRTUAL | LOOKUP_DEFAULTED;

  compound_stmt = begin_compound_stmt (0);
  parm = convert_from_reference (parm);

  if (trivial
      && is_empty_class (current_class_type))
    /* Don't copy the padding byte; it might not have been allocated
       if *this is a base subobject.  */;
  else if (trivial)
    {
      tree t = build2 (MODIFY_EXPR, void_type_node, current_class_ref, parm);
      finish_expr_stmt (t);
    }
  else
    {
      tree fields;
      int cvquals = cp_type_quals (TREE_TYPE (parm));
      int i;
      tree binfo, base_binfo;

      /* Assign to each of the direct base classes.  */
      for (binfo = TYPE_BINFO (current_class_type), i = 0;
	   BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
	{
	  tree converted_parm;

	  /* We must convert PARM directly to the base class
	     explicitly since the base class may be ambiguous.  */
	  converted_parm = build_base_path (PLUS_EXPR, parm, base_binfo, 1,
					    tf_warning_or_error);
	  if (move_p)
	    converted_parm = move (converted_parm);
	  /* Call the base class assignment operator.  */
	  releasing_vec parmvec (make_tree_vector_single (converted_parm));
	  finish_expr_stmt
	    (build_special_member_call (current_class_ref,
					assign_op_identifier,
					&parmvec,
					base_binfo,
					flags,
                                        tf_warning_or_error));
	}

      /* Assign to each of the non-static data members.  */
      for (fields = TYPE_FIELDS (current_class_type);
	   fields;
	   fields = DECL_CHAIN (fields))
	{
	  tree comp = current_class_ref;
	  tree init = parm;
	  tree field = fields;
	  tree expr_type;
	  int quals;

	  if (TREE_CODE (field) != FIELD_DECL || DECL_ARTIFICIAL (field))
	    continue;

	  expr_type = TREE_TYPE (field);

	  if (CP_TYPE_CONST_P (expr_type))
	    {
	      error ("non-static const member %q#D, cannot use default "
		     "assignment operator", field);
	      continue;
	    }
	  else if (TYPE_REF_P (expr_type))
	    {
	      error ("non-static reference member %q#D, cannot use "
		     "default assignment operator", field);
	      continue;
	    }

	  if (DECL_NAME (field))
	    {
	      if (VFIELD_NAME_P (DECL_NAME (field)))
		continue;
	    }
	  else if (ANON_AGGR_TYPE_P (expr_type)
		   && TYPE_FIELDS (expr_type) != NULL_TREE)
	    /* Just use the field; anonymous types can't have
	       nontrivial copy ctors or assignment ops or this
	       function would be deleted.  */;
	  else
	    continue;

	  comp = build3 (COMPONENT_REF, expr_type, comp, field, NULL_TREE);

	  /* Compute the type of init->field  */
	  quals = cvquals;
	  if (DECL_MUTABLE_P (field))
	    quals &= ~TYPE_QUAL_CONST;
	  expr_type = cp_build_qualified_type (expr_type, quals);

	  init = build3 (COMPONENT_REF, expr_type, init, field, NULL_TREE);
	  if (move_p && !TYPE_REF_P (expr_type)
	      /* 'move' breaks bit-fields, and has no effect for scalars.  */
	      && !scalarish_type_p (expr_type))
	    init = move (init);

	  if (DECL_NAME (field))
	    init = cp_build_modify_expr (input_location, comp, NOP_EXPR, init,
					 tf_warning_or_error);
	  else
	    init = build2 (MODIFY_EXPR, TREE_TYPE (comp), comp, init);
	  finish_expr_stmt (init);
	}
    }
  finish_return_stmt (current_class_ref);
  finish_compound_stmt (compound_stmt);
}

/* C++20 <compare> comparison category types.  */

enum comp_cat_tag
{
  cc_partial_ordering,
  cc_weak_ordering,
  cc_strong_ordering,
  cc_last
};

/* Names of the comparison categories and their value members, to be indexed by
   comp_cat_tag enumerators.  genericize_spaceship below relies on the ordering
   of the members.  */

struct comp_cat_info_t
{
  const char *name;
  const char *members[4];
};
static const comp_cat_info_t comp_cat_info[cc_last]
= {
   { "partial_ordering", { "equivalent", "greater", "less", "unordered" } },
   { "weak_ordering", { "equivalent", "greater", "less" } },
   { "strong_ordering", { "equal", "greater", "less" } }
};

/* A cache of the category types to speed repeated lookups.  */

static GTY((deletable)) tree comp_cat_cache[cc_last];

/* Look up one of the result variables in the comparison category type.  */

static tree
lookup_comparison_result (tree type, const char *name_str,
			  tsubst_flags_t complain = tf_warning_or_error)
{
  tree name = get_identifier (name_str);
  tree decl = lookup_qualified_name (type, name);
  if (TREE_CODE (decl) != VAR_DECL)
    {
      if (complain & tf_error)
	{
	  auto_diagnostic_group d;
	  if (decl == error_mark_node || TREE_CODE (decl) == TREE_LIST)
	    qualified_name_lookup_error (type, name, decl, input_location);
	  else
	    error ("%qD is not a static data member", decl);
	  inform (input_location, "determining value of %qs", "operator<=>");
	}
      return error_mark_node;
    }
  return decl;
}

/* Look up a <compare> comparison category type in std.  */

static tree
lookup_comparison_category (comp_cat_tag tag,
			    tsubst_flags_t complain = tf_warning_or_error)
{
  if (tree cached = comp_cat_cache[tag])
    return cached;

  tree name = get_identifier (comp_cat_info[tag].name);
  tree decl = lookup_qualified_name (std_node, name);
  if (TREE_CODE (decl) != TYPE_DECL)
    {
      if (complain & tf_error)
	{
	  auto_diagnostic_group d;
	  if (decl == error_mark_node || TREE_CODE (decl) == TREE_LIST)
	    qualified_name_lookup_error (std_node, name, decl, input_location);
	  else
	    error ("%qD is not a type", decl);
	  inform (input_location, "forming type of %qs", "operator<=>");
	}
      return error_mark_node;
    }
  /* Also make sure we can look up the value members now, since we won't
     really use them until genericize time.  */
  tree type = TREE_TYPE (decl);
  for (int i = 0; i < 4; ++i)
    {
      const char *p = comp_cat_info[tag].members[i];
      if (!p) break;
      if (lookup_comparison_result (type, p, complain)
	  == error_mark_node)
	return error_mark_node;
    }
  return comp_cat_cache[tag] = type;
}

/* Wrapper that takes the tag rather than the type.  */

static tree
lookup_comparison_result (comp_cat_tag tag, const char *name_str,
			  tsubst_flags_t complain = tf_warning_or_error)
{
  tree type = lookup_comparison_category (tag, complain);
  return lookup_comparison_result (type, name_str, complain);
}

/* Wrapper that takes the index into the members array instead of the name.  */

static tree
lookup_comparison_result (comp_cat_tag tag, tree type, int idx)
{
  const char *name_str = comp_cat_info[tag].members[idx];
  if (!name_str)
    return NULL_TREE;
  return lookup_comparison_result (type, name_str);
}

/* Does TYPE correspond to TAG?  */

static bool
is_cat (tree type, comp_cat_tag tag)
{
  tree name = TYPE_LINKAGE_IDENTIFIER (type);
  return id_equal (name, comp_cat_info[tag].name);
}

/* Return the comp_cat_tag for TYPE.  */

static comp_cat_tag
cat_tag_for (tree type)
{
  if (!CLASS_TYPE_P (type) || !decl_in_std_namespace_p (TYPE_MAIN_DECL (type)))
    return cc_last;
  for (int i = 0; i < cc_last; ++i)
    {
      comp_cat_tag tag = (comp_cat_tag)i;
      if (is_cat (type, tag))
	return tag;
    }
  return cc_last;
}

/* Return the comparison category tag of a <=> expression with non-class type
   OPTYPE.  */

static comp_cat_tag
spaceship_comp_cat (tree optype)
{
  if (INTEGRAL_OR_ENUMERATION_TYPE_P (optype) || TYPE_PTROBV_P (optype))
    return cc_strong_ordering;
  else if (TREE_CODE (optype) == REAL_TYPE)
    return cc_partial_ordering;

  /* ??? should vector <=> produce a vector of one of the above?  */
  gcc_unreachable ();
}

/* Return the comparison category type of a <=> expression with non-class type
   OPTYPE.  */

tree
spaceship_type (tree optype, tsubst_flags_t complain)
{
  comp_cat_tag tag = spaceship_comp_cat (optype);
  return lookup_comparison_category (tag, complain);
}

/* Turn <=> with type TYPE and operands OP0 and OP1 into GENERIC.
   This is also used by build_comparison_op for fallback to op< and op==
   in a defaulted op<=>.  */

tree
genericize_spaceship (location_t loc, tree type, tree op0, tree op1)
{
  /* ??? maybe optimize based on knowledge of representation? */
  comp_cat_tag tag = cat_tag_for (type);

  if (tag == cc_last && is_auto (type))
    {
      /* build_comparison_op is checking to see if we want to suggest changing
	 the op<=> return type from auto to a specific comparison category; any
	 category will do for now.  */
      tag = cc_strong_ordering;
      type = lookup_comparison_category (tag, tf_none);
      if (type == error_mark_node)
	return error_mark_node;
    }

  gcc_checking_assert (tag < cc_last);

  tree r;
  bool scalar = SCALAR_TYPE_P (TREE_TYPE (op0));
  if (scalar)
    {
      op0 = save_expr (op0);
      op1 = save_expr (op1);
    }

  tree gt = lookup_comparison_result (tag, type, 1);

  int flags = LOOKUP_NORMAL;
  tsubst_flags_t complain = tf_none;
  tree comp;

  if (tag == cc_partial_ordering)
    {
      /* op0 == op1 ? equivalent : op0 < op1 ? less :
	 op1 < op0 ? greater : unordered */
      tree uo = lookup_comparison_result (tag, type, 3);
      if (scalar)
	{
	  /* For scalars use the low level operations; using build_new_op causes
	     trouble with constexpr eval in the middle of genericize (100367).  */
	  comp = fold_build2 (LT_EXPR, boolean_type_node, op1, op0);
	  r = fold_build3 (COND_EXPR, type, comp, gt, uo);
	}
      else
	{
	  comp = build_new_op (loc, LT_EXPR, flags, op1, op0, complain);
	  r = build_conditional_expr (loc, comp, gt, uo, complain);
	}
    }
  else
    /* op0 == op1 ? equal : op0 < op1 ? less : greater */
    r = gt;

  tree lt = lookup_comparison_result (tag, type, 2);
  if (scalar)
    {
      comp = fold_build2 (LT_EXPR, boolean_type_node, op0, op1);
      r = fold_build3 (COND_EXPR, type, comp, lt, r);
    }
  else
    {
      comp = build_new_op (loc, LT_EXPR, flags, op0, op1, complain);
      r = build_conditional_expr (loc, comp, lt, r, complain);
    }

  tree eq = lookup_comparison_result (tag, type, 0);
  if (scalar)
    {
      comp = fold_build2 (EQ_EXPR, boolean_type_node, op0, op1);
      r = fold_build3 (COND_EXPR, type, comp, eq, r);
    }
  else
    {
      comp = build_new_op (loc, EQ_EXPR, flags, op0, op1, complain);
      r = build_conditional_expr (loc, comp, eq, r, complain);
    }

  return r;
}

/* Check that the signature of a defaulted comparison operator is
   well-formed.  */

static bool
early_check_defaulted_comparison (tree fn)
{
  location_t loc = DECL_SOURCE_LOCATION (fn);
  tree ctx;
  if (DECL_CLASS_SCOPE_P (fn))
    ctx = DECL_CONTEXT (fn);
  else
    ctx = DECL_FRIEND_CONTEXT (fn);
  bool ok = true;

  if (cxx_dialect < cxx20)
    {
      error_at (loc, "defaulted %qD only available with %<-std=c++20%> or "
		     "%<-std=gnu++20%>", fn);
      return false;
    }

  if (!DECL_OVERLOADED_OPERATOR_IS (fn, SPACESHIP_EXPR)
      && !same_type_p (TREE_TYPE (TREE_TYPE (fn)), boolean_type_node))
    {
      diagnostic_t kind = DK_UNSPECIFIED;
      int opt = 0;
      if (is_auto (TREE_TYPE (fn)))
	kind = DK_PEDWARN;
      else
	kind = DK_ERROR;
      emit_diagnostic (kind, loc, opt,
		       "defaulted %qD must return %<bool%>", fn);
      if (kind == DK_ERROR)
	ok = false;
    }

  bool mem = DECL_NONSTATIC_MEMBER_FUNCTION_P (fn);
  if (mem && type_memfn_quals (TREE_TYPE (fn)) != TYPE_QUAL_CONST)
    {
      error_at (loc, "defaulted %qD must be %<const%>", fn);
      ok = false;
    }
  if (mem && type_memfn_rqual (TREE_TYPE (fn)) == REF_QUAL_RVALUE)
    {
      error_at (loc, "defaulted %qD must not have %<&&%> ref-qualifier", fn);
      ok = false;
    }
  tree parmnode = FUNCTION_FIRST_USER_PARMTYPE (fn);
  bool saw_byval = false;
  bool saw_byref = mem;
  bool saw_bad = false;
  for (; parmnode != void_list_node; parmnode = TREE_CHAIN (parmnode))
    {
      tree parmtype = TREE_VALUE (parmnode);
      if (CLASS_TYPE_P (parmtype))
	saw_byval = true;
      else if (TREE_CODE (parmtype) == REFERENCE_TYPE
	       && !TYPE_REF_IS_RVALUE (parmtype)
	       && TYPE_QUALS (TREE_TYPE (parmtype)) == TYPE_QUAL_CONST)
	{
	  saw_byref = true;
	  parmtype = TREE_TYPE (parmtype);
	}
      else
	saw_bad = true;

      if (!saw_bad && !ctx)
	{
	  /* Defaulted outside the class body.  */
	  ctx = TYPE_MAIN_VARIANT (parmtype);
	  if (!is_friend (ctx, fn))
	    error_at (loc, "defaulted %qD is not a friend of %qT", fn, ctx);
	}
      else if (!same_type_ignoring_top_level_qualifiers_p (parmtype, ctx))
	saw_bad = true;
    }

  if (saw_bad || (saw_byval && saw_byref))
    {
      if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fn))
	error_at (loc, "defaulted member %qD must have parameter type "
		  "%<const %T&%>", fn, ctx);
      else if (saw_bad)
	error_at (loc, "defaulted %qD must have parameters of either type "
		  "%<const %T&%> or %qT", fn, ctx, ctx);
      else
	error_at (loc, "defaulted %qD must have parameters of either type "
		  "%<const %T&%> or %qT, not both", fn, ctx, ctx);
      ok = false;
    }

  /* We still need to deduce deleted/constexpr/noexcept and maybe return. */
  DECL_MAYBE_DELETED (fn) = ok;

  return ok;
}

/* Subroutine of build_comparison_op.  Given the vec of memberwise
   comparisons COMPS, calculate the overall comparison category for
   operator<=>.  */

static tree
common_comparison_type (vec<tree> &comps)
{
  tree seen[cc_last] = {};

  for (unsigned i = 0; i < comps.length(); ++i)
    {
      tree comp = comps[i];
      if (TREE_CODE (comp) == TREE_LIST)
	comp = TREE_VALUE (comp);
      tree ctype = TREE_TYPE (comp);
      comp_cat_tag tag = cat_tag_for (ctype);
      /* build_comparison_op already checked this.  */
      gcc_checking_assert (tag < cc_last);
      seen[tag] = ctype;
    }

  /* Otherwise, if at least one T i is std::partial_ordering, U is
     std::partial_ordering.  */
  if (tree t = seen[cc_partial_ordering]) return t;

  /* Otherwise, if at least one T i is std::weak_ordering, U is
     std::weak_ordering.  */
  if (tree t = seen[cc_weak_ordering]) return t;

  /* Otherwise, U is std::strong_ordering.  */
  if (tree t = seen[cc_strong_ordering]) return t;
  return lookup_comparison_category (cc_strong_ordering);
}

/* Data structure for build_comparison_op.  */

struct comp_info
{
  tree fndecl;
  location_t loc;
  tsubst_flags_t complain;
  tree_code code;
  comp_cat_tag retcat;
  bool first_time;
  bool constexp;
  bool was_constexp;
  bool noex;

  comp_info (tree fndecl, tsubst_flags_t complain)
    : fndecl (fndecl), complain (complain)
  {
    loc = DECL_SOURCE_LOCATION (fndecl);

    first_time = DECL_MAYBE_DELETED (fndecl);
    DECL_MAYBE_DELETED (fndecl) = false;

    /* Do we want to try to set constexpr?  */
    was_constexp = DECL_DECLARED_CONSTEXPR_P (fndecl);
    constexp = first_time;
    if (constexp)
      /* Set this for var_in_constexpr_fn.  */
      DECL_DECLARED_CONSTEXPR_P (fndecl) = true;

    /* Do we want to try to set noexcept?  */
    noex = first_time;
    if (noex)
      {
	tree raises = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fndecl));
	if (raises && !UNEVALUATED_NOEXCEPT_SPEC_P (raises))
	  /* There was an explicit exception-specification.  */
	  noex = false;
      }
  }

  /* EXPR is an expression built as part of the function body.
     Adjust the properties appropriately.  */
  void check (tree expr)
  {
    if (expr == error_mark_node)
      DECL_DELETED_FN (fndecl) = true;
    if ((constexp || was_constexp)
	&& !potential_rvalue_constant_expression (expr))
      {
	if (was_constexp)
	  require_potential_rvalue_constant_expression_fncheck (expr);
	else
	  constexp = false;
      }
    if (noex && !expr_noexcept_p (expr, tf_none))
      noex = false;
  }

  ~comp_info ()
  {
    if (first_time)
      {
	DECL_DECLARED_CONSTEXPR_P (fndecl) = constexp || was_constexp;
	tree raises = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fndecl));
	if (!raises || UNEVALUATED_NOEXCEPT_SPEC_P (raises))
	  {
	    raises = noex ? noexcept_true_spec : noexcept_false_spec;
	    TREE_TYPE (fndecl) = build_exception_variant (TREE_TYPE (fndecl),
							  raises);
	  }
      }
  }
};

/* Subroutine of build_comparison_op, to compare a single subobject.  */

static tree
do_one_comp (location_t loc, const comp_info &info, tree sub, tree lhs, tree rhs)
{
  const tree_code code = info.code;
  const tree fndecl = info.fndecl;
  const comp_cat_tag retcat = info.retcat;
  const tsubst_flags_t complain = info.complain;

  tree overload = NULL_TREE;
  int flags = LOOKUP_NORMAL | LOOKUP_NONVIRTUAL | LOOKUP_DEFAULTED;
  /* If we have an explicit comparison category return type we can fall back
     to </=, so don't give an error yet if <=> lookup fails.  */
  bool tentative = retcat != cc_last;
  tree comp = build_new_op (loc, code, flags, lhs, rhs,
			    NULL_TREE, NULL_TREE, &overload,
			    tentative ? tf_none : complain);

  if (code != SPACESHIP_EXPR)
    return comp;

  tree rettype = TREE_TYPE (TREE_TYPE (fndecl));

  if (comp == error_mark_node)
    {
      if (overload == NULL_TREE && (tentative || complain))
	{
	  /* No viable <=>, try using op< and op==.  */
	  tree lteq = genericize_spaceship (loc, rettype, lhs, rhs);
	  if (lteq != error_mark_node)
	    {
	      /* We found usable < and ==.  */
	      if (retcat != cc_last)
		/* Return type is a comparison category, use them.  */
		comp = lteq;
	      else if (complain & tf_error)
		/* Return type is auto, suggest changing it.  */
		inform (info.loc, "changing the return type from %qs "
			"to a comparison category type will allow the "
			"comparison to use %qs and %qs", "auto",
			"operator<", "operator==");
	    }
	  else if (tentative && complain)
	    /* No usable < and ==, give an error for op<=>.  */
	    build_new_op (loc, code, flags, lhs, rhs, complain);
	}
      if (comp == error_mark_node)
	return error_mark_node;
    }

  if (FNDECL_USED_AUTO (fndecl)
      && cat_tag_for (TREE_TYPE (comp)) == cc_last)
    {
      /* The operator function is defined as deleted if ... Ri is not a
	 comparison category type.  */
      if (complain & tf_error)
	inform (loc,
		"three-way comparison of %qD has type %qT, not a "
		"comparison category type", sub, TREE_TYPE (comp));
      return error_mark_node;
    }
  else if (!FNDECL_USED_AUTO (fndecl)
	   && !can_convert (rettype, TREE_TYPE (comp), complain))
    {
      if (complain & tf_error)
	error_at (loc,
		  "three-way comparison of %qD has type %qT, which "
		  "does not convert to %qT",
		  sub, TREE_TYPE (comp), rettype);
      return error_mark_node;
    }

  return comp;
}

/* Build up the definition of a defaulted comparison operator.  Unlike other
   defaulted functions that use synthesized_method_walk to determine whether
   the function is e.g. deleted, for comparisons we use the same code.  We try
   to use synthesize_method at the earliest opportunity and bail out if the
   function ends up being deleted.  */

void
build_comparison_op (tree fndecl, bool defining, tsubst_flags_t complain)
{
  comp_info info (fndecl, complain);

  if (!defining && !(complain & tf_error) && !DECL_MAYBE_DELETED (fndecl))
    return;

  int flags = LOOKUP_NORMAL;
  const ovl_op_info_t *op = IDENTIFIER_OVL_OP_INFO (DECL_NAME (fndecl));
  tree_code code = info.code = op->tree_code;

  tree lhs = DECL_ARGUMENTS (fndecl);
  tree rhs = DECL_CHAIN (lhs);
  if (is_this_parameter (lhs))
    lhs = cp_build_fold_indirect_ref (lhs);
  else
    lhs = convert_from_reference (lhs);
  rhs = convert_from_reference (rhs);
  tree ctype = TYPE_MAIN_VARIANT (TREE_TYPE (lhs));
  gcc_assert (!defining || COMPLETE_TYPE_P (ctype));

  iloc_sentinel ils (info.loc);

  /* A defaulted comparison operator function for class C is defined as
     deleted if ... C has variant members.  */
  if (TREE_CODE (ctype) == UNION_TYPE
      && next_aggregate_field (TYPE_FIELDS (ctype)))
    {
      if (complain & tf_error)
	inform (info.loc, "cannot default compare union %qT", ctype);
      DECL_DELETED_FN (fndecl) = true;
      return;
    }

  tree compound_stmt = NULL_TREE;
  if (defining)
    compound_stmt = begin_compound_stmt (0);
  else
    ++cp_unevaluated_operand;

  tree rettype = TREE_TYPE (TREE_TYPE (fndecl));
  if (code != SPACESHIP_EXPR && is_auto (rettype))
    {
      rettype = boolean_type_node;
      apply_deduced_return_type (fndecl, rettype);
    }

  if (code == EQ_EXPR || code == SPACESHIP_EXPR)
    {
      comp_cat_tag &retcat = (info.retcat = cc_last);
      if (code == SPACESHIP_EXPR && !FNDECL_USED_AUTO (fndecl))
	retcat = cat_tag_for (rettype);

      bool bad = false;
      auto_vec<tree> comps;

      /* Compare the base subobjects.  We handle them this way, rather than in
	 the field loop below, because maybe_instantiate_noexcept might bring
	 us here before we've built the base fields.  */
      for (tree base_binfo : BINFO_BASE_BINFOS (TYPE_BINFO (ctype)))
	{
	  tree lhs_base
	    = build_base_path (PLUS_EXPR, lhs, base_binfo, 0, complain);
	  tree rhs_base
	    = build_base_path (PLUS_EXPR, rhs, base_binfo, 0, complain);

	  location_t loc = DECL_SOURCE_LOCATION (TYPE_MAIN_DECL (ctype));
	  tree comp = do_one_comp (loc, info, BINFO_TYPE (base_binfo),
				   lhs_base, rhs_base);
	  if (comp == error_mark_node)
	    {
	      bad = true;
	      continue;
	    }

	  comps.safe_push (comp);
	}

      /* Now compare the field subobjects.  */
      for (tree field = next_aggregate_field (TYPE_FIELDS (ctype));
	   field;
	   field = next_aggregate_field (DECL_CHAIN (field)))
	{
	  if (DECL_VIRTUAL_P (field) || DECL_FIELD_IS_BASE (field))
	    /* We ignore the vptr, and we already handled bases.  */
	    continue;

	  tree expr_type = TREE_TYPE (field);

	  location_t field_loc = DECL_SOURCE_LOCATION (field);

	  /* A defaulted comparison operator function for class C is defined as
	     deleted if any non-static data member of C is of reference type or
	     C has variant members.  */
	  if (TREE_CODE (expr_type) == REFERENCE_TYPE)
	    {
	      if (complain & tf_error)
		inform (field_loc, "cannot default compare "
			"reference member %qD", field);
	      bad = true;
	      continue;
	    }
	  else if (ANON_UNION_TYPE_P (expr_type)
		   && next_aggregate_field (TYPE_FIELDS (expr_type)))
	    {
	      if (complain & tf_error)
		inform (field_loc, "cannot default compare "
			"anonymous union member");
	      bad = true;
	      continue;
	    }

	  tree lhs_mem = build3_loc (field_loc, COMPONENT_REF, expr_type, lhs,
				     field, NULL_TREE);
	  tree rhs_mem = build3_loc (field_loc, COMPONENT_REF, expr_type, rhs,
				     field, NULL_TREE);
	  tree loop_indexes = NULL_TREE;
	  while (TREE_CODE (expr_type) == ARRAY_TYPE)
	    {
	      /* Flexible array member.  */
	      if (TYPE_DOMAIN (expr_type) == NULL_TREE
		  || TYPE_MAX_VALUE (TYPE_DOMAIN (expr_type)) == NULL_TREE)
		{
		  if (complain & tf_error)
		    inform (field_loc, "cannot default compare "
				       "flexible array member");
		  bad = true;
		  break;
		}
	      tree maxval = TYPE_MAX_VALUE (TYPE_DOMAIN (expr_type));
	      /* [0] array.  No subobjects to compare, just skip it.  */
	      if (integer_all_onesp (maxval))
		break;
	      tree idx;
	      /* [1] array, no loop needed, just add [0] ARRAY_REF.
		 Similarly if !defining.  */
	      if (integer_zerop (maxval) || !defining)
		idx = size_zero_node;
	      /* Some other array, will need runtime loop.  */
	      else
		{
		  idx = force_target_expr (sizetype, maxval, complain);
		  loop_indexes = tree_cons (idx, NULL_TREE, loop_indexes);
		}
	      expr_type = TREE_TYPE (expr_type);
	      lhs_mem = build4_loc (field_loc, ARRAY_REF, expr_type, lhs_mem,
				    idx, NULL_TREE, NULL_TREE);
	      rhs_mem = build4_loc (field_loc, ARRAY_REF, expr_type, rhs_mem,
				    idx, NULL_TREE, NULL_TREE);
	    }
	  if (TREE_CODE (expr_type) == ARRAY_TYPE)
	    continue;

	  tree comp = do_one_comp (field_loc, info, field, lhs_mem, rhs_mem);
	  if (comp == error_mark_node)
	    {
	      bad = true;
	      continue;
	    }

	  /* Most of the time, comp is the expression that should be evaluated
	     to compare the two members.  If the expression needs to be
	     evaluated more than once in a loop, it will be a TREE_LIST
	     instead, whose TREE_VALUE is the expression for one array element,
	     TREE_PURPOSE is innermost iterator temporary and if the array
	     is multidimensional, TREE_CHAIN will contain another TREE_LIST
	     with second innermost iterator in its TREE_PURPOSE and so on.  */
	  if (loop_indexes)
	    {
	      TREE_VALUE (loop_indexes) = comp;
	      comp = loop_indexes;
	    }
	  comps.safe_push (comp);
	}
      if (code == SPACESHIP_EXPR && is_auto (rettype))
	{
	  rettype = common_comparison_type (comps);
	  apply_deduced_return_type (fndecl, rettype);
	}
      if (bad)
	{
	  DECL_DELETED_FN (fndecl) = true;
	  goto out;
	}
      for (unsigned i = 0; i < comps.length(); ++i)
	{
	  tree comp = comps[i];
	  tree eq, retval = NULL_TREE, if_ = NULL_TREE;
	  tree loop_indexes = NULL_TREE;
	  if (defining)
	    {
	      if (TREE_CODE (comp) == TREE_LIST)
		{
		  loop_indexes = comp;
		  comp = TREE_VALUE (comp);
		  loop_indexes = nreverse (loop_indexes);
		  for (tree loop_index = loop_indexes; loop_index;
		       loop_index = TREE_CHAIN (loop_index))
		    {
		      tree for_stmt = begin_for_stmt (NULL_TREE, NULL_TREE);
		      tree idx = TREE_PURPOSE (loop_index);
		      tree maxval = TARGET_EXPR_INITIAL (idx);
		      TARGET_EXPR_INITIAL (idx) = size_zero_node;
		      add_stmt (idx);
		      finish_init_stmt (for_stmt);
		      finish_for_cond (build2 (LE_EXPR, boolean_type_node, idx,
					       maxval), for_stmt, false, 0);
		      finish_for_expr (cp_build_unary_op (PREINCREMENT_EXPR,
							  TARGET_EXPR_SLOT (idx),
							  false, complain),
							  for_stmt);
		      /* Store in TREE_VALUE the for_stmt tree, so that we can
			 later on call finish_for_stmt on it (in the reverse
			 order).  */
		      TREE_VALUE (loop_index) = for_stmt;
		    }
		  loop_indexes = nreverse (loop_indexes);
		}
	      if_ = begin_if_stmt ();
	    }
	  /* Spaceship is specified to use !=, but for the comparison category
	     types, != is equivalent to !(==), so let's use == directly.  */
	  if (code == EQ_EXPR)
	    {
	      /* if (x==y); else return false; */
	      eq = comp;
	      retval = boolean_false_node;
	    }
	  else
	    {
	      /* if (auto v = x<=>y, v == 0); else return v; */
	      if (TREE_CODE (comp) == SPACESHIP_EXPR)
		TREE_TYPE (comp) = rettype;
	      else
		comp = build_static_cast (input_location, rettype, comp,
					  complain);
	      info.check (comp);
	      if (defining)
		{
		  tree var = create_temporary_var (rettype);
		  pushdecl (var);
		  cp_finish_decl (var, comp, false, NULL_TREE, flags);
		  comp = retval = var;
		}
	      eq = build_new_op (info.loc, EQ_EXPR, flags, comp,
				 integer_zero_node, NULL_TREE, NULL_TREE,
				 NULL, complain);
	    }
	  tree ceq = contextual_conv_bool (eq, complain);
	  info.check (ceq);
	  if (defining)
	    {
	      finish_if_stmt_cond (ceq, if_);
	      finish_then_clause (if_);
	      begin_else_clause (if_);
	      finish_return_stmt (retval);
	      finish_else_clause (if_);
	      finish_if_stmt (if_);
	      for (tree loop_index = loop_indexes; loop_index;
		   loop_index = TREE_CHAIN (loop_index))
		finish_for_stmt (TREE_VALUE (loop_index));
	    }
	}
      if (defining)
	{
	  tree val;
	  if (code == EQ_EXPR)
	    val = boolean_true_node;
	  else
	    {
	      tree seql = lookup_comparison_result (cc_strong_ordering,
						    "equal", complain);
	      val = build_static_cast (input_location, rettype, seql,
				       complain);
	    }
	  finish_return_stmt (val);
	}
    }
  else if (code == NE_EXPR)
    {
      tree comp = build_new_op (info.loc, EQ_EXPR, flags, lhs, rhs,
				NULL_TREE, NULL_TREE, NULL, complain);
      comp = contextual_conv_bool (comp, complain);
      info.check (comp);
      if (defining)
	{
	  tree neg = build1 (TRUTH_NOT_EXPR, boolean_type_node, comp);
	  finish_return_stmt (neg);
	}
    }
  else
    {
      tree comp = build_new_op (info.loc, SPACESHIP_EXPR, flags, lhs, rhs,
				NULL_TREE, NULL_TREE, NULL, complain);
      tree comp2 = build_new_op (info.loc, code, flags, comp, integer_zero_node,
				 NULL_TREE, NULL_TREE, NULL, complain);
      info.check (comp2);
      if (defining)
	finish_return_stmt (comp2);
    }

 out:
  if (defining)
    finish_compound_stmt (compound_stmt);
  else
    --cp_unevaluated_operand;
}

/* True iff DECL is an implicitly-declared special member function with no real
   source location, so we can use its DECL_SOURCE_LOCATION to remember where we
   triggered its synthesis.  */

bool
decl_remember_implicit_trigger_p (tree decl)
{
  if (!DECL_ARTIFICIAL (decl))
    return false;
  special_function_kind sfk = special_function_p (decl);
  /* Inherited constructors have the location of their using-declaration, and
     operator== has the location of the corresponding operator<=>.  */
  return (sfk != sfk_inheriting_constructor
	  && sfk != sfk_comparison);
}

/* Synthesize FNDECL, a non-static member function.   */

void
synthesize_method (tree fndecl)
{
  bool nested = (current_function_decl != NULL_TREE);
  tree context = decl_function_context (fndecl);
  bool need_body = true;
  tree stmt;
  location_t save_input_location = input_location;
  int error_count = errorcount;
  int warning_count = warningcount + werrorcount;
  special_function_kind sfk = special_function_p (fndecl);

  /* Reset the source location, we might have been previously
     deferred, and thus have saved where we were first needed.  */
  if (decl_remember_implicit_trigger_p (fndecl))
    DECL_SOURCE_LOCATION (fndecl)
      = DECL_SOURCE_LOCATION (TYPE_NAME (DECL_CONTEXT (fndecl)));

  /* If we've been asked to synthesize a clone, just synthesize the
     cloned function instead.  Doing so will automatically fill in the
     body for the clone.  */
  if (DECL_CLONED_FUNCTION_P (fndecl))
    fndecl = DECL_CLONED_FUNCTION (fndecl);

  /* We may be in the middle of deferred access check.  Disable
     it now.  */
  push_deferring_access_checks (dk_no_deferred);

  if (! context)
    push_to_top_level ();
  else if (nested)
    push_function_context ();

  input_location = DECL_SOURCE_LOCATION (fndecl);

  start_preparsed_function (fndecl, NULL_TREE, SF_DEFAULT | SF_PRE_PARSED);
  stmt = begin_function_body ();

  if (DECL_ASSIGNMENT_OPERATOR_P (fndecl)
      && DECL_OVERLOADED_OPERATOR_IS (fndecl, NOP_EXPR))
    {
      do_build_copy_assign (fndecl);
      need_body = false;
    }
  else if (DECL_CONSTRUCTOR_P (fndecl))
    {
      tree arg_chain = FUNCTION_FIRST_USER_PARMTYPE (fndecl);
      if (arg_chain != void_list_node)
	do_build_copy_constructor (fndecl);
      else
	finish_mem_initializers (NULL_TREE);
    }
  else if (sfk == sfk_comparison)
    {
      /* Pass tf_none so the function is just deleted if there's a problem.  */
      build_comparison_op (fndecl, true, tf_none);
      need_body = false;
    }

  /* If we haven't yet generated the body of the function, just
     generate an empty compound statement.  */
  if (need_body)
    {
      tree compound_stmt;
      compound_stmt = begin_compound_stmt (BCS_FN_BODY);
      finish_compound_stmt (compound_stmt);
    }

  finish_function_body (stmt);
  finish_function (/*inline_p=*/false);

  if (!DECL_DELETED_FN (fndecl))
    expand_or_defer_fn (fndecl);

  input_location = save_input_location;

  if (! context)
    pop_from_top_level ();
  else if (nested)
    pop_function_context ();

  pop_deferring_access_checks ();

  if (error_count != errorcount || warning_count != warningcount + werrorcount)
    if (DECL_ARTIFICIAL (fndecl))
      inform (input_location, "synthesized method %qD first required here",
	      fndecl);
}

/* Like synthesize_method, but don't actually synthesize defaulted comparison
   methods if their class is still incomplete.  Just deduce the return
   type in that case.  */

void
maybe_synthesize_method (tree fndecl)
{
  if (special_function_p (fndecl) == sfk_comparison)
    {
      tree lhs = DECL_ARGUMENTS (fndecl);
      if (is_this_parameter (lhs))
	lhs = cp_build_fold_indirect_ref (lhs);
      else
	lhs = convert_from_reference (lhs);
      tree ctype = TYPE_MAIN_VARIANT (TREE_TYPE (lhs));
      if (!COMPLETE_TYPE_P (ctype))
	{
	  push_deferring_access_checks (dk_no_deferred);
	  build_comparison_op (fndecl, false, tf_none);
	  pop_deferring_access_checks ();
	  return;
	}
    }
  return synthesize_method (fndecl);
}

/* Build a reference to type TYPE with cv-quals QUALS, which is an
   rvalue if RVALUE is true.  */

static tree
build_stub_type (tree type, int quals, bool rvalue)
{
  tree argtype = cp_build_qualified_type (type, quals);
  return cp_build_reference_type (argtype, rvalue);
}

/* Build a dummy glvalue from dereferencing a dummy reference of type
   REFTYPE.  */

tree
build_stub_object (tree reftype)
{
  if (!TYPE_REF_P (reftype))
    reftype = cp_build_reference_type (reftype, /*rval*/true);
  tree stub = build1 (CONVERT_EXPR, reftype, integer_one_node);
  return convert_from_reference (stub);
}

/* Determine which function will be called when looking up NAME in TYPE,
   called with a single ARGTYPE argument, or no argument if ARGTYPE is
   null.  FLAGS and COMPLAIN are as for build_new_method_call.

   Returns a FUNCTION_DECL if all is well.
   Returns NULL_TREE if overload resolution failed.
   Returns error_mark_node if the chosen function cannot be called.  */

static tree
locate_fn_flags (tree type, tree name, tree argtype, int flags,
		 tsubst_flags_t complain)
{
  tree ob, fn, fns, binfo, rval;

  if (TYPE_P (type))
    binfo = TYPE_BINFO (type);
  else
    {
      binfo = type;
      type = BINFO_TYPE (binfo);
    }

  ob = build_stub_object (cp_build_reference_type (type, false));
  releasing_vec args;
  if (argtype)
    {
      if (TREE_CODE (argtype) == TREE_LIST)
	{
	  for (tree elt = argtype; elt && elt != void_list_node;
	       elt = TREE_CHAIN (elt))
	    {
	      tree type = TREE_VALUE (elt);
	      tree arg = build_stub_object (type);
	      vec_safe_push (args, arg);
	    }
	}
      else
	{
	  tree arg = build_stub_object (argtype);
	  args->quick_push (arg);
	}
    }

  fns = lookup_fnfields (binfo, name, 0, complain);
  rval = build_new_method_call (ob, fns, &args, binfo, flags, &fn, complain);

  if (fn && rval == error_mark_node)
    return rval;
  else
    return fn;
}

/* Locate the dtor of TYPE.  */

tree
get_dtor (tree type, tsubst_flags_t complain)
{
  tree fn = locate_fn_flags (type, complete_dtor_identifier, NULL_TREE,
			     LOOKUP_NORMAL, complain);
  if (fn == error_mark_node)
    return NULL_TREE;
  return fn;
}

/* Locate the default ctor of TYPE.  */

tree
locate_ctor (tree type)
{
  tree fn;

  push_deferring_access_checks (dk_no_check);
  fn = locate_fn_flags (type, complete_ctor_identifier, NULL_TREE,
			LOOKUP_SPECULATIVE, tf_none);
  pop_deferring_access_checks ();
  if (fn == error_mark_node)
    return NULL_TREE;
  return fn;
}

/* Likewise, but give any appropriate errors.  */

tree
get_default_ctor (tree type)
{
  tree fn = locate_fn_flags (type, complete_ctor_identifier, NULL_TREE,
			     LOOKUP_NORMAL, tf_warning_or_error);
  if (fn == error_mark_node)
    return NULL_TREE;
  return fn;
}

/* Locate the copy ctor of TYPE.  */

tree
get_copy_ctor (tree type, tsubst_flags_t complain)
{
  int quals = (TYPE_HAS_CONST_COPY_CTOR (type)
	       ? TYPE_QUAL_CONST : TYPE_UNQUALIFIED);
  tree argtype = build_stub_type (type, quals, false);
  tree fn = locate_fn_flags (type, complete_ctor_identifier, argtype,
			     LOOKUP_NORMAL, complain);
  if (fn == error_mark_node)
    return NULL_TREE;
  return fn;
}

/* Locate the copy assignment operator of TYPE.  */

tree
get_copy_assign (tree type)
{
  int quals = (TYPE_HAS_CONST_COPY_ASSIGN (type)
	       ? TYPE_QUAL_CONST : TYPE_UNQUALIFIED);
  tree argtype = build_stub_type (type, quals, false);
  tree fn = locate_fn_flags (type, assign_op_identifier, argtype,
			     LOOKUP_NORMAL, tf_warning_or_error);
  if (fn == error_mark_node)
    return NULL_TREE;
  return fn;
}

/* walk_tree helper function for is_trivially_xible.  If *TP is a call,
   return it if it calls something other than a trivial special member
   function.  */

static tree
check_nontriv (tree *tp, int *, void *)
{
  tree fn = cp_get_callee (*tp);
  if (fn == NULL_TREE)
    return NULL_TREE;

  if (TREE_CODE (fn) == ADDR_EXPR)
    fn = TREE_OPERAND (fn, 0);

  if (TREE_CODE (fn) != FUNCTION_DECL
      || !trivial_fn_p (fn))
    return fn;
  return NULL_TREE;
}

/* Return declval<T>() = declval<U>() treated as an unevaluated operand.  */

static tree
assignable_expr (tree to, tree from)
{
  cp_unevaluated cp_uneval_guard;
  to = build_stub_object (to);
  from = build_stub_object (from);
  tree r = cp_build_modify_expr (input_location, to, NOP_EXPR, from, tf_none);
  return r;
}

/* The predicate condition for a template specialization
   is_constructible<T, Args...> shall be satisfied if and only if the
   following variable definition would be well-formed for some invented
   variable t: T t(create<Args>()...);

   Return something equivalent in well-formedness and triviality.  */

static tree
constructible_expr (tree to, tree from)
{
  tree expr;
  cp_unevaluated cp_uneval_guard;
  if (CLASS_TYPE_P (to))
    {
      tree ctype = to;
      vec<tree, va_gc> *args = NULL;
      if (!TYPE_REF_P (to))
	to = cp_build_reference_type (to, /*rval*/false);
      tree ob = build_stub_object (to);
      for (; from; from = TREE_CHAIN (from))
	vec_safe_push (args, build_stub_object (TREE_VALUE (from)));
      expr = build_special_member_call (ob, complete_ctor_identifier, &args,
					ctype, LOOKUP_NORMAL, tf_none);
      if (expr == error_mark_node)
	return error_mark_node;
      /* The current state of the standard vis-a-vis LWG 2116 is that
	 is_*constructible involves destruction as well.  */
      if (type_build_dtor_call (ctype))
	{
	  tree dtor = build_special_member_call (ob, complete_dtor_identifier,
						 NULL, ctype, LOOKUP_NORMAL,
						 tf_none);
	  if (dtor == error_mark_node)
	    return error_mark_node;
	  if (!TYPE_HAS_TRIVIAL_DESTRUCTOR (ctype))
	    expr = build2 (COMPOUND_EXPR, void_type_node, expr, dtor);
	}
    }
  else
    {
      if (from == NULL_TREE)
	return build_value_init (strip_array_types (to), tf_none);
      const int len = list_length (from);
      if (len > 1)
	{
	  if (cxx_dialect < cxx20)
	    /* Too many initializers.  */
	    return error_mark_node;

	  /* In C++20 this is well-formed:
	       using T = int[2];
	       T t(1, 2);
	     which means that std::is_constructible_v<int[2], int, int>
	     should be true.  */
	  vec<constructor_elt, va_gc> *v;
	  vec_alloc (v, len);
	  for (tree t = from; t; t = TREE_CHAIN (t))
	    {
	      tree stub = build_stub_object (TREE_VALUE (t));
	      constructor_elt elt = { NULL_TREE, stub };
	      v->quick_push (elt);
	    }
	  from = build_constructor (init_list_type_node, v);
	  CONSTRUCTOR_IS_DIRECT_INIT (from) = true;
	  CONSTRUCTOR_IS_PAREN_INIT (from) = true;
	}
      else
	from = build_stub_object (TREE_VALUE (from));
      expr = perform_direct_initialization_if_possible (to, from,
							/*cast*/false,
							tf_none);
      /* If t(e) didn't work, maybe t{e} will.  */
      if (expr == NULL_TREE
	  && len == 1
	  && cxx_dialect >= cxx20)
	{
	  from = build_constructor_single (init_list_type_node, NULL_TREE,
					   from);
	  CONSTRUCTOR_IS_DIRECT_INIT (from) = true;
	  CONSTRUCTOR_IS_PAREN_INIT (from) = true;
	  expr = perform_direct_initialization_if_possible (to, from,
							    /*cast*/false,
							    tf_none);
	}
    }
  return expr;
}

/* Returns a tree iff TO is assignable (if CODE is MODIFY_EXPR) or
   constructible (otherwise) from FROM, which is a single type for
   assignment or a list of types for construction.  */

static tree
is_xible_helper (enum tree_code code, tree to, tree from, bool trivial)
{
  to = complete_type (to);
  deferring_access_check_sentinel acs (dk_no_deferred);
  if (VOID_TYPE_P (to) || ABSTRACT_CLASS_TYPE_P (to)
      || (from && FUNC_OR_METHOD_TYPE_P (from)
	  && (TYPE_READONLY (from) || FUNCTION_REF_QUALIFIED (from))))
    return error_mark_node;
  tree expr;
  if (code == MODIFY_EXPR)
    expr = assignable_expr (to, from);
  else if (trivial && from && TREE_CHAIN (from)
	   && cxx_dialect < cxx20)
    return error_mark_node; // only 0- and 1-argument ctors can be trivial
			    // before C++20 aggregate paren init
  else if (TREE_CODE (to) == ARRAY_TYPE && !TYPE_DOMAIN (to))
    return error_mark_node; // can't construct an array of unknown bound
  else
    expr = constructible_expr (to, from);
  return expr;
}

/* Returns true iff TO is trivially assignable (if CODE is MODIFY_EXPR) or
   constructible (otherwise) from FROM, which is a single type for
   assignment or a list of types for construction.  */

bool
is_trivially_xible (enum tree_code code, tree to, tree from)
{
  tree expr = is_xible_helper (code, to, from, /*trivial*/true);
  if (expr == NULL_TREE || expr == error_mark_node)
    return false;
  tree nt = cp_walk_tree_without_duplicates (&expr, check_nontriv, NULL);
  return !nt;
}

/* Returns true iff TO is nothrow assignable (if CODE is MODIFY_EXPR) or
   constructible (otherwise) from FROM, which is a single type for
   assignment or a list of types for construction.  */

bool
is_nothrow_xible (enum tree_code code, tree to, tree from)
{
  tree expr = is_xible_helper (code, to, from, /*trivial*/false);
  if (expr == NULL_TREE || expr == error_mark_node)
    return false;
  return expr_noexcept_p (expr, tf_none);
}

/* Returns true iff TO is assignable (if CODE is MODIFY_EXPR) or
   constructible (otherwise) from FROM, which is a single type for
   assignment or a list of types for construction.  */

bool
is_xible (enum tree_code code, tree to, tree from)
{
  tree expr = is_xible_helper (code, to, from, /*trivial*/false);
  if (expr == error_mark_node)
    return false;
  return !!expr;
}

/* Return true iff conjunction_v<is_reference<T>, is_constructible<T, U>> is
   true, and the initialization
     T t(VAL<U>); // DIRECT_INIT_P
   or
     T t = VAL<U>; // !DIRECT_INIT_P
   binds t to a temporary object whose lifetime is extended.
   VAL<T> is defined in [meta.unary.prop]:
   -- If T is a reference or function type, VAL<T> is an expression with the
   same type and value category as declval<T>().
   -- Otherwise, VAL<T> is a prvalue that initially has type T.   */

bool
ref_xes_from_temporary (tree to, tree from, bool direct_init_p)
{
  /* Check is_reference<T>.  */
  if (!TYPE_REF_P (to))
    return false;
  /* We don't check is_constructible<T, U>: if T isn't constructible
     from U, we won't be able to create a conversion.  */
  tree val = build_stub_object (from);
  if (!TYPE_REF_P (from) && TREE_CODE (from) != FUNCTION_TYPE)
    val = CLASS_TYPE_P (from) ? force_rvalue (val, tf_none) : rvalue (val);
  return ref_conv_binds_to_temporary (to, val, direct_init_p).is_true ();
}

/* Worker for is_{,nothrow_}convertible.  Attempt to perform an implicit
   conversion from FROM to TO and return the result.  */

static tree
is_convertible_helper (tree from, tree to)
{
  if (VOID_TYPE_P (from) && VOID_TYPE_P (to))
    return integer_one_node;
  cp_unevaluated u;
  tree expr = build_stub_object (from);
  deferring_access_check_sentinel acs (dk_no_deferred);
  return perform_implicit_conversion (to, expr, tf_none);
}

/* Return true if FROM can be converted to TO using implicit conversions,
   or both FROM and TO are possibly cv-qualified void.  NB: This doesn't
   implement the "Access checks are performed as if from a context unrelated
   to either type" restriction.  */

bool
is_convertible (tree from, tree to)
{
  tree expr = is_convertible_helper (from, to);
  if (expr == error_mark_node)
    return false;
  return !!expr;
}

/* Like is_convertible, but the conversion is also noexcept.  */

bool
is_nothrow_convertible (tree from, tree to)
{
  tree expr = is_convertible_helper (from, to);
  if (expr == NULL_TREE || expr == error_mark_node)
    return false;
  return expr_noexcept_p (expr, tf_none);
}

/* Categorize various special_function_kinds.  */
#define SFK_CTOR_P(sfk) \
  ((sfk) >= sfk_constructor && (sfk) <= sfk_move_constructor)
#define SFK_DTOR_P(sfk) \
  ((sfk) == sfk_destructor || (sfk) == sfk_virtual_destructor)
#define SFK_ASSIGN_P(sfk) \
  ((sfk) == sfk_copy_assignment || (sfk) == sfk_move_assignment)
#define SFK_COPY_P(sfk) \
  ((sfk) == sfk_copy_constructor || (sfk) == sfk_copy_assignment)
#define SFK_MOVE_P(sfk) \
  ((sfk) == sfk_move_constructor || (sfk) == sfk_move_assignment)

/* Subroutine of synthesized_method_walk.  Update SPEC_P, TRIVIAL_P and
   DELETED_P or give an error message MSG with argument ARG.  */

static void
process_subob_fn (tree fn, special_function_kind sfk, tree *spec_p,
		  bool *trivial_p, bool *deleted_p, bool *constexpr_p,
		  bool diag, tree arg, bool dtor_from_ctor = false)
{
  if (!fn || fn == error_mark_node)
    {
      if (deleted_p)
	*deleted_p = true;
      return;
    }

  if (spec_p)
    {
      if (!maybe_instantiate_noexcept (fn))
	*spec_p = error_mark_node;
      else
	{
	  tree raises = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fn));
	  *spec_p = merge_exception_specifiers (*spec_p, raises);
	}
    }

  if (!trivial_fn_p (fn) && !dtor_from_ctor)
    {
      if (trivial_p)
	*trivial_p = false;
      if (TREE_CODE (arg) == FIELD_DECL
	  && TREE_CODE (DECL_CONTEXT (arg)) == UNION_TYPE)
	{
	  if (deleted_p)
	    *deleted_p = true;
	  if (diag)
	    error ("union member %q+D with non-trivial %qD", arg, fn);
	}
    }

  if (constexpr_p && !DECL_DECLARED_CONSTEXPR_P (fn))
    {
      *constexpr_p = false;
      if (diag)
	{
	  inform (DECL_SOURCE_LOCATION (fn),
		  SFK_DTOR_P (sfk)
		  ? G_("defaulted destructor calls non-%<constexpr%> %qD")
		  : G_("defaulted constructor calls non-%<constexpr%> %qD"),
		  fn);
	  explain_invalid_constexpr_fn (fn);
	}
    }
}

/* Subroutine of synthesized_method_walk to allow recursion into anonymous
   aggregates.  If DTOR_FROM_CTOR is true, we're walking subobject destructors
   called from a synthesized constructor, in which case we don't consider
   the triviality of the subobject destructor.  */

static void
walk_field_subobs (tree fields, special_function_kind sfk, tree fnname,
		   int quals, tree *spec_p, bool *trivial_p,
		   bool *deleted_p, bool *constexpr_p,
		   bool diag, int flags, tsubst_flags_t complain,
		   bool dtor_from_ctor)
{
  if (!fields)
    return;

  tree ctx = DECL_CONTEXT (fields);

  /* CWG2084: A defaulted default ctor for a union with a DMI only initializes
     that member, so don't check other members.  */
  enum { unknown, no, yes }
  only_dmi_mem = (sfk == sfk_constructor && TREE_CODE (ctx) == UNION_TYPE
		  ? unknown : no);

 again:
  for (tree field = fields; field; field = DECL_CHAIN (field))
    {
      tree mem_type, argtype, rval;

      if (TREE_CODE (field) != FIELD_DECL
	  || DECL_ARTIFICIAL (field)
	  || DECL_UNNAMED_BIT_FIELD (field))
	continue;

      /* Variant members only affect deletedness.  In particular, they don't
	 affect the exception-specification of a user-provided destructor,
	 which we're figuring out via get_defaulted_eh_spec.  So if we aren't
	 asking if this is deleted, don't even look up the function; we don't
	 want an error about a deleted function we aren't actually calling.  */
      if (sfk == sfk_destructor && deleted_p == NULL
	  && TREE_CODE (ctx) == UNION_TYPE)
	break;

      if (only_dmi_mem != no)
	{
	  if (DECL_INITIAL (field))
	    only_dmi_mem = yes;
	  else
	    /* Don't check this until we know there's no DMI.  */
	    continue;
	}

      mem_type = strip_array_types (TREE_TYPE (field));
      if (SFK_ASSIGN_P (sfk))
	{
	  bool bad = true;
	  if (CP_TYPE_CONST_P (mem_type) && !CLASS_TYPE_P (mem_type))
	    {
	      if (diag)
		error ("non-static const member %q#D, cannot use default "
		       "assignment operator", field);
	    }
	  else if (TYPE_REF_P (mem_type))
	    {
	      if (diag)
		error ("non-static reference member %q#D, cannot use "
		       "default assignment operator", field);
	    }
	  else
	    bad = false;

	  if (bad && deleted_p)
	    *deleted_p = true;
	}
      else if (sfk == sfk_constructor || sfk == sfk_inheriting_constructor)
	{
	  bool bad;

	  if (DECL_INITIAL (field))
	    {
	      if (diag && DECL_INITIAL (field) == error_mark_node)
		inform (DECL_SOURCE_LOCATION (field),
			"initializer for %q#D is invalid", field);
	      if (trivial_p)
		*trivial_p = false;
	      /* Core 1351: If the field has an NSDMI that could throw, the
		 default constructor is noexcept(false).  */
	      if (spec_p)
		{
		  tree nsdmi = get_nsdmi (field, /*ctor*/false, complain);
		  if (nsdmi == error_mark_node)
		    *spec_p = error_mark_node;
		  else if (*spec_p != error_mark_node
			   && !expr_noexcept_p (nsdmi, tf_none))
		    *spec_p = noexcept_false_spec;
		}
	      /* Don't do the normal processing.  */
	      continue;
	    }

	  bad = false;
	  if (CP_TYPE_CONST_P (mem_type)
	      && default_init_uninitialized_part (mem_type))
	    {
	      if (diag)
		{
		  error ("uninitialized const member in %q#T",
			 current_class_type);
		  inform (DECL_SOURCE_LOCATION (field),
			  "%q#D should be initialized", field);
		}
	      bad = true;
	    }
	  else if (TYPE_REF_P (mem_type))
	    {
	      if (diag)
		{
		  error ("uninitialized reference member in %q#T",
			 current_class_type);
		  inform (DECL_SOURCE_LOCATION (field),
			  "%q#D should be initialized", field);
		}
	      bad = true;
	    }

	  if (bad && deleted_p)
	    *deleted_p = true;

	  /* Before C++20, for an implicitly-defined default constructor to
	     be constexpr, every member must have a user-provided default
	     constructor or an explicit initializer.  */
	  if (constexpr_p
	      && cxx_dialect < cxx20
	      && !CLASS_TYPE_P (mem_type)
	      && TREE_CODE (ctx) != UNION_TYPE)
	    {
	      *constexpr_p = false;
	      if (diag)
		inform (DECL_SOURCE_LOCATION (field),
			"defaulted default constructor does not "
			"initialize %q#D", field);
	    }
	}
      else if (sfk == sfk_copy_constructor)
	{
	  /* 12.8p11b5 */
	  if (TYPE_REF_P (mem_type)
	      && TYPE_REF_IS_RVALUE (mem_type))
	    {
	      if (diag)
		error ("copying non-static data member %q#D of rvalue "
		       "reference type", field);
	      if (deleted_p)
		*deleted_p = true;
	    }
	}

      if (!CLASS_TYPE_P (mem_type))
	continue;

      if (ANON_AGGR_TYPE_P (mem_type))
	{
	  walk_field_subobs (TYPE_FIELDS (mem_type), sfk, fnname, quals,
			     spec_p, trivial_p, deleted_p, constexpr_p,
			     diag, flags, complain, dtor_from_ctor);
	  continue;
	}

      if (SFK_COPY_P (sfk) || SFK_MOVE_P (sfk))
	{
	  int mem_quals = cp_type_quals (mem_type) | quals;
	  if (DECL_MUTABLE_P (field))
	    mem_quals &= ~TYPE_QUAL_CONST;
	  argtype = build_stub_type (mem_type, mem_quals, SFK_MOVE_P (sfk));
	}
      else
	argtype = NULL_TREE;

      rval = locate_fn_flags (mem_type, fnname, argtype, flags, complain);

      process_subob_fn (rval, sfk, spec_p, trivial_p, deleted_p,
			constexpr_p, diag, field, dtor_from_ctor);
    }

  /* We didn't find a DMI in this union, now check all the members.  */
  if (only_dmi_mem == unknown)
    {
      only_dmi_mem = no;
      goto again;
    }
}

/* Base walker helper for synthesized_method_walk.  Inspect a direct
   or virtual base.  BINFO is the parent type's binfo.  BASE_BINFO is
   the base binfo of interests.  All other parms are as for
   synthesized_method_walk, or its local vars.  */

static tree
synthesized_method_base_walk (tree binfo, tree base_binfo,
			      special_function_kind sfk, tree fnname, int quals,
			      tree *inheriting_ctor, tree inherited_parms,
			      int flags, bool diag,
			      tree *spec_p, bool *trivial_p,
			      bool *deleted_p, bool *constexpr_p)
{
  bool inherited_binfo = false;
  tree argtype = NULL_TREE;
  deferring_kind defer = dk_no_deferred;

  if (SFK_COPY_P (sfk) || SFK_MOVE_P (sfk))
    argtype = build_stub_type (BINFO_TYPE (base_binfo), quals, SFK_MOVE_P (sfk));
  else if (inheriting_ctor
	   && (inherited_binfo
	       = binfo_inherited_from (binfo, base_binfo, *inheriting_ctor)))
    {
      argtype = inherited_parms;
      /* Don't check access on the inherited constructor.  */
      if (flag_new_inheriting_ctors)
	defer = dk_deferred;
    }
  else if (cxx_dialect >= cxx14 && sfk == sfk_virtual_destructor
	   && BINFO_VIRTUAL_P (base_binfo)
	   && ABSTRACT_CLASS_TYPE_P (BINFO_TYPE (binfo)))
    /* Don't check access when looking at vbases of abstract class's
       virtual destructor.  */
    defer = dk_no_check;

  if (defer != dk_no_deferred)
    push_deferring_access_checks (defer);
  tree rval = locate_fn_flags (base_binfo, fnname, argtype, flags,
			       diag ? tf_warning_or_error : tf_none);
  if (defer != dk_no_deferred)
    pop_deferring_access_checks ();

  /* Replace an inherited template with the appropriate specialization.  */
  if (inherited_binfo && rval
      && DECL_P (*inheriting_ctor) && DECL_P (rval)
      && DECL_CONTEXT (*inheriting_ctor) == DECL_CONTEXT (rval))
    *inheriting_ctor = DECL_CLONED_FUNCTION (rval);

  process_subob_fn (rval, sfk, spec_p, trivial_p, deleted_p,
		    constexpr_p, diag, BINFO_TYPE (base_binfo));
  if (SFK_CTOR_P (sfk)
      && (!BINFO_VIRTUAL_P (base_binfo)
	  || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (BINFO_TYPE (base_binfo))))
    {
      /* In a constructor we also need to check the subobject
	 destructors for cleanup of partially constructed objects.  */
      tree dtor = locate_fn_flags (base_binfo, complete_dtor_identifier,
				   NULL_TREE, flags,
				   diag ? tf_warning_or_error : tf_none);
      /* Note that we don't pass down trivial_p; the subobject
	 destructors don't affect triviality of the constructor.  Nor
	 do they affect constexpr-ness (a constant expression doesn't
	 throw) or exception-specification (a throw from one of the
	 dtors would be a double-fault).  */
      process_subob_fn (dtor, sfk, NULL, NULL, deleted_p, NULL, false,
			BINFO_TYPE (base_binfo), /*dtor_from_ctor*/true);
    }

  return rval;
}

/* The caller wants to generate an implicit declaration of SFK for
   CTYPE which is const if relevant and CONST_P is set.  If SPEC_P,
   TRIVIAL_P, DELETED_P or CONSTEXPR_P are non-null, set their
   referent appropriately.  If DIAG is true, we're either being called
   from maybe_explain_implicit_delete to give errors, or if
   CONSTEXPR_P is non-null, from explain_invalid_constexpr_fn.  */

static void
synthesized_method_walk (tree ctype, special_function_kind sfk, bool const_p,
			 tree *spec_p, bool *trivial_p, bool *deleted_p,
			 bool *constexpr_p, bool diag,
			 tree *inheriting_ctor, tree inherited_parms)
{
  tree binfo, base_binfo;
  int i;

  /* SFK must be exactly one category.  */
  gcc_checking_assert (SFK_DTOR_P(sfk) + SFK_CTOR_P(sfk)
		       + SFK_ASSIGN_P(sfk) == 1);

  if (spec_p)
    *spec_p = (cxx_dialect >= cxx11 ? noexcept_true_spec : empty_except_spec);

  if (deleted_p)
    {
      /* "The closure type associated with a lambda-expression has a deleted
	 default constructor and a deleted copy assignment operator."
	 This is diagnosed in maybe_explain_implicit_delete.
	 In C++20, only lambda-expressions with lambda-captures have those
	 deleted.  */
      if (LAMBDA_TYPE_P (ctype)
	  && (sfk == sfk_constructor || sfk == sfk_copy_assignment)
	  && (cxx_dialect < cxx20
	      || LAMBDA_EXPR_CAPTURE_LIST (CLASSTYPE_LAMBDA_EXPR (ctype))
	      || LAMBDA_EXPR_DEFAULT_CAPTURE_MODE
				(CLASSTYPE_LAMBDA_EXPR (ctype)) != CPLD_NONE))
	{
	  *deleted_p = true;
	  return;
	}

      *deleted_p = false;
    }

  bool check_vdtor = false;
  tree fnname;

  if (SFK_DTOR_P (sfk))
    {
      check_vdtor = true;
      /* The synthesized method will call base dtors, but check complete
	 here to avoid having to deal with VTT.  */
      fnname = complete_dtor_identifier;
    }
  else if (SFK_ASSIGN_P (sfk))
    fnname = assign_op_identifier;
  else
    fnname = complete_ctor_identifier;

  gcc_assert ((sfk == sfk_inheriting_constructor)
	      == (inheriting_ctor && *inheriting_ctor != NULL_TREE));

  /* If that user-written default constructor would satisfy the
     requirements of a constexpr constructor (7.1.5), the
     implicitly-defined default constructor is constexpr.

     C++20:
     The implicitly-defined copy/move assignment operator is constexpr if
      - X is a literal type, and
      - the assignment operator selected to copy/move each direct base class
	subobject is a constexpr function, and
      - for each non-static data member of X that is of class type (or array
	thereof), the assignment operator selected to copy/move that
	member is a constexpr function.

      C++23:
      The implicitly-defined copy/move assignment operator is constexpr.  */
  if (constexpr_p)
    *constexpr_p = (SFK_CTOR_P (sfk)
		    || (SFK_ASSIGN_P (sfk) && cxx_dialect >= cxx14)
		    || (SFK_DTOR_P (sfk) && cxx_dialect >= cxx20));

  bool expected_trivial = type_has_trivial_fn (ctype, sfk);
  if (trivial_p)
    *trivial_p = expected_trivial;

  /* The TYPE_HAS_COMPLEX_* flags tell us about constraints from base
     class versions and other properties of the type.  But a subobject
     class can be trivially copyable and yet have overload resolution
     choose a template constructor for initialization, depending on
     rvalueness and cv-quals.  And furthermore, a member in a base might
     be trivial but deleted or otherwise not callable.  So we can't exit
     early in C++0x.  The same considerations apply in C++98/03, but
     there the definition of triviality does not consider overload
     resolution, so a constructor can be trivial even if it would otherwise
     call a non-trivial constructor.  */
  if (expected_trivial
      && (!(SFK_COPY_P (sfk) || SFK_MOVE_P (sfk)) || cxx_dialect < cxx11))
    {
      if (constexpr_p && sfk == sfk_constructor)
	{
	  bool cx = trivial_default_constructor_is_constexpr (ctype);
	  *constexpr_p = cx;
	  if (diag && !cx && TREE_CODE (ctype) == UNION_TYPE)
	    /* A trivial constructor doesn't have any NSDMI.  */
	    inform (input_location, "defaulted default constructor does "
		    "not initialize any non-static data member");
	}
      if (!diag && cxx_dialect < cxx11)
	return;
    }

  ++cp_unevaluated_operand;
  ++c_inhibit_evaluation_warnings;
  push_deferring_access_checks (dk_no_deferred);

  tree scope = push_scope (ctype);

  int flags = LOOKUP_NORMAL | LOOKUP_SPECULATIVE;
  if (sfk != sfk_inheriting_constructor)
    flags |= LOOKUP_DEFAULTED;

  tsubst_flags_t complain = diag ? tf_warning_or_error : tf_none;
  if (diag && spec_p)
    /* We're in get_defaulted_eh_spec; we don't actually want any walking
       diagnostics, we just want complain set.  */
    diag = false;
  int quals = const_p ? TYPE_QUAL_CONST : TYPE_UNQUALIFIED;

  for (binfo = TYPE_BINFO (ctype), i = 0;
       BINFO_BASE_ITERATE (binfo, i, base_binfo); ++i)
    {
      if (!SFK_ASSIGN_P (sfk) && BINFO_VIRTUAL_P (base_binfo))
	/* We'll handle virtual bases below.  */
	continue;

      tree fn = synthesized_method_base_walk (binfo, base_binfo,
					      sfk, fnname, quals,
					      inheriting_ctor, inherited_parms,
					      flags, diag, spec_p, trivial_p,
					      deleted_p, constexpr_p);

      if (diag && SFK_ASSIGN_P (sfk) && SFK_MOVE_P (sfk)
	  && BINFO_VIRTUAL_P (base_binfo)
	  && fn && TREE_CODE (fn) == FUNCTION_DECL
	  && move_fn_p (fn) && !trivial_fn_p (fn)
	  && vbase_has_user_provided_move_assign (BINFO_TYPE (base_binfo)))
	warning (OPT_Wvirtual_move_assign,
		 "defaulted move assignment for %qT calls a non-trivial "
		 "move assignment operator for virtual base %qT",
		 ctype, BINFO_TYPE (base_binfo));

      if (check_vdtor && type_has_virtual_destructor (BINFO_TYPE (base_binfo)))
	{
	  /* Unlike for base ctor/op=/dtor, for operator delete it's fine
	     to have a null fn (no class-specific op delete).  */
	  fn = locate_fn_flags (ctype, ovl_op_identifier (false, DELETE_EXPR),
				ptr_type_node, flags, tf_none);
	  if (fn && fn == error_mark_node)
	    {
	      if (complain & tf_error)
		locate_fn_flags (ctype, ovl_op_identifier (false, DELETE_EXPR),
				 ptr_type_node, flags, complain);
	      if (deleted_p)
		*deleted_p = true;
	    }
	  check_vdtor = false;
	}
    }

  vec<tree, va_gc> *vbases = CLASSTYPE_VBASECLASSES (ctype);
  if (SFK_ASSIGN_P (sfk))
    /* Already examined vbases above.  */;
  else if (vec_safe_is_empty (vbases))
    /* No virtual bases to worry about.  */;
  else if (ABSTRACT_CLASS_TYPE_P (ctype) && cxx_dialect >= cxx14
	   /* DR 1658 specifies that vbases of abstract classes are
	      ignored for both ctors and dtors.  Except DR 2336
	      overrides that skipping when determing the eh-spec of a
	      virtual destructor.  */
	   && sfk != sfk_virtual_destructor)
    /* Vbase cdtors are not relevant.  */;
  else
    {
      if (constexpr_p)
	*constexpr_p = false;

      FOR_EACH_VEC_ELT (*vbases, i, base_binfo)
	synthesized_method_base_walk (binfo, base_binfo, sfk, fnname, quals,
				      inheriting_ctor, inherited_parms,
				      flags, diag,
				      spec_p, trivial_p, deleted_p, constexpr_p);
    }

  /* Now handle the non-static data members.  */
  walk_field_subobs (TYPE_FIELDS (ctype), sfk, fnname, quals,
		     spec_p, trivial_p, deleted_p, constexpr_p,
		     diag, flags, complain, /*dtor_from_ctor*/false);
  if (SFK_CTOR_P (sfk))
    walk_field_subobs (TYPE_FIELDS (ctype), sfk_destructor,
		       complete_dtor_identifier, TYPE_UNQUALIFIED,
		       NULL, NULL, deleted_p, NULL,
		       false, flags, complain, /*dtor_from_ctor*/true);

  pop_scope (scope);

  pop_deferring_access_checks ();
  --cp_unevaluated_operand;
  --c_inhibit_evaluation_warnings;
}

/* DECL is a defaulted function whose exception specification is now
   needed.  Return what it should be.  */

tree
get_defaulted_eh_spec (tree decl, tsubst_flags_t complain)
{
  /* For DECL_MAYBE_DELETED this should already have been handled by
     synthesize_method.  */
  gcc_assert (!DECL_MAYBE_DELETED (decl));

  if (DECL_CLONED_FUNCTION_P (decl))
    decl = DECL_CLONED_FUNCTION (decl);
  special_function_kind sfk = special_function_p (decl);
  tree ctype = DECL_CONTEXT (decl);
  tree parms = FUNCTION_FIRST_USER_PARMTYPE (decl);
  tree parm_type = TREE_VALUE (parms);
  bool const_p = CP_TYPE_CONST_P (non_reference (parm_type));
  tree spec = empty_except_spec;
  bool diag = !DECL_DELETED_FN (decl) && (complain & tf_error);
  tree inh = DECL_INHERITED_CTOR (decl);
  if (SFK_DTOR_P (sfk) && DECL_VIRTUAL_P (decl))
    /* We have to examine virtual bases even if abstract.  */
    sfk = sfk_virtual_destructor;
  bool pushed = false;
  if (CLASSTYPE_TEMPLATE_INSTANTIATION (ctype))
    pushed = push_tinst_level (decl);
  synthesized_method_walk (ctype, sfk, const_p, &spec, NULL, NULL,
			   NULL, diag, &inh, parms);
  if (pushed)
    pop_tinst_level ();
  return spec;
}

/* DECL is a deleted function.  If it's implicitly deleted, explain why and
   return true; else return false.  */

bool
maybe_explain_implicit_delete (tree decl)
{
  /* If decl is a clone, get the primary variant.  */
  decl = DECL_ORIGIN (decl);
  gcc_assert (DECL_DELETED_FN (decl));
  if (DECL_DEFAULTED_FN (decl))
    {
      /* Not marked GTY; it doesn't need to be GC'd or written to PCH.  */
      static hash_set<tree> *explained;

      special_function_kind sfk;
      location_t loc;
      bool informed;
      tree ctype;

      if (!explained)
	explained = new hash_set<tree>;
      if (explained->add (decl))
	return true;

      sfk = special_function_p (decl);
      ctype = DECL_CONTEXT (decl);
      loc = input_location;
      input_location = DECL_SOURCE_LOCATION (decl);

      informed = false;
      if (LAMBDA_TYPE_P (ctype))
	{
	  informed = true;
	  if (sfk == sfk_constructor)
	    inform (DECL_SOURCE_LOCATION (decl),
		    "a lambda closure type has a deleted default constructor");
	  else if (sfk == sfk_copy_assignment)
	    inform (DECL_SOURCE_LOCATION (decl),
		    "a lambda closure type has a deleted copy assignment operator");
	  else
	    informed = false;
	}
      else if (DECL_ARTIFICIAL (decl)
	       && (sfk == sfk_copy_assignment || sfk == sfk_copy_constructor)
	       && classtype_has_move_assign_or_move_ctor_p (ctype, true))
	{
	  inform (DECL_SOURCE_LOCATION (decl),
		  "%q#D is implicitly declared as deleted because %qT "
		  "declares a move constructor or move assignment operator",
		  decl, ctype);
	  informed = true;
	}
      else if (sfk == sfk_inheriting_constructor)
	{
	  tree binfo = inherited_ctor_binfo (decl);
	  if (TREE_CODE (binfo) != TREE_BINFO)
	    {
	      inform (DECL_SOURCE_LOCATION (decl),
		      "%q#D inherits from multiple base subobjects",
		      decl);
	      informed = true;
	    }
	}
      if (!informed && sfk == sfk_comparison)
	{
	  inform (DECL_SOURCE_LOCATION (decl),
		  "%q#D is implicitly deleted because the default "
		  "definition would be ill-formed:", decl);
	  build_comparison_op (decl, false, tf_warning_or_error);
	}
      else if (!informed)
	{
	  tree parms = FUNCTION_FIRST_USER_PARMTYPE (decl);
	  bool const_p = false;
	  if (parms)
	    {
	      tree parm_type = TREE_VALUE (parms);
	      const_p = CP_TYPE_CONST_P (non_reference (parm_type));
	    }
	  tree raises = NULL_TREE;
	  bool deleted_p = false;
	  tree scope = push_scope (ctype);
	  tree inh = DECL_INHERITED_CTOR (decl);

	  synthesized_method_walk (ctype, sfk, const_p,
				   &raises, NULL, &deleted_p, NULL, false,
				   &inh, parms);
	  if (deleted_p)
	    {
	      inform (DECL_SOURCE_LOCATION (decl),
		      "%q#D is implicitly deleted because the default "
		      "definition would be ill-formed:", decl);
	      synthesized_method_walk (ctype, sfk, const_p,
				       NULL, NULL, &deleted_p, NULL, true,
				       &inh, parms);
	    }
	  else if (!comp_except_specs
		   (TYPE_RAISES_EXCEPTIONS (TREE_TYPE (decl)),
		    raises, ce_normal))
	    inform (DECL_SOURCE_LOCATION (decl), "%q#F is implicitly "
		    "deleted because its exception-specification does not "
		    "match the implicit exception-specification %qX",
		    decl, raises);
	  else if (flag_checking)
	    gcc_unreachable ();

	  pop_scope (scope);
	}

      input_location = loc;
      return true;
    }
  return false;
}

/* DECL is a defaulted function which was declared constexpr.  Explain why
   it can't be constexpr.  */

void
explain_implicit_non_constexpr (tree decl)
{
  tree parms = FUNCTION_FIRST_USER_PARMTYPE (decl);
  bool const_p = CP_TYPE_CONST_P (non_reference (TREE_VALUE (parms)));
  tree inh = DECL_INHERITED_CTOR (decl);
  bool dummy;
  special_function_kind sfk = special_function_p (decl);
  if (sfk == sfk_comparison)
    {
      DECL_DECLARED_CONSTEXPR_P (decl) = true;
      build_comparison_op (decl, false, tf_warning_or_error);
      DECL_DECLARED_CONSTEXPR_P (decl) = false;
    }
  else
    synthesized_method_walk (DECL_CLASS_CONTEXT (decl),
			     sfk, const_p,
			     NULL, NULL, NULL, &dummy, true,
			     &inh, parms);
}

/* DECL is an instantiation of an inheriting constructor template.  Deduce
   the correct exception-specification and deletedness for this particular
   specialization.  Return true if the deduction succeeds; false otherwise.  */

bool
deduce_inheriting_ctor (tree decl)
{
  decl = DECL_ORIGIN (decl);
  gcc_assert (DECL_INHERITED_CTOR (decl));
  tree spec;
  bool trivial, constexpr_, deleted;
  tree inh = DECL_INHERITED_CTOR (decl);
  synthesized_method_walk (DECL_CONTEXT (decl), sfk_inheriting_constructor,
			   false, &spec, &trivial, &deleted, &constexpr_,
			   /*diag*/false,
			   &inh,
			   FUNCTION_FIRST_USER_PARMTYPE (decl));
  if (spec == error_mark_node)
    return false;
  if (TREE_CODE (inherited_ctor_binfo (decl)) != TREE_BINFO)
    /* Inherited the same constructor from different base subobjects.  */
    deleted = true;
  DECL_DELETED_FN (decl) = deleted;
  TREE_TYPE (decl) = build_exception_variant (TREE_TYPE (decl), spec);
  SET_DECL_INHERITED_CTOR (decl, inh);

  tree clone;
  FOR_EACH_CLONE (clone, decl)
    {
      DECL_DELETED_FN (clone) = deleted;
      TREE_TYPE (clone) = build_exception_variant (TREE_TYPE (clone), spec);
      SET_DECL_INHERITED_CTOR (clone, inh);
    }

  return true;
}

/* Implicitly declare the special function indicated by KIND, as a
   member of TYPE.  For copy constructors and assignment operators,
   CONST_P indicates whether these functions should take a const
   reference argument or a non-const reference.
   Returns the FUNCTION_DECL for the implicitly declared function.  */

tree
implicitly_declare_fn (special_function_kind kind, tree type,
		       bool const_p, tree pattern_fn,
		       tree inherited_parms)
{
  tree fn;
  tree parameter_types = void_list_node;
  tree return_type;
  tree fn_type;
  tree raises = empty_except_spec;
  tree rhs_parm_type = NULL_TREE;
  tree this_parm;
  tree name;
  HOST_WIDE_INT saved_processing_template_decl;
  bool deleted_p = false;
  bool constexpr_p = false;
  tree inherited_ctor = (kind == sfk_inheriting_constructor
			 ? pattern_fn : NULL_TREE);

  /* Because we create declarations for implicitly declared functions
     lazily, we may be creating the declaration for a member of TYPE
     while in some completely different context.  However, TYPE will
     never be a dependent class (because we never want to do lookups
     for implicitly defined functions in a dependent class).  */
  gcc_assert (!dependent_type_p (type));

  /* If the member-specification does not explicitly declare any member or
     friend named operator==, an == operator function is declared
     implicitly for each three-way comparison operator function defined as
     defaulted in the member-specification, with the same access and
     function-definition and in the same class scope as the respective
     three-way comparison operator function, except that the return type is
     replaced with bool and the declarator-id is replaced with
     operator==.

     [Note: Such an implicitly-declared == operator for a class X is
     defined as defaulted in the definition of X and has the same
     parameter-declaration-clause and trailing requires-clause as the
     respective three-way comparison operator. It is declared with friend,
     virtual, constexpr, or consteval if the three-way comparison operator
     function is so declared. If the three-way comparison operator function
     has no noexcept-specifier, the implicitly-declared == operator
     function has an implicit exception specification (14.5) that may
     differ from the implicit exception specification of the three-way
     comparison operator function. --end note]  */
  if (kind == sfk_comparison)
    {
      fn = copy_operator_fn (pattern_fn, EQ_EXPR);
      DECL_ARTIFICIAL (fn) = 1;
      TREE_TYPE (fn) = change_return_type (boolean_type_node, TREE_TYPE (fn));
      return fn;
    }

  /* Furthermore, we must set PROCESSING_TEMPLATE_DECL to zero here
     because we only create clones for constructors and destructors
     when not in a template.  */
  saved_processing_template_decl = processing_template_decl;
  processing_template_decl = 0;

  type = TYPE_MAIN_VARIANT (type);

  if (targetm.cxx.cdtor_returns_this ())
    {
      if (kind == sfk_destructor)
	/* See comment in check_special_function_return_type.  */
	return_type = build_pointer_type (void_type_node);
      else
	return_type = build_pointer_type (type);
    }
  else
    return_type = void_type_node;

  int this_quals = TYPE_UNQUALIFIED;
  switch (kind)
    {
    case sfk_destructor:
      /* Destructor.  */
      name = dtor_identifier;
      break;

    case sfk_constructor:
      /* Default constructor.  */
      name = ctor_identifier;
      break;

    case sfk_copy_constructor:
    case sfk_copy_assignment:
    case sfk_move_constructor:
    case sfk_move_assignment:
    case sfk_inheriting_constructor:
    {
      if (kind == sfk_copy_assignment
	  || kind == sfk_move_assignment)
	{
	  return_type = build_reference_type (type);
	  name = assign_op_identifier;
	}
      else
	name = ctor_identifier;

      if (kind == sfk_inheriting_constructor)
	parameter_types = inherited_parms;
      else
	{
	  if (const_p)
	    rhs_parm_type = cp_build_qualified_type (type, TYPE_QUAL_CONST);
	  else
	    rhs_parm_type = type;
	  bool move_p = (kind == sfk_move_assignment
			 || kind == sfk_move_constructor);
	  rhs_parm_type = cp_build_reference_type (rhs_parm_type, move_p);

	  parameter_types = tree_cons (NULL_TREE, rhs_parm_type, parameter_types);
	}
      break;
    }

    default:
      gcc_unreachable ();
    }

  bool trivial_p = false;

  if (inherited_ctor)
    {
      /* For an inheriting constructor, just copy these flags from the
	 inherited constructor until deduce_inheriting_ctor.  */
      raises = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (inherited_ctor));
      deleted_p = DECL_DELETED_FN (inherited_ctor);
      constexpr_p = DECL_DECLARED_CONSTEXPR_P (inherited_ctor);
    }
  else if (cxx_dialect >= cxx11)
    {
      raises = noexcept_deferred_spec;
      synthesized_method_walk (type, kind, const_p, NULL, &trivial_p,
			       &deleted_p, &constexpr_p, false,
			       &inherited_ctor, inherited_parms);
    }
  else
    synthesized_method_walk (type, kind, const_p, &raises, &trivial_p,
			     &deleted_p, &constexpr_p, false,
			     &inherited_ctor, inherited_parms);
  /* Don't bother marking a deleted constructor as constexpr.  */
  if (deleted_p)
    constexpr_p = false;
  /* A trivial copy/move constructor is also a constexpr constructor,
     unless the class has virtual bases (7.1.5p4).  */
  else if (trivial_p
	   && cxx_dialect >= cxx11
	   && (kind == sfk_copy_constructor
	       || kind == sfk_move_constructor)
	   && !CLASSTYPE_VBASECLASSES (type))
    gcc_assert (constexpr_p);

  if (!trivial_p && type_has_trivial_fn (type, kind))
    type_set_nontrivial_flag (type, kind);

  /* Create the function.  */
  tree this_type = cp_build_qualified_type (type, this_quals);
  fn_type = build_method_type_directly (this_type, return_type,
					parameter_types);

  if (raises)
    {
      if (raises != error_mark_node)
	fn_type = build_exception_variant (fn_type, raises);
      else
	{
	  /* Can happen, e.g., in C++98 mode for an ill-formed non-static data
	     member initializer (c++/89914).  Also, in C++98, we might have
	     failed to deduce RAISES, so try again but complain this time.  */
	  if (cxx_dialect < cxx11)
	    synthesized_method_walk (type, kind, const_p, &raises, nullptr,
				     nullptr, nullptr, /*diag=*/true,
				     &inherited_ctor, inherited_parms);
	  /* We should have seen an error at this point.  */
	  gcc_assert (seen_error ());
	}
    }
  fn = build_lang_decl (FUNCTION_DECL, name, fn_type);
  if (kind != sfk_inheriting_constructor)
    DECL_SOURCE_LOCATION (fn) = DECL_SOURCE_LOCATION (TYPE_NAME (type));

  if (IDENTIFIER_OVL_OP_P (name))
    {
      const ovl_op_info_t *op = IDENTIFIER_OVL_OP_INFO (name);
      DECL_OVERLOADED_OPERATOR_CODE_RAW (fn) = op->ovl_op_code;
    }
  else if (IDENTIFIER_CTOR_P (name))
    DECL_CXX_CONSTRUCTOR_P (fn) = true;
  else if (IDENTIFIER_DTOR_P (name))
    DECL_CXX_DESTRUCTOR_P (fn) = true;
  else
    gcc_unreachable ();

  SET_DECL_ALIGN (fn, MINIMUM_METHOD_BOUNDARY);

  /* Create the explicit arguments.  */
  if (rhs_parm_type)
    {
      /* Note that this parameter is *not* marked DECL_ARTIFICIAL; we
	 want its type to be included in the mangled function
	 name.  */
      tree decl = cp_build_parm_decl (fn, NULL_TREE, rhs_parm_type);
      TREE_READONLY (decl) = 1;
      retrofit_lang_decl (decl);
      DECL_PARM_INDEX (decl) = DECL_PARM_LEVEL (decl) = 1;
      DECL_ARGUMENTS (fn) = decl;
    }
  else if (kind == sfk_inheriting_constructor)
    {
      tree *p = &DECL_ARGUMENTS (fn);
      int index = 1;
      for (tree parm = inherited_parms; parm && parm != void_list_node;
	   parm = TREE_CHAIN (parm))
	{
	  *p = cp_build_parm_decl (fn, NULL_TREE, TREE_VALUE (parm));
	  retrofit_lang_decl (*p);
	  DECL_PARM_LEVEL (*p) = 1;
	  DECL_PARM_INDEX (*p) = index++;
	  p = &DECL_CHAIN (*p);
	}
      SET_DECL_INHERITED_CTOR (fn, inherited_ctor);
      DECL_NONCONVERTING_P (fn) = DECL_NONCONVERTING_P (inherited_ctor);
      /* A constructor so declared has the same access as the corresponding
	 constructor in X.  */
      TREE_PRIVATE (fn) = TREE_PRIVATE (inherited_ctor);
      TREE_PROTECTED (fn) = TREE_PROTECTED (inherited_ctor);
      /* Copy constexpr from the inherited constructor even if the
	 inheriting constructor doesn't satisfy the requirements.  */
      constexpr_p = DECL_DECLARED_CONSTEXPR_P (inherited_ctor);
    }

  /* Add the "this" parameter.  */
  this_parm = build_this_parm (fn, fn_type, this_quals);
  DECL_CHAIN (this_parm) = DECL_ARGUMENTS (fn);
  DECL_ARGUMENTS (fn) = this_parm;

  grokclassfn (type, fn, kind == sfk_destructor ? DTOR_FLAG : NO_SPECIAL);

  DECL_IN_AGGR_P (fn) = 1;
  DECL_ARTIFICIAL (fn) = 1;
  DECL_DEFAULTED_FN (fn) = 1;
  if (cxx_dialect >= cxx11)
    {
      DECL_DELETED_FN (fn) = deleted_p;
      DECL_DECLARED_CONSTEXPR_P (fn) = constexpr_p;
    }
  DECL_EXTERNAL (fn) = true;
  DECL_NOT_REALLY_EXTERN (fn) = 1;
  DECL_DECLARED_INLINE_P (fn) = 1;
  set_linkage_according_to_type (type, fn);
  if (TREE_PUBLIC (fn))
    DECL_COMDAT (fn) = 1;
  rest_of_decl_compilation (fn, namespace_bindings_p (), at_eof);
  gcc_assert (!TREE_USED (fn));

  /* Propagate constraints from the inherited constructor. */
  if (flag_concepts && inherited_ctor)
    if (tree orig_ci = get_constraints (inherited_ctor))
      {
        tree new_ci = copy_node (orig_ci);
        set_constraints (fn, new_ci);
      }

  /* Restore PROCESSING_TEMPLATE_DECL.  */
  processing_template_decl = saved_processing_template_decl;

  if (inherited_ctor && TREE_CODE (inherited_ctor) == TEMPLATE_DECL)
    fn = add_inherited_template_parms (fn, inherited_ctor);

  /* Warn about calling a non-trivial move assignment in a virtual base.  */
  if (kind == sfk_move_assignment && !deleted_p && !trivial_p
      && CLASSTYPE_VBASECLASSES (type))
    {
      location_t loc = input_location;
      input_location = DECL_SOURCE_LOCATION (fn);
      synthesized_method_walk (type, kind, const_p,
			       NULL, NULL, NULL, NULL, true,
			       NULL, NULL_TREE);
      input_location = loc;
    }

  return fn;
}

/* Gives any errors about defaulted functions which need to be deferred
   until the containing class is complete.  */

void
defaulted_late_check (tree fn)
{
  /* Complain about invalid signature for defaulted fn.  */
  tree ctx = DECL_CONTEXT (fn);
  special_function_kind kind = special_function_p (fn);

  if (kind == sfk_comparison)
    {
      /* If the function was declared constexpr, check that the definition
	 qualifies.  Otherwise we can define the function lazily.  */
      if (DECL_DECLARED_CONSTEXPR_P (fn) && !DECL_INITIAL (fn))
	{
	  /* Prevent GC.  */
	  function_depth++;
	  synthesize_method (fn);
	  function_depth--;
	}
      return;
    }

  bool fn_const_p = (copy_fn_p (fn) == 2);
  tree implicit_fn = implicitly_declare_fn (kind, ctx, fn_const_p,
					    NULL, NULL);
  tree eh_spec = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (implicit_fn));

  if (!same_type_p (TREE_TYPE (TREE_TYPE (fn)),
		    TREE_TYPE (TREE_TYPE (implicit_fn)))
      || !compparms (TYPE_ARG_TYPES (TREE_TYPE (fn)),
		     TYPE_ARG_TYPES (TREE_TYPE (implicit_fn))))
    {
      error ("defaulted declaration %q+D does not match the "
	     "expected signature", fn);
      inform (DECL_SOURCE_LOCATION (fn),
	      "expected signature: %qD", implicit_fn);
    }

  if (DECL_DELETED_FN (implicit_fn))
    {
      DECL_DELETED_FN (fn) = 1;
      return;
    }

  /* If a function is explicitly defaulted on its first declaration without an
     exception-specification, it is implicitly considered to have the same
     exception-specification as if it had been implicitly declared.  */
  if (!TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fn))
      && DECL_DEFAULTED_IN_CLASS_P (fn))
    TREE_TYPE (fn) = build_exception_variant (TREE_TYPE (fn), eh_spec);

  if (DECL_DEFAULTED_IN_CLASS_P (fn)
      && DECL_DECLARED_CONSTEXPR_P (implicit_fn))
    {
      /* Hmm...should we do this for out-of-class too? Should it be OK to
	 add constexpr later like inline, rather than requiring
	 declarations to match?  */
      DECL_DECLARED_CONSTEXPR_P (fn) = true;
      if (kind == sfk_constructor)
	TYPE_HAS_CONSTEXPR_CTOR (ctx) = true;
    }

  if (!DECL_DECLARED_CONSTEXPR_P (implicit_fn)
      && DECL_DECLARED_CONSTEXPR_P (fn))
    {
      if (!CLASSTYPE_TEMPLATE_INSTANTIATION (ctx))
	{
	  error ("explicitly defaulted function %q+D cannot be declared "
		 "%qs because the implicit declaration is not %qs:", fn,
		 DECL_IMMEDIATE_FUNCTION_P (fn) ? "consteval" : "constexpr",
		 "constexpr");
	  explain_implicit_non_constexpr (fn);
	}
      DECL_DECLARED_CONSTEXPR_P (fn) = false;
    }
}

/* Returns true iff FN can be explicitly defaulted, and gives any
   errors if defaulting FN is ill-formed.  */

bool
defaultable_fn_check (tree fn)
{
  special_function_kind kind = sfk_none;

  if (template_parm_scope_p ())
    {
      error ("a template cannot be defaulted");
      return false;
    }

  if (DECL_CONSTRUCTOR_P (fn))
    {
      if (FUNCTION_FIRST_USER_PARMTYPE (fn) == void_list_node)
	kind = sfk_constructor;
      else if (copy_fn_p (fn) > 0
	       && (TREE_CHAIN (FUNCTION_FIRST_USER_PARMTYPE (fn))
		   == void_list_node))
	kind = sfk_copy_constructor;
      else if (move_fn_p (fn))
	kind = sfk_move_constructor;
    }
  else if (DECL_DESTRUCTOR_P (fn))
    kind = sfk_destructor;
  else if (DECL_ASSIGNMENT_OPERATOR_P (fn)
	   && DECL_OVERLOADED_OPERATOR_IS (fn, NOP_EXPR))
    {
      if (copy_fn_p (fn))
	kind = sfk_copy_assignment;
      else if (move_fn_p (fn))
	kind = sfk_move_assignment;
    }
  else if (DECL_OVERLOADED_OPERATOR_CODE_RAW (fn) >= OVL_OP_EQ_EXPR
	   && DECL_OVERLOADED_OPERATOR_CODE_RAW (fn) <= OVL_OP_SPACESHIP_EXPR)
    {
      kind = sfk_comparison;
      if (!early_check_defaulted_comparison (fn))
	return false;
    }

  if (kind == sfk_none)
    {
      error ("%qD cannot be defaulted", fn);
      return false;
    }
  else
    {
      for (tree t = FUNCTION_FIRST_USER_PARMTYPE (fn);
	   t && t != void_list_node; t = TREE_CHAIN (t))
	if (TREE_PURPOSE (t))
	  {
	    error ("defaulted function %q+D with default argument", fn);
	    break;
	  }

      /* Avoid do_warn_unused_parameter warnings.  */
      for (tree p = FUNCTION_FIRST_USER_PARM (fn); p; p = DECL_CHAIN (p))
	if (DECL_NAME (p))
	  suppress_warning (p, OPT_Wunused_parameter);

      if (current_class_type && TYPE_BEING_DEFINED (current_class_type))
	/* Defer checking.  */;
      else if (!processing_template_decl)
	defaulted_late_check (fn);

      return true;
    }
}

/* Add an implicit declaration to TYPE for the kind of function
   indicated by SFK.  Return the FUNCTION_DECL for the new implicit
   declaration.  */

tree
lazily_declare_fn (special_function_kind sfk, tree type)
{
  tree fn;
  /* Whether or not the argument has a const reference type.  */
  bool const_p = false;

  type = TYPE_MAIN_VARIANT (type);

  switch (sfk)
    {
    case sfk_constructor:
      CLASSTYPE_LAZY_DEFAULT_CTOR (type) = 0;
      break;
    case sfk_copy_constructor:
      const_p = TYPE_HAS_CONST_COPY_CTOR (type);
      CLASSTYPE_LAZY_COPY_CTOR (type) = 0;
      break;
    case sfk_move_constructor:
      CLASSTYPE_LAZY_MOVE_CTOR (type) = 0;
      break;
    case sfk_copy_assignment:
      const_p = TYPE_HAS_CONST_COPY_ASSIGN (type);
      CLASSTYPE_LAZY_COPY_ASSIGN (type) = 0;
      break;
    case sfk_move_assignment:
      CLASSTYPE_LAZY_MOVE_ASSIGN (type) = 0;
      break;
    case sfk_destructor:
      CLASSTYPE_LAZY_DESTRUCTOR (type) = 0;
      break;
    default:
      gcc_unreachable ();
    }

  /* Declare the function.  */
  fn = implicitly_declare_fn (sfk, type, const_p, NULL, NULL);

  /* [class.copy]/8 If the class definition declares a move constructor or
     move assignment operator, the implicitly declared copy constructor is
     defined as deleted.... */
  if ((sfk == sfk_copy_assignment || sfk == sfk_copy_constructor)
      && cxx_dialect >= cxx11)
    {
      if (classtype_has_move_assign_or_move_ctor_p (type, true))
	DECL_DELETED_FN (fn) = true;
      else if (classtype_has_depr_implicit_copy (type))
	/* The implicit definition of a copy constructor as defaulted is
	   deprecated if the class has a user-declared copy assignment operator
	   or a user-declared destructor. The implicit definition of a copy
	   assignment operator as defaulted is deprecated if the class has a
	   user-declared copy constructor or a user-declared destructor (15.4,
	   15.8).  */
	TREE_DEPRECATED (fn) = true;
    }

  /* Destructors and assignment operators may be virtual.  */
  if (sfk == sfk_destructor
      || sfk == sfk_move_assignment
      || sfk == sfk_copy_assignment)
    check_for_override (fn, type);

  /* Add it to the class  */
  bool added = add_method (type, fn, false);
  gcc_assert (added || errorcount);

  /* Add it to TYPE_FIELDS.  */
  if (sfk == sfk_destructor
      && DECL_VIRTUAL_P (fn))
    /* The ABI requires that a virtual destructor go at the end of the
       vtable.  */
    TYPE_FIELDS (type) = chainon (TYPE_FIELDS (type), fn);
  else
    {
      DECL_CHAIN (fn) = TYPE_FIELDS (type);
      TYPE_FIELDS (type) = fn;
    }
  /* Propagate TYPE_FIELDS.  */
  fixup_type_variants (type);

  maybe_add_class_template_decl_list (type, fn, /*friend_p=*/0);
  if (DECL_MAYBE_IN_CHARGE_CDTOR_P (fn))
    /* Create appropriate clones.  */
    clone_cdtor (fn, /*update_methods=*/true);

  return fn;
}

/* Given a FUNCTION_DECL FN and a chain LIST, skip as many elements of LIST
   as there are artificial parms in FN.  */

tree
skip_artificial_parms_for (const_tree fn, tree list)
{
  if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fn))
    list = TREE_CHAIN (list);
  else
    return list;

  if (DECL_HAS_IN_CHARGE_PARM_P (fn))
    list = TREE_CHAIN (list);
  if (DECL_HAS_VTT_PARM_P (fn))
    list = TREE_CHAIN (list);
  return list;
}

/* Given a FUNCTION_DECL FN and a chain LIST, return the number of
   artificial parms in FN.  */

int
num_artificial_parms_for (const_tree fn)
{
  int count = 0;

  if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fn))
    count++;
  else
    return 0;

  if (DECL_HAS_IN_CHARGE_PARM_P (fn))
    count++;
  if (DECL_HAS_VTT_PARM_P (fn))
    count++;
  return count;
}


#include "gt-cp-method.h"
