/* 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 = build2 (INIT_EXPR, void_type_node, 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 = build2 (INIT_EXPR, void_type_node, 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 (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_initializable_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_initializable_field (TYPE_FIELDS (ctype));
	   field;
	   field = next_initializable_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_initializable_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;
}

/* 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)
{
  tree field;
  for (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 (DECL_CONTEXT (field)) == UNION_TYPE)
	break;

      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 (DECL_CONTEXT (field)) != 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);
    }
}

/* 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.

     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.  */
  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"
