/* Build expressions with type checking for C++ compiler.
   Copyright (C) 1987-2021 Free Software Foundation, Inc.
   Hacked by Michael Tiemann (tiemann@cygnus.com)

This file is part of GCC.

GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.

GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */


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

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "target.h"
#include "cp-tree.h"
#include "stor-layout.h"
#include "varasm.h"
#include "intl.h"
#include "convert.h"
#include "c-family/c-objc.h"
#include "c-family/c-ubsan.h"
#include "gcc-rich-location.h"
#include "stringpool.h"
#include "attribs.h"
#include "asan.h"
#include "gimplify.h"

static tree cp_build_addr_expr_strict (tree, tsubst_flags_t);
static tree cp_build_function_call (tree, tree, tsubst_flags_t);
static tree pfn_from_ptrmemfunc (tree);
static tree delta_from_ptrmemfunc (tree);
static tree convert_for_assignment (tree, tree, impl_conv_rhs, tree, int,
				    tsubst_flags_t, int);
static tree cp_pointer_int_sum (location_t, enum tree_code, tree, tree,
				tsubst_flags_t);
static tree rationalize_conditional_expr (enum tree_code, tree, 
					  tsubst_flags_t);
static bool comp_ptr_ttypes_real (tree, tree, int);
static bool comp_except_types (tree, tree, bool);
static bool comp_array_types (const_tree, const_tree, compare_bounds_t, bool);
static tree pointer_diff (location_t, tree, tree, tree, tsubst_flags_t, tree *);
static tree get_delta_difference (tree, tree, bool, bool, tsubst_flags_t);
static void casts_away_constness_r (tree *, tree *, tsubst_flags_t);
static bool casts_away_constness (tree, tree, tsubst_flags_t);
static bool maybe_warn_about_returning_address_of_local (tree, location_t = UNKNOWN_LOCATION);
static void error_args_num (location_t, tree, bool);
static int convert_arguments (tree, vec<tree, va_gc> **, tree, int,
                              tsubst_flags_t);
static bool is_std_move_p (tree);
static bool is_std_forward_p (tree);

/* Do `exp = require_complete_type (exp);' to make sure exp
   does not have an incomplete type.  (That includes void types.)
   Returns error_mark_node if the VALUE does not have
   complete type when this function returns.  */

tree
require_complete_type_sfinae (tree value, tsubst_flags_t complain)
{
  tree type;

  if (processing_template_decl || value == error_mark_node)
    return value;

  if (TREE_CODE (value) == OVERLOAD)
    type = unknown_type_node;
  else
    type = TREE_TYPE (value);

  if (type == error_mark_node)
    return error_mark_node;

  /* First, detect a valid value with a complete type.  */
  if (COMPLETE_TYPE_P (type))
    return value;

  if (complete_type_or_maybe_complain (type, value, complain))
    return value;
  else
    return error_mark_node;
}

tree
require_complete_type (tree value)
{
  return require_complete_type_sfinae (value, tf_warning_or_error);
}

/* Try to complete TYPE, if it is incomplete.  For example, if TYPE is
   a template instantiation, do the instantiation.  Returns TYPE,
   whether or not it could be completed, unless something goes
   horribly wrong, in which case the error_mark_node is returned.  */

tree
complete_type (tree type)
{
  if (type == NULL_TREE)
    /* Rather than crash, we return something sure to cause an error
       at some point.  */
    return error_mark_node;

  if (type == error_mark_node || COMPLETE_TYPE_P (type))
    ;
  else if (TREE_CODE (type) == ARRAY_TYPE)
    {
      tree t = complete_type (TREE_TYPE (type));
      unsigned int needs_constructing, has_nontrivial_dtor;
      if (COMPLETE_TYPE_P (t) && !dependent_type_p (type))
	layout_type (type);
      needs_constructing
	= TYPE_NEEDS_CONSTRUCTING (TYPE_MAIN_VARIANT (t));
      has_nontrivial_dtor
	= TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TYPE_MAIN_VARIANT (t));
      for (t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
	{
	  TYPE_NEEDS_CONSTRUCTING (t) = needs_constructing;
	  TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t) = has_nontrivial_dtor;
	}
    }
  else if (CLASS_TYPE_P (type))
    {
      if (modules_p ())
	/* TYPE could be a class member we've not loaded the definition of.  */ 
	lazy_load_pendings (TYPE_NAME (TYPE_MAIN_VARIANT (type)));

      if (CLASSTYPE_TEMPLATE_INSTANTIATION (type))
	instantiate_class_template (TYPE_MAIN_VARIANT (type));
    }

  return type;
}

/* Like complete_type, but issue an error if the TYPE cannot be completed.
   VALUE is used for informative diagnostics.
   Returns NULL_TREE if the type cannot be made complete.  */

tree
complete_type_or_maybe_complain (tree type, tree value, tsubst_flags_t complain)
{
  type = complete_type (type);
  if (type == error_mark_node)
    /* We already issued an error.  */
    return NULL_TREE;
  else if (!COMPLETE_TYPE_P (type))
    {
      if (complain & tf_error)
	cxx_incomplete_type_diagnostic (value, type, DK_ERROR);
      note_failed_type_completion_for_satisfaction (type);
      return NULL_TREE;
    }
  else
    return type;
}

tree
complete_type_or_else (tree type, tree value)
{
  return complete_type_or_maybe_complain (type, value, tf_warning_or_error);
}


/* Return the common type of two parameter lists.
   We assume that comptypes has already been done and returned 1;
   if that isn't so, this may crash.

   As an optimization, free the space we allocate if the parameter
   lists are already common.  */

static tree
commonparms (tree p1, tree p2)
{
  tree oldargs = p1, newargs, n;
  int i, len;
  int any_change = 0;

  len = list_length (p1);
  newargs = tree_last (p1);

  if (newargs == void_list_node)
    i = 1;
  else
    {
      i = 0;
      newargs = 0;
    }

  for (; i < len; i++)
    newargs = tree_cons (NULL_TREE, NULL_TREE, newargs);

  n = newargs;

  for (i = 0; p1;
       p1 = TREE_CHAIN (p1), p2 = TREE_CHAIN (p2), n = TREE_CHAIN (n), i++)
    {
      if (TREE_PURPOSE (p1) && !TREE_PURPOSE (p2))
	{
	  TREE_PURPOSE (n) = TREE_PURPOSE (p1);
	  any_change = 1;
	}
      else if (! TREE_PURPOSE (p1))
	{
	  if (TREE_PURPOSE (p2))
	    {
	      TREE_PURPOSE (n) = TREE_PURPOSE (p2);
	      any_change = 1;
	    }
	}
      else
	{
	  if (simple_cst_equal (TREE_PURPOSE (p1), TREE_PURPOSE (p2)) != 1)
	    any_change = 1;
	  TREE_PURPOSE (n) = TREE_PURPOSE (p2);
	}
      if (TREE_VALUE (p1) != TREE_VALUE (p2))
	{
	  any_change = 1;
	  TREE_VALUE (n) = merge_types (TREE_VALUE (p1), TREE_VALUE (p2));
	}
      else
	TREE_VALUE (n) = TREE_VALUE (p1);
    }
  if (! any_change)
    return oldargs;

  return newargs;
}

/* Given a type, perhaps copied for a typedef,
   find the "original" version of it.  */
static tree
original_type (tree t)
{
  int quals = cp_type_quals (t);
  while (t != error_mark_node
	 && TYPE_NAME (t) != NULL_TREE)
    {
      tree x = TYPE_NAME (t);
      if (TREE_CODE (x) != TYPE_DECL)
	break;
      x = DECL_ORIGINAL_TYPE (x);
      if (x == NULL_TREE)
	break;
      t = x;
    }
  return cp_build_qualified_type (t, quals);
}

/* Merge the attributes of type OTHER_TYPE into the attributes of type TYPE
   and return a variant of TYPE with the merged attributes.  */

static tree
merge_type_attributes_from (tree type, tree other_type)
{
  tree attrs = targetm.merge_type_attributes (type, other_type);
  attrs = restrict_type_identity_attributes_to (attrs, TYPE_ATTRIBUTES (type));
  return cp_build_type_attribute_variant (type, attrs);
}

/* Return the common type for two arithmetic types T1 and T2 under the
   usual arithmetic conversions.  The default conversions have already
   been applied, and enumerated types converted to their compatible
   integer types.  */

static tree
cp_common_type (tree t1, tree t2)
{
  enum tree_code code1 = TREE_CODE (t1);
  enum tree_code code2 = TREE_CODE (t2);
  tree attributes;
  int i;


  /* In what follows, we slightly generalize the rules given in [expr] so
     as to deal with `long long' and `complex'.  First, merge the
     attributes.  */
  attributes = (*targetm.merge_type_attributes) (t1, t2);

  if (SCOPED_ENUM_P (t1) || SCOPED_ENUM_P (t2))
    {
      if (TYPE_MAIN_VARIANT (t1) == TYPE_MAIN_VARIANT (t2))
	return build_type_attribute_variant (t1, attributes);
      else
	return NULL_TREE;
    }

  /* FIXME: Attributes.  */
  gcc_assert (ARITHMETIC_TYPE_P (t1)
	      || VECTOR_TYPE_P (t1)
	      || UNSCOPED_ENUM_P (t1));
  gcc_assert (ARITHMETIC_TYPE_P (t2)
	      || VECTOR_TYPE_P (t2)
	      || UNSCOPED_ENUM_P (t2));

  /* If one type is complex, form the common type of the non-complex
     components, then make that complex.  Use T1 or T2 if it is the
     required type.  */
  if (code1 == COMPLEX_TYPE || code2 == COMPLEX_TYPE)
    {
      tree subtype1 = code1 == COMPLEX_TYPE ? TREE_TYPE (t1) : t1;
      tree subtype2 = code2 == COMPLEX_TYPE ? TREE_TYPE (t2) : t2;
      tree subtype
	= type_after_usual_arithmetic_conversions (subtype1, subtype2);

      if (code1 == COMPLEX_TYPE && TREE_TYPE (t1) == subtype)
	return build_type_attribute_variant (t1, attributes);
      else if (code2 == COMPLEX_TYPE && TREE_TYPE (t2) == subtype)
	return build_type_attribute_variant (t2, attributes);
      else
	return build_type_attribute_variant (build_complex_type (subtype),
					     attributes);
    }

  if (code1 == VECTOR_TYPE)
    {
      /* When we get here we should have two vectors of the same size.
	 Just prefer the unsigned one if present.  */
      if (TYPE_UNSIGNED (t1))
	return merge_type_attributes_from (t1, t2);
      else
	return merge_type_attributes_from (t2, t1);
    }

  /* If only one is real, use it as the result.  */
  if (code1 == REAL_TYPE && code2 != REAL_TYPE)
    return build_type_attribute_variant (t1, attributes);
  if (code2 == REAL_TYPE && code1 != REAL_TYPE)
    return build_type_attribute_variant (t2, attributes);

  /* Both real or both integers; use the one with greater precision.  */
  if (TYPE_PRECISION (t1) > TYPE_PRECISION (t2))
    return build_type_attribute_variant (t1, attributes);
  else if (TYPE_PRECISION (t2) > TYPE_PRECISION (t1))
    return build_type_attribute_variant (t2, attributes);

  /* The types are the same; no need to do anything fancy.  */
  if (TYPE_MAIN_VARIANT (t1) == TYPE_MAIN_VARIANT (t2))
    return build_type_attribute_variant (t1, attributes);

  if (code1 != REAL_TYPE)
    {
      /* If one is unsigned long long, then convert the other to unsigned
	 long long.  */
      if (same_type_p (TYPE_MAIN_VARIANT (t1), long_long_unsigned_type_node)
	  || same_type_p (TYPE_MAIN_VARIANT (t2), long_long_unsigned_type_node))
	return build_type_attribute_variant (long_long_unsigned_type_node,
					     attributes);
      /* If one is a long long, and the other is an unsigned long, and
	 long long can represent all the values of an unsigned long, then
	 convert to a long long.  Otherwise, convert to an unsigned long
	 long.  Otherwise, if either operand is long long, convert the
	 other to long long.

	 Since we're here, we know the TYPE_PRECISION is the same;
	 therefore converting to long long cannot represent all the values
	 of an unsigned long, so we choose unsigned long long in that
	 case.  */
      if (same_type_p (TYPE_MAIN_VARIANT (t1), long_long_integer_type_node)
	  || same_type_p (TYPE_MAIN_VARIANT (t2), long_long_integer_type_node))
	{
	  tree t = ((TYPE_UNSIGNED (t1) || TYPE_UNSIGNED (t2))
		    ? long_long_unsigned_type_node
		    : long_long_integer_type_node);
	  return build_type_attribute_variant (t, attributes);
	}

      /* Go through the same procedure, but for longs.  */
      if (same_type_p (TYPE_MAIN_VARIANT (t1), long_unsigned_type_node)
	  || same_type_p (TYPE_MAIN_VARIANT (t2), long_unsigned_type_node))
	return build_type_attribute_variant (long_unsigned_type_node,
					     attributes);
      if (same_type_p (TYPE_MAIN_VARIANT (t1), long_integer_type_node)
	  || same_type_p (TYPE_MAIN_VARIANT (t2), long_integer_type_node))
	{
	  tree t = ((TYPE_UNSIGNED (t1) || TYPE_UNSIGNED (t2))
		    ? long_unsigned_type_node : long_integer_type_node);
	  return build_type_attribute_variant (t, attributes);
	}

      /* For __intN types, either the type is __int128 (and is lower
	 priority than the types checked above, but higher than other
	 128-bit types) or it's known to not be the same size as other
	 types (enforced in toplev.c).  Prefer the unsigned type. */
      for (i = 0; i < NUM_INT_N_ENTS; i ++)
	{
	  if (int_n_enabled_p [i]
	      && (same_type_p (TYPE_MAIN_VARIANT (t1), int_n_trees[i].signed_type)
		  || same_type_p (TYPE_MAIN_VARIANT (t2), int_n_trees[i].signed_type)
		  || same_type_p (TYPE_MAIN_VARIANT (t1), int_n_trees[i].unsigned_type)
		  || same_type_p (TYPE_MAIN_VARIANT (t2), int_n_trees[i].unsigned_type)))
	    {
	      tree t = ((TYPE_UNSIGNED (t1) || TYPE_UNSIGNED (t2))
			? int_n_trees[i].unsigned_type
			: int_n_trees[i].signed_type);
	      return build_type_attribute_variant (t, attributes);
	    }
	}

      /* Otherwise prefer the unsigned one.  */
      if (TYPE_UNSIGNED (t1))
	return build_type_attribute_variant (t1, attributes);
      else
	return build_type_attribute_variant (t2, attributes);
    }
  else
    {
      if (same_type_p (TYPE_MAIN_VARIANT (t1), long_double_type_node)
	  || same_type_p (TYPE_MAIN_VARIANT (t2), long_double_type_node))
	return build_type_attribute_variant (long_double_type_node,
					     attributes);
      if (same_type_p (TYPE_MAIN_VARIANT (t1), double_type_node)
	  || same_type_p (TYPE_MAIN_VARIANT (t2), double_type_node))
	return build_type_attribute_variant (double_type_node,
					     attributes);
      if (same_type_p (TYPE_MAIN_VARIANT (t1), float_type_node)
	  || same_type_p (TYPE_MAIN_VARIANT (t2), float_type_node))
	return build_type_attribute_variant (float_type_node,
					     attributes);

      /* Two floating-point types whose TYPE_MAIN_VARIANTs are none of
	 the standard C++ floating-point types.  Logic earlier in this
	 function has already eliminated the possibility that
	 TYPE_PRECISION (t2) != TYPE_PRECISION (t1), so there's no
	 compelling reason to choose one or the other.  */
      return build_type_attribute_variant (t1, attributes);
    }
}

/* T1 and T2 are arithmetic or enumeration types.  Return the type
   that will result from the "usual arithmetic conversions" on T1 and
   T2 as described in [expr].  */

tree
type_after_usual_arithmetic_conversions (tree t1, tree t2)
{
  gcc_assert (ARITHMETIC_TYPE_P (t1)
	      || VECTOR_TYPE_P (t1)
	      || UNSCOPED_ENUM_P (t1));
  gcc_assert (ARITHMETIC_TYPE_P (t2)
	      || VECTOR_TYPE_P (t2)
	      || UNSCOPED_ENUM_P (t2));

  /* Perform the integral promotions.  We do not promote real types here.  */
  if (INTEGRAL_OR_ENUMERATION_TYPE_P (t1)
      && INTEGRAL_OR_ENUMERATION_TYPE_P (t2))
    {
      t1 = type_promotes_to (t1);
      t2 = type_promotes_to (t2);
    }

  return cp_common_type (t1, t2);
}

static void
composite_pointer_error (const op_location_t &location,
			 diagnostic_t kind, tree t1, tree t2,
			 composite_pointer_operation operation)
{
  switch (operation)
    {
    case CPO_COMPARISON:
      emit_diagnostic (kind, location, 0,
		       "comparison between "
		       "distinct pointer types %qT and %qT lacks a cast",
		       t1, t2);
      break;
    case CPO_CONVERSION:
      emit_diagnostic (kind, location, 0,
		       "conversion between "
		       "distinct pointer types %qT and %qT lacks a cast",
		       t1, t2);
      break;
    case CPO_CONDITIONAL_EXPR:
      emit_diagnostic (kind, location, 0,
		       "conditional expression between "
		       "distinct pointer types %qT and %qT lacks a cast",
		       t1, t2);
      break;
    default:
      gcc_unreachable ();
    }
}

/* Subroutine of composite_pointer_type to implement the recursive
   case.  See that function for documentation of the parameters.  And ADD_CONST
   is used to track adding "const" where needed.  */

static tree
composite_pointer_type_r (const op_location_t &location,
			  tree t1, tree t2, bool *add_const,
			  composite_pointer_operation operation,
			  tsubst_flags_t complain)
{
  tree pointee1;
  tree pointee2;
  tree result_type;
  tree attributes;

  /* Determine the types pointed to by T1 and T2.  */
  if (TYPE_PTR_P (t1))
    {
      pointee1 = TREE_TYPE (t1);
      pointee2 = TREE_TYPE (t2);
    }
  else
    {
      pointee1 = TYPE_PTRMEM_POINTED_TO_TYPE (t1);
      pointee2 = TYPE_PTRMEM_POINTED_TO_TYPE (t2);
    }

  /* [expr.type]

     If T1 and T2 are similar types, the result is the cv-combined type of
     T1 and T2.  */
  if (same_type_ignoring_top_level_qualifiers_p (pointee1, pointee2))
    result_type = pointee1;
  else if ((TYPE_PTR_P (pointee1) && TYPE_PTR_P (pointee2))
	   || (TYPE_PTRMEM_P (pointee1) && TYPE_PTRMEM_P (pointee2)))
    {
      result_type = composite_pointer_type_r (location, pointee1, pointee2,
					      add_const, operation, complain);
      if (result_type == error_mark_node)
	return error_mark_node;
    }
  else
    {
      if (complain & tf_error)
	composite_pointer_error (location, DK_PERMERROR,
				 t1, t2, operation);
      else
	return error_mark_node;
      result_type = void_type_node;
    }
  const int q1 = cp_type_quals (pointee1);
  const int q2 = cp_type_quals (pointee2);
  const int quals = q1 | q2;
  result_type = cp_build_qualified_type (result_type,
					 (quals | (*add_const
						   ? TYPE_QUAL_CONST
						   : TYPE_UNQUALIFIED)));
  /* The cv-combined type can add "const" as per [conv.qual]/3.3 (except for
     the TLQ).  The reason is that both T1 and T2 can then be converted to the
     cv-combined type of T1 and T2.  */
  if (quals != q1 || quals != q2)
    *add_const = true;
  /* If the original types were pointers to members, so is the
     result.  */
  if (TYPE_PTRMEM_P (t1))
    {
      if (!same_type_p (TYPE_PTRMEM_CLASS_TYPE (t1),
			TYPE_PTRMEM_CLASS_TYPE (t2)))
	{
	  if (complain & tf_error)
	    composite_pointer_error (location, DK_PERMERROR,
				     t1, t2, operation);
	  else
	    return error_mark_node;
	}
      result_type = build_ptrmem_type (TYPE_PTRMEM_CLASS_TYPE (t1),
				       result_type);
    }
  else
    result_type = build_pointer_type (result_type);

  /* Merge the attributes.  */
  attributes = (*targetm.merge_type_attributes) (t1, t2);
  return build_type_attribute_variant (result_type, attributes);
}

/* Return the composite pointer type (see [expr.type]) for T1 and T2.
   ARG1 and ARG2 are the values with those types.  The OPERATION is to
   describe the operation between the pointer types,
   in case an error occurs.

   This routine also implements the computation of a common type for
   pointers-to-members as per [expr.eq].  */

tree
composite_pointer_type (const op_location_t &location,
			tree t1, tree t2, tree arg1, tree arg2,
			composite_pointer_operation operation, 
			tsubst_flags_t complain)
{
  tree class1;
  tree class2;

  /* [expr.type]

     If one operand is a null pointer constant, the composite pointer
     type is the type of the other operand.  */
  if (null_ptr_cst_p (arg1))
    return t2;
  if (null_ptr_cst_p (arg2))
    return t1;

  /* We have:

       [expr.type]

       If one of the operands has type "pointer to cv1 void", then
       the other has type "pointer to cv2 T", and the composite pointer
       type is "pointer to cv12 void", where cv12 is the union of cv1
       and cv2.

    If either type is a pointer to void, make sure it is T1.  */
  if (TYPE_PTR_P (t2) && VOID_TYPE_P (TREE_TYPE (t2)))
    std::swap (t1, t2);

  /* Now, if T1 is a pointer to void, merge the qualifiers.  */
  if (TYPE_PTR_P (t1) && VOID_TYPE_P (TREE_TYPE (t1)))
    {
      tree attributes;
      tree result_type;

      if (TYPE_PTRFN_P (t2))
	{
	  if (complain & tf_error)
	    {
	      switch (operation)
		{
		case CPO_COMPARISON:
		  pedwarn (location, OPT_Wpedantic, 
			   "ISO C++ forbids comparison between pointer "
			   "of type %<void *%> and pointer-to-function");
		  break;
		case CPO_CONVERSION:
		  pedwarn (location, OPT_Wpedantic,
			   "ISO C++ forbids conversion between pointer "
			   "of type %<void *%> and pointer-to-function");
		  break;
		case CPO_CONDITIONAL_EXPR:
		  pedwarn (location, OPT_Wpedantic,
			   "ISO C++ forbids conditional expression between "
			   "pointer of type %<void *%> and "
			   "pointer-to-function");
		  break;
		default:
		  gcc_unreachable ();
		}
	    }
	  else
	    return error_mark_node;
        }
      result_type
	= cp_build_qualified_type (void_type_node,
				   (cp_type_quals (TREE_TYPE (t1))
				    | cp_type_quals (TREE_TYPE (t2))));
      result_type = build_pointer_type (result_type);
      /* Merge the attributes.  */
      attributes = (*targetm.merge_type_attributes) (t1, t2);
      return build_type_attribute_variant (result_type, attributes);
    }

  if (c_dialect_objc () && TYPE_PTR_P (t1)
      && TYPE_PTR_P (t2))
    {
      if (objc_have_common_type (t1, t2, -3, NULL_TREE))
	return objc_common_type (t1, t2);
    }

  /* if T1 or T2 is "pointer to noexcept function" and the other type is
     "pointer to function", where the function types are otherwise the same,
     "pointer to function" */
  if (fnptr_conv_p (t1, t2))
    return t1;
  if (fnptr_conv_p (t2, t1))
    return t2;

  /* [expr.eq] permits the application of a pointer conversion to
     bring the pointers to a common type.  */
  if (TYPE_PTR_P (t1) && TYPE_PTR_P (t2)
      && CLASS_TYPE_P (TREE_TYPE (t1))
      && CLASS_TYPE_P (TREE_TYPE (t2))
      && !same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (t1),
						     TREE_TYPE (t2)))
    {
      class1 = TREE_TYPE (t1);
      class2 = TREE_TYPE (t2);

      if (DERIVED_FROM_P (class1, class2))
	t2 = (build_pointer_type
	      (cp_build_qualified_type (class1, cp_type_quals (class2))));
      else if (DERIVED_FROM_P (class2, class1))
	t1 = (build_pointer_type
	      (cp_build_qualified_type (class2, cp_type_quals (class1))));
      else
        {
          if (complain & tf_error)
	    composite_pointer_error (location, DK_ERROR, t1, t2, operation);
          return error_mark_node;
        }
    }
  /* [expr.eq] permits the application of a pointer-to-member
     conversion to change the class type of one of the types.  */
  else if (TYPE_PTRMEM_P (t1)
           && !same_type_p (TYPE_PTRMEM_CLASS_TYPE (t1),
			    TYPE_PTRMEM_CLASS_TYPE (t2)))
    {
      class1 = TYPE_PTRMEM_CLASS_TYPE (t1);
      class2 = TYPE_PTRMEM_CLASS_TYPE (t2);

      if (DERIVED_FROM_P (class1, class2))
	t1 = build_ptrmem_type (class2, TYPE_PTRMEM_POINTED_TO_TYPE (t1));
      else if (DERIVED_FROM_P (class2, class1))
	t2 = build_ptrmem_type (class1, TYPE_PTRMEM_POINTED_TO_TYPE (t2));
      else
        {
          if (complain & tf_error)
            switch (operation)
              {
              case CPO_COMPARISON:
                error_at (location, "comparison between distinct "
			  "pointer-to-member types %qT and %qT lacks a cast",
			  t1, t2);
                break;
              case CPO_CONVERSION:
                error_at (location, "conversion between distinct "
			  "pointer-to-member types %qT and %qT lacks a cast",
			  t1, t2);
                break;
              case CPO_CONDITIONAL_EXPR:
                error_at (location, "conditional expression between distinct "
			  "pointer-to-member types %qT and %qT lacks a cast",
			  t1, t2);
                break;
              default:
                gcc_unreachable ();
              }
          return error_mark_node;
        }
    }

  bool add_const = false;
  return composite_pointer_type_r (location, t1, t2, &add_const, operation,
				   complain);
}

/* Return the merged type of two types.
   We assume that comptypes has already been done and returned 1;
   if that isn't so, this may crash.

   This just combines attributes and default arguments; any other
   differences would cause the two types to compare unalike.  */

tree
merge_types (tree t1, tree t2)
{
  enum tree_code code1;
  enum tree_code code2;
  tree attributes;

  /* Save time if the two types are the same.  */
  if (t1 == t2)
    return t1;
  if (original_type (t1) == original_type (t2))
    return t1;

  /* If one type is nonsense, use the other.  */
  if (t1 == error_mark_node)
    return t2;
  if (t2 == error_mark_node)
    return t1;

  /* Handle merging an auto redeclaration with a previous deduced
     return type.  */
  if (is_auto (t1))
    return t2;

  /* Merge the attributes.  */
  attributes = (*targetm.merge_type_attributes) (t1, t2);

  if (TYPE_PTRMEMFUNC_P (t1))
    t1 = TYPE_PTRMEMFUNC_FN_TYPE (t1);
  if (TYPE_PTRMEMFUNC_P (t2))
    t2 = TYPE_PTRMEMFUNC_FN_TYPE (t2);

  code1 = TREE_CODE (t1);
  code2 = TREE_CODE (t2);
  if (code1 != code2)
    {
      gcc_assert (code1 == TYPENAME_TYPE || code2 == TYPENAME_TYPE);
      if (code1 == TYPENAME_TYPE)
	{
          t1 = resolve_typename_type (t1, /*only_current_p=*/true);
	  code1 = TREE_CODE (t1);
	}
      else
	{
          t2 = resolve_typename_type (t2, /*only_current_p=*/true);
	  code2 = TREE_CODE (t2);
	}
    }

  switch (code1)
    {
    case POINTER_TYPE:
    case REFERENCE_TYPE:
      /* For two pointers, do this recursively on the target type.  */
      {
	tree target = merge_types (TREE_TYPE (t1), TREE_TYPE (t2));
	int quals = cp_type_quals (t1);

	if (code1 == POINTER_TYPE)
	  {
	    t1 = build_pointer_type (target);
	    if (TREE_CODE (target) == METHOD_TYPE)
	      t1 = build_ptrmemfunc_type (t1);
	  }
	else
	  t1 = cp_build_reference_type (target, TYPE_REF_IS_RVALUE (t1));
	t1 = build_type_attribute_variant (t1, attributes);
	t1 = cp_build_qualified_type (t1, quals);

	return t1;
      }

    case OFFSET_TYPE:
      {
	int quals;
	tree pointee;
	quals = cp_type_quals (t1);
	pointee = merge_types (TYPE_PTRMEM_POINTED_TO_TYPE (t1),
			       TYPE_PTRMEM_POINTED_TO_TYPE (t2));
	t1 = build_ptrmem_type (TYPE_PTRMEM_CLASS_TYPE (t1),
				pointee);
	t1 = cp_build_qualified_type (t1, quals);
	break;
      }

    case ARRAY_TYPE:
      {
	tree elt = merge_types (TREE_TYPE (t1), TREE_TYPE (t2));
	/* Save space: see if the result is identical to one of the args.  */
	if (elt == TREE_TYPE (t1) && TYPE_DOMAIN (t1))
	  return build_type_attribute_variant (t1, attributes);
	if (elt == TREE_TYPE (t2) && TYPE_DOMAIN (t2))
	  return build_type_attribute_variant (t2, attributes);
	/* Merge the element types, and have a size if either arg has one.  */
	t1 = build_cplus_array_type
	  (elt, TYPE_DOMAIN (TYPE_DOMAIN (t1) ? t1 : t2));
	break;
      }

    case FUNCTION_TYPE:
      /* Function types: prefer the one that specified arg types.
	 If both do, merge the arg types.  Also merge the return types.  */
      {
	tree valtype = merge_types (TREE_TYPE (t1), TREE_TYPE (t2));
	tree p1 = TYPE_ARG_TYPES (t1);
	tree p2 = TYPE_ARG_TYPES (t2);
	tree parms;

	/* Save space: see if the result is identical to one of the args.  */
	if (valtype == TREE_TYPE (t1) && ! p2)
	  return cp_build_type_attribute_variant (t1, attributes);
	if (valtype == TREE_TYPE (t2) && ! p1)
	  return cp_build_type_attribute_variant (t2, attributes);

	/* Simple way if one arg fails to specify argument types.  */
	if (p1 == NULL_TREE || TREE_VALUE (p1) == void_type_node)
	  parms = p2;
	else if (p2 == NULL_TREE || TREE_VALUE (p2) == void_type_node)
	  parms = p1;
	else
	  parms = commonparms (p1, p2);

	cp_cv_quals quals = type_memfn_quals (t1);
	cp_ref_qualifier rqual = type_memfn_rqual (t1);
	gcc_assert (quals == type_memfn_quals (t2));
	gcc_assert (rqual == type_memfn_rqual (t2));

	tree rval = build_function_type (valtype, parms);
	rval = apply_memfn_quals (rval, quals);
	tree raises = merge_exception_specifiers (TYPE_RAISES_EXCEPTIONS (t1),
						  TYPE_RAISES_EXCEPTIONS (t2));
	bool late_return_type_p = TYPE_HAS_LATE_RETURN_TYPE (t1);
	t1 = build_cp_fntype_variant (rval, rqual, raises, late_return_type_p);
	break;
      }

    case METHOD_TYPE:
      {
	/* Get this value the long way, since TYPE_METHOD_BASETYPE
	   is just the main variant of this.  */
	tree basetype = class_of_this_parm (t2);
	tree raises = merge_exception_specifiers (TYPE_RAISES_EXCEPTIONS (t1),
						  TYPE_RAISES_EXCEPTIONS (t2));
	cp_ref_qualifier rqual = type_memfn_rqual (t1);
	tree t3;
	bool late_return_type_1_p = TYPE_HAS_LATE_RETURN_TYPE (t1);

	/* If this was a member function type, get back to the
	   original type of type member function (i.e., without
	   the class instance variable up front.  */
	t1 = build_function_type (TREE_TYPE (t1),
				  TREE_CHAIN (TYPE_ARG_TYPES (t1)));
	t2 = build_function_type (TREE_TYPE (t2),
				  TREE_CHAIN (TYPE_ARG_TYPES (t2)));
	t3 = merge_types (t1, t2);
	t3 = build_method_type_directly (basetype, TREE_TYPE (t3),
					 TYPE_ARG_TYPES (t3));
	t1 = build_cp_fntype_variant (t3, rqual, raises, late_return_type_1_p);
	break;
      }

    case TYPENAME_TYPE:
      /* There is no need to merge attributes into a TYPENAME_TYPE.
	 When the type is instantiated it will have whatever
	 attributes result from the instantiation.  */
      return t1;

    default:;
      if (attribute_list_equal (TYPE_ATTRIBUTES (t1), attributes))
	return t1;
      else if (attribute_list_equal (TYPE_ATTRIBUTES (t2), attributes))
	return t2;
      break;
    }

  return cp_build_type_attribute_variant (t1, attributes);
}

/* Return the ARRAY_TYPE type without its domain.  */

tree
strip_array_domain (tree type)
{
  tree t2;
  gcc_assert (TREE_CODE (type) == ARRAY_TYPE);
  if (TYPE_DOMAIN (type) == NULL_TREE)
    return type;
  t2 = build_cplus_array_type (TREE_TYPE (type), NULL_TREE);
  return cp_build_type_attribute_variant (t2, TYPE_ATTRIBUTES (type));
}

/* Wrapper around cp_common_type that is used by c-common.c and other
   front end optimizations that remove promotions.  

   Return the common type for two arithmetic types T1 and T2 under the
   usual arithmetic conversions.  The default conversions have already
   been applied, and enumerated types converted to their compatible
   integer types.  */

tree
common_type (tree t1, tree t2)
{
  /* If one type is nonsense, use the other  */
  if (t1 == error_mark_node)
    return t2;
  if (t2 == error_mark_node)
    return t1;

  return cp_common_type (t1, t2);
}

/* Return the common type of two pointer types T1 and T2.  This is the
   type for the result of most arithmetic operations if the operands
   have the given two types.
 
   We assume that comp_target_types has already been done and returned
   nonzero; if that isn't so, this may crash.  */

tree
common_pointer_type (tree t1, tree t2)
{
  gcc_assert ((TYPE_PTR_P (t1) && TYPE_PTR_P (t2))
              || (TYPE_PTRDATAMEM_P (t1) && TYPE_PTRDATAMEM_P (t2))
              || (TYPE_PTRMEMFUNC_P (t1) && TYPE_PTRMEMFUNC_P (t2)));

  return composite_pointer_type (input_location, t1, t2,
				 error_mark_node, error_mark_node,
                                 CPO_CONVERSION, tf_warning_or_error);
}

/* Compare two exception specifier types for exactness or subsetness, if
   allowed. Returns false for mismatch, true for match (same, or
   derived and !exact).

   [except.spec] "If a class X ... objects of class X or any class publicly
   and unambiguously derived from X. Similarly, if a pointer type Y * ...
   exceptions of type Y * or that are pointers to any type publicly and
   unambiguously derived from Y. Otherwise a function only allows exceptions
   that have the same type ..."
   This does not mention cv qualifiers and is different to what throw
   [except.throw] and catch [except.catch] will do. They will ignore the
   top level cv qualifiers, and allow qualifiers in the pointer to class
   example.

   We implement the letter of the standard.  */

static bool
comp_except_types (tree a, tree b, bool exact)
{
  if (same_type_p (a, b))
    return true;
  else if (!exact)
    {
      if (cp_type_quals (a) || cp_type_quals (b))
	return false;

      if (TYPE_PTR_P (a) && TYPE_PTR_P (b))
	{
	  a = TREE_TYPE (a);
	  b = TREE_TYPE (b);
	  if (cp_type_quals (a) || cp_type_quals (b))
	    return false;
	}

      if (TREE_CODE (a) != RECORD_TYPE
	  || TREE_CODE (b) != RECORD_TYPE)
	return false;

      if (publicly_uniquely_derived_p (a, b))
	return true;
    }
  return false;
}

/* Return true if TYPE1 and TYPE2 are equivalent exception specifiers.
   If EXACT is ce_derived, T2 can be stricter than T1 (according to 15.4/5).
   If EXACT is ce_type, the C++17 type compatibility rules apply.
   If EXACT is ce_normal, the compatibility rules in 15.4/3 apply.
   If EXACT is ce_exact, the specs must be exactly the same. Exception lists
   are unordered, but we've already filtered out duplicates. Most lists will
   be in order, we should try to make use of that.  */

bool
comp_except_specs (const_tree t1, const_tree t2, int exact)
{
  const_tree probe;
  const_tree base;
  int  length = 0;

  if (t1 == t2)
    return true;

  /* First handle noexcept.  */
  if (exact < ce_exact)
    {
      if (exact == ce_type
	  && (canonical_eh_spec (CONST_CAST_TREE (t1))
	      == canonical_eh_spec (CONST_CAST_TREE (t2))))
	return true;

      /* noexcept(false) is compatible with no exception-specification,
	 and less strict than any spec.  */
      if (t1 == noexcept_false_spec)
	return t2 == NULL_TREE || exact == ce_derived;
      /* Even a derived noexcept(false) is compatible with no
	 exception-specification.  */
      if (t2 == noexcept_false_spec)
	return t1 == NULL_TREE;

      /* Otherwise, if we aren't looking for an exact match, noexcept is
	 equivalent to throw().  */
      if (t1 == noexcept_true_spec)
	t1 = empty_except_spec;
      if (t2 == noexcept_true_spec)
	t2 = empty_except_spec;
    }

  /* If any noexcept is left, it is only comparable to itself;
     either we're looking for an exact match or we're redeclaring a
     template with dependent noexcept.  */
  if ((t1 && TREE_PURPOSE (t1))
      || (t2 && TREE_PURPOSE (t2)))
    return (t1 && t2
	    && cp_tree_equal (TREE_PURPOSE (t1), TREE_PURPOSE (t2)));

  if (t1 == NULL_TREE)			   /* T1 is ...  */
    return t2 == NULL_TREE || exact == ce_derived;
  if (!TREE_VALUE (t1))			   /* t1 is EMPTY */
    return t2 != NULL_TREE && !TREE_VALUE (t2);
  if (t2 == NULL_TREE)			   /* T2 is ...  */
    return false;
  if (TREE_VALUE (t1) && !TREE_VALUE (t2)) /* T2 is EMPTY, T1 is not */
    return exact == ce_derived;

  /* Neither set is ... or EMPTY, make sure each part of T2 is in T1.
     Count how many we find, to determine exactness. For exact matching and
     ordered T1, T2, this is an O(n) operation, otherwise its worst case is
     O(nm).  */
  for (base = t1; t2 != NULL_TREE; t2 = TREE_CHAIN (t2))
    {
      for (probe = base; probe != NULL_TREE; probe = TREE_CHAIN (probe))
	{
	  tree a = TREE_VALUE (probe);
	  tree b = TREE_VALUE (t2);

	  if (comp_except_types (a, b, exact))
	    {
	      if (probe == base && exact > ce_derived)
		base = TREE_CHAIN (probe);
	      length++;
	      break;
	    }
	}
      if (probe == NULL_TREE)
	return false;
    }
  return exact == ce_derived || base == NULL_TREE || length == list_length (t1);
}

/* Compare the array types T1 and T2.  CB says how we should behave when
   comparing array bounds: bounds_none doesn't allow dimensionless arrays,
   bounds_either says than any array can be [], bounds_first means that
   onlt T1 can be an array with unknown bounds.  STRICT is true if
   qualifiers must match when comparing the types of the array elements.  */

static bool
comp_array_types (const_tree t1, const_tree t2, compare_bounds_t cb,
		  bool strict)
{
  tree d1;
  tree d2;
  tree max1, max2;

  if (t1 == t2)
    return true;

  /* The type of the array elements must be the same.  */
  if (strict
      ? !same_type_p (TREE_TYPE (t1), TREE_TYPE (t2))
      : !similar_type_p (TREE_TYPE (t1), TREE_TYPE (t2)))
    return false;

  d1 = TYPE_DOMAIN (t1);
  d2 = TYPE_DOMAIN (t2);

  if (d1 == d2)
    return true;

  /* If one of the arrays is dimensionless, and the other has a
     dimension, they are of different types.  However, it is valid to
     write:

       extern int a[];
       int a[3];

     by [basic.link]:

       declarations for an array object can specify
       array types that differ by the presence or absence of a major
       array bound (_dcl.array_).  */
  if (!d1 && d2)
    return cb >= bounds_either;
  else if (d1 && !d2)
    return cb == bounds_either;

  /* Check that the dimensions are the same.  */

  if (!cp_tree_equal (TYPE_MIN_VALUE (d1), TYPE_MIN_VALUE (d2)))
    return false;
  max1 = TYPE_MAX_VALUE (d1);
  max2 = TYPE_MAX_VALUE (d2);

  if (!cp_tree_equal (max1, max2))
    return false;

  return true;
}

/* Compare the relative position of T1 and T2 into their respective
   template parameter list.
   T1 and T2 must be template parameter types.
   Return TRUE if T1 and T2 have the same position, FALSE otherwise.  */

static bool
comp_template_parms_position (tree t1, tree t2)
{
  tree index1, index2;
  gcc_assert (t1 && t2
	      && TREE_CODE (t1) == TREE_CODE (t2)
	      && (TREE_CODE (t1) == BOUND_TEMPLATE_TEMPLATE_PARM
		  || TREE_CODE (t1) == TEMPLATE_TEMPLATE_PARM
		  || TREE_CODE (t1) == TEMPLATE_TYPE_PARM));

  index1 = TEMPLATE_TYPE_PARM_INDEX (TYPE_MAIN_VARIANT (t1));
  index2 = TEMPLATE_TYPE_PARM_INDEX (TYPE_MAIN_VARIANT (t2));

  /* Then compare their relative position.  */
  if (TEMPLATE_PARM_IDX (index1) != TEMPLATE_PARM_IDX (index2)
      || TEMPLATE_PARM_LEVEL (index1) != TEMPLATE_PARM_LEVEL (index2)
      || (TEMPLATE_PARM_PARAMETER_PACK (index1)
	  != TEMPLATE_PARM_PARAMETER_PACK (index2)))
    return false;

  /* In C++14 we can end up comparing 'auto' to a normal template
     parameter.  Don't confuse them.  */
  if (cxx_dialect >= cxx14 && (is_auto (t1) || is_auto (t2)))
    return TYPE_IDENTIFIER (t1) == TYPE_IDENTIFIER (t2);

  return true;
}

/* Heuristic check if two parameter types can be considered ABI-equivalent.  */

static bool
cxx_safe_arg_type_equiv_p (tree t1, tree t2)
{
  t1 = TYPE_MAIN_VARIANT (t1);
  t2 = TYPE_MAIN_VARIANT (t2);

  if (TYPE_PTR_P (t1)
      && TYPE_PTR_P (t2))
    return true;

  /* The signedness of the parameter matters only when an integral
     type smaller than int is promoted to int, otherwise only the
     precision of the parameter matters.
     This check should make sure that the callee does not see
     undefined values in argument registers.  */
  if (INTEGRAL_TYPE_P (t1)
      && INTEGRAL_TYPE_P (t2)
      && TYPE_PRECISION (t1) == TYPE_PRECISION (t2)
      && (TYPE_UNSIGNED (t1) == TYPE_UNSIGNED (t2)
	  || !targetm.calls.promote_prototypes (NULL_TREE)
	  || TYPE_PRECISION (t1) >= TYPE_PRECISION (integer_type_node)))
    return true;

  return same_type_p (t1, t2);
}

/* Check if a type cast between two function types can be considered safe.  */

static bool
cxx_safe_function_type_cast_p (tree t1, tree t2)
{
  if (TREE_TYPE (t1) == void_type_node &&
      TYPE_ARG_TYPES (t1) == void_list_node)
    return true;

  if (TREE_TYPE (t2) == void_type_node &&
      TYPE_ARG_TYPES (t2) == void_list_node)
    return true;

  if (!cxx_safe_arg_type_equiv_p (TREE_TYPE (t1), TREE_TYPE (t2)))
    return false;

  for (t1 = TYPE_ARG_TYPES (t1), t2 = TYPE_ARG_TYPES (t2);
       t1 && t2;
       t1 = TREE_CHAIN (t1), t2 = TREE_CHAIN (t2))
    if (!cxx_safe_arg_type_equiv_p (TREE_VALUE (t1), TREE_VALUE (t2)))
      return false;

  return true;
}

/* Subroutine in comptypes.  */

static bool
structural_comptypes (tree t1, tree t2, int strict)
{
  /* Both should be types that are not obviously the same.  */
  gcc_checking_assert (t1 != t2 && TYPE_P (t1) && TYPE_P (t2));

  /* Suppress typename resolution under spec_hasher::equal in place of calling
     push_to_top_level there.  */
  if (!comparing_specializations)
    {
      /* TYPENAME_TYPEs should be resolved if the qualifying scope is the
	 current instantiation.  */
      if (TREE_CODE (t1) == TYPENAME_TYPE)
	t1 = resolve_typename_type (t1, /*only_current_p=*/true);

      if (TREE_CODE (t2) == TYPENAME_TYPE)
	t2 = resolve_typename_type (t2, /*only_current_p=*/true);
    }

  if (TYPE_PTRMEMFUNC_P (t1))
    t1 = TYPE_PTRMEMFUNC_FN_TYPE (t1);
  if (TYPE_PTRMEMFUNC_P (t2))
    t2 = TYPE_PTRMEMFUNC_FN_TYPE (t2);

  /* Different classes of types can't be compatible.  */
  if (TREE_CODE (t1) != TREE_CODE (t2))
    return false;

  /* Qualifiers must match.  For array types, we will check when we
     recur on the array element types.  */
  if (TREE_CODE (t1) != ARRAY_TYPE
      && cp_type_quals (t1) != cp_type_quals (t2))
    return false;
  if (TREE_CODE (t1) == FUNCTION_TYPE
      && type_memfn_quals (t1) != type_memfn_quals (t2))
    return false;
  /* Need to check this before TYPE_MAIN_VARIANT.
     FIXME function qualifiers should really change the main variant.  */
  if (FUNC_OR_METHOD_TYPE_P (t1))
    {
      if (type_memfn_rqual (t1) != type_memfn_rqual (t2))
	return false;
      if (flag_noexcept_type
	  && !comp_except_specs (TYPE_RAISES_EXCEPTIONS (t1),
				 TYPE_RAISES_EXCEPTIONS (t2),
				 ce_type))
	return false;
    }

  /* Allow for two different type nodes which have essentially the same
     definition.  Note that we already checked for equality of the type
     qualifiers (just above).  */
  if (TREE_CODE (t1) != ARRAY_TYPE
      && TYPE_MAIN_VARIANT (t1) == TYPE_MAIN_VARIANT (t2))
    goto check_alias;

  /* Compare the types.  Return false on known not-same. Break on not
     known.   Never return true from this switch -- you'll break
     specialization comparison.    */
  switch (TREE_CODE (t1))
    {
    case VOID_TYPE:
    case BOOLEAN_TYPE:
      /* All void and bool types are the same.  */
      break;

    case OPAQUE_TYPE:
    case INTEGER_TYPE:
    case FIXED_POINT_TYPE:
    case REAL_TYPE:
      /* With these nodes, we can't determine type equivalence by
	 looking at what is stored in the nodes themselves, because
	 two nodes might have different TYPE_MAIN_VARIANTs but still
	 represent the same type.  For example, wchar_t and int could
	 have the same properties (TYPE_PRECISION, TYPE_MIN_VALUE,
	 TYPE_MAX_VALUE, etc.), but have different TYPE_MAIN_VARIANTs
	 and are distinct types. On the other hand, int and the
	 following typedef

           typedef int INT __attribute((may_alias));

	 have identical properties, different TYPE_MAIN_VARIANTs, but
	 represent the same type.  The canonical type system keeps
	 track of equivalence in this case, so we fall back on it.  */
      if (TYPE_CANONICAL (t1) != TYPE_CANONICAL (t2))
	return false;

      /* We don't need or want the attribute comparison.  */
      goto check_alias;

    case TEMPLATE_TEMPLATE_PARM:
    case BOUND_TEMPLATE_TEMPLATE_PARM:
      if (!comp_template_parms_position (t1, t2))
	return false;
      if (!comp_template_parms
	  (DECL_TEMPLATE_PARMS (TEMPLATE_TEMPLATE_PARM_TEMPLATE_DECL (t1)),
	   DECL_TEMPLATE_PARMS (TEMPLATE_TEMPLATE_PARM_TEMPLATE_DECL (t2))))
	return false;
      if (TREE_CODE (t1) == TEMPLATE_TEMPLATE_PARM)
	break;
      /* Don't check inheritance.  */
      strict = COMPARE_STRICT;
      /* Fall through.  */

    case RECORD_TYPE:
    case UNION_TYPE:
      if (TYPE_TEMPLATE_INFO (t1) && TYPE_TEMPLATE_INFO (t2)
	  && (TYPE_TI_TEMPLATE (t1) == TYPE_TI_TEMPLATE (t2)
	      || TREE_CODE (t1) == BOUND_TEMPLATE_TEMPLATE_PARM)
	  && comp_template_args (TYPE_TI_ARGS (t1), TYPE_TI_ARGS (t2)))
	break;

      if ((strict & COMPARE_BASE) && DERIVED_FROM_P (t1, t2))
	break;
      else if ((strict & COMPARE_DERIVED) && DERIVED_FROM_P (t2, t1))
	break;

      return false;

    case OFFSET_TYPE:
      if (!comptypes (TYPE_OFFSET_BASETYPE (t1), TYPE_OFFSET_BASETYPE (t2),
		      strict & ~COMPARE_REDECLARATION))
	return false;
      if (!same_type_p (TREE_TYPE (t1), TREE_TYPE (t2)))
	return false;
      break;

    case REFERENCE_TYPE:
      if (TYPE_REF_IS_RVALUE (t1) != TYPE_REF_IS_RVALUE (t2))
	return false;
      /* fall through to checks for pointer types */
      gcc_fallthrough ();

    case POINTER_TYPE:
      if (TYPE_MODE (t1) != TYPE_MODE (t2)
	  || !same_type_p (TREE_TYPE (t1), TREE_TYPE (t2)))
	return false;
      break;

    case METHOD_TYPE:
    case FUNCTION_TYPE:
      /* Exception specs and memfn_rquals were checked above.  */
      if (!same_type_p (TREE_TYPE (t1), TREE_TYPE (t2)))
	return false;
      if (!compparms (TYPE_ARG_TYPES (t1), TYPE_ARG_TYPES (t2)))
	return false;
      break;

    case ARRAY_TYPE:
      /* Target types must match incl. qualifiers.  */
      if (!comp_array_types (t1, t2, ((strict & COMPARE_REDECLARATION)
				      ? bounds_either : bounds_none),
			     /*strict=*/true))
	return false;
      break;

    case TEMPLATE_TYPE_PARM:
      /* If T1 and T2 don't have the same relative position in their
	 template parameters set, they can't be equal.  */
      if (!comp_template_parms_position (t1, t2))
	return false;
      /* If T1 and T2 don't represent the same class template deduction,
         they aren't equal.  */
      if (CLASS_PLACEHOLDER_TEMPLATE (t1)
	  != CLASS_PLACEHOLDER_TEMPLATE (t2))
	return false;
      /* Constrained 'auto's are distinct from parms that don't have the same
	 constraints.  */
      if (!equivalent_placeholder_constraints (t1, t2))
	return false;
      break;

    case TYPENAME_TYPE:
      if (!cp_tree_equal (TYPENAME_TYPE_FULLNAME (t1),
			  TYPENAME_TYPE_FULLNAME (t2)))
	return false;
      /* Qualifiers don't matter on scopes.  */
      if (!same_type_ignoring_top_level_qualifiers_p (TYPE_CONTEXT (t1),
						      TYPE_CONTEXT (t2)))
	return false;
      break;

    case UNBOUND_CLASS_TEMPLATE:
      if (!cp_tree_equal (TYPE_IDENTIFIER (t1), TYPE_IDENTIFIER (t2)))
	return false;
      if (!same_type_p (TYPE_CONTEXT (t1), TYPE_CONTEXT (t2)))
	return false;
      break;

    case COMPLEX_TYPE:
      if (!same_type_p (TREE_TYPE (t1), TREE_TYPE (t2)))
	return false;
      break;

    case VECTOR_TYPE:
      if (gnu_vector_type_p (t1) != gnu_vector_type_p (t2)
	  || maybe_ne (TYPE_VECTOR_SUBPARTS (t1), TYPE_VECTOR_SUBPARTS (t2))
	  || !same_type_p (TREE_TYPE (t1), TREE_TYPE (t2)))
	return false;
      break;

    case TYPE_PACK_EXPANSION:
      return (same_type_p (PACK_EXPANSION_PATTERN (t1),
			   PACK_EXPANSION_PATTERN (t2))
	      && comp_template_args (PACK_EXPANSION_EXTRA_ARGS (t1),
				     PACK_EXPANSION_EXTRA_ARGS (t2)));

    case DECLTYPE_TYPE:
      if (DECLTYPE_TYPE_ID_EXPR_OR_MEMBER_ACCESS_P (t1)
          != DECLTYPE_TYPE_ID_EXPR_OR_MEMBER_ACCESS_P (t2))
	return false;
      if (DECLTYPE_FOR_LAMBDA_CAPTURE (t1) != DECLTYPE_FOR_LAMBDA_CAPTURE (t2))
	return false;
      if (DECLTYPE_FOR_LAMBDA_PROXY (t1) != DECLTYPE_FOR_LAMBDA_PROXY (t2))
	return false;
      if (!cp_tree_equal (DECLTYPE_TYPE_EXPR (t1), DECLTYPE_TYPE_EXPR (t2)))
        return false;
      break;

    case UNDERLYING_TYPE:
      if (!same_type_p (UNDERLYING_TYPE_TYPE (t1), UNDERLYING_TYPE_TYPE (t2)))
	return false;
      break;

    case TYPEOF_TYPE:
      if (!cp_tree_equal (TYPEOF_TYPE_EXPR (t1), TYPEOF_TYPE_EXPR (t2)))
	return false;
      break;

    default:
      return false;
    }

  /* If we get here, we know that from a target independent POV the
     types are the same.  Make sure the target attributes are also
     the same.  */
  if (!comp_type_attributes (t1, t2))
    return false;

 check_alias:
  if (comparing_dependent_aliases)
    {
      /* Don't treat an alias template specialization with dependent
	 arguments as equivalent to its underlying type when used as a
	 template argument; we need them to be distinct so that we
	 substitute into the specialization arguments at instantiation
	 time.  And aliases can't be equivalent without being ==, so
	 we don't need to look any deeper.  */
      tree dep1 = dependent_alias_template_spec_p (t1, nt_transparent);
      tree dep2 = dependent_alias_template_spec_p (t2, nt_transparent);
      if ((dep1 || dep2) && dep1 != dep2)
	return false;
    }

  return true;
}

/* Return true if T1 and T2 are related as allowed by STRICT.  STRICT
   is a bitwise-or of the COMPARE_* flags.  */

bool
comptypes (tree t1, tree t2, int strict)
{
  gcc_checking_assert (t1 && t2);

  /* TYPE_ARGUMENT_PACKS are not really types.  */
  gcc_checking_assert (TREE_CODE (t1) != TYPE_ARGUMENT_PACK
		       && TREE_CODE (t2) != TYPE_ARGUMENT_PACK);

  if (t1 == t2)
    return true;

  /* Suppress errors caused by previously reported errors.  */
  if (t1 == error_mark_node || t2 == error_mark_node)
    return false;

  if (strict == COMPARE_STRICT)
    {
      if (TYPE_STRUCTURAL_EQUALITY_P (t1) || TYPE_STRUCTURAL_EQUALITY_P (t2))
	/* At least one of the types requires structural equality, so
	   perform a deep check. */
	return structural_comptypes (t1, t2, strict);

      if (flag_checking && param_use_canonical_types)
	{
	  bool result = structural_comptypes (t1, t2, strict);
	  
	  if (result && TYPE_CANONICAL (t1) != TYPE_CANONICAL (t2))
	    /* The two types are structurally equivalent, but their
	       canonical types were different. This is a failure of the
	       canonical type propagation code.*/
	    internal_error 
	      ("canonical types differ for identical types %qT and %qT",
	       t1, t2);
	  else if (!result && TYPE_CANONICAL (t1) == TYPE_CANONICAL (t2))
	    /* Two types are structurally different, but the canonical
	       types are the same. This means we were over-eager in
	       assigning canonical types. */
	    internal_error 
	      ("same canonical type node for different types %qT and %qT",
	       t1, t2);
	  
	  return result;
	}
      if (!flag_checking && param_use_canonical_types)
	return TYPE_CANONICAL (t1) == TYPE_CANONICAL (t2);
      else
	return structural_comptypes (t1, t2, strict);
    }
  else if (strict == COMPARE_STRUCTURAL)
    return structural_comptypes (t1, t2, COMPARE_STRICT);
  else
    return structural_comptypes (t1, t2, strict);
}

/* Returns nonzero iff TYPE1 and TYPE2 are the same type, ignoring
   top-level qualifiers.  */

bool
same_type_ignoring_top_level_qualifiers_p (tree type1, tree type2)
{
  if (type1 == error_mark_node || type2 == error_mark_node)
    return false;
  if (type1 == type2)
    return true;

  type1 = cp_build_qualified_type (type1, TYPE_UNQUALIFIED);
  type2 = cp_build_qualified_type (type2, TYPE_UNQUALIFIED);
  return same_type_p (type1, type2);
}

/* Returns nonzero iff TYPE1 and TYPE2 are similar, as per [conv.qual].  */

bool
similar_type_p (tree type1, tree type2)
{
  if (type1 == error_mark_node || type2 == error_mark_node)
    return false;

  /* Informally, two types are similar if, ignoring top-level cv-qualification:
     * they are the same type; or
     * they are both pointers, and the pointed-to types are similar; or
     * they are both pointers to member of the same class, and the types of
       the pointed-to members are similar; or
     * they are both arrays of the same size or both arrays of unknown bound,
       and the array element types are similar.  */

  if (same_type_ignoring_top_level_qualifiers_p (type1, type2))
    return true;

  if ((TYPE_PTR_P (type1) && TYPE_PTR_P (type2))
      || (TYPE_PTRDATAMEM_P (type1) && TYPE_PTRDATAMEM_P (type2))
      || (TREE_CODE (type1) == ARRAY_TYPE && TREE_CODE (type2) == ARRAY_TYPE))
    return comp_ptr_ttypes_const (type1, type2, bounds_either);

  return false;
}

/* Helper function for layout_compatible_type_p and
   is_corresponding_member_aggr.  Advance to next members (NULL if
   no further ones) and return true if those members are still part of
   the common initial sequence.  */

bool
next_common_initial_seqence (tree &memb1, tree &memb2)
{
  while (memb1)
    {
      if (TREE_CODE (memb1) != FIELD_DECL
	  || (DECL_FIELD_IS_BASE (memb1) && is_empty_field (memb1)))
	{
	  memb1 = DECL_CHAIN (memb1);
	  continue;
	}
      if (DECL_FIELD_IS_BASE (memb1))
	{
	  memb1 = TYPE_FIELDS (TREE_TYPE (memb1));
	  continue;
	}
      break;
    }
  while (memb2)
    {
      if (TREE_CODE (memb2) != FIELD_DECL
	  || (DECL_FIELD_IS_BASE (memb2) && is_empty_field (memb2)))
	{
	  memb2 = DECL_CHAIN (memb2);
	  continue;
	}
      if (DECL_FIELD_IS_BASE (memb2))
	{
	  memb2 = TYPE_FIELDS (TREE_TYPE (memb2));
	  continue;
	}
      break;
    }
  if (memb1 == NULL_TREE && memb2 == NULL_TREE)
    return true;
  if (memb1 == NULL_TREE || memb2 == NULL_TREE)
    return false;
  if (DECL_BIT_FIELD_TYPE (memb1))
    {
      if (!DECL_BIT_FIELD_TYPE (memb2))
	return false;
      if (!layout_compatible_type_p (DECL_BIT_FIELD_TYPE (memb1),
				     DECL_BIT_FIELD_TYPE (memb2)))
	return false;
      if (TYPE_PRECISION (TREE_TYPE (memb1))
	  != TYPE_PRECISION (TREE_TYPE (memb2)))
	return false;
    }
  else if (DECL_BIT_FIELD_TYPE (memb2))
    return false;
  else if (!layout_compatible_type_p (TREE_TYPE (memb1), TREE_TYPE (memb2)))
    return false;
  if ((!lookup_attribute ("no_unique_address", DECL_ATTRIBUTES (memb1)))
      != !lookup_attribute ("no_unique_address", DECL_ATTRIBUTES (memb2)))
    return false;
  if (!tree_int_cst_equal (bit_position (memb1), bit_position (memb2)))
    return false;
  return true;
}

/* Return true if TYPE1 and TYPE2 are layout-compatible types.  */

bool
layout_compatible_type_p (tree type1, tree type2)
{
  if (type1 == error_mark_node || type2 == error_mark_node)
    return false;
  if (type1 == type2)
    return true;
  if (TREE_CODE (type1) != TREE_CODE (type2))
    return false;

  type1 = cp_build_qualified_type (type1, TYPE_UNQUALIFIED);
  type2 = cp_build_qualified_type (type2, TYPE_UNQUALIFIED);

  if (TREE_CODE (type1) == ENUMERAL_TYPE)
    return (TYPE_ALIGN (type1) == TYPE_ALIGN (type2)
	    && tree_int_cst_equal (TYPE_SIZE (type1), TYPE_SIZE (type2))
	    && same_type_p (finish_underlying_type (type1),
			    finish_underlying_type (type2)));

  if (CLASS_TYPE_P (type1)
      && std_layout_type_p (type1)
      && std_layout_type_p (type2)
      && TYPE_ALIGN (type1) == TYPE_ALIGN (type2)
      && tree_int_cst_equal (TYPE_SIZE (type1), TYPE_SIZE (type2)))
    {
      tree field1 = TYPE_FIELDS (type1);
      tree field2 = TYPE_FIELDS (type2);
      if (TREE_CODE (type1) == RECORD_TYPE)
	{
	  while (1)
	    {
	      if (!next_common_initial_seqence (field1, field2))
		return false;
	      if (field1 == NULL_TREE)
		return true;
	      field1 = DECL_CHAIN (field1);
	      field2 = DECL_CHAIN (field2);
	    }
	}
      /* Otherwise both types must be union types.
	 The standard says:
	 "Two standard-layout unions are layout-compatible if they have
	 the same number of non-static data members and corresponding
	 non-static data members (in any order) have layout-compatible
	 types."
	 but the code anticipates that bitfield vs. non-bitfield,
	 different bitfield widths or presence/absence of
	 [[no_unique_address]] should be checked as well.  */
      auto_vec<tree, 16> vec;
      unsigned int count = 0;
      for (; field1; field1 = DECL_CHAIN (field1))
	if (TREE_CODE (field1) == FIELD_DECL)
	  count++;
      for (; field2; field2 = DECL_CHAIN (field2))
	if (TREE_CODE (field2) == FIELD_DECL)
	  vec.safe_push (field2);
      /* Discussions on core lean towards treating multiple union fields
	 of the same type as the same field, so this might need changing
	 in the future.  */
      if (count != vec.length ())
	return false;
      for (field1 = TYPE_FIELDS (type1); field1; field1 = DECL_CHAIN (field1))
	{
	  if (TREE_CODE (field1) != FIELD_DECL)
	    continue;
	  unsigned int j;
	  tree t1 = DECL_BIT_FIELD_TYPE (field1);
	  if (t1 == NULL_TREE)
	    t1 = TREE_TYPE (field1);
	  FOR_EACH_VEC_ELT (vec, j, field2)
	    {
	      tree t2 = DECL_BIT_FIELD_TYPE (field2);
	      if (t2 == NULL_TREE)
		t2 = TREE_TYPE (field2);
	      if (DECL_BIT_FIELD_TYPE (field1))
		{
		  if (!DECL_BIT_FIELD_TYPE (field2))
		    continue;
		  if (TYPE_PRECISION (TREE_TYPE (field1))
		      != TYPE_PRECISION (TREE_TYPE (field2)))
		    continue;
		}
	      else if (DECL_BIT_FIELD_TYPE (field2))
		continue;
	      if (!layout_compatible_type_p (t1, t2))
		continue;
	      if ((!lookup_attribute ("no_unique_address",
				      DECL_ATTRIBUTES (field1)))
		  != !lookup_attribute ("no_unique_address",
					DECL_ATTRIBUTES (field2)))
		continue;
	      break;
	    }
	  if (j == vec.length ())
	    return false;
	  vec.unordered_remove (j);
	}
      return true;
    }

  return same_type_p (type1, type2);
}

/* Returns 1 if TYPE1 is at least as qualified as TYPE2.  */

bool
at_least_as_qualified_p (const_tree type1, const_tree type2)
{
  int q1 = cp_type_quals (type1);
  int q2 = cp_type_quals (type2);

  /* All qualifiers for TYPE2 must also appear in TYPE1.  */
  return (q1 & q2) == q2;
}

/* Returns 1 if TYPE1 is more cv-qualified than TYPE2, -1 if TYPE2 is
   more cv-qualified that TYPE1, and 0 otherwise.  */

int
comp_cv_qualification (int q1, int q2)
{
  if (q1 == q2)
    return 0;

  if ((q1 & q2) == q2)
    return 1;
  else if ((q1 & q2) == q1)
    return -1;

  return 0;
}

int
comp_cv_qualification (const_tree type1, const_tree type2)
{
  int q1 = cp_type_quals (type1);
  int q2 = cp_type_quals (type2);
  return comp_cv_qualification (q1, q2);
}

/* Returns 1 if the cv-qualification signature of TYPE1 is a proper
   subset of the cv-qualification signature of TYPE2, and the types
   are similar.  Returns -1 if the other way 'round, and 0 otherwise.  */

int
comp_cv_qual_signature (tree type1, tree type2)
{
  if (comp_ptr_ttypes_real (type2, type1, -1))
    return 1;
  else if (comp_ptr_ttypes_real (type1, type2, -1))
    return -1;
  else
    return 0;
}

/* Subroutines of `comptypes'.  */

/* Return true if two parameter type lists PARMS1 and PARMS2 are
   equivalent in the sense that functions with those parameter types
   can have equivalent types.  The two lists must be equivalent,
   element by element.  */

bool
compparms (const_tree parms1, const_tree parms2)
{
  const_tree t1, t2;

  /* An unspecified parmlist matches any specified parmlist
     whose argument types don't need default promotions.  */

  for (t1 = parms1, t2 = parms2;
       t1 || t2;
       t1 = TREE_CHAIN (t1), t2 = TREE_CHAIN (t2))
    {
      /* If one parmlist is shorter than the other,
	 they fail to match.  */
      if (!t1 || !t2)
	return false;
      if (!same_type_p (TREE_VALUE (t1), TREE_VALUE (t2)))
	return false;
    }
  return true;
}


/* Process a sizeof or alignof expression where the operand is a
   type. STD_ALIGNOF indicates whether an alignof has C++11 (minimum alignment)
   or GNU (preferred alignment) semantics; it is ignored if op is
   SIZEOF_EXPR.  */

tree
cxx_sizeof_or_alignof_type (location_t loc, tree type, enum tree_code op,
			    bool std_alignof, bool complain)
{
  gcc_assert (op == SIZEOF_EXPR || op == ALIGNOF_EXPR);
  if (type == error_mark_node)
    return error_mark_node;

  type = non_reference (type);
  if (TREE_CODE (type) == METHOD_TYPE)
    {
      if (complain)
	{
	  pedwarn (loc, OPT_Wpointer_arith,
		   "invalid application of %qs to a member function",
		   OVL_OP_INFO (false, op)->name);
	  return size_one_node;
	}
      else
	return error_mark_node;
    }

  bool dependent_p = dependent_type_p (type);
  if (!dependent_p)
    complete_type (type);
  if (dependent_p
      /* VLA types will have a non-constant size.  In the body of an
	 uninstantiated template, we don't need to try to compute the
	 value, because the sizeof expression is not an integral
	 constant expression in that case.  And, if we do try to
	 compute the value, we'll likely end up with SAVE_EXPRs, which
	 the template substitution machinery does not expect to see.  */
      || (processing_template_decl 
	  && COMPLETE_TYPE_P (type)
	  && TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST))
    {
      tree value = build_min (op, size_type_node, type);
      TREE_READONLY (value) = 1;
      if (op == ALIGNOF_EXPR && std_alignof)
	ALIGNOF_EXPR_STD_P (value) = true;
      SET_EXPR_LOCATION (value, loc);
      return value;
    }

  return c_sizeof_or_alignof_type (loc, complete_type (type),
				   op == SIZEOF_EXPR, std_alignof,
				   complain);
}

/* Return the size of the type, without producing any warnings for
   types whose size cannot be taken.  This routine should be used only
   in some other routine that has already produced a diagnostic about
   using the size of such a type.  */
tree 
cxx_sizeof_nowarn (tree type)
{
  if (TREE_CODE (type) == FUNCTION_TYPE
      || VOID_TYPE_P (type)
      || TREE_CODE (type) == ERROR_MARK)
    return size_one_node;
  else if (!COMPLETE_TYPE_P (type))
    return size_zero_node;
  else
    return cxx_sizeof_or_alignof_type (input_location, type,
				       SIZEOF_EXPR, false, false);
}

/* Process a sizeof expression where the operand is an expression.  */

static tree
cxx_sizeof_expr (location_t loc, tree e, tsubst_flags_t complain)
{
  if (e == error_mark_node)
    return error_mark_node;

  if (instantiation_dependent_uneval_expression_p (e))
    {
      e = build_min (SIZEOF_EXPR, size_type_node, e);
      TREE_SIDE_EFFECTS (e) = 0;
      TREE_READONLY (e) = 1;
      SET_EXPR_LOCATION (e, loc);

      return e;
    }

  location_t e_loc = cp_expr_loc_or_loc (e, loc);
  STRIP_ANY_LOCATION_WRAPPER (e);

  /* To get the size of a static data member declared as an array of
     unknown bound, we need to instantiate it.  */
  if (VAR_P (e)
      && VAR_HAD_UNKNOWN_BOUND (e)
      && DECL_TEMPLATE_INSTANTIATION (e))
    instantiate_decl (e, /*defer_ok*/true, /*expl_inst_mem*/false);

  if (TREE_CODE (e) == PARM_DECL
      && DECL_ARRAY_PARAMETER_P (e)
      && (complain & tf_warning))
    {
      auto_diagnostic_group d;
      if (warning_at (e_loc, OPT_Wsizeof_array_argument,
		      "%<sizeof%> on array function parameter %qE "
		      "will return size of %qT", e, TREE_TYPE (e)))
	inform (DECL_SOURCE_LOCATION (e), "declared here");
    }

  e = mark_type_use (e);

  if (bitfield_p (e))
    {
      if (complain & tf_error)
	error_at (e_loc,
		  "invalid application of %<sizeof%> to a bit-field");
      else
        return error_mark_node;
      e = char_type_node;
    }
  else if (is_overloaded_fn (e))
    {
      if (complain & tf_error)
	permerror (e_loc, "ISO C++ forbids applying %<sizeof%> to "
		   "an expression of function type");
      else
        return error_mark_node;
      e = char_type_node;
    }
  else if (type_unknown_p (e))
    {
      if (complain & tf_error)
        cxx_incomplete_type_error (e_loc, e, TREE_TYPE (e));
      else
        return error_mark_node;
      e = char_type_node;
    }
  else
    e = TREE_TYPE (e);

  return cxx_sizeof_or_alignof_type (loc, e, SIZEOF_EXPR, false,
				     complain & tf_error);
}

/* Implement the __alignof keyword: Return the minimum required
   alignment of E, measured in bytes.  For VAR_DECL's and
   FIELD_DECL's return DECL_ALIGN (which can be set from an
   "aligned" __attribute__ specification).  STD_ALIGNOF acts
   like in cxx_sizeof_or_alignof_type.  */

static tree
cxx_alignof_expr (location_t loc, tree e, bool std_alignof,
		  tsubst_flags_t complain)
{
  tree t;

  if (e == error_mark_node)
    return error_mark_node;

  if (processing_template_decl)
    {
      e = build_min (ALIGNOF_EXPR, size_type_node, e);
      TREE_SIDE_EFFECTS (e) = 0;
      TREE_READONLY (e) = 1;
      SET_EXPR_LOCATION (e, loc);
      ALIGNOF_EXPR_STD_P (e) = std_alignof;

      return e;
    }

  location_t e_loc = cp_expr_loc_or_loc (e, loc);
  STRIP_ANY_LOCATION_WRAPPER (e);

  e = mark_type_use (e);

  if (!verify_type_context (loc, TCTX_ALIGNOF, TREE_TYPE (e),
			    !(complain & tf_error)))
    {
      if (!(complain & tf_error))
	return error_mark_node;
      t = size_one_node;
    }
  else if (VAR_P (e))
    t = size_int (DECL_ALIGN_UNIT (e));
  else if (bitfield_p (e))
    {
      if (complain & tf_error)
	error_at (e_loc,
		  "invalid application of %<__alignof%> to a bit-field");
      else
        return error_mark_node;
      t = size_one_node;
    }
  else if (TREE_CODE (e) == COMPONENT_REF
	   && TREE_CODE (TREE_OPERAND (e, 1)) == FIELD_DECL)
    t = size_int (DECL_ALIGN_UNIT (TREE_OPERAND (e, 1)));
  else if (is_overloaded_fn (e))
    {
      if (complain & tf_error)
	permerror (e_loc, "ISO C++ forbids applying %<__alignof%> to "
		   "an expression of function type");
      else
        return error_mark_node;
      if (TREE_CODE (e) == FUNCTION_DECL)
	t = size_int (DECL_ALIGN_UNIT (e));
      else
	t = size_one_node;
    }
  else if (type_unknown_p (e))
    {
      if (complain & tf_error)
        cxx_incomplete_type_error (e_loc, e, TREE_TYPE (e));
      else
        return error_mark_node;
      t = size_one_node;
    }
  else
    return cxx_sizeof_or_alignof_type (loc, TREE_TYPE (e),
				       ALIGNOF_EXPR, std_alignof,
                                       complain & tf_error);

  return fold_convert_loc (loc, size_type_node, t);
}

/* Process a sizeof or alignof expression E with code OP where the operand
   is an expression. STD_ALIGNOF acts like in cxx_sizeof_or_alignof_type.  */

tree
cxx_sizeof_or_alignof_expr (location_t loc, tree e, enum tree_code op,
			    bool std_alignof, bool complain)
{
  gcc_assert (op == SIZEOF_EXPR || op == ALIGNOF_EXPR);
  if (op == SIZEOF_EXPR)
    return cxx_sizeof_expr (loc, e, complain? tf_warning_or_error : tf_none);
  else
    return cxx_alignof_expr (loc, e, std_alignof,
			     complain? tf_warning_or_error : tf_none);
}

/*  Build a representation of an expression 'alignas(E).'  Return the
    folded integer value of E if it is an integral constant expression
    that resolves to a valid alignment.  If E depends on a template
    parameter, return a syntactic representation tree of kind
    ALIGNOF_EXPR.  Otherwise, return an error_mark_node if the
    expression is ill formed, or NULL_TREE if E is NULL_TREE.  */

tree
cxx_alignas_expr (tree e)
{
  if (e == NULL_TREE || e == error_mark_node
      || (!TYPE_P (e) && !require_potential_rvalue_constant_expression (e)))
    return e;
  
  if (TYPE_P (e))
    /* [dcl.align]/3:
       
	   When the alignment-specifier is of the form
	   alignas(type-id ), it shall have the same effect as
	   alignas(alignof(type-id )).  */

    return cxx_sizeof_or_alignof_type (input_location,
				       e, ALIGNOF_EXPR, true, false);
  
  /* If we reach this point, it means the alignas expression if of
     the form "alignas(assignment-expression)", so we should follow
     what is stated by [dcl.align]/2.  */

  if (value_dependent_expression_p (e))
    /* Leave value-dependent expression alone for now. */
    return e;

  e = instantiate_non_dependent_expr (e);
  e = mark_rvalue_use (e);

  /* [dcl.align]/2 says:

         the assignment-expression shall be an integral constant
	 expression.  */

  if (!INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (TREE_TYPE (e)))
    {
      error ("%<alignas%> argument has non-integral type %qT", TREE_TYPE (e));
      return error_mark_node;
    }
  
  return cxx_constant_value (e);
}


/* EXPR is being used in a context that is not a function call.
   Enforce:

     [expr.ref]

     The expression can be used only as the left-hand operand of a
     member function call.

     [expr.mptr.operator]

     If the result of .* or ->* is a function, then that result can be
     used only as the operand for the function call operator ().

   by issuing an error message if appropriate.  Returns true iff EXPR
   violates these rules.  */

bool
invalid_nonstatic_memfn_p (location_t loc, tree expr, tsubst_flags_t complain)
{
  if (expr == NULL_TREE)
    return false;
  /* Don't enforce this in MS mode.  */
  if (flag_ms_extensions)
    return false;
  if (is_overloaded_fn (expr) && !really_overloaded_fn (expr))
    expr = get_first_fn (expr);
  if (DECL_NONSTATIC_MEMBER_FUNCTION_P (expr))
    {
      if (complain & tf_error)
	{
	  if (DECL_P (expr))
	    {
	      error_at (loc, "invalid use of non-static member function %qD",
			expr);
	      inform (DECL_SOURCE_LOCATION (expr), "declared here");
	    }
	  else
	    error_at (loc, "invalid use of non-static member function of "
		      "type %qT", TREE_TYPE (expr));
	}
      return true;
    }
  return false;
}

/* If EXP is a reference to a bitfield, and the type of EXP does not
   match the declared type of the bitfield, return the declared type
   of the bitfield.  Otherwise, return NULL_TREE.  */

tree
is_bitfield_expr_with_lowered_type (const_tree exp)
{
  switch (TREE_CODE (exp))
    {
    case COND_EXPR:
      if (!is_bitfield_expr_with_lowered_type (TREE_OPERAND (exp, 1)
					       ? TREE_OPERAND (exp, 1)
					       : TREE_OPERAND (exp, 0)))
	return NULL_TREE;
      return is_bitfield_expr_with_lowered_type (TREE_OPERAND (exp, 2));

    case COMPOUND_EXPR:
      return is_bitfield_expr_with_lowered_type (TREE_OPERAND (exp, 1));

    case MODIFY_EXPR:
    case SAVE_EXPR:
      return is_bitfield_expr_with_lowered_type (TREE_OPERAND (exp, 0));

    case COMPONENT_REF:
      {
	tree field;
	
	field = TREE_OPERAND (exp, 1);
	if (TREE_CODE (field) != FIELD_DECL || !DECL_BIT_FIELD_TYPE (field))
	  return NULL_TREE;
	if (same_type_ignoring_top_level_qualifiers_p
	    (TREE_TYPE (exp), DECL_BIT_FIELD_TYPE (field)))
	  return NULL_TREE;
	return DECL_BIT_FIELD_TYPE (field);
      }

    case VAR_DECL:
      if (DECL_HAS_VALUE_EXPR_P (exp))
	return is_bitfield_expr_with_lowered_type (DECL_VALUE_EXPR
						   (CONST_CAST_TREE (exp)));
      return NULL_TREE;

    case VIEW_CONVERT_EXPR:
      if (location_wrapper_p (exp))
	return is_bitfield_expr_with_lowered_type (TREE_OPERAND (exp, 0));
      else
	return NULL_TREE;

    default:
      return NULL_TREE;
    }
}

/* Like is_bitfield_with_lowered_type, except that if EXP is not a
   bitfield with a lowered type, the type of EXP is returned, rather
   than NULL_TREE.  */

tree
unlowered_expr_type (const_tree exp)
{
  tree type;
  tree etype = TREE_TYPE (exp);

  type = is_bitfield_expr_with_lowered_type (exp);
  if (type)
    type = cp_build_qualified_type (type, cp_type_quals (etype));
  else
    type = etype;

  return type;
}

/* Perform the conversions in [expr] that apply when an lvalue appears
   in an rvalue context: the lvalue-to-rvalue, array-to-pointer, and
   function-to-pointer conversions.  In addition, bitfield references are
   converted to their declared types. Note that this function does not perform
   the lvalue-to-rvalue conversion for class types. If you need that conversion
   for class types, then you probably need to use force_rvalue.

   Although the returned value is being used as an rvalue, this
   function does not wrap the returned expression in a
   NON_LVALUE_EXPR; the caller is expected to be mindful of the fact
   that the return value is no longer an lvalue.  */

tree
decay_conversion (tree exp,
		  tsubst_flags_t complain,
		  bool reject_builtin /* = true */)
{
  tree type;
  enum tree_code code;
  location_t loc = cp_expr_loc_or_input_loc (exp);

  type = TREE_TYPE (exp);
  if (type == error_mark_node)
    return error_mark_node;

  exp = resolve_nondeduced_context_or_error (exp, complain);

  code = TREE_CODE (type);

  if (error_operand_p (exp))
    return error_mark_node;

  if (NULLPTR_TYPE_P (type) && !TREE_SIDE_EFFECTS (exp))
    {
      mark_rvalue_use (exp, loc, reject_builtin);
      return nullptr_node;
    }

  /* build_c_cast puts on a NOP_EXPR to make the result not an lvalue.
     Leave such NOP_EXPRs, since RHS is being used in non-lvalue context.  */
  if (code == VOID_TYPE)
    {
      if (complain & tf_error)
	error_at (loc, "void value not ignored as it ought to be");
      return error_mark_node;
    }
  if (invalid_nonstatic_memfn_p (loc, exp, complain))
    return error_mark_node;
  if (code == FUNCTION_TYPE || is_overloaded_fn (exp))
    {
      exp = mark_lvalue_use (exp);
      if (reject_builtin && reject_gcc_builtin (exp, loc))
	return error_mark_node;
      return cp_build_addr_expr (exp, complain);
    }
  if (code == ARRAY_TYPE)
    {
      tree adr;
      tree ptrtype;

      exp = mark_lvalue_use (exp);

      if (INDIRECT_REF_P (exp))
	return build_nop (build_pointer_type (TREE_TYPE (type)),
			  TREE_OPERAND (exp, 0));

      if (TREE_CODE (exp) == COMPOUND_EXPR)
	{
	  tree op1 = decay_conversion (TREE_OPERAND (exp, 1), complain);
	  if (op1 == error_mark_node)
            return error_mark_node;
	  return build2 (COMPOUND_EXPR, TREE_TYPE (op1),
			 TREE_OPERAND (exp, 0), op1);
	}

      if (!obvalue_p (exp)
	  && ! (TREE_CODE (exp) == CONSTRUCTOR && TREE_STATIC (exp)))
	{
	  if (complain & tf_error)
	    error_at (loc, "invalid use of non-lvalue array");
	  return error_mark_node;
	}

      /* Don't let an array compound literal decay to a pointer.  It can
	 still be used to initialize an array or bind to a reference.  */
      if (TREE_CODE (exp) == TARGET_EXPR)
	{
	  if (complain & tf_error)
	    error_at (loc, "taking address of temporary array");
	  return error_mark_node;
	}

      ptrtype = build_pointer_type (TREE_TYPE (type));

      if (VAR_P (exp))
	{
	  if (!cxx_mark_addressable (exp))
	    return error_mark_node;
	  adr = build_nop (ptrtype, build_address (exp));
	  return adr;
	}
      /* This way is better for a COMPONENT_REF since it can
	 simplify the offset for a component.  */
      adr = cp_build_addr_expr (exp, complain);
      return cp_convert (ptrtype, adr, complain);
    }

  /* Otherwise, it's the lvalue-to-rvalue conversion.  */
  exp = mark_rvalue_use (exp, loc, reject_builtin);

  /* If a bitfield is used in a context where integral promotion
     applies, then the caller is expected to have used
     default_conversion.  That function promotes bitfields correctly
     before calling this function.  At this point, if we have a
     bitfield referenced, we may assume that is not subject to
     promotion, and that, therefore, the type of the resulting rvalue
     is the declared type of the bitfield.  */
  exp = convert_bitfield_to_declared_type (exp);

  /* We do not call rvalue() here because we do not want to wrap EXP
     in a NON_LVALUE_EXPR.  */

  /* [basic.lval]

     Non-class rvalues always have cv-unqualified types.  */
  type = TREE_TYPE (exp);
  if (!CLASS_TYPE_P (type) && cv_qualified_p (type))
    exp = build_nop (cv_unqualified (type), exp);

  if (!complete_type_or_maybe_complain (type, exp, complain))
    return error_mark_node;

  return exp;
}

/* Perform preparatory conversions, as part of the "usual arithmetic
   conversions".  In particular, as per [expr]:

     Whenever an lvalue expression appears as an operand of an
     operator that expects the rvalue for that operand, the
     lvalue-to-rvalue, array-to-pointer, or function-to-pointer
     standard conversions are applied to convert the expression to an
     rvalue.

   In addition, we perform integral promotions here, as those are
   applied to both operands to a binary operator before determining
   what additional conversions should apply.  */

static tree
cp_default_conversion (tree exp, tsubst_flags_t complain)
{
  /* Check for target-specific promotions.  */
  tree promoted_type = targetm.promoted_type (TREE_TYPE (exp));
  if (promoted_type)
    exp = cp_convert (promoted_type, exp, complain);
  /* Perform the integral promotions first so that bitfield
     expressions (which may promote to "int", even if the bitfield is
     declared "unsigned") are promoted correctly.  */
  else if (INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (TREE_TYPE (exp)))
    exp = cp_perform_integral_promotions (exp, complain);
  /* Perform the other conversions.  */
  exp = decay_conversion (exp, complain);

  return exp;
}

/* C version.  */

tree
default_conversion (tree exp)
{
  return cp_default_conversion (exp, tf_warning_or_error);
}

/* EXPR is an expression with an integral or enumeration type.
   Perform the integral promotions in [conv.prom], and return the
   converted value.  */

tree
cp_perform_integral_promotions (tree expr, tsubst_flags_t complain)
{
  tree type;
  tree promoted_type;

  expr = mark_rvalue_use (expr);
  if (error_operand_p (expr))
    return error_mark_node;

  type = TREE_TYPE (expr);

  /* [conv.prom]

     A prvalue for an integral bit-field (11.3.9) can be converted to a prvalue
     of type int if int can represent all the values of the bit-field;
     otherwise, it can be converted to unsigned int if unsigned int can
     represent all the values of the bit-field. If the bit-field is larger yet,
     no integral promotion applies to it. If the bit-field has an enumerated
     type, it is treated as any other value of that type for promotion
     purposes.  */
  tree bitfield_type = is_bitfield_expr_with_lowered_type (expr);
  if (bitfield_type
      && (TREE_CODE (bitfield_type) == ENUMERAL_TYPE
	  || TYPE_PRECISION (type) > TYPE_PRECISION (integer_type_node)))
    type = bitfield_type;

  gcc_assert (INTEGRAL_OR_ENUMERATION_TYPE_P (type));
  /* Scoped enums don't promote.  */
  if (SCOPED_ENUM_P (type))
    return expr;
  promoted_type = type_promotes_to (type);
  if (type != promoted_type)
    expr = cp_convert (promoted_type, expr, complain);
  else if (bitfield_type && bitfield_type != type)
    /* Prevent decay_conversion from converting to bitfield_type.  */
    expr = build_nop (type, expr);
  return expr;
}

/* C version.  */

tree
perform_integral_promotions (tree expr)
{
  return cp_perform_integral_promotions (expr, tf_warning_or_error);
}

/* Returns nonzero iff exp is a STRING_CST or the result of applying
   decay_conversion to one.  */

int
string_conv_p (const_tree totype, const_tree exp, int warn)
{
  tree t;

  if (!TYPE_PTR_P (totype))
    return 0;

  t = TREE_TYPE (totype);
  if (!same_type_p (t, char_type_node)
      && !same_type_p (t, char8_type_node)
      && !same_type_p (t, char16_type_node)
      && !same_type_p (t, char32_type_node)
      && !same_type_p (t, wchar_type_node))
    return 0;

  location_t loc = EXPR_LOC_OR_LOC (exp, input_location);

  STRIP_ANY_LOCATION_WRAPPER (exp);

  if (TREE_CODE (exp) == STRING_CST)
    {
      /* Make sure that we don't try to convert between char and wide chars.  */
      if (!same_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (exp))), t))
	return 0;
    }
  else
    {
      /* Is this a string constant which has decayed to 'const char *'?  */
      t = build_pointer_type (cp_build_qualified_type (t, TYPE_QUAL_CONST));
      if (!same_type_p (TREE_TYPE (exp), t))
	return 0;
      STRIP_NOPS (exp);
      if (TREE_CODE (exp) != ADDR_EXPR
	  || TREE_CODE (TREE_OPERAND (exp, 0)) != STRING_CST)
	return 0;
    }
  if (warn)
    {
      if (cxx_dialect >= cxx11)
	pedwarn (loc, OPT_Wwrite_strings,
		 "ISO C++ forbids converting a string constant to %qT",
		 totype);
      else
	warning_at (loc, OPT_Wwrite_strings,
		    "deprecated conversion from string constant to %qT",
		    totype);
    }

  return 1;
}

/* Given a COND_EXPR, MIN_EXPR, or MAX_EXPR in T, return it in a form that we
   can, for example, use as an lvalue.  This code used to be in
   unary_complex_lvalue, but we needed it to deal with `a = (d == c) ? b : c'
   expressions, where we're dealing with aggregates.  But now it's again only
   called from unary_complex_lvalue.  The case (in particular) that led to
   this was with CODE == ADDR_EXPR, since it's not an lvalue when we'd
   get it there.  */

static tree
rationalize_conditional_expr (enum tree_code code, tree t,
                              tsubst_flags_t complain)
{
  location_t loc = cp_expr_loc_or_input_loc (t);

  /* For MIN_EXPR or MAX_EXPR, fold-const.c has arranged things so that
     the first operand is always the one to be used if both operands
     are equal, so we know what conditional expression this used to be.  */
  if (TREE_CODE (t) == MIN_EXPR || TREE_CODE (t) == MAX_EXPR)
    {
      tree op0 = TREE_OPERAND (t, 0);
      tree op1 = TREE_OPERAND (t, 1);

      /* The following code is incorrect if either operand side-effects.  */
      gcc_assert (!TREE_SIDE_EFFECTS (op0)
		  && !TREE_SIDE_EFFECTS (op1));
      return
	build_conditional_expr (loc,
				build_x_binary_op (loc,
						   (TREE_CODE (t) == MIN_EXPR
						    ? LE_EXPR : GE_EXPR),
						   op0, TREE_CODE (op0),
						   op1, TREE_CODE (op1),
						   /*overload=*/NULL,
						   complain),
                                cp_build_unary_op (code, op0, false, complain),
                                cp_build_unary_op (code, op1, false, complain),
                                complain);
    }

  tree op1 = TREE_OPERAND (t, 1);
  if (TREE_CODE (op1) != THROW_EXPR)
    op1 = cp_build_unary_op (code, op1, false, complain);
  tree op2 = TREE_OPERAND (t, 2);
  if (TREE_CODE (op2) != THROW_EXPR)
    op2 = cp_build_unary_op (code, op2, false, complain);

  return
    build_conditional_expr (loc, TREE_OPERAND (t, 0), op1, op2, complain);
}

/* Given the TYPE of an anonymous union field inside T, return the
   FIELD_DECL for the field.  If not found return NULL_TREE.  Because
   anonymous unions can nest, we must also search all anonymous unions
   that are directly reachable.  */

tree
lookup_anon_field (tree, tree type)
{
  tree field;

  type = TYPE_MAIN_VARIANT (type);
  field = ANON_AGGR_TYPE_FIELD (type);
  gcc_assert (field);
  return field;
}

/* Build an expression representing OBJECT.MEMBER.  OBJECT is an
   expression; MEMBER is a DECL or baselink.  If ACCESS_PATH is
   non-NULL, it indicates the path to the base used to name MEMBER.
   If PRESERVE_REFERENCE is true, the expression returned will have
   REFERENCE_TYPE if the MEMBER does.  Otherwise, the expression
   returned will have the type referred to by the reference.

   This function does not perform access control; that is either done
   earlier by the parser when the name of MEMBER is resolved to MEMBER
   itself, or later when overload resolution selects one of the
   functions indicated by MEMBER.  */

tree
build_class_member_access_expr (cp_expr object, tree member,
				tree access_path, bool preserve_reference,
				tsubst_flags_t complain)
{
  tree object_type;
  tree member_scope;
  tree result = NULL_TREE;
  tree using_decl = NULL_TREE;

  if (error_operand_p (object) || error_operand_p (member))
    return error_mark_node;

  gcc_assert (DECL_P (member) || BASELINK_P (member));

  /* [expr.ref]

     The type of the first expression shall be "class object" (of a
     complete type).  */
  object_type = TREE_TYPE (object);
  if (!currently_open_class (object_type)
      && !complete_type_or_maybe_complain (object_type, object, complain))
    return error_mark_node;
  if (!CLASS_TYPE_P (object_type))
    {
      if (complain & tf_error)
	{
	  if (INDIRECT_TYPE_P (object_type)
	      && CLASS_TYPE_P (TREE_TYPE (object_type)))
	    error ("request for member %qD in %qE, which is of pointer "
		   "type %qT (maybe you meant to use %<->%> ?)",
		   member, object.get_value (), object_type);
	  else
	    error ("request for member %qD in %qE, which is of non-class "
		   "type %qT", member, object.get_value (), object_type);
	}
      return error_mark_node;
    }

  /* The standard does not seem to actually say that MEMBER must be a
     member of OBJECT_TYPE.  However, that is clearly what is
     intended.  */
  if (DECL_P (member))
    {
      member_scope = DECL_CLASS_CONTEXT (member);
      if (!mark_used (member, complain) && !(complain & tf_error))
	return error_mark_node;

      if (TREE_UNAVAILABLE (member))
	error_unavailable_use (member, NULL_TREE);
      else if (TREE_DEPRECATED (member))
	warn_deprecated_use (member, NULL_TREE);
    }
  else
    member_scope = BINFO_TYPE (BASELINK_ACCESS_BINFO (member));
  /* If MEMBER is from an anonymous aggregate, MEMBER_SCOPE will
     presently be the anonymous union.  Go outwards until we find a
     type related to OBJECT_TYPE.  */
  while ((ANON_AGGR_TYPE_P (member_scope) || UNSCOPED_ENUM_P (member_scope))
	 && !same_type_ignoring_top_level_qualifiers_p (member_scope,
							object_type))
    member_scope = TYPE_CONTEXT (member_scope);
  if (!member_scope || !DERIVED_FROM_P (member_scope, object_type))
    {
      if (complain & tf_error)
	{
	  if (TREE_CODE (member) == FIELD_DECL)
	    error ("invalid use of non-static data member %qE", member);
	  else
	    error ("%qD is not a member of %qT", member, object_type);
	}
      return error_mark_node;
    }

  /* Transform `(a, b).x' into `(*(a, &b)).x', `(a ? b : c).x' into
     `(*(a ?  &b : &c)).x', and so on.  A COND_EXPR is only an lvalue
     in the front end; only _DECLs and _REFs are lvalues in the back end.  */
  {
    tree temp = unary_complex_lvalue (ADDR_EXPR, object);
    if (temp)
      {
	temp = cp_build_fold_indirect_ref (temp);
	if (xvalue_p (object) && !xvalue_p (temp))
	  /* Preserve xvalue kind.  */
	  temp = move (temp);
	object = temp;
      }
  }

  /* In [expr.ref], there is an explicit list of the valid choices for
     MEMBER.  We check for each of those cases here.  */
  if (VAR_P (member))
    {
      /* A static data member.  */
      result = member;
      mark_exp_read (object);

      if (tree wrap = maybe_get_tls_wrapper_call (result))
	/* Replace an evaluated use of the thread_local variable with
	   a call to its wrapper.  */
	result = wrap;

      /* If OBJECT has side-effects, they are supposed to occur.  */
      if (TREE_SIDE_EFFECTS (object))
	result = build2 (COMPOUND_EXPR, TREE_TYPE (result), object, result);
    }
  else if (TREE_CODE (member) == FIELD_DECL)
    {
      /* A non-static data member.  */
      bool null_object_p;
      int type_quals;
      tree member_type;

      if (INDIRECT_REF_P (object))
	null_object_p =
	  integer_zerop (tree_strip_nop_conversions (TREE_OPERAND (object, 0)));
      else
	null_object_p = false;

      /* Convert OBJECT to the type of MEMBER.  */
      if (!same_type_p (TYPE_MAIN_VARIANT (object_type),
			TYPE_MAIN_VARIANT (member_scope)))
	{
	  tree binfo;
	  base_kind kind;

	  /* We didn't complain above about a currently open class, but now we
	     must: we don't know how to refer to a base member before layout is
	     complete.  But still don't complain in a template.  */
	  if (!cp_unevaluated_operand
	      && !dependent_type_p (object_type)
	      && !complete_type_or_maybe_complain (object_type, object,
						   complain))
	    return error_mark_node;

	  binfo = lookup_base (access_path ? access_path : object_type,
			       member_scope, ba_unique, &kind, complain);
	  if (binfo == error_mark_node)
	    return error_mark_node;

	  /* It is invalid to try to get to a virtual base of a
	     NULL object.  The most common cause is invalid use of
	     offsetof macro.  */
	  if (null_object_p && kind == bk_via_virtual)
	    {
	      if (complain & tf_error)
		{
		  error ("invalid access to non-static data member %qD in "
			 "virtual base of NULL object", member);
		}
	      return error_mark_node;
	    }

	  /* Convert to the base.  */
	  object = build_base_path (PLUS_EXPR, object, binfo,
				    /*nonnull=*/1, complain);
	  /* If we found the base successfully then we should be able
	     to convert to it successfully.  */
	  gcc_assert (object != error_mark_node);
	}

      /* If MEMBER is from an anonymous aggregate, we have converted
	 OBJECT so that it refers to the class containing the
	 anonymous union.  Generate a reference to the anonymous union
	 itself, and recur to find MEMBER.  */
      if (ANON_AGGR_TYPE_P (DECL_CONTEXT (member))
	  /* When this code is called from build_field_call, the
	     object already has the type of the anonymous union.
	     That is because the COMPONENT_REF was already
	     constructed, and was then disassembled before calling
	     build_field_call.  After the function-call code is
	     cleaned up, this waste can be eliminated.  */
	  && (!same_type_ignoring_top_level_qualifiers_p
	      (TREE_TYPE (object), DECL_CONTEXT (member))))
	{
	  tree anonymous_union;

	  anonymous_union = lookup_anon_field (TREE_TYPE (object),
					       DECL_CONTEXT (member));
	  object = build_class_member_access_expr (object,
						   anonymous_union,
						   /*access_path=*/NULL_TREE,
						   preserve_reference,
						   complain);
	}

      /* Compute the type of the field, as described in [expr.ref].  */
      type_quals = TYPE_UNQUALIFIED;
      member_type = TREE_TYPE (member);
      if (!TYPE_REF_P (member_type))
	{
	  type_quals = (cp_type_quals (member_type)
			| cp_type_quals (object_type));

	  /* A field is const (volatile) if the enclosing object, or the
	     field itself, is const (volatile).  But, a mutable field is
	     not const, even within a const object.  */
	  if (DECL_MUTABLE_P (member))
	    type_quals &= ~TYPE_QUAL_CONST;
	  member_type = cp_build_qualified_type (member_type, type_quals);
	}

      result = build3_loc (input_location, COMPONENT_REF, member_type,
			   object, member, NULL_TREE);

      /* Mark the expression const or volatile, as appropriate.  Even
	 though we've dealt with the type above, we still have to mark the
	 expression itself.  */
      if (type_quals & TYPE_QUAL_CONST)
	TREE_READONLY (result) = 1;
      if (type_quals & TYPE_QUAL_VOLATILE)
	TREE_THIS_VOLATILE (result) = 1;
    }
  else if (BASELINK_P (member))
    {
      /* The member is a (possibly overloaded) member function.  */
      tree functions;
      tree type;

      /* If the MEMBER is exactly one static member function, then we
	 know the type of the expression.  Otherwise, we must wait
	 until overload resolution has been performed.  */
      functions = BASELINK_FUNCTIONS (member);
      if (TREE_CODE (functions) == FUNCTION_DECL
	  && DECL_STATIC_FUNCTION_P (functions))
	type = TREE_TYPE (functions);
      else
	type = unknown_type_node;
      /* Note that we do not convert OBJECT to the BASELINK_BINFO
	 base.  That will happen when the function is called.  */
      result = build3_loc (input_location, COMPONENT_REF, type, object, member,
			   NULL_TREE);
    }
  else if (TREE_CODE (member) == CONST_DECL)
    {
      /* The member is an enumerator.  */
      result = member;
      /* If OBJECT has side-effects, they are supposed to occur.  */
      if (TREE_SIDE_EFFECTS (object))
	result = build2 (COMPOUND_EXPR, TREE_TYPE (result),
			 object, result);
    }
  else if ((using_decl = strip_using_decl (member)) != member)
    result = build_class_member_access_expr (object,
					     using_decl,
					     access_path, preserve_reference,
					     complain);
  else
    {
      if (complain & tf_error)
	error ("invalid use of %qD", member);
      return error_mark_node;
    }

  if (!preserve_reference)
    /* [expr.ref]

       If E2 is declared to have type "reference to T", then ... the
       type of E1.E2 is T.  */
    result = convert_from_reference (result);

  return result;
}

/* Return the destructor denoted by OBJECT.SCOPE::DTOR_NAME, or, if
   SCOPE is NULL, by OBJECT.DTOR_NAME, where DTOR_NAME is ~type.  */

tree
lookup_destructor (tree object, tree scope, tree dtor_name,
		   tsubst_flags_t complain)
{
  tree object_type = TREE_TYPE (object);
  tree dtor_type = TREE_OPERAND (dtor_name, 0);
  tree expr;

  /* We've already complained about this destructor.  */
  if (dtor_type == error_mark_node)
    return error_mark_node;

  if (scope && !check_dtor_name (scope, dtor_type))
    {
      if (complain & tf_error)
	error ("qualified type %qT does not match destructor name ~%qT",
	       scope, dtor_type);
      return error_mark_node;
    }
  if (is_auto (dtor_type))
    dtor_type = object_type;
  else if (identifier_p (dtor_type))
    {
      /* In a template, names we can't find a match for are still accepted
	 destructor names, and we check them here.  */
      if (check_dtor_name (object_type, dtor_type))
	dtor_type = object_type;
      else
	{
	  if (complain & tf_error)
	    error ("object type %qT does not match destructor name ~%qT",
		   object_type, dtor_type);
	  return error_mark_node;
	}
      
    }
  else if (!DERIVED_FROM_P (dtor_type, TYPE_MAIN_VARIANT (object_type)))
    {
      if (complain & tf_error)
	error ("the type being destroyed is %qT, but the destructor "
	       "refers to %qT", TYPE_MAIN_VARIANT (object_type), dtor_type);
      return error_mark_node;
    }
  expr = lookup_member (dtor_type, complete_dtor_identifier,
			/*protect=*/1, /*want_type=*/false,
			tf_warning_or_error);
  if (!expr)
    {
      if (complain & tf_error)
	cxx_incomplete_type_error (dtor_name, dtor_type);
      return error_mark_node;
    }
  expr = (adjust_result_of_qualified_name_lookup
	  (expr, dtor_type, object_type));
  if (scope == NULL_TREE)
    /* We need to call adjust_result_of_qualified_name_lookup in case the
       destructor names a base class, but we unset BASELINK_QUALIFIED_P so
       that we still get virtual function binding.  */
    BASELINK_QUALIFIED_P (expr) = false;
  return expr;
}

/* An expression of the form "A::template B" has been resolved to
   DECL.  Issue a diagnostic if B is not a template or template
   specialization.  */

void
check_template_keyword (tree decl)
{
  /* The standard says:

      [temp.names]

      If a name prefixed by the keyword template is not a member
      template, the program is ill-formed.

     DR 228 removed the restriction that the template be a member
     template.

     DR 96, if accepted would add the further restriction that explicit
     template arguments must be provided if the template keyword is
     used, but, as of 2005-10-16, that DR is still in "drafting".  If
     this DR is accepted, then the semantic checks here can be
     simplified, as the entity named must in fact be a template
     specialization, rather than, as at present, a set of overloaded
     functions containing at least one template function.  */
  if (TREE_CODE (decl) != TEMPLATE_DECL
      && TREE_CODE (decl) != TEMPLATE_ID_EXPR)
    {
      if (VAR_P (decl))
	{
	  if (DECL_USE_TEMPLATE (decl)
	      && PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (decl)))
	    ;
	  else
	    permerror (input_location, "%qD is not a template", decl);
	}
      else if (!is_overloaded_fn (decl))
	permerror (input_location, "%qD is not a template", decl);
      else
	{
	  bool found = false;

	  for (lkp_iterator iter (MAYBE_BASELINK_FUNCTIONS (decl));
	       !found && iter; ++iter)
	    {
	      tree fn = *iter;
	      if (TREE_CODE (fn) == TEMPLATE_DECL
		  || TREE_CODE (fn) == TEMPLATE_ID_EXPR
		  || (TREE_CODE (fn) == FUNCTION_DECL
		      && DECL_USE_TEMPLATE (fn)
		      && PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (fn))))
		found = true;
	    }
	  if (!found)
	    permerror (input_location, "%qD is not a template", decl);
	}
    }
}

/* Record that an access failure occurred on BASETYPE_PATH attempting
   to access DECL, where DIAG_DECL should be used for diagnostics.  */

void
access_failure_info::record_access_failure (tree basetype_path,
					    tree decl, tree diag_decl)
{
  m_was_inaccessible = true;
  m_basetype_path = basetype_path;
  m_decl = decl;
  m_diag_decl = diag_decl;
}

/* If an access failure was recorded, then attempt to locate an
   accessor function for the pertinent field.
   Otherwise, return NULL_TREE.  */

tree
access_failure_info::get_any_accessor (bool const_p) const
{
  if (!was_inaccessible_p ())
    return NULL_TREE;

  tree accessor
    = locate_field_accessor (m_basetype_path, m_diag_decl, const_p);
  if (!accessor)
    return NULL_TREE;

  /* The accessor must itself be accessible for it to be a reasonable
     suggestion.  */
  if (!accessible_p (m_basetype_path, accessor, true))
    return NULL_TREE;

  return accessor;
}

/* Add a fix-it hint to RICHLOC suggesting the use of ACCESSOR_DECL, by
   replacing the primary location in RICHLOC with "accessor()".  */

void
access_failure_info::add_fixit_hint (rich_location *richloc,
				     tree accessor_decl)
{
  pretty_printer pp;
  pp_string (&pp, IDENTIFIER_POINTER (DECL_NAME (accessor_decl)));
  pp_string (&pp, "()");
  richloc->add_fixit_replace (pp_formatted_text (&pp));
}

/* If an access failure was recorded, then attempt to locate an
   accessor function for the pertinent field, and if one is
   available, add a note and fix-it hint suggesting using it.  */

void
access_failure_info::maybe_suggest_accessor (bool const_p) const
{
  tree accessor = get_any_accessor (const_p);
  if (accessor == NULL_TREE)
    return;
  rich_location richloc (line_table, input_location);
  add_fixit_hint (&richloc, accessor);
  inform (&richloc, "field %q#D can be accessed via %q#D",
	  m_diag_decl, accessor);
}

/* Subroutine of finish_class_member_access_expr.
   Issue an error about NAME not being a member of ACCESS_PATH (or
   OBJECT_TYPE), potentially providing a fix-it hint for misspelled
   names.  */

static void
complain_about_unrecognized_member (tree access_path, tree name,
				    tree object_type)
{
  /* Attempt to provide a hint about misspelled names.  */
  tree guessed_id = lookup_member_fuzzy (access_path, name,
					 /*want_type=*/false);
  if (guessed_id == NULL_TREE)
    {
      /* No hint.  */
      error ("%q#T has no member named %qE",
	     TREE_CODE (access_path) == TREE_BINFO
	     ? TREE_TYPE (access_path) : object_type, name);
      return;
    }

  location_t bogus_component_loc = input_location;
  gcc_rich_location rich_loc (bogus_component_loc);

  /* Check that the guessed name is accessible along access_path.  */
  access_failure_info afi;
  lookup_member (access_path, guessed_id, /*protect=*/1,
		 /*want_type=*/false, /*complain=*/false,
		 &afi);
  if (afi.was_inaccessible_p ())
    {
      tree accessor = afi.get_any_accessor (TYPE_READONLY (object_type));
      if (accessor)
	{
	  /* The guessed name isn't directly accessible, but can be accessed
	     via an accessor member function.  */
	  afi.add_fixit_hint (&rich_loc, accessor);
	  error_at (&rich_loc,
		    "%q#T has no member named %qE;"
		    " did you mean %q#D? (accessible via %q#D)",
		    TREE_CODE (access_path) == TREE_BINFO
		    ? TREE_TYPE (access_path) : object_type,
		    name, afi.get_diag_decl (), accessor);
	}
      else
	{
	  /* The guessed name isn't directly accessible, and no accessor
	     member function could be found.  */
	  error_at (&rich_loc,
		    "%q#T has no member named %qE;"
		    " did you mean %q#D? (not accessible from this context)",
		    TREE_CODE (access_path) == TREE_BINFO
		    ? TREE_TYPE (access_path) : object_type,
		    name, afi.get_diag_decl ());
	  complain_about_access (afi.get_decl (), afi.get_diag_decl (),
				 afi.get_diag_decl (), false, ak_none);
	}
    }
  else
    {
      /* The guessed name is directly accessible; suggest it.  */
      rich_loc.add_fixit_misspelled_id (bogus_component_loc,
					guessed_id);
      error_at (&rich_loc,
		"%q#T has no member named %qE;"
		" did you mean %qE?",
		TREE_CODE (access_path) == TREE_BINFO
		? TREE_TYPE (access_path) : object_type,
		name, guessed_id);
    }
}

/* This function is called by the parser to process a class member
   access expression of the form OBJECT.NAME.  NAME is a node used by
   the parser to represent a name; it is not yet a DECL.  It may,
   however, be a BASELINK where the BASELINK_FUNCTIONS is a
   TEMPLATE_ID_EXPR.  Templates must be looked up by the parser, and
   there is no reason to do the lookup twice, so the parser keeps the
   BASELINK.  TEMPLATE_P is true iff NAME was explicitly declared to
   be a template via the use of the "A::template B" syntax.  */

tree
finish_class_member_access_expr (cp_expr object, tree name, bool template_p,
				 tsubst_flags_t complain)
{
  tree expr;
  tree object_type;
  tree member;
  tree access_path = NULL_TREE;
  tree orig_object = object;
  tree orig_name = name;

  if (object == error_mark_node || name == error_mark_node)
    return error_mark_node;

  /* If OBJECT is an ObjC class instance, we must obey ObjC access rules.  */
  if (!objc_is_public (object, name))
    return error_mark_node;

  object_type = TREE_TYPE (object);

  if (processing_template_decl)
    {
      if (/* If OBJECT is dependent, so is OBJECT.NAME.  */
	  type_dependent_object_expression_p (object)
	  /* If NAME is "f<args>", where either 'f' or 'args' is
	     dependent, then the expression is dependent.  */
	  || (TREE_CODE (name) == TEMPLATE_ID_EXPR
	      && dependent_template_id_p (TREE_OPERAND (name, 0),
					  TREE_OPERAND (name, 1)))
	  /* If NAME is "T::X" where "T" is dependent, then the
	     expression is dependent.  */
	  || (TREE_CODE (name) == SCOPE_REF
	      && TYPE_P (TREE_OPERAND (name, 0))
	      && dependent_scope_p (TREE_OPERAND (name, 0)))
	  /* If NAME is operator T where "T" is dependent, we can't
	     lookup until we instantiate the T.  */
	  || (TREE_CODE (name) == IDENTIFIER_NODE
	      && IDENTIFIER_CONV_OP_P (name)
	      && dependent_type_p (TREE_TYPE (name))))
	{
	dependent:
	  return build_min_nt_loc (UNKNOWN_LOCATION, COMPONENT_REF,
				   orig_object, orig_name, NULL_TREE);
	}
      object = build_non_dependent_expr (object);
    }
  else if (c_dialect_objc ()
	   && identifier_p (name)
	   && (expr = objc_maybe_build_component_ref (object, name)))
    return expr;
    
  /* [expr.ref]

     The type of the first expression shall be "class object" (of a
     complete type).  */
  if (!currently_open_class (object_type)
      && !complete_type_or_maybe_complain (object_type, object, complain))
    return error_mark_node;
  if (!CLASS_TYPE_P (object_type))
    {
      if (complain & tf_error)
	{
	  if (INDIRECT_TYPE_P (object_type)
	      && CLASS_TYPE_P (TREE_TYPE (object_type)))
	    error ("request for member %qD in %qE, which is of pointer "
		   "type %qT (maybe you meant to use %<->%> ?)",
		   name, object.get_value (), object_type);
	  else
	    error ("request for member %qD in %qE, which is of non-class "
		   "type %qT", name, object.get_value (), object_type);
	}
      return error_mark_node;
    }

  if (BASELINK_P (name))
    /* A member function that has already been looked up.  */
    member = name;
  else
    {
      bool is_template_id = false;
      tree template_args = NULL_TREE;
      tree scope = NULL_TREE;

      access_path = object_type;

      if (TREE_CODE (name) == SCOPE_REF)
	{
	  /* A qualified name.  The qualifying class or namespace `S'
	     has already been looked up; it is either a TYPE or a
	     NAMESPACE_DECL.  */
	  scope = TREE_OPERAND (name, 0);
	  name = TREE_OPERAND (name, 1);

	  /* If SCOPE is a namespace, then the qualified name does not
	     name a member of OBJECT_TYPE.  */
	  if (TREE_CODE (scope) == NAMESPACE_DECL)
	    {
	      if (complain & tf_error)
		error ("%<%D::%D%> is not a member of %qT",
		       scope, name, object_type);
	      return error_mark_node;
	    }
	}
      
      if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
	{
	  is_template_id = true;
	  template_args = TREE_OPERAND (name, 1);
	  name = TREE_OPERAND (name, 0);

	  if (!identifier_p (name))
	    name = OVL_NAME (name);
	}

      if (scope)
	{
	  if (TREE_CODE (scope) == ENUMERAL_TYPE)
	    {
	      gcc_assert (!is_template_id);
	      /* Looking up a member enumerator (c++/56793).  */
	      if (!TYPE_CLASS_SCOPE_P (scope)
		  || !DERIVED_FROM_P (TYPE_CONTEXT (scope), object_type))
		{
		  if (complain & tf_error)
		    error ("%<%D::%D%> is not a member of %qT",
			   scope, name, object_type);
		  return error_mark_node;
		}
	      tree val = lookup_enumerator (scope, name);
	      if (!val)
		{
		  if (complain & tf_error)
		    error ("%qD is not a member of %qD",
			   name, scope);
		  return error_mark_node;
		}
	      
	      if (TREE_SIDE_EFFECTS (object))
		val = build2 (COMPOUND_EXPR, TREE_TYPE (val), object, val);
	      return val;
	    }

	  gcc_assert (CLASS_TYPE_P (scope));
	  gcc_assert (identifier_p (name) || TREE_CODE (name) == BIT_NOT_EXPR);

	  if (constructor_name_p (name, scope))
	    {
	      if (complain & tf_error)
		error ("cannot call constructor %<%T::%D%> directly",
		       scope, name);
	      return error_mark_node;
	    }

	  /* Find the base of OBJECT_TYPE corresponding to SCOPE.  */
	  access_path = lookup_base (object_type, scope, ba_check,
				     NULL, complain);
	  if (access_path == error_mark_node)
	    return error_mark_node;
	  if (!access_path)
	    {
	      if (any_dependent_bases_p (object_type))
		goto dependent;
	      if (complain & tf_error)
		error ("%qT is not a base of %qT", scope, object_type);
	      return error_mark_node;
	    }
	}

      if (TREE_CODE (name) == BIT_NOT_EXPR)
	{
	  if (dependent_type_p (object_type))
	    /* The destructor isn't declared yet.  */
	    goto dependent;
	  member = lookup_destructor (object, scope, name, complain);
	}
      else
	{
	  /* Look up the member.  */
	  access_failure_info afi;
	  if (processing_template_decl)
	    /* Even though this class member access expression is at this
	       point not dependent, the member itself may be dependent, and
	       we must not potentially push a access check for a dependent
	       member onto TI_DEFERRED_ACCESS_CHECKS.  So don't check access
	       ahead of time here; we're going to redo this member lookup at
	       instantiation time anyway.  */
	    push_deferring_access_checks (dk_no_check);
	  member = lookup_member (access_path, name, /*protect=*/1,
				  /*want_type=*/false, complain,
				  &afi);
	  if (processing_template_decl)
	    pop_deferring_access_checks ();
	  afi.maybe_suggest_accessor (TYPE_READONLY (object_type));
	  if (member == NULL_TREE)
	    {
	      if (dependent_type_p (object_type))
		/* Try again at instantiation time.  */
		goto dependent;
	      if (complain & tf_error)
		complain_about_unrecognized_member (access_path, name,
						    object_type);
	      return error_mark_node;
	    }
	  if (member == error_mark_node)
	    return error_mark_node;
	  if (DECL_P (member)
	      && any_dependent_type_attributes_p (DECL_ATTRIBUTES (member)))
	    /* Dependent type attributes on the decl mean that the TREE_TYPE is
	       wrong, so don't use it.  */
	    goto dependent;
	  if (TREE_CODE (member) == USING_DECL && DECL_DEPENDENT_P (member))
	    goto dependent;
	}

      if (is_template_id)
	{
	  tree templ = member;

	  if (BASELINK_P (templ))
	    member = lookup_template_function (templ, template_args);
	  else if (variable_template_p (templ))
	    member = (lookup_and_finish_template_variable
		      (templ, template_args, complain));
	  else
	    {
	      if (complain & tf_error)
		error ("%qD is not a member template function", name);
	      return error_mark_node;
	    }
	}
    }

  if (TREE_UNAVAILABLE (member))
    error_unavailable_use (member, NULL_TREE);
  else if (TREE_DEPRECATED (member))
    warn_deprecated_use (member, NULL_TREE);

  if (template_p)
    check_template_keyword (member);

  expr = build_class_member_access_expr (object, member, access_path,
					 /*preserve_reference=*/false,
					 complain);
  if (processing_template_decl && expr != error_mark_node)
    {
      if (BASELINK_P (member))
	{
	  if (TREE_CODE (orig_name) == SCOPE_REF)
	    BASELINK_QUALIFIED_P (member) = 1;
	  orig_name = member;
	}
      return build_min_non_dep (COMPONENT_REF, expr,
				orig_object, orig_name,
				NULL_TREE);
    }

  return expr;
}

/* Build a COMPONENT_REF of OBJECT and MEMBER with the appropriate
   type.  */

tree
build_simple_component_ref (tree object, tree member)
{
  tree type = cp_build_qualified_type (TREE_TYPE (member),
				       cp_type_quals (TREE_TYPE (object)));
  return build3_loc (input_location,
		     COMPONENT_REF, type,
		     object, member, NULL_TREE);
}

/* Return an expression for the MEMBER_NAME field in the internal
   representation of PTRMEM, a pointer-to-member function.  (Each
   pointer-to-member function type gets its own RECORD_TYPE so it is
   more convenient to access the fields by name than by FIELD_DECL.)
   This routine converts the NAME to a FIELD_DECL and then creates the
   node for the complete expression.  */

tree
build_ptrmemfunc_access_expr (tree ptrmem, tree member_name)
{
  tree ptrmem_type;
  tree member;

  if (TREE_CODE (ptrmem) == CONSTRUCTOR)
    {
      unsigned int ix;
      tree index, value;
      FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (ptrmem),
				ix, index, value)
	if (index && DECL_P (index) && DECL_NAME (index) == member_name)
	  return value;
      gcc_unreachable ();
    }

  /* This code is a stripped down version of
     build_class_member_access_expr.  It does not work to use that
     routine directly because it expects the object to be of class
     type.  */
  ptrmem_type = TREE_TYPE (ptrmem);
  gcc_assert (TYPE_PTRMEMFUNC_P (ptrmem_type));
  for (member = TYPE_FIELDS (ptrmem_type); member;
       member = DECL_CHAIN (member))
    if (DECL_NAME (member) == member_name)
      break;
  return build_simple_component_ref (ptrmem, member);
}

/* Given an expression PTR for a pointer, return an expression
   for the value pointed to.
   ERRORSTRING is the name of the operator to appear in error messages.

   This function may need to overload OPERATOR_FNNAME.
   Must also handle REFERENCE_TYPEs for C++.  */

tree
build_x_indirect_ref (location_t loc, tree expr, ref_operator errorstring, 
                      tsubst_flags_t complain)
{
  tree orig_expr = expr;
  tree rval;
  tree overload = NULL_TREE;

  if (processing_template_decl)
    {
      /* Retain the type if we know the operand is a pointer.  */
      if (TREE_TYPE (expr) && INDIRECT_TYPE_P (TREE_TYPE (expr)))
	{
	  if (expr == current_class_ptr
	      || (TREE_CODE (expr) == NOP_EXPR
		  && TREE_OPERAND (expr, 0) == current_class_ptr
		  && (same_type_ignoring_top_level_qualifiers_p
			(TREE_TYPE (expr), TREE_TYPE (current_class_ptr)))))
	    return current_class_ref;
	  return build_min (INDIRECT_REF, TREE_TYPE (TREE_TYPE (expr)), expr);
	}
      if (type_dependent_expression_p (expr))
	return build_min_nt_loc (loc, INDIRECT_REF, expr);
      expr = build_non_dependent_expr (expr);
    }

  rval = build_new_op (loc, INDIRECT_REF, LOOKUP_NORMAL, expr,
		       NULL_TREE, NULL_TREE, &overload, complain);
  if (!rval)
    rval = cp_build_indirect_ref (loc, expr, errorstring, complain);

  if (processing_template_decl && rval != error_mark_node)
    {
      if (overload != NULL_TREE)
	return (build_min_non_dep_op_overload
		(INDIRECT_REF, rval, overload, orig_expr));

      return build_min_non_dep (INDIRECT_REF, rval, orig_expr);
    }
  else
    return rval;
}

/* Like c-family strict_aliasing_warning, but don't warn for dependent
   types or expressions.  */

static bool
cp_strict_aliasing_warning (location_t loc, tree type, tree expr)
{
  if (processing_template_decl)
    {
      tree e = expr;
      STRIP_NOPS (e);
      if (dependent_type_p (type) || type_dependent_expression_p (e))
	return false;
    }
  return strict_aliasing_warning (loc, type, expr);
}

/* The implementation of the above, and of indirection implied by other
   constructs.  If DO_FOLD is true, fold away INDIRECT_REF of ADDR_EXPR.  */

static tree
cp_build_indirect_ref_1 (location_t loc, tree ptr, ref_operator errorstring,
			 tsubst_flags_t complain, bool do_fold)
{
  tree pointer, type;

  /* RO_NULL should only be used with the folding entry points below, not
     cp_build_indirect_ref.  */
  gcc_checking_assert (errorstring != RO_NULL || do_fold);

  if (ptr == current_class_ptr
      || (TREE_CODE (ptr) == NOP_EXPR
	  && TREE_OPERAND (ptr, 0) == current_class_ptr
	  && (same_type_ignoring_top_level_qualifiers_p
	      (TREE_TYPE (ptr), TREE_TYPE (current_class_ptr)))))
    return current_class_ref;

  pointer = (TYPE_REF_P (TREE_TYPE (ptr))
	     ? ptr : decay_conversion (ptr, complain));
  if (pointer == error_mark_node)
    return error_mark_node;

  type = TREE_TYPE (pointer);

  if (INDIRECT_TYPE_P (type))
    {
      /* [expr.unary.op]

	 If the type of the expression is "pointer to T," the type
	 of  the  result  is  "T."  */
      tree t = TREE_TYPE (type);

      if ((CONVERT_EXPR_P (ptr)
	   || TREE_CODE (ptr) == VIEW_CONVERT_EXPR)
	  && (!CLASS_TYPE_P (t) || !CLASSTYPE_EMPTY_P (t)))
	{
	  /* If a warning is issued, mark it to avoid duplicates from
	     the backend.  This only needs to be done at
	     warn_strict_aliasing > 2.  */
	  if (warn_strict_aliasing > 2
	      && cp_strict_aliasing_warning (EXPR_LOCATION (ptr),
					     type, TREE_OPERAND (ptr, 0)))
	    suppress_warning (ptr, OPT_Wstrict_aliasing);
	}

      if (VOID_TYPE_P (t))
	{
	  /* A pointer to incomplete type (other than cv void) can be
	     dereferenced [expr.unary.op]/1  */
          if (complain & tf_error)
            error_at (loc, "%qT is not a pointer-to-object type", type);
	  return error_mark_node;
	}
      else if (do_fold && TREE_CODE (pointer) == ADDR_EXPR
	       && same_type_p (t, TREE_TYPE (TREE_OPERAND (pointer, 0))))
	/* The POINTER was something like `&x'.  We simplify `*&x' to
	   `x'.  */
	return TREE_OPERAND (pointer, 0);
      else
	{
	  tree ref = build1 (INDIRECT_REF, t, pointer);

	  /* We *must* set TREE_READONLY when dereferencing a pointer to const,
	     so that we get the proper error message if the result is used
	     to assign to.  Also, &* is supposed to be a no-op.  */
	  TREE_READONLY (ref) = CP_TYPE_CONST_P (t);
	  TREE_THIS_VOLATILE (ref) = CP_TYPE_VOLATILE_P (t);
	  TREE_SIDE_EFFECTS (ref)
	    = (TREE_THIS_VOLATILE (ref) || TREE_SIDE_EFFECTS (pointer));
	  return ref;
	}
    }
  else if (!(complain & tf_error))
    /* Don't emit any errors; we'll just return ERROR_MARK_NODE later.  */
    ;
  /* `pointer' won't be an error_mark_node if we were given a
     pointer to member, so it's cool to check for this here.  */
  else if (TYPE_PTRMEM_P (type))
    switch (errorstring)
      {
         case RO_ARRAY_INDEXING:
           error_at (loc,
		     "invalid use of array indexing on pointer to member");
           break;
         case RO_UNARY_STAR:
           error_at (loc, "invalid use of unary %<*%> on pointer to member");
           break;
         case RO_IMPLICIT_CONVERSION:
           error_at (loc, "invalid use of implicit conversion on pointer "
		     "to member");
           break;
         case RO_ARROW_STAR:
           error_at (loc, "left hand operand of %<->*%> must be a pointer to "
		     "class, but is a pointer to member of type %qT", type);
           break;
         default:
           gcc_unreachable ();
      }
  else if (pointer != error_mark_node)
    invalid_indirection_error (loc, type, errorstring);

  return error_mark_node;
}

/* Entry point used by c-common, which expects folding.  */

tree
build_indirect_ref (location_t loc, tree ptr, ref_operator errorstring)
{
  return cp_build_indirect_ref_1 (loc, ptr, errorstring,
				  tf_warning_or_error, true);
}

/* Entry point used by internal indirection needs that don't correspond to any
   syntactic construct.  */

tree
cp_build_fold_indirect_ref (tree pointer)
{
  return cp_build_indirect_ref_1 (input_location, pointer, RO_NULL,
				  tf_warning_or_error, true);
}

/* Entry point used by indirection needs that correspond to some syntactic
   construct.  */

tree
cp_build_indirect_ref (location_t loc, tree ptr, ref_operator errorstring,
		       tsubst_flags_t complain)
{
  return cp_build_indirect_ref_1 (loc, ptr, errorstring, complain, false);
}

/* This handles expressions of the form "a[i]", which denotes
   an array reference.

   This is logically equivalent in C to *(a+i), but we may do it differently.
   If A is a variable or a member, we generate a primitive ARRAY_REF.
   This avoids forcing the array out of registers, and can work on
   arrays that are not lvalues (for example, members of structures returned
   by functions).

   If INDEX is of some user-defined type, it must be converted to
   integer type.  Otherwise, to make a compatible PLUS_EXPR, it
   will inherit the type of the array, which will be some pointer type.
   
   LOC is the location to use in building the array reference.  */

tree
cp_build_array_ref (location_t loc, tree array, tree idx,
		    tsubst_flags_t complain)
{
  tree ret;

  if (idx == 0)
    {
      if (complain & tf_error)
	error_at (loc, "subscript missing in array reference");
      return error_mark_node;
    }

  if (TREE_TYPE (array) == error_mark_node
      || TREE_TYPE (idx) == error_mark_node)
    return error_mark_node;

  /* If ARRAY is a COMPOUND_EXPR or COND_EXPR, move our reference
     inside it.  */
  switch (TREE_CODE (array))
    {
    case COMPOUND_EXPR:
      {
	tree value = cp_build_array_ref (loc, TREE_OPERAND (array, 1), idx,
					 complain);
	ret = build2 (COMPOUND_EXPR, TREE_TYPE (value),
		      TREE_OPERAND (array, 0), value);
	SET_EXPR_LOCATION (ret, loc);
	return ret;
      }

    case COND_EXPR:
      ret = build_conditional_expr
	       (loc, TREE_OPERAND (array, 0),
	       cp_build_array_ref (loc, TREE_OPERAND (array, 1), idx,
				   complain),
	       cp_build_array_ref (loc, TREE_OPERAND (array, 2), idx,
				   complain),
	       complain);
      protected_set_expr_location (ret, loc);
      return ret;

    default:
      break;
    }

  bool non_lvalue = convert_vector_to_array_for_subscript (loc, &array, idx);

  if (TREE_CODE (TREE_TYPE (array)) == ARRAY_TYPE)
    {
      tree rval, type;

      warn_array_subscript_with_type_char (loc, idx);

      if (!INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (TREE_TYPE (idx)))
	{
	  if (complain & tf_error)
	    error_at (loc, "array subscript is not an integer");
	  return error_mark_node;
	}

      /* Apply integral promotions *after* noticing character types.
	 (It is unclear why we do these promotions -- the standard
	 does not say that we should.  In fact, the natural thing would
	 seem to be to convert IDX to ptrdiff_t; we're performing
	 pointer arithmetic.)  */
      idx = cp_perform_integral_promotions (idx, complain);

      idx = maybe_fold_non_dependent_expr (idx, complain);

      /* An array that is indexed by a non-constant
	 cannot be stored in a register; we must be able to do
	 address arithmetic on its address.
	 Likewise an array of elements of variable size.  */
      if (TREE_CODE (idx) != INTEGER_CST
	  || (COMPLETE_TYPE_P (TREE_TYPE (TREE_TYPE (array)))
	      && (TREE_CODE (TYPE_SIZE (TREE_TYPE (TREE_TYPE (array))))
		  != INTEGER_CST)))
	{
	  if (!cxx_mark_addressable (array, true))
	    return error_mark_node;
	}

      /* An array that is indexed by a constant value which is not within
	 the array bounds cannot be stored in a register either; because we
	 would get a crash in store_bit_field/extract_bit_field when trying
	 to access a non-existent part of the register.  */
      if (TREE_CODE (idx) == INTEGER_CST
	  && TYPE_DOMAIN (TREE_TYPE (array))
	  && ! int_fits_type_p (idx, TYPE_DOMAIN (TREE_TYPE (array))))
	{
	  if (!cxx_mark_addressable (array))
	    return error_mark_node;
	}

      /* Note in C++ it is valid to subscript a `register' array, since
	 it is valid to take the address of something with that
	 storage specification.  */
      if (extra_warnings)
	{
	  tree foo = array;
	  while (TREE_CODE (foo) == COMPONENT_REF)
	    foo = TREE_OPERAND (foo, 0);
	  if (VAR_P (foo) && DECL_REGISTER (foo)
	      && (complain & tf_warning))
	    warning_at (loc, OPT_Wextra,
			"subscripting array declared %<register%>");
	}

      type = TREE_TYPE (TREE_TYPE (array));
      rval = build4 (ARRAY_REF, type, array, idx, NULL_TREE, NULL_TREE);
      /* Array ref is const/volatile if the array elements are
	 or if the array is..  */
      TREE_READONLY (rval)
	|= (CP_TYPE_CONST_P (type) | TREE_READONLY (array));
      TREE_SIDE_EFFECTS (rval)
	|= (CP_TYPE_VOLATILE_P (type) | TREE_SIDE_EFFECTS (array));
      TREE_THIS_VOLATILE (rval)
	|= (CP_TYPE_VOLATILE_P (type) | TREE_THIS_VOLATILE (array));
      ret = require_complete_type_sfinae (rval, complain);
      protected_set_expr_location (ret, loc);
      if (non_lvalue)
	ret = non_lvalue_loc (loc, ret);
      return ret;
    }

  {
    tree ar = cp_default_conversion (array, complain);
    tree ind = cp_default_conversion (idx, complain);
    tree first = NULL_TREE;

    if (flag_strong_eval_order == 2 && TREE_SIDE_EFFECTS (ind))
      ar = first = save_expr (ar);

    /* Put the integer in IND to simplify error checking.  */
    if (TREE_CODE (TREE_TYPE (ar)) == INTEGER_TYPE)
      std::swap (ar, ind);

    if (ar == error_mark_node || ind == error_mark_node)
      return error_mark_node;

    if (!TYPE_PTR_P (TREE_TYPE (ar)))
      {
	if (complain & tf_error)
	  error_at (loc, "subscripted value is neither array nor pointer");
	return error_mark_node;
      }
    if (TREE_CODE (TREE_TYPE (ind)) != INTEGER_TYPE)
      {
	if (complain & tf_error)
	  error_at (loc, "array subscript is not an integer");
	return error_mark_node;
      }

    warn_array_subscript_with_type_char (loc, idx);

    ret = cp_build_binary_op (input_location, PLUS_EXPR, ar, ind, complain);
    if (first)
      ret = build2_loc (loc, COMPOUND_EXPR, TREE_TYPE (ret), first, ret);
    ret = cp_build_indirect_ref (loc, ret, RO_ARRAY_INDEXING, complain);
    protected_set_expr_location (ret, loc);
    if (non_lvalue)
      ret = non_lvalue_loc (loc, ret);
    return ret;
  }
}

/* Entry point for Obj-C++.  */

tree
build_array_ref (location_t loc, tree array, tree idx)
{
  return cp_build_array_ref (loc, array, idx, tf_warning_or_error);
}

/* Resolve a pointer to member function.  INSTANCE is the object
   instance to use, if the member points to a virtual member.

   This used to avoid checking for virtual functions if basetype
   has no virtual functions, according to an earlier ANSI draft.
   With the final ISO C++ rules, such an optimization is
   incorrect: A pointer to a derived member can be static_cast
   to pointer-to-base-member, as long as the dynamic object
   later has the right member.  So now we only do this optimization
   when we know the dynamic type of the object.  */

tree
get_member_function_from_ptrfunc (tree *instance_ptrptr, tree function,
				  tsubst_flags_t complain)
{
  if (TREE_CODE (function) == OFFSET_REF)
    function = TREE_OPERAND (function, 1);

  if (TYPE_PTRMEMFUNC_P (TREE_TYPE (function)))
    {
      tree idx, delta, e1, e2, e3, vtbl;
      bool nonvirtual;
      tree fntype = TYPE_PTRMEMFUNC_FN_TYPE (TREE_TYPE (function));
      tree basetype = TYPE_METHOD_BASETYPE (TREE_TYPE (fntype));

      tree instance_ptr = *instance_ptrptr;
      tree instance_save_expr = 0;
      if (instance_ptr == error_mark_node)
	{
	  if (TREE_CODE (function) == PTRMEM_CST)
	    {
	      /* Extracting the function address from a pmf is only
		 allowed with -Wno-pmf-conversions. It only works for
		 pmf constants.  */
	      e1 = build_addr_func (PTRMEM_CST_MEMBER (function), complain);
	      e1 = convert (fntype, e1);
	      return e1;
	    }
	  else
	    {
	      if (complain & tf_error)
		error ("object missing in use of %qE", function);
	      return error_mark_node;
	    }
	}

      /* True if we know that the dynamic type of the object doesn't have
	 virtual functions, so we can assume the PFN field is a pointer.  */
      nonvirtual = (COMPLETE_TYPE_P (basetype)
		    && !TYPE_POLYMORPHIC_P (basetype)
		    && resolves_to_fixed_type_p (instance_ptr, 0));

      /* If we don't really have an object (i.e. in an ill-formed
	 conversion from PMF to pointer), we can't resolve virtual
	 functions anyway.  */
      if (!nonvirtual && is_dummy_object (instance_ptr))
	nonvirtual = true;

      if (TREE_SIDE_EFFECTS (instance_ptr))
	instance_ptr = instance_save_expr = save_expr (instance_ptr);

      if (TREE_SIDE_EFFECTS (function))
	function = save_expr (function);

      /* Start by extracting all the information from the PMF itself.  */
      e3 = pfn_from_ptrmemfunc (function);
      delta = delta_from_ptrmemfunc (function);
      idx = build1 (NOP_EXPR, vtable_index_type, e3);
      switch (TARGET_PTRMEMFUNC_VBIT_LOCATION)
	{
	  int flag_sanitize_save;
	case ptrmemfunc_vbit_in_pfn:
	  e1 = cp_build_binary_op (input_location,
				   BIT_AND_EXPR, idx, integer_one_node,
				   complain);
	  idx = cp_build_binary_op (input_location,
				    MINUS_EXPR, idx, integer_one_node,
				    complain);
	  if (idx == error_mark_node)
	    return error_mark_node;
	  break;

	case ptrmemfunc_vbit_in_delta:
	  e1 = cp_build_binary_op (input_location,
				   BIT_AND_EXPR, delta, integer_one_node,
				   complain);
	  /* Don't instrument the RSHIFT_EXPR we're about to create because
	     we're going to use DELTA number of times, and that wouldn't play
	     well with SAVE_EXPRs therein.  */
	  flag_sanitize_save = flag_sanitize;
	  flag_sanitize = 0;
	  delta = cp_build_binary_op (input_location,
				      RSHIFT_EXPR, delta, integer_one_node,
				      complain);
	  flag_sanitize = flag_sanitize_save;
	  if (delta == error_mark_node)
	    return error_mark_node;
	  break;

	default:
	  gcc_unreachable ();
	}

      if (e1 == error_mark_node)
	return error_mark_node;

      /* Convert down to the right base before using the instance.  A
	 special case is that in a pointer to member of class C, C may
	 be incomplete.  In that case, the function will of course be
	 a member of C, and no conversion is required.  In fact,
	 lookup_base will fail in that case, because incomplete
	 classes do not have BINFOs.  */
      if (!same_type_ignoring_top_level_qualifiers_p
	  (basetype, TREE_TYPE (TREE_TYPE (instance_ptr))))
	{
	  basetype = lookup_base (TREE_TYPE (TREE_TYPE (instance_ptr)),
				  basetype, ba_check, NULL, complain);
	  instance_ptr = build_base_path (PLUS_EXPR, instance_ptr, basetype,
					  1, complain);
	  if (instance_ptr == error_mark_node)
	    return error_mark_node;
	}
      /* ...and then the delta in the PMF.  */
      instance_ptr = fold_build_pointer_plus (instance_ptr, delta);

      /* Hand back the adjusted 'this' argument to our caller.  */
      *instance_ptrptr = instance_ptr;

      if (nonvirtual)
	/* Now just return the pointer.  */
	return e3;

      /* Next extract the vtable pointer from the object.  */
      vtbl = build1 (NOP_EXPR, build_pointer_type (vtbl_ptr_type_node),
		     instance_ptr);
      vtbl = cp_build_fold_indirect_ref (vtbl);
      if (vtbl == error_mark_node)
	return error_mark_node;

      /* Finally, extract the function pointer from the vtable.  */
      e2 = fold_build_pointer_plus_loc (input_location, vtbl, idx);
      e2 = cp_build_fold_indirect_ref (e2);
      if (e2 == error_mark_node)
	return error_mark_node;
      TREE_CONSTANT (e2) = 1;

      /* When using function descriptors, the address of the
	 vtable entry is treated as a function pointer.  */
      if (TARGET_VTABLE_USES_DESCRIPTORS)
	e2 = build1 (NOP_EXPR, TREE_TYPE (e2),
		     cp_build_addr_expr (e2, complain));

      e2 = fold_convert (TREE_TYPE (e3), e2);
      e1 = build_conditional_expr (input_location, e1, e2, e3, complain);
      if (e1 == error_mark_node)
	return error_mark_node;

      /* Make sure this doesn't get evaluated first inside one of the
	 branches of the COND_EXPR.  */
      if (instance_save_expr)
	e1 = build2 (COMPOUND_EXPR, TREE_TYPE (e1),
		     instance_save_expr, e1);

      function = e1;
    }
  return function;
}

/* Used by the C-common bits.  */
tree
build_function_call (location_t /*loc*/, 
		     tree function, tree params)
{
  return cp_build_function_call (function, params, tf_warning_or_error);
}

/* Used by the C-common bits.  */
tree
build_function_call_vec (location_t /*loc*/, vec<location_t> /*arg_loc*/,
			 tree function, vec<tree, va_gc> *params,
			 vec<tree, va_gc> * /*origtypes*/, tree orig_function)
{
  vec<tree, va_gc> *orig_params = params;
  tree ret = cp_build_function_call_vec (function, &params,
					 tf_warning_or_error, orig_function);

  /* cp_build_function_call_vec can reallocate PARAMS by adding
     default arguments.  That should never happen here.  Verify
     that.  */
  gcc_assert (params == orig_params);

  return ret;
}

/* Build a function call using a tree list of arguments.  */

static tree
cp_build_function_call (tree function, tree params, tsubst_flags_t complain)
{
  tree ret;

  releasing_vec vec;
  for (; params != NULL_TREE; params = TREE_CHAIN (params))
    vec_safe_push (vec, TREE_VALUE (params));
  ret = cp_build_function_call_vec (function, &vec, complain);
  return ret;
}

/* Build a function call using varargs.  */

tree
cp_build_function_call_nary (tree function, tsubst_flags_t complain, ...)
{
  va_list args;
  tree ret, t;

  releasing_vec vec;
  va_start (args, complain);
  for (t = va_arg (args, tree); t != NULL_TREE; t = va_arg (args, tree))
    vec_safe_push (vec, t);
  va_end (args);
  ret = cp_build_function_call_vec (function, &vec, complain);
  return ret;
}

/* Build a function call using a vector of arguments.
   If FUNCTION is the result of resolving an overloaded target built-in,
   ORIG_FNDECL is the original function decl, otherwise it is null.
   PARAMS may be NULL if there are no parameters.  This changes the
   contents of PARAMS.  */

tree
cp_build_function_call_vec (tree function, vec<tree, va_gc> **params,
			    tsubst_flags_t complain, tree orig_fndecl)
{
  tree fntype, fndecl;
  int is_method;
  tree original = function;
  int nargs;
  tree *argarray;
  tree parm_types;
  vec<tree, va_gc> *allocated = NULL;
  tree ret;

  /* For Objective-C, convert any calls via a cast to OBJC_TYPE_REF
     expressions, like those used for ObjC messenger dispatches.  */
  if (params != NULL && !vec_safe_is_empty (*params))
    function = objc_rewrite_function_call (function, (**params)[0]);

  /* build_c_cast puts on a NOP_EXPR to make the result not an lvalue.
     Strip such NOP_EXPRs, since FUNCTION is used in non-lvalue context.  */
  if (TREE_CODE (function) == NOP_EXPR
      && TREE_TYPE (function) == TREE_TYPE (TREE_OPERAND (function, 0)))
    function = TREE_OPERAND (function, 0);

  if (TREE_CODE (function) == FUNCTION_DECL)
    {
      if (!mark_used (function, complain))
	return error_mark_node;
      fndecl = function;

      /* Convert anything with function type to a pointer-to-function.  */
      if (DECL_MAIN_P (function))
	{
	  if (complain & tf_error)
	    pedwarn (input_location, OPT_Wpedantic, 
		     "ISO C++ forbids calling %<::main%> from within program");
	  else
	    return error_mark_node;
	}
      function = build_addr_func (function, complain);
    }
  else
    {
      fndecl = NULL_TREE;

      function = build_addr_func (function, complain);
    }

  if (function == error_mark_node)
    return error_mark_node;

  fntype = TREE_TYPE (function);

  if (TYPE_PTRMEMFUNC_P (fntype))
    {
      if (complain & tf_error)
	error ("must use %<.*%> or %<->*%> to call pointer-to-member "
	       "function in %<%E (...)%>, e.g. %<(... ->* %E) (...)%>",
	       original, original);
      return error_mark_node;
    }

  is_method = (TYPE_PTR_P (fntype)
	       && TREE_CODE (TREE_TYPE (fntype)) == METHOD_TYPE);

  if (!(TYPE_PTRFN_P (fntype)
	|| is_method
	|| TREE_CODE (function) == TEMPLATE_ID_EXPR))
    {
      if (complain & tf_error)
	{
	  if (!flag_diagnostics_show_caret)
	    error_at (input_location,
		      "%qE cannot be used as a function", original);
	  else if (DECL_P (original))
	    error_at (input_location,
		      "%qD cannot be used as a function", original);
	  else 
	    error_at (input_location,
		      "expression cannot be used as a function");
	}

      return error_mark_node;
    }

  /* fntype now gets the type of function pointed to.  */
  fntype = TREE_TYPE (fntype);
  parm_types = TYPE_ARG_TYPES (fntype);

  if (params == NULL)
    {
      allocated = make_tree_vector ();
      params = &allocated;
    }

    nargs = convert_arguments (parm_types, params, fndecl, LOOKUP_NORMAL,
			       complain);
  if (nargs < 0)
    return error_mark_node;

  argarray = (*params)->address ();

  /* Check for errors in format strings and inappropriately
     null parameters.  */
  bool warned_p = check_function_arguments (input_location, fndecl, fntype,
					    nargs, argarray, NULL);

  ret = build_cxx_call (function, nargs, argarray, complain, orig_fndecl);

  if (warned_p)
    {
      tree c = extract_call_expr (ret);
      if (TREE_CODE (c) == CALL_EXPR)
	suppress_warning (c, OPT_Wnonnull);
    }

  if (allocated != NULL)
    release_tree_vector (allocated);

  return ret;
}

/* Subroutine of convert_arguments.
   Print an error message about a wrong number of arguments.  */

static void
error_args_num (location_t loc, tree fndecl, bool too_many_p)
{
  if (fndecl)
    {
      if (TREE_CODE (TREE_TYPE (fndecl)) == METHOD_TYPE)
	{
	  if (DECL_NAME (fndecl) == NULL_TREE
	      || (DECL_NAME (fndecl)
		  == DECL_NAME (TYPE_NAME (DECL_CONTEXT (fndecl)))))
	    error_at (loc,
		      too_many_p
		      ? G_("too many arguments to constructor %q#D")
		      : G_("too few arguments to constructor %q#D"),
		      fndecl);
	  else
	    error_at (loc,
		      too_many_p
		      ? G_("too many arguments to member function %q#D")
		      : G_("too few arguments to member function %q#D"),
		      fndecl);
	}
      else
	error_at (loc,
		  too_many_p
		  ? G_("too many arguments to function %q#D")
		  : G_("too few arguments to function %q#D"),
		  fndecl);
      if (!DECL_IS_UNDECLARED_BUILTIN (fndecl))
	inform (DECL_SOURCE_LOCATION (fndecl), "declared here");
    }
  else
    {
      if (c_dialect_objc ()  &&  objc_message_selector ())
	error_at (loc,
		  too_many_p 
		  ? G_("too many arguments to method %q#D")
		  : G_("too few arguments to method %q#D"),
		  objc_message_selector ());
      else
	error_at (loc, too_many_p ? G_("too many arguments to function")
		                  : G_("too few arguments to function"));
    }
}

/* Convert the actual parameter expressions in the list VALUES to the
   types in the list TYPELIST.  The converted expressions are stored
   back in the VALUES vector.
   If parmdecls is exhausted, or when an element has NULL as its type,
   perform the default conversions.

   NAME is an IDENTIFIER_NODE or 0.  It is used only for error messages.

   This is also where warnings about wrong number of args are generated.

   Returns the actual number of arguments processed (which might be less
   than the length of the vector), or -1 on error.

   In C++, unspecified trailing parameters can be filled in with their
   default arguments, if such were specified.  Do so here.  */

static int
convert_arguments (tree typelist, vec<tree, va_gc> **values, tree fndecl,
		   int flags, tsubst_flags_t complain)
{
  tree typetail;
  unsigned int i;

  /* Argument passing is always copy-initialization.  */
  flags |= LOOKUP_ONLYCONVERTING;

  for (i = 0, typetail = typelist;
       i < vec_safe_length (*values);
       i++)
    {
      tree type = typetail ? TREE_VALUE (typetail) : 0;
      tree val = (**values)[i];

      if (val == error_mark_node || type == error_mark_node)
	return -1;

      if (type == void_type_node)
	{
          if (complain & tf_error)
            {
	      error_args_num (input_location, fndecl, /*too_many_p=*/true);
              return i;
            }
          else
            return -1;
	}

      /* build_c_cast puts on a NOP_EXPR to make the result not an lvalue.
	 Strip such NOP_EXPRs, since VAL is used in non-lvalue context.  */
      if (TREE_CODE (val) == NOP_EXPR
	  && TREE_TYPE (val) == TREE_TYPE (TREE_OPERAND (val, 0))
	  && (type == 0 || !TYPE_REF_P (type)))
	val = TREE_OPERAND (val, 0);

      if (type == 0 || !TYPE_REF_P (type))
	{
	  if (TREE_CODE (TREE_TYPE (val)) == ARRAY_TYPE
	      || FUNC_OR_METHOD_TYPE_P (TREE_TYPE (val)))
	    val = decay_conversion (val, complain);
	}

      if (val == error_mark_node)
	return -1;

      if (type != 0)
	{
	  /* Formal parm type is specified by a function prototype.  */
	  tree parmval;

	  if (!COMPLETE_TYPE_P (complete_type (type)))
	    {
              if (complain & tf_error)
                {
		  location_t loc = EXPR_LOC_OR_LOC (val, input_location);
                  if (fndecl)
		    {
		      auto_diagnostic_group d;
		      error_at (loc,
				"parameter %P of %qD has incomplete type %qT",
				i, fndecl, type);
		      inform (get_fndecl_argument_location (fndecl, i),
			      "  declared here");
		    }
                  else
		    error_at (loc, "parameter %P has incomplete type %qT", i,
			      type);
                }
	      parmval = error_mark_node;
	    }
	  else
	    {
	      parmval = convert_for_initialization
		(NULL_TREE, type, val, flags,
		 ICR_ARGPASS, fndecl, i, complain);
	      parmval = convert_for_arg_passing (type, parmval, complain);
	    }

	  if (parmval == error_mark_node)
	    return -1;

	  (**values)[i] = parmval;
	}
      else
	{
	  if (fndecl && magic_varargs_p (fndecl))
	    /* Don't do ellipsis conversion for __built_in_constant_p
	       as this will result in spurious errors for non-trivial
	       types.  */
	    val = require_complete_type_sfinae (val, complain);
	  else
	    val = convert_arg_to_ellipsis (val, complain);

	  (**values)[i] = val;
	}

      if (typetail)
	typetail = TREE_CHAIN (typetail);
    }

  if (typetail != 0 && typetail != void_list_node)
    {
      /* See if there are default arguments that can be used.  Because
	 we hold default arguments in the FUNCTION_TYPE (which is so
	 wrong), we can see default parameters here from deduced
	 contexts (and via typeof) for indirect function calls.
	 Fortunately we know whether we have a function decl to
	 provide default arguments in a language conformant
	 manner.  */
      if (fndecl && TREE_PURPOSE (typetail)
	  && TREE_CODE (TREE_PURPOSE (typetail)) != DEFERRED_PARSE)
	{
	  for (; typetail != void_list_node; ++i)
	    {
	      /* After DR777, with explicit template args we can end up with a
		 default argument followed by no default argument.  */
	      if (!TREE_PURPOSE (typetail))
		break;
	      tree parmval
		= convert_default_arg (TREE_VALUE (typetail),
				       TREE_PURPOSE (typetail),
				       fndecl, i, complain);

	      if (parmval == error_mark_node)
		return -1;

	      vec_safe_push (*values, parmval);
	      typetail = TREE_CHAIN (typetail);
	      /* ends with `...'.  */
	      if (typetail == NULL_TREE)
		break;
	    }
	}

      if (typetail && typetail != void_list_node)
	{
	  if (complain & tf_error)
	    error_args_num (input_location, fndecl, /*too_many_p=*/false);
	  return -1;
	}
    }

  return (int) i;
}

/* Build a binary-operation expression, after performing default
   conversions on the operands.  CODE is the kind of expression to
   build.  ARG1 and ARG2 are the arguments.  ARG1_CODE and ARG2_CODE
   are the tree codes which correspond to ARG1 and ARG2 when issuing
   warnings about possibly misplaced parentheses.  They may differ
   from the TREE_CODE of ARG1 and ARG2 if the parser has done constant
   folding (e.g., if the parser sees "a | 1 + 1", it may call this
   routine with ARG2 being an INTEGER_CST and ARG2_CODE == PLUS_EXPR).
   To avoid issuing any parentheses warnings, pass ARG1_CODE and/or
   ARG2_CODE as ERROR_MARK.  */

tree
build_x_binary_op (const op_location_t &loc, enum tree_code code, tree arg1,
		   enum tree_code arg1_code, tree arg2,
		   enum tree_code arg2_code, tree *overload_p,
		   tsubst_flags_t complain)
{
  tree orig_arg1;
  tree orig_arg2;
  tree expr;
  tree overload = NULL_TREE;

  orig_arg1 = arg1;
  orig_arg2 = arg2;

  if (processing_template_decl)
    {
      if (type_dependent_expression_p (arg1)
	  || type_dependent_expression_p (arg2))
	{
	  expr = build_min_nt_loc (loc, code, arg1, arg2);
	  maybe_save_operator_binding (expr);
	  return expr;
	}
      arg1 = build_non_dependent_expr (arg1);
      arg2 = build_non_dependent_expr (arg2);
    }

  if (code == DOTSTAR_EXPR)
    expr = build_m_component_ref (arg1, arg2, complain);
  else
    expr = build_new_op (loc, code, LOOKUP_NORMAL, arg1, arg2, NULL_TREE,
			 &overload, complain);

  if (overload_p != NULL)
    *overload_p = overload;

  /* Check for cases such as x+y<<z which users are likely to
     misinterpret.  But don't warn about obj << x + y, since that is a
     common idiom for I/O.  */
  if (warn_parentheses
      && (complain & tf_warning)
      && !processing_template_decl
      && !error_operand_p (arg1)
      && !error_operand_p (arg2)
      && (code != LSHIFT_EXPR
	  || !CLASS_TYPE_P (TREE_TYPE (arg1))))
    warn_about_parentheses (loc, code, arg1_code, orig_arg1,
			    arg2_code, orig_arg2);

  if (processing_template_decl && expr != error_mark_node)
    {
      if (overload != NULL_TREE)
	return (build_min_non_dep_op_overload
		(code, expr, overload, orig_arg1, orig_arg2));

      return build_min_non_dep (code, expr, orig_arg1, orig_arg2);
    }

  return expr;
}

/* Build and return an ARRAY_REF expression.  */

tree
build_x_array_ref (location_t loc, tree arg1, tree arg2,
		   tsubst_flags_t complain)
{
  tree orig_arg1 = arg1;
  tree orig_arg2 = arg2;
  tree expr;
  tree overload = NULL_TREE;

  if (processing_template_decl)
    {
      if (type_dependent_expression_p (arg1)
	  || type_dependent_expression_p (arg2))
	return build_min_nt_loc (loc, ARRAY_REF, arg1, arg2,
				 NULL_TREE, NULL_TREE);
      arg1 = build_non_dependent_expr (arg1);
      arg2 = build_non_dependent_expr (arg2);
    }

  expr = build_new_op (loc, ARRAY_REF, LOOKUP_NORMAL, arg1, arg2,
		       NULL_TREE, &overload, complain);

  if (processing_template_decl && expr != error_mark_node)
    {
      if (overload != NULL_TREE)
	return (build_min_non_dep_op_overload
		(ARRAY_REF, expr, overload, orig_arg1, orig_arg2));

      return build_min_non_dep (ARRAY_REF, expr, orig_arg1, orig_arg2,
				NULL_TREE, NULL_TREE);
    }
  return expr;
}

/* Return whether OP is an expression of enum type cast to integer
   type.  In C++ even unsigned enum types are cast to signed integer
   types.  We do not want to issue warnings about comparisons between
   signed and unsigned types when one of the types is an enum type.
   Those warnings are always false positives in practice.  */

static bool
enum_cast_to_int (tree op)
{
  if (CONVERT_EXPR_P (op)
      && TREE_TYPE (op) == integer_type_node
      && TREE_CODE (TREE_TYPE (TREE_OPERAND (op, 0))) == ENUMERAL_TYPE
      && TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (op, 0))))
    return true;

  /* The cast may have been pushed into a COND_EXPR.  */
  if (TREE_CODE (op) == COND_EXPR)
    return (enum_cast_to_int (TREE_OPERAND (op, 1))
	    || enum_cast_to_int (TREE_OPERAND (op, 2)));

  return false;
}

/* For the c-common bits.  */
tree
build_binary_op (location_t location, enum tree_code code, tree op0, tree op1,
		 bool /*convert_p*/)
{
  return cp_build_binary_op (location, code, op0, op1, tf_warning_or_error);
}

/* Build a vector comparison of ARG0 and ARG1 using CODE opcode
   into a value of TYPE type.  Comparison is done via VEC_COND_EXPR.  */

static tree
build_vec_cmp (tree_code code, tree type,
	       tree arg0, tree arg1)
{
  tree zero_vec = build_zero_cst (type);
  tree minus_one_vec = build_minus_one_cst (type);
  tree cmp_type = truth_type_for (type);
  tree cmp = build2 (code, cmp_type, arg0, arg1);
  return build3 (VEC_COND_EXPR, type, cmp, minus_one_vec, zero_vec);
}

/* Possibly warn about an address never being NULL.  */

static void
warn_for_null_address (location_t location, tree op, tsubst_flags_t complain)
{
  if (!warn_address
      || (complain & tf_warning) == 0
      || c_inhibit_evaluation_warnings != 0
      || warning_suppressed_p (op, OPT_Waddress))
    return;

  if (TREE_CODE (op) == NON_DEPENDENT_EXPR)
    op = TREE_OPERAND (op, 0);

  tree cop = fold_for_warn (op);

  if (TREE_CODE (cop) == NON_LVALUE_EXPR)
    /* Unwrap the expression for C++ 98.  */
    cop = TREE_OPERAND (cop, 0);

  if (TREE_CODE (cop) == PTRMEM_CST)
    {
      /* The address of a nonstatic data member is never null.  */
      warning_at (location, OPT_Waddress,
		  "the address %qE will never be NULL",
		  cop);
      return;
    }

  if (TREE_CODE (cop) == NOP_EXPR)
    {
      /* Allow casts to intptr_t to suppress the warning.  */
      tree type = TREE_TYPE (cop);
      if (TREE_CODE (type) == INTEGER_TYPE)
	return;

      STRIP_NOPS (cop);
    }

  bool warned = false;
  if (TREE_CODE (cop) == ADDR_EXPR)
    {
      cop = TREE_OPERAND (cop, 0);

      /* Set to true in the loop below if OP dereferences its operand.
	 In such a case the ultimate target need not be a decl for
	 the null [in]equality test to be necessarily constant.  */
      bool deref = false;

      /* Get the outermost array or object, or member.  */
      while (handled_component_p (cop))
	{
	  if (TREE_CODE (cop) == COMPONENT_REF)
	    {
	      /* Get the member (its address is never null).  */
	      cop = TREE_OPERAND (cop, 1);
	      break;
	    }

	  /* Get the outer array/object to refer to in the warning.  */
	  cop = TREE_OPERAND (cop, 0);
	  deref = true;
	}

      if ((!deref && !decl_with_nonnull_addr_p (cop))
	  || from_macro_expansion_at (location)
	  || warning_suppressed_p (cop, OPT_Waddress))
	return;

      warned = warning_at (location, OPT_Waddress,
			   "the address of %qD will never be NULL", cop);
      op = cop;
    }
  else if (TREE_CODE (cop) == POINTER_PLUS_EXPR)
    {
      /* Adding zero to the null pointer is well-defined in C++.  When
	 the offset is unknown (i.e., not a constant) warn anyway since
	 it's less likely that the pointer operand is null than not.  */
      tree off = TREE_OPERAND (cop, 1);
      if (!integer_zerop (off)
	  && !warning_suppressed_p (cop, OPT_Waddress))
	warning_at (location, OPT_Waddress, "comparing the result of pointer "
		    "addition %qE and NULL", cop);
      return;
    }
  else if (CONVERT_EXPR_P (op)
      && TYPE_REF_P (TREE_TYPE (TREE_OPERAND (op, 0))))
    {
      STRIP_NOPS (op);

      if (DECL_P (op))
	warned = warning_at (location, OPT_Waddress,
			     "the compiler can assume that the address of "
			     "%qD will never be NULL", op);
    }

  if (warned && DECL_P (op))
    inform (DECL_SOURCE_LOCATION (op), "%qD declared here", op);
}

/* Warn about [expr.arith.conv]/2: If one operand is of enumeration type and
   the other operand is of a different enumeration type or a floating-point
   type, this behavior is deprecated ([depr.arith.conv.enum]).  CODE is the
   code of the binary operation, TYPE0 and TYPE1 are the types of the operands,
   and LOC is the location for the whole binary expression.
   TODO: Consider combining this with -Wenum-compare in build_new_op_1.  */

static void
do_warn_enum_conversions (location_t loc, enum tree_code code, tree type0,
			  tree type1)
{
  if (TREE_CODE (type0) == ENUMERAL_TYPE
      && TREE_CODE (type1) == ENUMERAL_TYPE
      && TYPE_MAIN_VARIANT (type0) != TYPE_MAIN_VARIANT (type1))
    {
      /* In C++20, -Wdeprecated-enum-enum-conversion is on by default.
	 Otherwise, warn if -Wenum-conversion is on.  */
      enum opt_code opt;
      if (warn_deprecated_enum_enum_conv)
	opt = OPT_Wdeprecated_enum_enum_conversion;
      else if (warn_enum_conversion)
	opt = OPT_Wenum_conversion;
      else
	return;

      switch (code)
	{
	case GT_EXPR:
	case LT_EXPR:
	case GE_EXPR:
	case LE_EXPR:
	case EQ_EXPR:
	case NE_EXPR:
	  /* Comparisons are handled by -Wenum-compare.  */
	  return;
	case SPACESHIP_EXPR:
	  /* This is invalid, don't warn.  */
	  return;
	case BIT_AND_EXPR:
	case BIT_IOR_EXPR:
	case BIT_XOR_EXPR:
	  warning_at (loc, opt, "bitwise operation between different "
		      "enumeration types %qT and %qT is deprecated",
		      type0, type1);
	  return;
	default:
	  warning_at (loc, opt, "arithmetic between different enumeration "
		      "types %qT and %qT is deprecated", type0, type1);
	  return;
	}
    }
  else if ((TREE_CODE (type0) == ENUMERAL_TYPE
	    && TREE_CODE (type1) == REAL_TYPE)
	   || (TREE_CODE (type0) == REAL_TYPE
	       && TREE_CODE (type1) == ENUMERAL_TYPE))
    {
      const bool enum_first_p = TREE_CODE (type0) == ENUMERAL_TYPE;
      /* In C++20, -Wdeprecated-enum-float-conversion is on by default.
	 Otherwise, warn if -Wenum-conversion is on.  */
      enum opt_code opt;
      if (warn_deprecated_enum_float_conv)
	opt = OPT_Wdeprecated_enum_float_conversion;
      else if (warn_enum_conversion)
	opt = OPT_Wenum_conversion;
      else
	return;

      switch (code)
	{
	case GT_EXPR:
	case LT_EXPR:
	case GE_EXPR:
	case LE_EXPR:
	case EQ_EXPR:
	case NE_EXPR:
	  if (enum_first_p)
	    warning_at (loc, opt, "comparison of enumeration type %qT with "
			"floating-point type %qT is deprecated",
			type0, type1);
	  else
	    warning_at (loc, opt, "comparison of floating-point type %qT "
			"with enumeration type %qT is deprecated",
			type0, type1);
	  return;
	case SPACESHIP_EXPR:
	  /* This is invalid, don't warn.  */
	  return;
	default:
	  if (enum_first_p)
	    warning_at (loc, opt, "arithmetic between enumeration type %qT "
			"and floating-point type %qT is deprecated",
			type0, type1);
	  else
	    warning_at (loc, opt, "arithmetic between floating-point type %qT "
			"and enumeration type %qT is deprecated",
			type0, type1);
	  return;
	}
    }
}

/* Build a binary-operation expression without default conversions.
   CODE is the kind of expression to build.
   LOCATION is the location_t of the operator in the source code.
   This function differs from `build' in several ways:
   the data type of the result is computed and recorded in it,
   warnings are generated if arg data types are invalid,
   special handling for addition and subtraction of pointers is known,
   and some optimization is done (operations on narrow ints
   are done in the narrower type when that gives the same result).
   Constant folding is also done before the result is returned.

   Note that the operands will never have enumeral types
   because either they have just had the default conversions performed
   or they have both just been converted to some other type in which
   the arithmetic is to be done.

   C++: must do special pointer arithmetic when implementing
   multiple inheritance, and deal with pointer to member functions.  */

tree
cp_build_binary_op (const op_location_t &location,
		    enum tree_code code, tree orig_op0, tree orig_op1,
		    tsubst_flags_t complain)
{
  tree op0, op1;
  enum tree_code code0, code1;
  tree type0, type1;
  const char *invalid_op_diag;

  /* Expression code to give to the expression when it is built.
     Normally this is CODE, which is what the caller asked for,
     but in some special cases we change it.  */
  enum tree_code resultcode = code;

  /* Data type in which the computation is to be performed.
     In the simplest cases this is the common type of the arguments.  */
  tree result_type = NULL_TREE;

  /* Nonzero means operands have already been type-converted
     in whatever way is necessary.
     Zero means they need to be converted to RESULT_TYPE.  */
  int converted = 0;

  /* Nonzero means create the expression with this type, rather than
     RESULT_TYPE.  */
  tree build_type = 0;

  /* Nonzero means after finally constructing the expression
     convert it to this type.  */
  tree final_type = 0;

  tree result, result_ovl;

  /* Nonzero if this is an operation like MIN or MAX which can
     safely be computed in short if both args are promoted shorts.
     Also implies COMMON.
     -1 indicates a bitwise operation; this makes a difference
     in the exact conditions for when it is safe to do the operation
     in a narrower mode.  */
  int shorten = 0;

  /* Nonzero if this is a comparison operation;
     if both args are promoted shorts, compare the original shorts.
     Also implies COMMON.  */
  int short_compare = 0;

  /* Nonzero if this is a right-shift operation, which can be computed on the
     original short and then promoted if the operand is a promoted short.  */
  int short_shift = 0;

  /* Nonzero means set RESULT_TYPE to the common type of the args.  */
  int common = 0;

  /* True if both operands have arithmetic type.  */
  bool arithmetic_types_p;

  /* Remember whether we're doing / or %.  */
  bool doing_div_or_mod = false;

  /* Remember whether we're doing << or >>.  */
  bool doing_shift = false;

  /* Tree holding instrumentation expression.  */
  tree instrument_expr = NULL_TREE;

  /* Apply default conversions.  */
  op0 = resolve_nondeduced_context (orig_op0, complain);
  op1 = resolve_nondeduced_context (orig_op1, complain);

  if (code == TRUTH_AND_EXPR || code == TRUTH_ANDIF_EXPR
      || code == TRUTH_OR_EXPR || code == TRUTH_ORIF_EXPR
      || code == TRUTH_XOR_EXPR)
    {
      if (!really_overloaded_fn (op0) && !VOID_TYPE_P (TREE_TYPE (op0)))
	op0 = decay_conversion (op0, complain);
      if (!really_overloaded_fn (op1) && !VOID_TYPE_P (TREE_TYPE (op1)))
	op1 = decay_conversion (op1, complain);
    }
  else
    {
      if (!really_overloaded_fn (op0) && !VOID_TYPE_P (TREE_TYPE (op0)))
	op0 = cp_default_conversion (op0, complain);
      if (!really_overloaded_fn (op1) && !VOID_TYPE_P (TREE_TYPE (op1)))
	op1 = cp_default_conversion (op1, complain);
    }

  /* Strip NON_LVALUE_EXPRs, etc., since we aren't using as an lvalue.  */
  STRIP_TYPE_NOPS (op0);
  STRIP_TYPE_NOPS (op1);

  /* DTRT if one side is an overloaded function, but complain about it.  */
  if (type_unknown_p (op0))
    {
      tree t = instantiate_type (TREE_TYPE (op1), op0, tf_none);
      if (t != error_mark_node)
	{
	  if (complain & tf_error)
	    permerror (location,
		       "assuming cast to type %qT from overloaded function",
		       TREE_TYPE (t));
	  op0 = t;
	}
    }
  if (type_unknown_p (op1))
    {
      tree t = instantiate_type (TREE_TYPE (op0), op1, tf_none);
      if (t != error_mark_node)
	{
	  if (complain & tf_error)
	    permerror (location,
		       "assuming cast to type %qT from overloaded function",
		       TREE_TYPE (t));
	  op1 = t;
	}
    }

  type0 = TREE_TYPE (op0); 
  type1 = TREE_TYPE (op1);

  /* The expression codes of the data types of the arguments tell us
     whether the arguments are integers, floating, pointers, etc.  */
  code0 = TREE_CODE (type0);
  code1 = TREE_CODE (type1);

  /* If an error was already reported for one of the arguments,
     avoid reporting another error.  */
  if (code0 == ERROR_MARK || code1 == ERROR_MARK)
    return error_mark_node;

  if ((invalid_op_diag
       = targetm.invalid_binary_op (code, type0, type1)))
    {
      if (complain & tf_error)
	error (invalid_op_diag);
      return error_mark_node;
    }

  /* Issue warnings about peculiar, but valid, uses of NULL.  */
  if ((null_node_p (orig_op0) || null_node_p (orig_op1))
      /* It's reasonable to use pointer values as operands of &&
	 and ||, so NULL is no exception.  */
      && code != TRUTH_ANDIF_EXPR && code != TRUTH_ORIF_EXPR 
      && ( /* Both are NULL (or 0) and the operation was not a
	      comparison or a pointer subtraction.  */
	  (null_ptr_cst_p (orig_op0) && null_ptr_cst_p (orig_op1) 
	   && code != EQ_EXPR && code != NE_EXPR && code != MINUS_EXPR) 
	  /* Or if one of OP0 or OP1 is neither a pointer nor NULL.  */
	  || (!null_ptr_cst_p (orig_op0)
	      && !TYPE_PTR_OR_PTRMEM_P (type0))
	  || (!null_ptr_cst_p (orig_op1) 
	      && !TYPE_PTR_OR_PTRMEM_P (type1)))
      && (complain & tf_warning))
    {
      location_t loc =
	expansion_point_location_if_in_system_header (input_location);

      warning_at (loc, OPT_Wpointer_arith, "NULL used in arithmetic");
    }

  /* In case when one of the operands of the binary operation is
     a vector and another is a scalar -- convert scalar to vector.  */
  if ((gnu_vector_type_p (type0) && code1 != VECTOR_TYPE)
      || (gnu_vector_type_p (type1) && code0 != VECTOR_TYPE))
    {
      enum stv_conv convert_flag = scalar_to_vector (location, code, op0, op1,
						     complain & tf_error);

      switch (convert_flag)
        {
          case stv_error:
            return error_mark_node;
          case stv_firstarg:
            {
              op0 = convert (TREE_TYPE (type1), op0);
	      op0 = save_expr (op0);
              op0 = build_vector_from_val (type1, op0);
              type0 = TREE_TYPE (op0);
              code0 = TREE_CODE (type0);
              converted = 1;
              break;
            }
          case stv_secondarg:
            {
              op1 = convert (TREE_TYPE (type0), op1);
	      op1 = save_expr (op1);
              op1 = build_vector_from_val (type0, op1);
              type1 = TREE_TYPE (op1);
              code1 = TREE_CODE (type1);
              converted = 1;
              break;
            }
          default:
            break;
        }
    }

  switch (code)
    {
    case MINUS_EXPR:
      /* Subtraction of two similar pointers.
	 We must subtract them as integers, then divide by object size.  */
      if (code0 == POINTER_TYPE && code1 == POINTER_TYPE
	  && same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (type0),
							TREE_TYPE (type1)))
	{
	  result = pointer_diff (location, op0, op1,
				 common_pointer_type (type0, type1), complain,
				 &instrument_expr);
	  if (instrument_expr != NULL)
	    result = build2 (COMPOUND_EXPR, TREE_TYPE (result),
			     instrument_expr, result);

	  return result;
	}
      /* In all other cases except pointer - int, the usual arithmetic
	 rules apply.  */
      else if (!(code0 == POINTER_TYPE && code1 == INTEGER_TYPE))
	{
	  common = 1;
	  break;
	}
      /* The pointer - int case is just like pointer + int; fall
	 through.  */
      gcc_fallthrough ();
    case PLUS_EXPR:
      if ((code0 == POINTER_TYPE || code1 == POINTER_TYPE)
	  && (code0 == INTEGER_TYPE || code1 == INTEGER_TYPE))
	{
	  tree ptr_operand;
	  tree int_operand;
	  ptr_operand = ((code0 == POINTER_TYPE) ? op0 : op1);
	  int_operand = ((code0 == INTEGER_TYPE) ? op0 : op1);
	  if (processing_template_decl)
	    {
	      result_type = TREE_TYPE (ptr_operand);
	      break;
	    }
	  return cp_pointer_int_sum (location, code,
				     ptr_operand,
				     int_operand,
				     complain);
	}
      common = 1;
      break;

    case MULT_EXPR:
      common = 1;
      break;

    case TRUNC_DIV_EXPR:
    case CEIL_DIV_EXPR:
    case FLOOR_DIV_EXPR:
    case ROUND_DIV_EXPR:
    case EXACT_DIV_EXPR:
      if (TREE_CODE (op0) == SIZEOF_EXPR && TREE_CODE (op1) == SIZEOF_EXPR)
	{
	  tree type0 = TREE_OPERAND (op0, 0);
	  tree type1 = TREE_OPERAND (op1, 0);
	  tree first_arg = tree_strip_any_location_wrapper (type0);
	  if (!TYPE_P (type0))
	    type0 = TREE_TYPE (type0);
	  if (!TYPE_P (type1))
	    type1 = TREE_TYPE (type1);
	  if (INDIRECT_TYPE_P (type0) && same_type_p (TREE_TYPE (type0), type1))
	    {
	      if (!(TREE_CODE (first_arg) == PARM_DECL
		    && DECL_ARRAY_PARAMETER_P (first_arg)
		    && warn_sizeof_array_argument)
		  && (complain & tf_warning))
		{
		  auto_diagnostic_group d;
		  if (warning_at (location, OPT_Wsizeof_pointer_div,
				  "division %<sizeof (%T) / sizeof (%T)%> does "
				  "not compute the number of array elements",
				  type0, type1))
		    if (DECL_P (first_arg))
		      inform (DECL_SOURCE_LOCATION (first_arg),
			      "first %<sizeof%> operand was declared here");
		}
	    }
	  else if (TREE_CODE (type0) == ARRAY_TYPE
		   && !char_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (type0)))
		   /* Set by finish_parenthesized_expr.  */
		   && !warning_suppressed_p (op1, OPT_Wsizeof_array_div)
		   && (complain & tf_warning))
	    maybe_warn_sizeof_array_div (location, first_arg, type0,
					 op1, non_reference (type1));
	}

      if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE
	   || code0 == COMPLEX_TYPE || code0 == VECTOR_TYPE)
	  && (code1 == INTEGER_TYPE || code1 == REAL_TYPE
	      || code1 == COMPLEX_TYPE || code1 == VECTOR_TYPE))
	{
	  enum tree_code tcode0 = code0, tcode1 = code1;
	  doing_div_or_mod = true;
	  warn_for_div_by_zero (location, fold_for_warn (op1));

	  if (tcode0 == COMPLEX_TYPE || tcode0 == VECTOR_TYPE)
	    tcode0 = TREE_CODE (TREE_TYPE (TREE_TYPE (op0)));
	  if (tcode1 == COMPLEX_TYPE || tcode1 == VECTOR_TYPE)
	    tcode1 = TREE_CODE (TREE_TYPE (TREE_TYPE (op1)));

	  if (!(tcode0 == INTEGER_TYPE && tcode1 == INTEGER_TYPE))
	    resultcode = RDIV_EXPR;
	  else
	    {
	      /* When dividing two signed integers, we have to promote to int.
		 unless we divide by a constant != -1.  Note that default
		 conversion will have been performed on the operands at this
		 point, so we have to dig out the original type to find out if
		 it was unsigned.  */
	      tree stripped_op1 = tree_strip_any_location_wrapper (op1);
	      shorten = ((TREE_CODE (op0) == NOP_EXPR
			  && TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (op0, 0))))
			 || (TREE_CODE (stripped_op1) == INTEGER_CST
			     && ! integer_all_onesp (stripped_op1)));
	    }

	  common = 1;
	}
      break;

    case BIT_AND_EXPR:
    case BIT_IOR_EXPR:
    case BIT_XOR_EXPR:
      if ((code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
	  || (code0 == VECTOR_TYPE && code1 == VECTOR_TYPE
	      && !VECTOR_FLOAT_TYPE_P (type0)
	      && !VECTOR_FLOAT_TYPE_P (type1)))
	shorten = -1;
      break;

    case TRUNC_MOD_EXPR:
    case FLOOR_MOD_EXPR:
      doing_div_or_mod = true;
      warn_for_div_by_zero (location, fold_for_warn (op1));

      if (code0 == VECTOR_TYPE && code1 == VECTOR_TYPE
	  && TREE_CODE (TREE_TYPE (type0)) == INTEGER_TYPE
	  && TREE_CODE (TREE_TYPE (type1)) == INTEGER_TYPE)
	common = 1;
      else if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
	{
	  /* Although it would be tempting to shorten always here, that loses
	     on some targets, since the modulo instruction is undefined if the
	     quotient can't be represented in the computation mode.  We shorten
	     only if unsigned or if dividing by something we know != -1.  */
	  tree stripped_op1 = tree_strip_any_location_wrapper (op1);
	  shorten = ((TREE_CODE (op0) == NOP_EXPR
		      && TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (op0, 0))))
		     || (TREE_CODE (stripped_op1) == INTEGER_CST
			 && ! integer_all_onesp (stripped_op1)));
	  common = 1;
	}
      break;

    case TRUTH_ANDIF_EXPR:
    case TRUTH_ORIF_EXPR:
    case TRUTH_AND_EXPR:
    case TRUTH_OR_EXPR:
      if (!VECTOR_TYPE_P (type0) && gnu_vector_type_p (type1))
	{
	  if (!COMPARISON_CLASS_P (op1))
	    op1 = cp_build_binary_op (EXPR_LOCATION (op1), NE_EXPR, op1,
				      build_zero_cst (type1), complain);
	  if (code == TRUTH_ANDIF_EXPR)
	    {
	      tree z = build_zero_cst (TREE_TYPE (op1));
	      return build_conditional_expr (location, op0, op1, z, complain);
	    }
	  else if (code == TRUTH_ORIF_EXPR)
	    {
	      tree m1 = build_all_ones_cst (TREE_TYPE (op1));
	      return build_conditional_expr (location, op0, m1, op1, complain);
	    }
	  else
	    gcc_unreachable ();
	}
      if (gnu_vector_type_p (type0)
	  && (!VECTOR_TYPE_P (type1) || gnu_vector_type_p (type1)))
	{
	  if (!COMPARISON_CLASS_P (op0))
	    op0 = cp_build_binary_op (EXPR_LOCATION (op0), NE_EXPR, op0,
				      build_zero_cst (type0), complain);
	  if (!VECTOR_TYPE_P (type1))
	    {
	      tree m1 = build_all_ones_cst (TREE_TYPE (op0));
	      tree z = build_zero_cst (TREE_TYPE (op0));
	      op1 = build_conditional_expr (location, op1, m1, z, complain);
	    }
	  else if (!COMPARISON_CLASS_P (op1))
	    op1 = cp_build_binary_op (EXPR_LOCATION (op1), NE_EXPR, op1,
				      build_zero_cst (type1), complain);

	  if (code == TRUTH_ANDIF_EXPR)
	    code = BIT_AND_EXPR;
	  else if (code == TRUTH_ORIF_EXPR)
	    code = BIT_IOR_EXPR;
	  else
	    gcc_unreachable ();

	  return cp_build_binary_op (location, code, op0, op1, complain);
	}

      result_type = boolean_type_node;
      break;

      /* Shift operations: result has same type as first operand;
	 always convert second operand to int.
	 Also set SHORT_SHIFT if shifting rightward.  */

    case RSHIFT_EXPR:
      if (gnu_vector_type_p (type0)
	  && code1 == INTEGER_TYPE
	  && TREE_CODE (TREE_TYPE (type0)) == INTEGER_TYPE)
        {
          result_type = type0;
          converted = 1;
        }
      else if (gnu_vector_type_p (type0)
	       && gnu_vector_type_p (type1)
	       && TREE_CODE (TREE_TYPE (type0)) == INTEGER_TYPE
	       && TREE_CODE (TREE_TYPE (type1)) == INTEGER_TYPE
	       && known_eq (TYPE_VECTOR_SUBPARTS (type0),
			    TYPE_VECTOR_SUBPARTS (type1)))
	{
	  result_type = type0;
	  converted = 1;
	}
      else if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
	{
	  tree const_op1 = fold_for_warn (op1);
	  if (TREE_CODE (const_op1) != INTEGER_CST)
	    const_op1 = op1;
	  result_type = type0;
	  doing_shift = true;
	  if (TREE_CODE (const_op1) == INTEGER_CST)
	    {
	      if (tree_int_cst_lt (const_op1, integer_zero_node))
		{
		  if ((complain & tf_warning)
		      && c_inhibit_evaluation_warnings == 0)
		    warning_at (location, OPT_Wshift_count_negative,
				"right shift count is negative");
		}
	      else
		{
		  if (!integer_zerop (const_op1))
		    short_shift = 1;

		  if (compare_tree_int (const_op1, TYPE_PRECISION (type0)) >= 0
		      && (complain & tf_warning)
		      && c_inhibit_evaluation_warnings == 0)
		    warning_at (location, OPT_Wshift_count_overflow,
				"right shift count >= width of type");
		}
	    }
	  /* Avoid converting op1 to result_type later.  */
	  converted = 1;
	}
      break;

    case LSHIFT_EXPR:
      if (gnu_vector_type_p (type0)
	  && code1 == INTEGER_TYPE
          && TREE_CODE (TREE_TYPE (type0)) == INTEGER_TYPE)
        {
          result_type = type0;
          converted = 1;
        }
      else if (gnu_vector_type_p (type0)
	       && gnu_vector_type_p (type1)
	       && TREE_CODE (TREE_TYPE (type0)) == INTEGER_TYPE
	       && TREE_CODE (TREE_TYPE (type1)) == INTEGER_TYPE
	       && known_eq (TYPE_VECTOR_SUBPARTS (type0),
			    TYPE_VECTOR_SUBPARTS (type1)))
	{
	  result_type = type0;
	  converted = 1;
	}
      else if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
	{
	  tree const_op0 = fold_for_warn (op0);
	  if (TREE_CODE (const_op0) != INTEGER_CST)
	    const_op0 = op0;
	  tree const_op1 = fold_for_warn (op1);
	  if (TREE_CODE (const_op1) != INTEGER_CST)
	    const_op1 = op1;
	  result_type = type0;
	  doing_shift = true;
	  if (TREE_CODE (const_op0) == INTEGER_CST
	      && tree_int_cst_sgn (const_op0) < 0
	      && (complain & tf_warning)
	      && c_inhibit_evaluation_warnings == 0)
	    warning_at (location, OPT_Wshift_negative_value,
			"left shift of negative value");
	  if (TREE_CODE (const_op1) == INTEGER_CST)
	    {
	      if (tree_int_cst_lt (const_op1, integer_zero_node))
		{
		  if ((complain & tf_warning)
		      && c_inhibit_evaluation_warnings == 0)
		    warning_at (location, OPT_Wshift_count_negative,
				"left shift count is negative");
		}
	      else if (compare_tree_int (const_op1,
					 TYPE_PRECISION (type0)) >= 0)
		{
		  if ((complain & tf_warning)
		      && c_inhibit_evaluation_warnings == 0)
		    warning_at (location, OPT_Wshift_count_overflow,
				"left shift count >= width of type");
		}
	      else if (TREE_CODE (const_op0) == INTEGER_CST
		       && (complain & tf_warning))
		maybe_warn_shift_overflow (location, const_op0, const_op1);
	    }
	  /* Avoid converting op1 to result_type later.  */
	  converted = 1;
	}
      break;

    case EQ_EXPR:
    case NE_EXPR:
      if (gnu_vector_type_p (type0) && gnu_vector_type_p (type1))
	goto vector_compare;
      if ((complain & tf_warning)
	  && c_inhibit_evaluation_warnings == 0
	  && (FLOAT_TYPE_P (type0) || FLOAT_TYPE_P (type1)))
	warning_at (location, OPT_Wfloat_equal,
		    "comparing floating-point with %<==%> "
		    "or %<!=%> is unsafe");
      if (complain & tf_warning)
	{
	  tree stripped_orig_op0 = tree_strip_any_location_wrapper (orig_op0);
	  tree stripped_orig_op1 = tree_strip_any_location_wrapper (orig_op1);
	  if ((TREE_CODE (stripped_orig_op0) == STRING_CST
	       && !integer_zerop (cp_fully_fold (op1)))
	      || (TREE_CODE (stripped_orig_op1) == STRING_CST
		  && !integer_zerop (cp_fully_fold (op0))))
	    warning_at (location, OPT_Waddress,
			"comparison with string literal results in "
			"unspecified behavior");
	  else if (warn_array_compare
		   && TREE_CODE (TREE_TYPE (orig_op0)) == ARRAY_TYPE
		   && TREE_CODE (TREE_TYPE (orig_op1)) == ARRAY_TYPE)
	    do_warn_array_compare (location, code, stripped_orig_op0,
				   stripped_orig_op1);
	}

      build_type = boolean_type_node;
      if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE
	   || code0 == COMPLEX_TYPE || code0 == ENUMERAL_TYPE)
	  && (code1 == INTEGER_TYPE || code1 == REAL_TYPE
	      || code1 == COMPLEX_TYPE || code1 == ENUMERAL_TYPE))
	short_compare = 1;
      else if (((code0 == POINTER_TYPE || TYPE_PTRDATAMEM_P (type0))
		&& null_ptr_cst_p (orig_op1))
	       /* Handle, eg, (void*)0 (c++/43906), and more.  */
	       || (code0 == POINTER_TYPE
		   && TYPE_PTR_P (type1) && integer_zerop (op1)))
	{
	  if (TYPE_PTR_P (type1))
	    result_type = composite_pointer_type (location,
						  type0, type1, op0, op1,
						  CPO_COMPARISON, complain);
	  else
	    result_type = type0;

	  if (char_type_p (TREE_TYPE (orig_op1)))
	    {
	      auto_diagnostic_group d;
	      if (warning_at (location, OPT_Wpointer_compare,
			      "comparison between pointer and zero character "
			      "constant"))
		inform (location,
			"did you mean to dereference the pointer?");
	    }
	  warn_for_null_address (location, op0, complain);
	}
      else if (((code1 == POINTER_TYPE || TYPE_PTRDATAMEM_P (type1))
		&& null_ptr_cst_p (orig_op0))
	       /* Handle, eg, (void*)0 (c++/43906), and more.  */
	       || (code1 == POINTER_TYPE
		   && TYPE_PTR_P (type0) && integer_zerop (op0)))
	{
	  if (TYPE_PTR_P (type0))
	    result_type = composite_pointer_type (location,
						  type0, type1, op0, op1,
						  CPO_COMPARISON, complain);
	  else
	    result_type = type1;

	  if (char_type_p (TREE_TYPE (orig_op0)))
	    {
	      auto_diagnostic_group d;
	      if (warning_at (location, OPT_Wpointer_compare,
			     "comparison between pointer and zero character "
			     "constant"))
		inform (location,
			"did you mean to dereference the pointer?");
	    }
	  warn_for_null_address (location, op1, complain);
	}
      else if ((code0 == POINTER_TYPE && code1 == POINTER_TYPE)
	       || (TYPE_PTRDATAMEM_P (type0) && TYPE_PTRDATAMEM_P (type1)))
	result_type = composite_pointer_type (location,
					      type0, type1, op0, op1,
					      CPO_COMPARISON, complain);
      else if (null_ptr_cst_p (orig_op0) && null_ptr_cst_p (orig_op1))
	/* One of the operands must be of nullptr_t type.  */
        result_type = TREE_TYPE (nullptr_node);
      else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE)
	{
	  result_type = type0;
	  if (complain & tf_error)
	    permerror (location, "ISO C++ forbids comparison between "
		       "pointer and integer");
          else
            return error_mark_node;
	}
      else if (code0 == INTEGER_TYPE && code1 == POINTER_TYPE)
	{
	  result_type = type1;
	  if (complain & tf_error)
	    permerror (location, "ISO C++ forbids comparison between "
		       "pointer and integer");
          else
            return error_mark_node;
	}
      else if (TYPE_PTRMEMFUNC_P (type0) && null_ptr_cst_p (orig_op1))
	{
	  if (TARGET_PTRMEMFUNC_VBIT_LOCATION
	      == ptrmemfunc_vbit_in_delta)
	    {
	      tree pfn0, delta0, e1, e2;

	      if (TREE_SIDE_EFFECTS (op0))
		op0 = cp_save_expr (op0);

	      pfn0 = pfn_from_ptrmemfunc (op0);
	      delta0 = delta_from_ptrmemfunc (op0);
	      e1 = cp_build_binary_op (location,
				       EQ_EXPR,
	  			       pfn0,
				       build_zero_cst (TREE_TYPE (pfn0)),
				       complain);
	      e2 = cp_build_binary_op (location,
				       BIT_AND_EXPR,
				       delta0,
				       integer_one_node,
				       complain);

	      if (complain & tf_warning)
		maybe_warn_zero_as_null_pointer_constant (op1, input_location);

	      e2 = cp_build_binary_op (location,
				       EQ_EXPR, e2, integer_zero_node,
				       complain);
	      op0 = cp_build_binary_op (location,
					TRUTH_ANDIF_EXPR, e1, e2,
					complain);
	      op1 = cp_convert (TREE_TYPE (op0), integer_one_node, complain);
	    }
     	  else 
	    {
	      op0 = build_ptrmemfunc_access_expr (op0, pfn_identifier);
	      op1 = cp_convert (TREE_TYPE (op0), op1, complain);
	    }
	  result_type = TREE_TYPE (op0);

	  warn_for_null_address (location, orig_op0, complain);
	}
      else if (TYPE_PTRMEMFUNC_P (type1) && null_ptr_cst_p (orig_op0))
	return cp_build_binary_op (location, code, op1, op0, complain);
      else if (TYPE_PTRMEMFUNC_P (type0) && TYPE_PTRMEMFUNC_P (type1))
	{
	  tree type;
	  /* E will be the final comparison.  */
	  tree e;
	  /* E1 and E2 are for scratch.  */
	  tree e1;
	  tree e2;
	  tree pfn0;
	  tree pfn1;
	  tree delta0;
	  tree delta1;

	  type = composite_pointer_type (location, type0, type1, op0, op1, 
					 CPO_COMPARISON, complain);

	  if (!same_type_p (TREE_TYPE (op0), type))
	    op0 = cp_convert_and_check (type, op0, complain);
	  if (!same_type_p (TREE_TYPE (op1), type))
	    op1 = cp_convert_and_check (type, op1, complain);

	  if (op0 == error_mark_node || op1 == error_mark_node)
	    return error_mark_node;

	  if (TREE_SIDE_EFFECTS (op0))
	    op0 = save_expr (op0);
	  if (TREE_SIDE_EFFECTS (op1))
	    op1 = save_expr (op1);

	  pfn0 = pfn_from_ptrmemfunc (op0);
	  pfn0 = cp_fully_fold (pfn0);
	  /* Avoid -Waddress warnings (c++/64877).  */
	  if (TREE_CODE (pfn0) == ADDR_EXPR)
	    suppress_warning (pfn0, OPT_Waddress);
	  pfn1 = pfn_from_ptrmemfunc (op1);
	  pfn1 = cp_fully_fold (pfn1);
	  delta0 = delta_from_ptrmemfunc (op0);
	  delta1 = delta_from_ptrmemfunc (op1);
	  if (TARGET_PTRMEMFUNC_VBIT_LOCATION
	      == ptrmemfunc_vbit_in_delta)
	    {
	      /* We generate:

		 (op0.pfn == op1.pfn
		  && ((op0.delta == op1.delta)
     		       || (!op0.pfn && op0.delta & 1 == 0 
			   && op1.delta & 1 == 0))

	         The reason for the `!op0.pfn' bit is that a NULL
	         pointer-to-member is any member with a zero PFN and
	         LSB of the DELTA field is 0.  */

	      e1 = cp_build_binary_op (location, BIT_AND_EXPR,
				       delta0, 
				       integer_one_node,
				       complain);
	      e1 = cp_build_binary_op (location,
				       EQ_EXPR, e1, integer_zero_node,
				       complain);
	      e2 = cp_build_binary_op (location, BIT_AND_EXPR,
				       delta1,
				       integer_one_node,
				       complain);
	      e2 = cp_build_binary_op (location,
				       EQ_EXPR, e2, integer_zero_node,
				       complain);
	      e1 = cp_build_binary_op (location,
				       TRUTH_ANDIF_EXPR, e2, e1,
				       complain);
	      e2 = cp_build_binary_op (location, EQ_EXPR,
				       pfn0,
				       build_zero_cst (TREE_TYPE (pfn0)),
				       complain);
	      e2 = cp_build_binary_op (location,
				       TRUTH_ANDIF_EXPR, e2, e1, complain);
	      e1 = cp_build_binary_op (location,
				       EQ_EXPR, delta0, delta1, complain);
	      e1 = cp_build_binary_op (location,
				       TRUTH_ORIF_EXPR, e1, e2, complain);
	    }
	  else
	    {
	      /* We generate:

	         (op0.pfn == op1.pfn
	         && (!op0.pfn || op0.delta == op1.delta))

	         The reason for the `!op0.pfn' bit is that a NULL
	         pointer-to-member is any member with a zero PFN; the
	         DELTA field is unspecified.  */
 
    	      e1 = cp_build_binary_op (location,
				       EQ_EXPR, delta0, delta1, complain);
	      e2 = cp_build_binary_op (location,
				       EQ_EXPR,
		      		       pfn0,
			   	       build_zero_cst (TREE_TYPE (pfn0)),
				       complain);
	      e1 = cp_build_binary_op (location,
				       TRUTH_ORIF_EXPR, e1, e2, complain);
	    }
	  e2 = build2 (EQ_EXPR, boolean_type_node, pfn0, pfn1);
	  e = cp_build_binary_op (location,
				  TRUTH_ANDIF_EXPR, e2, e1, complain);
	  if (code == EQ_EXPR)
	    return e;
	  return cp_build_binary_op (location,
				     EQ_EXPR, e, integer_zero_node, complain);
	}
      else
	{
	  gcc_assert (!TYPE_PTRMEMFUNC_P (type0)
		      || !same_type_p (TYPE_PTRMEMFUNC_FN_TYPE (type0),
				       type1));
	  gcc_assert (!TYPE_PTRMEMFUNC_P (type1)
		      || !same_type_p (TYPE_PTRMEMFUNC_FN_TYPE (type1),
				       type0));
	}

      break;

    case MAX_EXPR:
    case MIN_EXPR:
      if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE)
	   && (code1 == INTEGER_TYPE || code1 == REAL_TYPE))
	shorten = 1;
      else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE)
	result_type = composite_pointer_type (location,
					      type0, type1, op0, op1,
					      CPO_COMPARISON, complain);
      break;

    case LE_EXPR:
    case GE_EXPR:
    case LT_EXPR:
    case GT_EXPR:
    case SPACESHIP_EXPR:
      if (TREE_CODE (orig_op0) == STRING_CST
	  || TREE_CODE (orig_op1) == STRING_CST)
	{
	  if (complain & tf_warning)
	    warning_at (location, OPT_Waddress,
			"comparison with string literal results "
			"in unspecified behavior");
	}
      else if (warn_array_compare
	       && TREE_CODE (TREE_TYPE (orig_op0)) == ARRAY_TYPE
	       && TREE_CODE (TREE_TYPE (orig_op1)) == ARRAY_TYPE
	       && code != SPACESHIP_EXPR
	       && (complain & tf_warning))
	do_warn_array_compare (location, code,
			       tree_strip_any_location_wrapper (orig_op0),
			       tree_strip_any_location_wrapper (orig_op1));

      if (gnu_vector_type_p (type0) && gnu_vector_type_p (type1))
	{
	vector_compare:
	  tree intt;
	  if (!same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (type0),
							  TREE_TYPE (type1))
	      && !vector_types_compatible_elements_p (type0, type1))
	    {
	      if (complain & tf_error)
		{
		  error_at (location, "comparing vectors with different "
				      "element types");
		  inform (location, "operand types are %qT and %qT",
			  type0, type1);
		}
	      return error_mark_node;
	    }

	  if (maybe_ne (TYPE_VECTOR_SUBPARTS (type0),
			TYPE_VECTOR_SUBPARTS (type1)))
	    {
	      if (complain & tf_error)
		{
		  error_at (location, "comparing vectors with different "
				      "number of elements");
		  inform (location, "operand types are %qT and %qT",
			  type0, type1);
		}
	      return error_mark_node;
	    }

	  /* It's not precisely specified how the usual arithmetic
	     conversions apply to the vector types.  Here, we use
	     the unsigned type if one of the operands is signed and
	     the other one is unsigned.  */
	  if (TYPE_UNSIGNED (type0) != TYPE_UNSIGNED (type1))
	    {
	      if (!TYPE_UNSIGNED (type0))
		op0 = build1 (VIEW_CONVERT_EXPR, type1, op0);
	      else
		op1 = build1 (VIEW_CONVERT_EXPR, type0, op1);
	      warning_at (location, OPT_Wsign_compare, "comparison between "
			  "types %qT and %qT", type0, type1);
	    }

	  if (resultcode == SPACESHIP_EXPR)
	    {
	      if (complain & tf_error)
		sorry_at (location, "three-way comparison of vectors");
	      return error_mark_node;
	    }

	  /* Always construct signed integer vector type.  */
	  intt = c_common_type_for_size
	    (GET_MODE_BITSIZE (SCALAR_TYPE_MODE (TREE_TYPE (type0))), 0);
	  if (!intt)
	    {
	      if (complain & tf_error)
		error_at (location, "could not find an integer type "
			  "of the same size as %qT", TREE_TYPE (type0));
	      return error_mark_node;
	    }
	  result_type = build_opaque_vector_type (intt,
						  TYPE_VECTOR_SUBPARTS (type0));
	  return build_vec_cmp (resultcode, result_type, op0, op1);
	}
      build_type = boolean_type_node;
      if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE
	   || code0 == ENUMERAL_TYPE)
	   && (code1 == INTEGER_TYPE || code1 == REAL_TYPE
	       || code1 == ENUMERAL_TYPE))
	short_compare = 1;
      else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE)
	result_type = composite_pointer_type (location,
					      type0, type1, op0, op1,
					      CPO_COMPARISON, complain);
      else if ((code0 == POINTER_TYPE && null_ptr_cst_p (orig_op1))
	       || (code1 == POINTER_TYPE && null_ptr_cst_p (orig_op0))
	       || (null_ptr_cst_p (orig_op0) && null_ptr_cst_p (orig_op1)))
	{
	  /* Core Issue 1512 made this ill-formed.  */
	  if (complain & tf_error)
	    error_at (location, "ordered comparison of pointer with "
		      "integer zero (%qT and %qT)", type0, type1);
	  return error_mark_node;
	}
      else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE)
	{
	  result_type = type0;
	  if (complain & tf_error)
	    permerror (location, "ISO C++ forbids comparison between "
		       "pointer and integer");
	  else
            return error_mark_node;
	}
      else if (code0 == INTEGER_TYPE && code1 == POINTER_TYPE)
	{
	  result_type = type1;
	  if (complain & tf_error)
	    permerror (location, "ISO C++ forbids comparison between "
		       "pointer and integer");
	  else
            return error_mark_node;
	}

      if ((code0 == POINTER_TYPE || code1 == POINTER_TYPE)
	  && !processing_template_decl
	  && sanitize_flags_p (SANITIZE_POINTER_COMPARE))
	{
	  op0 = save_expr (op0);
	  op1 = save_expr (op1);

	  tree tt = builtin_decl_explicit (BUILT_IN_ASAN_POINTER_COMPARE);
	  instrument_expr = build_call_expr_loc (location, tt, 2, op0, op1);
	}

      break;

    case UNORDERED_EXPR:
    case ORDERED_EXPR:
    case UNLT_EXPR:
    case UNLE_EXPR:
    case UNGT_EXPR:
    case UNGE_EXPR:
    case UNEQ_EXPR:
      build_type = integer_type_node;
      if (code0 != REAL_TYPE || code1 != REAL_TYPE)
	{
	  if (complain & tf_error)
	    error ("unordered comparison on non-floating-point argument");
	  return error_mark_node;
	}
      common = 1;
      break;

    default:
      break;
    }

  if (((code0 == INTEGER_TYPE || code0 == REAL_TYPE || code0 == COMPLEX_TYPE
	|| code0 == ENUMERAL_TYPE)
       && (code1 == INTEGER_TYPE || code1 == REAL_TYPE
	   || code1 == COMPLEX_TYPE || code1 == ENUMERAL_TYPE)))
    arithmetic_types_p = 1;
  else
    {
      arithmetic_types_p = 0;
      /* Vector arithmetic is only allowed when both sides are vectors.  */
      if (gnu_vector_type_p (type0) && gnu_vector_type_p (type1))
	{
	  if (!tree_int_cst_equal (TYPE_SIZE (type0), TYPE_SIZE (type1))
	      || !vector_types_compatible_elements_p (type0, type1))
	    {
	      if (complain & tf_error)
		{
		  /* "location" already embeds the locations of the
		     operands, so we don't need to add them separately
		     to richloc.  */
		  rich_location richloc (line_table, location);
		  binary_op_error (&richloc, code, type0, type1);
		}
	      return error_mark_node;
	    }
	  arithmetic_types_p = 1;
	}
    }
  /* Determine the RESULT_TYPE, if it is not already known.  */
  if (!result_type
      && arithmetic_types_p
      && (shorten || common || short_compare))
    {
      result_type = cp_common_type (type0, type1);
      if (complain & tf_warning)
	{
	  do_warn_double_promotion (result_type, type0, type1,
				    "implicit conversion from %qH to %qI "
				    "to match other operand of binary "
				    "expression",
				    location);
	  do_warn_enum_conversions (location, code, TREE_TYPE (orig_op0),
				    TREE_TYPE (orig_op1));
	}
    }

  if (code == SPACESHIP_EXPR)
    {
      iloc_sentinel s (location);

      tree orig_type0 = TREE_TYPE (orig_op0);
      tree_code orig_code0 = TREE_CODE (orig_type0);
      tree orig_type1 = TREE_TYPE (orig_op1);
      tree_code orig_code1 = TREE_CODE (orig_type1);
      if (!result_type)
	/* Nope.  */;
      else if ((orig_code0 == BOOLEAN_TYPE) != (orig_code1 == BOOLEAN_TYPE))
	/* "If one of the operands is of type bool and the other is not, the
	   program is ill-formed."  */
	result_type = NULL_TREE;
      else if (code0 == POINTER_TYPE && orig_code0 != POINTER_TYPE
	       && code1 == POINTER_TYPE && orig_code1 != POINTER_TYPE)
	/* We only do array/function-to-pointer conversion if "at least one of
	   the operands is of pointer type".  */
	result_type = NULL_TREE;
      else if (TYPE_PTRFN_P (result_type) || NULLPTR_TYPE_P (result_type))
	/* <=> no longer supports equality relations.  */
	result_type = NULL_TREE;
      else if (orig_code0 == ENUMERAL_TYPE && orig_code1 == ENUMERAL_TYPE
	       && !(same_type_ignoring_top_level_qualifiers_p
		    (orig_type0, orig_type1)))
	/* "If both operands have arithmetic types, or one operand has integral
	   type and the other operand has unscoped enumeration type, the usual
	   arithmetic conversions are applied to the operands."  So we don't do
	   arithmetic conversions if the operands both have enumeral type.  */
	result_type = NULL_TREE;
      else if ((orig_code0 == ENUMERAL_TYPE && orig_code1 == REAL_TYPE)
	       || (orig_code0 == REAL_TYPE && orig_code1 == ENUMERAL_TYPE))
	/* [depr.arith.conv.enum]: Three-way comparisons between such operands
	   [where one is of enumeration type and the other is of a different
	   enumeration type or a floating-point type] are ill-formed.  */
	result_type = NULL_TREE;

      if (result_type)
	{
	  build_type = spaceship_type (result_type, complain);
	  if (build_type == error_mark_node)
	    return error_mark_node;
	}

      if (result_type && arithmetic_types_p)
	{
	  /* If a narrowing conversion is required, other than from an integral
	     type to a floating point type, the program is ill-formed.  */
	  bool ok = true;
	  if (TREE_CODE (result_type) == REAL_TYPE
	      && CP_INTEGRAL_TYPE_P (orig_type0))
	    /* OK */;
	  else if (!check_narrowing (result_type, orig_op0, complain))
	    ok = false;
	  if (TREE_CODE (result_type) == REAL_TYPE
	      && CP_INTEGRAL_TYPE_P (orig_type1))
	    /* OK */;
	  else if (!check_narrowing (result_type, orig_op1, complain))
	    ok = false;
	  if (!ok && !(complain & tf_error))
	    return error_mark_node;
	}
    }

  if (!result_type)
    {
      if (complain & tf_error)
	{
	  binary_op_rich_location richloc (location,
					   orig_op0, orig_op1, true);
	  error_at (&richloc,
		    "invalid operands of types %qT and %qT to binary %qO",
		    TREE_TYPE (orig_op0), TREE_TYPE (orig_op1), code);
	}
      return error_mark_node;
    }

  /* If we're in a template, the only thing we need to know is the
     RESULT_TYPE.  */
  if (processing_template_decl)
    {
      /* Since the middle-end checks the type when doing a build2, we
	 need to build the tree in pieces.  This built tree will never
	 get out of the front-end as we replace it when instantiating
	 the template.  */
      tree tmp = build2 (resultcode,
			 build_type ? build_type : result_type,
			 NULL_TREE, op1);
      TREE_OPERAND (tmp, 0) = op0;
      return tmp;
    }

  /* Remember the original type; RESULT_TYPE might be changed later on
     by shorten_binary_op.  */
  tree orig_type = result_type;

  if (arithmetic_types_p)
    {
      bool first_complex = (code0 == COMPLEX_TYPE);
      bool second_complex = (code1 == COMPLEX_TYPE);
      int none_complex = (!first_complex && !second_complex);

      /* Adapted from patch for c/24581.  */
      if (first_complex != second_complex
	  && (code == PLUS_EXPR
	      || code == MINUS_EXPR
	      || code == MULT_EXPR
	      || (code == TRUNC_DIV_EXPR && first_complex))
	  && TREE_CODE (TREE_TYPE (result_type)) == REAL_TYPE
	  && flag_signed_zeros)
	{
	  /* An operation on mixed real/complex operands must be
	     handled specially, but the language-independent code can
	     more easily optimize the plain complex arithmetic if
	     -fno-signed-zeros.  */
	  tree real_type = TREE_TYPE (result_type);
	  tree real, imag;
	  if (first_complex)
	    {
	      if (TREE_TYPE (op0) != result_type)
		op0 = cp_convert_and_check (result_type, op0, complain);
	      if (TREE_TYPE (op1) != real_type)
		op1 = cp_convert_and_check (real_type, op1, complain);
	    }
	  else
	    {
	      if (TREE_TYPE (op0) != real_type)
		op0 = cp_convert_and_check (real_type, op0, complain);
	      if (TREE_TYPE (op1) != result_type)
		op1 = cp_convert_and_check (result_type, op1, complain);
	    }
	  if (TREE_CODE (op0) == ERROR_MARK || TREE_CODE (op1) == ERROR_MARK)
	    return error_mark_node;
	  if (first_complex)
	    {
	      op0 = save_expr (op0);
	      real = cp_build_unary_op (REALPART_EXPR, op0, true, complain);
	      imag = cp_build_unary_op (IMAGPART_EXPR, op0, true, complain);
	      switch (code)
		{
		case MULT_EXPR:
		case TRUNC_DIV_EXPR:
		  op1 = save_expr (op1);
		  imag = build2 (resultcode, real_type, imag, op1);
		  /* Fall through.  */
		case PLUS_EXPR:
		case MINUS_EXPR:
		  real = build2 (resultcode, real_type, real, op1);
		  break;
		default:
		  gcc_unreachable();
		}
	    }
	  else
	    {
	      op1 = save_expr (op1);
	      real = cp_build_unary_op (REALPART_EXPR, op1, true, complain);
	      imag = cp_build_unary_op (IMAGPART_EXPR, op1, true, complain);
	      switch (code)
		{
		case MULT_EXPR:
		  op0 = save_expr (op0);
		  imag = build2 (resultcode, real_type, op0, imag);
		  /* Fall through.  */
		case PLUS_EXPR:
		  real = build2 (resultcode, real_type, op0, real);
		  break;
		case MINUS_EXPR:
		  real = build2 (resultcode, real_type, op0, real);
		  imag = build1 (NEGATE_EXPR, real_type, imag);
		  break;
		default:
		  gcc_unreachable();
		}
	    }
	  result = build2 (COMPLEX_EXPR, result_type, real, imag);
	  return result;
	}

      /* For certain operations (which identify themselves by shorten != 0)
	 if both args were extended from the same smaller type,
	 do the arithmetic in that type and then extend.

	 shorten !=0 and !=1 indicates a bitwise operation.
	 For them, this optimization is safe only if
	 both args are zero-extended or both are sign-extended.
	 Otherwise, we might change the result.
	 E.g., (short)-1 | (unsigned short)-1 is (int)-1
	 but calculated in (unsigned short) it would be (unsigned short)-1.  */

      if (shorten && none_complex)
	{
	  final_type = result_type;
	  result_type = shorten_binary_op (result_type, op0, op1,
					   shorten == -1);
	}

      /* Shifts can be shortened if shifting right.  */

      if (short_shift)
	{
	  int unsigned_arg;
	  tree arg0 = get_narrower (op0, &unsigned_arg);
	  /* We're not really warning here but when we set short_shift we
	     used fold_for_warn to fold the operand.  */
	  tree const_op1 = fold_for_warn (op1);

	  final_type = result_type;

	  if (arg0 == op0 && final_type == TREE_TYPE (op0))
	    unsigned_arg = TYPE_UNSIGNED (TREE_TYPE (op0));

	  if (TYPE_PRECISION (TREE_TYPE (arg0)) < TYPE_PRECISION (result_type)
	      && tree_int_cst_sgn (const_op1) > 0
	      /* We can shorten only if the shift count is less than the
		 number of bits in the smaller type size.  */
	      && compare_tree_int (const_op1,
				   TYPE_PRECISION (TREE_TYPE (arg0))) < 0
	      /* We cannot drop an unsigned shift after sign-extension.  */
	      && (!TYPE_UNSIGNED (final_type) || unsigned_arg))
	    {
	      /* Do an unsigned shift if the operand was zero-extended.  */
	      result_type
		= c_common_signed_or_unsigned_type (unsigned_arg,
						    TREE_TYPE (arg0));
	      /* Convert value-to-be-shifted to that type.  */
	      if (TREE_TYPE (op0) != result_type)
		op0 = convert (result_type, op0);
	      converted = 1;
	    }
	}

      /* Comparison operations are shortened too but differently.
	 They identify themselves by setting short_compare = 1.  */

      if (short_compare)
	{
	  /* We call shorten_compare only for diagnostics.  */
	  tree xop0 = fold_simple (op0);
	  tree xop1 = fold_simple (op1);
	  tree xresult_type = result_type;
	  enum tree_code xresultcode = resultcode;
	  shorten_compare (location, &xop0, &xop1, &xresult_type,
			   &xresultcode);
	}

      if ((short_compare || code == MIN_EXPR || code == MAX_EXPR)
	  && warn_sign_compare
	  /* Do not warn until the template is instantiated; we cannot
	     bound the ranges of the arguments until that point.  */
	  && !processing_template_decl
          && (complain & tf_warning)
	  && c_inhibit_evaluation_warnings == 0
	  /* Even unsigned enum types promote to signed int.  We don't
	     want to issue -Wsign-compare warnings for this case.  */
	  && !enum_cast_to_int (orig_op0)
	  && !enum_cast_to_int (orig_op1))
	{
	  warn_for_sign_compare (location, orig_op0, orig_op1, op0, op1,
				 result_type, resultcode);
	}
    }

  /* If CONVERTED is zero, both args will be converted to type RESULT_TYPE.
     Then the expression will be built.
     It will be given type FINAL_TYPE if that is nonzero;
     otherwise, it will be given type RESULT_TYPE.  */
  if (! converted)
    {
      warning_sentinel w (warn_sign_conversion, short_compare);
      if (!same_type_p (TREE_TYPE (op0), result_type))
	op0 = cp_convert_and_check (result_type, op0, complain);
      if (!same_type_p (TREE_TYPE (op1), result_type))
	op1 = cp_convert_and_check (result_type, op1, complain);

      if (op0 == error_mark_node || op1 == error_mark_node)
	return error_mark_node;
    }

  if (build_type == NULL_TREE)
    build_type = result_type;

  if (doing_shift
      && flag_strong_eval_order == 2
      && TREE_SIDE_EFFECTS (op1)
      && !processing_template_decl)
    {
      /* In C++17, in both op0 << op1 and op0 >> op1 op0 is sequenced before
	 op1, so if op1 has side-effects, use SAVE_EXPR around op0.  */
      op0 = cp_save_expr (op0);
      instrument_expr = op0;
    }

  if (sanitize_flags_p ((SANITIZE_SHIFT
			 | SANITIZE_DIVIDE
			 | SANITIZE_FLOAT_DIVIDE
			 | SANITIZE_SI_OVERFLOW))
      && current_function_decl != NULL_TREE
      && !processing_template_decl
      && (doing_div_or_mod || doing_shift))
    {
      /* OP0 and/or OP1 might have side-effects.  */
      op0 = cp_save_expr (op0);
      op1 = cp_save_expr (op1);
      op0 = fold_non_dependent_expr (op0, complain);
      op1 = fold_non_dependent_expr (op1, complain);
      tree instrument_expr1 = NULL_TREE;
      if (doing_div_or_mod
	  && sanitize_flags_p (SANITIZE_DIVIDE
			       | SANITIZE_FLOAT_DIVIDE
			       | SANITIZE_SI_OVERFLOW))
	{
	  /* For diagnostics we want to use the promoted types without
	     shorten_binary_op.  So convert the arguments to the
	     original result_type.  */
	  tree cop0 = op0;
	  tree cop1 = op1;
	  if (TREE_TYPE (cop0) != orig_type)
	    cop0 = cp_convert (orig_type, op0, complain);
	  if (TREE_TYPE (cop1) != orig_type)
	    cop1 = cp_convert (orig_type, op1, complain);
	  instrument_expr1 = ubsan_instrument_division (location, cop0, cop1);
	}
      else if (doing_shift && sanitize_flags_p (SANITIZE_SHIFT))
	instrument_expr1 = ubsan_instrument_shift (location, code, op0, op1);
      if (instrument_expr != NULL)
	instrument_expr = add_stmt_to_compound (instrument_expr,
						instrument_expr1);
      else
	instrument_expr = instrument_expr1;
    }

  result = build2_loc (location, resultcode, build_type, op0, op1);
  if (final_type != 0)
    result = cp_convert (final_type, result, complain);

  if (instrument_expr != NULL)
    result = build2 (COMPOUND_EXPR, TREE_TYPE (result),
		     instrument_expr, result);

  if (!processing_template_decl)
    {
      if (resultcode == SPACESHIP_EXPR)
	result = get_target_expr_sfinae (result, complain);
      op0 = cp_fully_fold (op0);
      /* Only consider the second argument if the first isn't overflowed.  */
      if (!CONSTANT_CLASS_P (op0) || TREE_OVERFLOW_P (op0))
	return result;
      op1 = cp_fully_fold (op1);
      if (!CONSTANT_CLASS_P (op1) || TREE_OVERFLOW_P (op1))
	return result;
    }
  else if (!CONSTANT_CLASS_P (op0) || !CONSTANT_CLASS_P (op1)
	   || TREE_OVERFLOW_P (op0) || TREE_OVERFLOW_P (op1))
    return result;

  result_ovl = fold_build2 (resultcode, build_type, op0, op1);
  if (TREE_OVERFLOW_P (result_ovl))
    overflow_warning (location, result_ovl);

  return result;
}

/* Build a VEC_PERM_EXPR.
   This is a simple wrapper for c_build_vec_perm_expr.  */
tree
build_x_vec_perm_expr (location_t loc,
			tree arg0, tree arg1, tree arg2,
			tsubst_flags_t complain)
{
  tree orig_arg0 = arg0;
  tree orig_arg1 = arg1;
  tree orig_arg2 = arg2;
  if (processing_template_decl)
    {
      if (type_dependent_expression_p (arg0)
	  || type_dependent_expression_p (arg1)
	  || type_dependent_expression_p (arg2))
	return build_min_nt_loc (loc, VEC_PERM_EXPR, arg0, arg1, arg2);
      arg0 = build_non_dependent_expr (arg0);
      if (arg1)
	arg1 = build_non_dependent_expr (arg1);
      arg2 = build_non_dependent_expr (arg2);
    }
  tree exp = c_build_vec_perm_expr (loc, arg0, arg1, arg2, complain & tf_error);
  if (processing_template_decl && exp != error_mark_node)
    return build_min_non_dep (VEC_PERM_EXPR, exp, orig_arg0,
			      orig_arg1, orig_arg2);
  return exp;
}

/* Build a VEC_PERM_EXPR.
   This is a simple wrapper for c_build_shufflevector.  */
tree
build_x_shufflevector (location_t loc, vec<tree, va_gc> *args,
		       tsubst_flags_t complain)
{
  tree arg0 = (*args)[0];
  tree arg1 = (*args)[1];
  if (processing_template_decl)
    {
      for (unsigned i = 0; i < args->length (); ++i)
	if (type_dependent_expression_p ((*args)[i]))
	  {
	    tree exp = build_min_nt_call_vec (NULL, args);
	    CALL_EXPR_IFN (exp) = IFN_SHUFFLEVECTOR;
	    return exp;
	  }
      arg0 = build_non_dependent_expr (arg0);
      arg1 = build_non_dependent_expr (arg1);
      /* ???  Nothing needed for the index arguments?  */
    }
  auto_vec<tree, 16> mask;
  for (unsigned i = 2; i < args->length (); ++i)
    {
      tree idx = maybe_constant_value ((*args)[i]);
      mask.safe_push (idx);
    }
  tree exp = c_build_shufflevector (loc, arg0, arg1, mask, complain & tf_error);
  if (processing_template_decl && exp != error_mark_node)
    {
      exp = build_min_non_dep_call_vec (exp, NULL, args);
      CALL_EXPR_IFN (exp) = IFN_SHUFFLEVECTOR;
    }
  return exp;
}

/* Return a tree for the sum or difference (RESULTCODE says which)
   of pointer PTROP and integer INTOP.  */

static tree
cp_pointer_int_sum (location_t loc, enum tree_code resultcode, tree ptrop,
		    tree intop, tsubst_flags_t complain)
{
  tree res_type = TREE_TYPE (ptrop);

  /* pointer_int_sum() uses size_in_bytes() on the TREE_TYPE(res_type)
     in certain circumstance (when it's valid to do so).  So we need
     to make sure it's complete.  We don't need to check here, if we
     can actually complete it at all, as those checks will be done in
     pointer_int_sum() anyway.  */
  complete_type (TREE_TYPE (res_type));

  return pointer_int_sum (loc, resultcode, ptrop,
			  intop, complain & tf_warning_or_error);
}

/* Return a tree for the difference of pointers OP0 and OP1.
   The resulting tree has type int.  If POINTER_SUBTRACT sanitization is
   enabled, assign to INSTRUMENT_EXPR call to libsanitizer.  */

static tree
pointer_diff (location_t loc, tree op0, tree op1, tree ptrtype,
	      tsubst_flags_t complain, tree *instrument_expr)
{
  tree result, inttype;
  tree restype = ptrdiff_type_node;
  tree target_type = TREE_TYPE (ptrtype);

  if (!complete_type_or_maybe_complain (target_type, NULL_TREE, complain))
    return error_mark_node;

  if (VOID_TYPE_P (target_type))
    {
      if (complain & tf_error)
	permerror (loc, "ISO C++ forbids using pointer of "
		   "type %<void *%> in subtraction");
      else
	return error_mark_node;
    }
  if (TREE_CODE (target_type) == FUNCTION_TYPE)
    {
      if (complain & tf_error)
	permerror (loc, "ISO C++ forbids using pointer to "
		   "a function in subtraction");
      else
	return error_mark_node;
    }
  if (TREE_CODE (target_type) == METHOD_TYPE)
    {
      if (complain & tf_error)
	permerror (loc, "ISO C++ forbids using pointer to "
		   "a method in subtraction");
      else
	return error_mark_node;
    }
  else if (!verify_type_context (loc, TCTX_POINTER_ARITH,
				 TREE_TYPE (TREE_TYPE (op0)),
				 !(complain & tf_error))
	   || !verify_type_context (loc, TCTX_POINTER_ARITH,
				    TREE_TYPE (TREE_TYPE (op1)),
				    !(complain & tf_error)))
    return error_mark_node;

  /* Determine integer type result of the subtraction.  This will usually
     be the same as the result type (ptrdiff_t), but may need to be a wider
     type if pointers for the address space are wider than ptrdiff_t.  */
  if (TYPE_PRECISION (restype) < TYPE_PRECISION (TREE_TYPE (op0)))
    inttype = c_common_type_for_size (TYPE_PRECISION (TREE_TYPE (op0)), 0);
  else
    inttype = restype;

  if (!processing_template_decl
      && sanitize_flags_p (SANITIZE_POINTER_SUBTRACT))
    {
      op0 = save_expr (op0);
      op1 = save_expr (op1);

      tree tt = builtin_decl_explicit (BUILT_IN_ASAN_POINTER_SUBTRACT);
      *instrument_expr = build_call_expr_loc (loc, tt, 2, op0, op1);
    }

  /* First do the subtraction, then build the divide operator
     and only convert at the very end.
     Do not do default conversions in case restype is a short type.  */

  /* POINTER_DIFF_EXPR requires a signed integer type of the same size as
     pointers.  If some platform cannot provide that, or has a larger
     ptrdiff_type to support differences larger than half the address
     space, cast the pointers to some larger integer type and do the
     computations in that type.  */
  if (TYPE_PRECISION (inttype) > TYPE_PRECISION (TREE_TYPE (op0)))
    op0 = cp_build_binary_op (loc,
			      MINUS_EXPR,
			      cp_convert (inttype, op0, complain),
			      cp_convert (inttype, op1, complain),
			      complain);
  else
    op0 = build2_loc (loc, POINTER_DIFF_EXPR, inttype, op0, op1);

  /* This generates an error if op1 is a pointer to an incomplete type.  */
  if (!COMPLETE_TYPE_P (TREE_TYPE (TREE_TYPE (op1))))
    {
      if (complain & tf_error)
	error_at (loc, "invalid use of a pointer to an incomplete type in "
		  "pointer arithmetic");
      else
	return error_mark_node;
    }

  if (pointer_to_zero_sized_aggr_p (TREE_TYPE (op1)))
    {
      if (complain & tf_error)
	error_at (loc, "arithmetic on pointer to an empty aggregate");
      else
	return error_mark_node;
    }

  op1 = (TYPE_PTROB_P (ptrtype)
	 ? size_in_bytes_loc (loc, target_type)
	 : integer_one_node);

  /* Do the division.  */

  result = build2_loc (loc, EXACT_DIV_EXPR, inttype, op0,
		       cp_convert (inttype, op1, complain));
  return cp_convert (restype, result, complain);
}

/* Construct and perhaps optimize a tree representation
   for a unary operation.  CODE, a tree_code, specifies the operation
   and XARG is the operand.  */

tree
build_x_unary_op (location_t loc, enum tree_code code, cp_expr xarg,
		  tsubst_flags_t complain)
{
  tree orig_expr = xarg;
  tree exp;
  int ptrmem = 0;
  tree overload = NULL_TREE;

  if (processing_template_decl)
    {
      if (type_dependent_expression_p (xarg))
	{
	  tree e = build_min_nt_loc (loc, code, xarg.get_value (), NULL_TREE);
	  maybe_save_operator_binding (e);
	  return e;
	}

      xarg = build_non_dependent_expr (xarg);
    }

  exp = NULL_TREE;

  /* [expr.unary.op] says:

       The address of an object of incomplete type can be taken.

     (And is just the ordinary address operator, not an overloaded
     "operator &".)  However, if the type is a template
     specialization, we must complete the type at this point so that
     an overloaded "operator &" will be available if required.  */
  if (code == ADDR_EXPR
      && TREE_CODE (xarg) != TEMPLATE_ID_EXPR
      && ((CLASS_TYPE_P (TREE_TYPE (xarg))
	   && !COMPLETE_TYPE_P (complete_type (TREE_TYPE (xarg))))
	  || (TREE_CODE (xarg) == OFFSET_REF)))
    /* Don't look for a function.  */;
  else
    exp = build_new_op (loc, code, LOOKUP_NORMAL, xarg, NULL_TREE,
			NULL_TREE, &overload, complain);

  if (!exp && code == ADDR_EXPR)
    {
      if (is_overloaded_fn (xarg))
	{
	  tree fn = get_first_fn (xarg);
	  if (DECL_CONSTRUCTOR_P (fn) || DECL_DESTRUCTOR_P (fn))
	    {
	      if (complain & tf_error)
		error_at (loc, DECL_CONSTRUCTOR_P (fn)
			  ? G_("taking address of constructor %qD")
			  : G_("taking address of destructor %qD"),
			  fn);
	      return error_mark_node;
	    }
	}

      /* A pointer to member-function can be formed only by saying
	 &X::mf.  */
      if (!flag_ms_extensions && TREE_CODE (TREE_TYPE (xarg)) == METHOD_TYPE
	  && (TREE_CODE (xarg) != OFFSET_REF || !PTRMEM_OK_P (xarg)))
	{
	  if (TREE_CODE (xarg) != OFFSET_REF
	      || !TYPE_P (TREE_OPERAND (xarg, 0)))
	    {
	      if (complain & tf_error)
		{
		  error_at (loc, "invalid use of %qE to form a "
			    "pointer-to-member-function", xarg.get_value ());
		  if (TREE_CODE (xarg) != OFFSET_REF)
		    inform (loc, "  a qualified-id is required");
		}
	      return error_mark_node;
	    }
	  else
	    {
	      if (complain & tf_error)
		error_at (loc, "parentheses around %qE cannot be used to "
			  "form a pointer-to-member-function",
			  xarg.get_value ());
	      else
		return error_mark_node;
	      PTRMEM_OK_P (xarg) = 1;
	    }
	}

      if (TREE_CODE (xarg) == OFFSET_REF)
	{
	  ptrmem = PTRMEM_OK_P (xarg);

	  if (!ptrmem && !flag_ms_extensions
	      && TREE_CODE (TREE_TYPE (TREE_OPERAND (xarg, 1))) == METHOD_TYPE)
	    {
	      /* A single non-static member, make sure we don't allow a
		 pointer-to-member.  */
	      xarg = build2 (OFFSET_REF, TREE_TYPE (xarg),
			     TREE_OPERAND (xarg, 0),
			     ovl_make (TREE_OPERAND (xarg, 1)));
	      PTRMEM_OK_P (xarg) = ptrmem;
	    }
	}

      exp = cp_build_addr_expr_strict (xarg, complain);
    }

  if (processing_template_decl && exp != error_mark_node)
    {
      if (overload != NULL_TREE)
	return (build_min_non_dep_op_overload
		(code, exp, overload, orig_expr, integer_zero_node));

      exp = build_min_non_dep (code, exp, orig_expr,
			       /*For {PRE,POST}{INC,DEC}REMENT_EXPR*/NULL_TREE);
    }
  if (TREE_CODE (exp) == ADDR_EXPR)
    PTRMEM_OK_P (exp) = ptrmem;
  return exp;
}

/* Construct and perhaps optimize a tree representation
   for __builtin_addressof operation.  ARG specifies the operand.  */

tree
cp_build_addressof (location_t loc, tree arg, tsubst_flags_t complain)
{
  tree orig_expr = arg;

  if (processing_template_decl)
    {
      if (type_dependent_expression_p (arg))
	return build_min_nt_loc (loc, ADDRESSOF_EXPR, arg, NULL_TREE);

      arg = build_non_dependent_expr (arg);
    }

  tree exp = cp_build_addr_expr_strict (arg, complain);

  if (processing_template_decl && exp != error_mark_node)
    exp = build_min_non_dep (ADDRESSOF_EXPR, exp, orig_expr, NULL_TREE);
  return exp;
}

/* Like c_common_truthvalue_conversion, but handle pointer-to-member
   constants, where a null value is represented by an INTEGER_CST of
   -1.  */

tree
cp_truthvalue_conversion (tree expr, tsubst_flags_t complain)
{
  tree type = TREE_TYPE (expr);
  location_t loc = cp_expr_loc_or_input_loc (expr);
  if (TYPE_PTR_OR_PTRMEM_P (type)
      /* Avoid ICE on invalid use of non-static member function.  */
      || TREE_CODE (expr) == FUNCTION_DECL)
    return cp_build_binary_op (loc, NE_EXPR, expr, nullptr_node, complain);
  else
    return c_common_truthvalue_conversion (loc, expr);
}

/* Returns EXPR contextually converted to bool.  */

tree
contextual_conv_bool (tree expr, tsubst_flags_t complain)
{
  return perform_implicit_conversion_flags (boolean_type_node, expr,
					    complain, LOOKUP_NORMAL);
}

/* Just like cp_truthvalue_conversion, but we want a CLEANUP_POINT_EXPR.  This
   is a low-level function; most callers should use maybe_convert_cond.  */

tree
condition_conversion (tree expr)
{
  tree t = contextual_conv_bool (expr, tf_warning_or_error);
  if (!processing_template_decl)
    t = fold_build_cleanup_point_expr (boolean_type_node, t);
  return t;
}

/* Returns the address of T.  This function will fold away
   ADDR_EXPR of INDIRECT_REF.  This is only for low-level usage;
   most places should use cp_build_addr_expr instead.  */

tree
build_address (tree t)
{
  if (error_operand_p (t) || !cxx_mark_addressable (t))
    return error_mark_node;
  gcc_checking_assert (TREE_CODE (t) != CONSTRUCTOR
		       || processing_template_decl);
  t = build_fold_addr_expr_loc (EXPR_LOCATION (t), t);
  if (TREE_CODE (t) != ADDR_EXPR)
    t = rvalue (t);
  return t;
}

/* Return a NOP_EXPR converting EXPR to TYPE.  */

tree
build_nop (tree type, tree expr)
{
  if (type == error_mark_node || error_operand_p (expr))
    return expr;
  return build1_loc (EXPR_LOCATION (expr), NOP_EXPR, type, expr);
}

/* Take the address of ARG, whatever that means under C++ semantics.
   If STRICT_LVALUE is true, require an lvalue; otherwise, allow xvalues
   and class rvalues as well.

   Nothing should call this function directly; instead, callers should use
   cp_build_addr_expr or cp_build_addr_expr_strict.  */

static tree
cp_build_addr_expr_1 (tree arg, bool strict_lvalue, tsubst_flags_t complain)
{
  tree argtype;
  tree val;

  if (!arg || error_operand_p (arg))
    return error_mark_node;

  arg = mark_lvalue_use (arg);
  if (error_operand_p (arg))
    return error_mark_node;

  argtype = lvalue_type (arg);
  location_t loc = cp_expr_loc_or_input_loc (arg);

  gcc_assert (!(identifier_p (arg) && IDENTIFIER_ANY_OP_P (arg)));

  if (TREE_CODE (arg) == COMPONENT_REF && type_unknown_p (arg)
      && !really_overloaded_fn (arg))
    {
      /* They're trying to take the address of a unique non-static
	 member function.  This is ill-formed (except in MS-land),
	 but let's try to DTRT.
	 Note: We only handle unique functions here because we don't
	 want to complain if there's a static overload; non-unique
	 cases will be handled by instantiate_type.  But we need to
	 handle this case here to allow casts on the resulting PMF.
	 We could defer this in non-MS mode, but it's easier to give
	 a useful error here.  */

      /* Inside constant member functions, the `this' pointer
	 contains an extra const qualifier.  TYPE_MAIN_VARIANT
	 is used here to remove this const from the diagnostics
	 and the created OFFSET_REF.  */
      tree base = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_OPERAND (arg, 0)));
      tree fn = get_first_fn (TREE_OPERAND (arg, 1));
      if (!mark_used (fn, complain) && !(complain & tf_error))
	return error_mark_node;

      if (! flag_ms_extensions)
	{
	  tree name = DECL_NAME (fn);
	  if (!(complain & tf_error))
	    return error_mark_node;
	  else if (current_class_type
		   && TREE_OPERAND (arg, 0) == current_class_ref)
	    /* An expression like &memfn.  */
	    permerror (loc,
		       "ISO C++ forbids taking the address of an unqualified"
		       " or parenthesized non-static member function to form"
		       " a pointer to member function.  Say %<&%T::%D%>",
		       base, name);
	  else
	    permerror (loc,
		       "ISO C++ forbids taking the address of a bound member"
		       " function to form a pointer to member function."
		       "  Say %<&%T::%D%>",
		       base, name);
	}
      arg = build_offset_ref (base, fn, /*address_p=*/true, complain);
    }

  /* Uninstantiated types are all functions.  Taking the
     address of a function is a no-op, so just return the
     argument.  */
  if (type_unknown_p (arg))
    return build1 (ADDR_EXPR, unknown_type_node, arg);

  if (TREE_CODE (arg) == OFFSET_REF)
    /* We want a pointer to member; bypass all the code for actually taking
       the address of something.  */
    goto offset_ref;

  /* Anything not already handled and not a true memory reference
     is an error.  */
  if (!FUNC_OR_METHOD_TYPE_P (argtype))
    {
      cp_lvalue_kind kind = lvalue_kind (arg);
      if (kind == clk_none)
	{
	  if (complain & tf_error)
	    lvalue_error (loc, lv_addressof);
	  return error_mark_node;
	}
      if (strict_lvalue && (kind & (clk_rvalueref|clk_class)))
	{
	  if (!(complain & tf_error))
	    return error_mark_node;
	  /* Make this a permerror because we used to accept it.  */
	  permerror (loc, "taking address of rvalue");
	}
    }

  if (TYPE_REF_P (argtype))
    {
      tree type = build_pointer_type (TREE_TYPE (argtype));
      arg = build1 (CONVERT_EXPR, type, arg);
      return arg;
    }
  else if (pedantic && DECL_MAIN_P (tree_strip_any_location_wrapper (arg)))
    {
      /* ARM $3.4 */
      /* Apparently a lot of autoconf scripts for C++ packages do this,
	 so only complain if -Wpedantic.  */
      if (complain & (flag_pedantic_errors ? tf_error : tf_warning))
	pedwarn (loc, OPT_Wpedantic,
		 "ISO C++ forbids taking address of function %<::main%>");
      else if (flag_pedantic_errors)
	return error_mark_node;
    }

  /* Let &* cancel out to simplify resulting code.  */
  if (INDIRECT_REF_P (arg))
    {
      arg = TREE_OPERAND (arg, 0);
      if (TYPE_REF_P (TREE_TYPE (arg)))
	{
	  tree type = build_pointer_type (TREE_TYPE (TREE_TYPE (arg)));
	  arg = build1 (CONVERT_EXPR, type, arg);
	}
      else
	/* Don't let this be an lvalue.  */
	arg = rvalue (arg);
      return arg;
    }

  /* Handle complex lvalues (when permitted)
     by reduction to simpler cases.  */
  val = unary_complex_lvalue (ADDR_EXPR, arg);
  if (val != 0)
    return val;

  switch (TREE_CODE (arg))
    {
    CASE_CONVERT:
    case FLOAT_EXPR:
    case FIX_TRUNC_EXPR:
      /* We should have handled this above in the lvalue_kind check.  */
      gcc_unreachable ();
      break;

    case BASELINK:
      arg = BASELINK_FUNCTIONS (arg);
      /* Fall through.  */

    case OVERLOAD:
      arg = OVL_FIRST (arg);
      break;

    case OFFSET_REF:
    offset_ref:
      /* Turn a reference to a non-static data member into a
	 pointer-to-member.  */
      {
	tree type;
	tree t;

	gcc_assert (PTRMEM_OK_P (arg));

	t = TREE_OPERAND (arg, 1);
	if (TYPE_REF_P (TREE_TYPE (t)))
	  {
	    if (complain & tf_error)
	      error_at (loc,
			"cannot create pointer to reference member %qD", t);
	    return error_mark_node;
	  }

	type = build_ptrmem_type (context_for_name_lookup (t),
				  TREE_TYPE (t));
	t = make_ptrmem_cst (type, TREE_OPERAND (arg, 1));
	return t;
      }

    default:
      break;
    }

  if (argtype != error_mark_node)
    argtype = build_pointer_type (argtype);

  if (bitfield_p (arg))
    {
      if (complain & tf_error)
	error_at (loc, "attempt to take address of bit-field");
      return error_mark_node;
    }

  /* In a template, we are processing a non-dependent expression
     so we can just form an ADDR_EXPR with the correct type.  */
  if (processing_template_decl || TREE_CODE (arg) != COMPONENT_REF)
    {
      tree stripped_arg = tree_strip_any_location_wrapper (arg);
      if (TREE_CODE (stripped_arg) == FUNCTION_DECL
	  && DECL_IMMEDIATE_FUNCTION_P (stripped_arg)
	  && cp_unevaluated_operand == 0
	  && (current_function_decl == NULL_TREE
	      || !DECL_IMMEDIATE_FUNCTION_P (current_function_decl)))
	{
	  if (complain & tf_error)
	    error_at (loc, "taking address of an immediate function %qD",
		      stripped_arg);
	  return error_mark_node;
	}
      if (TREE_CODE (stripped_arg) == FUNCTION_DECL
	  && !mark_used (stripped_arg, complain) && !(complain & tf_error))
	return error_mark_node;
      val = build_address (arg);
      if (TREE_CODE (arg) == OFFSET_REF)
	PTRMEM_OK_P (val) = PTRMEM_OK_P (arg);
    }
  else if (BASELINK_P (TREE_OPERAND (arg, 1)))
    {
      tree fn = BASELINK_FUNCTIONS (TREE_OPERAND (arg, 1));

      /* We can only get here with a single static member
	 function.  */
      gcc_assert (TREE_CODE (fn) == FUNCTION_DECL
		  && DECL_STATIC_FUNCTION_P (fn));
      if (!mark_used (fn, complain) && !(complain & tf_error))
	return error_mark_node;
      val = build_address (fn);
      if (TREE_SIDE_EFFECTS (TREE_OPERAND (arg, 0)))
	/* Do not lose object's side effects.  */
	val = build2 (COMPOUND_EXPR, TREE_TYPE (val),
		      TREE_OPERAND (arg, 0), val);
    }
  else
    {
      tree object = TREE_OPERAND (arg, 0);
      tree field = TREE_OPERAND (arg, 1);
      gcc_assert (same_type_ignoring_top_level_qualifiers_p
		  (TREE_TYPE (object), decl_type_context (field)));
      val = build_address (arg);
    }

  if (TYPE_PTR_P (argtype)
      && TREE_CODE (TREE_TYPE (argtype)) == METHOD_TYPE)
    {
      build_ptrmemfunc_type (argtype);
      val = build_ptrmemfunc (argtype, val, 0,
			      /*c_cast_p=*/false,
			      complain);
    }

  return val;
}

/* Take the address of ARG if it has one, even if it's an rvalue.  */

tree
cp_build_addr_expr (tree arg, tsubst_flags_t complain)
{
  return cp_build_addr_expr_1 (arg, 0, complain);
}

/* Take the address of ARG, but only if it's an lvalue.  */

static tree
cp_build_addr_expr_strict (tree arg, tsubst_flags_t complain)
{
  return cp_build_addr_expr_1 (arg, 1, complain);
}

/* C++: Must handle pointers to members.

   Perhaps type instantiation should be extended to handle conversion
   from aggregates to types we don't yet know we want?  (Or are those
   cases typically errors which should be reported?)

   NOCONVERT suppresses the default promotions (such as from short to int).  */

tree
cp_build_unary_op (enum tree_code code, tree xarg, bool noconvert,
                   tsubst_flags_t complain)
{
  /* No default_conversion here.  It causes trouble for ADDR_EXPR.  */
  tree arg = xarg;
  location_t location = cp_expr_loc_or_input_loc (arg);
  tree argtype = 0;
  const char *errstring = NULL;
  tree val;
  const char *invalid_op_diag;

  if (!arg || error_operand_p (arg))
    return error_mark_node;

  arg = resolve_nondeduced_context (arg, complain);

  if ((invalid_op_diag
       = targetm.invalid_unary_op ((code == UNARY_PLUS_EXPR
				    ? CONVERT_EXPR
				    : code),
				   TREE_TYPE (arg))))
    {
      if (complain & tf_error)
	error (invalid_op_diag);
      return error_mark_node;
    }

  switch (code)
    {
    case UNARY_PLUS_EXPR:
    case NEGATE_EXPR:
      {
	int flags = WANT_ARITH | WANT_ENUM;
	/* Unary plus (but not unary minus) is allowed on pointers.  */
	if (code == UNARY_PLUS_EXPR)
	  flags |= WANT_POINTER;
	arg = build_expr_type_conversion (flags, arg, true);
	if (!arg)
	  errstring = (code == NEGATE_EXPR
		       ? _("wrong type argument to unary minus")
		       : _("wrong type argument to unary plus"));
	else
	  {
	    if (!noconvert && INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (arg)))
	      arg = cp_perform_integral_promotions (arg, complain);

	    /* Make sure the result is not an lvalue: a unary plus or minus
	       expression is always a rvalue.  */
	    arg = rvalue (arg);
	  }
      }
      break;

    case BIT_NOT_EXPR:
      if (TREE_CODE (TREE_TYPE (arg)) == COMPLEX_TYPE)
	{
	  code = CONJ_EXPR;
	  if (!noconvert)
	    {
	      arg = cp_default_conversion (arg, complain);
	      if (arg == error_mark_node)
		return error_mark_node;
	    }
	}
      else if (!(arg = build_expr_type_conversion (WANT_INT | WANT_ENUM
						   | WANT_VECTOR_OR_COMPLEX,
						   arg, true)))
	errstring = _("wrong type argument to bit-complement");
      else if (!noconvert && INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (arg)))
	{
	  /* Warn if the expression has boolean value.  */
	  if (TREE_CODE (TREE_TYPE (arg)) == BOOLEAN_TYPE
	      && (complain & tf_warning)
	      && warning_at (location, OPT_Wbool_operation,
			     "%<~%> on an expression of type %<bool%>"))
	    inform (location, "did you mean to use logical not (%<!%>)?");
	  arg = cp_perform_integral_promotions (arg, complain);
	}
      else if (!noconvert && VECTOR_TYPE_P (TREE_TYPE (arg)))
	arg = mark_rvalue_use (arg);
      break;

    case ABS_EXPR:
      if (!(arg = build_expr_type_conversion (WANT_ARITH | WANT_ENUM, arg, true)))
	errstring = _("wrong type argument to abs");
      else if (!noconvert)
	{
	  arg = cp_default_conversion (arg, complain);
	  if (arg == error_mark_node)
	    return error_mark_node;
	}
      break;

    case CONJ_EXPR:
      /* Conjugating a real value is a no-op, but allow it anyway.  */
      if (!(arg = build_expr_type_conversion (WANT_ARITH | WANT_ENUM, arg, true)))
	errstring = _("wrong type argument to conjugation");
      else if (!noconvert)
	{
	  arg = cp_default_conversion (arg, complain);
	  if (arg == error_mark_node)
	    return error_mark_node;
	}
      break;

    case TRUTH_NOT_EXPR:
      if (gnu_vector_type_p (TREE_TYPE (arg)))
	return cp_build_binary_op (input_location, EQ_EXPR, arg,
				   build_zero_cst (TREE_TYPE (arg)), complain);
      arg = perform_implicit_conversion (boolean_type_node, arg,
					 complain);
      val = invert_truthvalue_loc (location, arg);
      if (arg != error_mark_node)
	return val;
      errstring = _("in argument to unary !");
      break;

    case NOP_EXPR:
      break;

    case REALPART_EXPR:
    case IMAGPART_EXPR:
      arg = build_real_imag_expr (input_location, code, arg);
      return arg;

    case PREINCREMENT_EXPR:
    case POSTINCREMENT_EXPR:
    case PREDECREMENT_EXPR:
    case POSTDECREMENT_EXPR:
      /* Handle complex lvalues (when permitted)
	 by reduction to simpler cases.  */

      val = unary_complex_lvalue (code, arg);
      if (val != 0)
	return val;

      arg = mark_lvalue_use (arg);

      /* Increment or decrement the real part of the value,
	 and don't change the imaginary part.  */
      if (TREE_CODE (TREE_TYPE (arg)) == COMPLEX_TYPE)
	{
	  tree real, imag;

	  arg = cp_stabilize_reference (arg);
	  real = cp_build_unary_op (REALPART_EXPR, arg, true, complain);
	  imag = cp_build_unary_op (IMAGPART_EXPR, arg, true, complain);
	  real = cp_build_unary_op (code, real, true, complain);
	  if (real == error_mark_node || imag == error_mark_node)
	    return error_mark_node;
	  return build2 (COMPLEX_EXPR, TREE_TYPE (arg),
			 real, imag);
	}

      /* Report invalid types.  */

      if (!(arg = build_expr_type_conversion (WANT_ARITH | WANT_POINTER,
					      arg, true)))
	{
	  if (code == PREINCREMENT_EXPR)
	    errstring = _("no pre-increment operator for type");
	  else if (code == POSTINCREMENT_EXPR)
	    errstring = _("no post-increment operator for type");
	  else if (code == PREDECREMENT_EXPR)
	    errstring = _("no pre-decrement operator for type");
	  else
	    errstring = _("no post-decrement operator for type");
	  break;
	}
      else if (arg == error_mark_node)
	return error_mark_node;

      /* Report something read-only.  */

      if (CP_TYPE_CONST_P (TREE_TYPE (arg))
	  || TREE_READONLY (arg)) 
        {
          if (complain & tf_error)
	    cxx_readonly_error (location, arg,
				((code == PREINCREMENT_EXPR
				  || code == POSTINCREMENT_EXPR)
				 ? lv_increment : lv_decrement));
          else
            return error_mark_node;
        }

      {
	tree inc;
	tree declared_type = unlowered_expr_type (arg);

	argtype = TREE_TYPE (arg);

	/* ARM $5.2.5 last annotation says this should be forbidden.  */
	if (TREE_CODE (argtype) == ENUMERAL_TYPE)
          {
            if (complain & tf_error)
              permerror (location, (code == PREINCREMENT_EXPR
				    || code == POSTINCREMENT_EXPR)
                         ? G_("ISO C++ forbids incrementing an enum")
                         : G_("ISO C++ forbids decrementing an enum"));
            else
              return error_mark_node;
          }

	/* Compute the increment.  */

	if (TYPE_PTR_P (argtype))
	  {
	    tree type = complete_type (TREE_TYPE (argtype));

	    if (!COMPLETE_OR_VOID_TYPE_P (type))
              {
                if (complain & tf_error)
                  error_at (location, ((code == PREINCREMENT_EXPR
					|| code == POSTINCREMENT_EXPR))
			    ? G_("cannot increment a pointer to incomplete "
				 "type %qT")
			    : G_("cannot decrement a pointer to incomplete "
				 "type %qT"),
			    TREE_TYPE (argtype));
                else
                  return error_mark_node;
              }
	    else if (!TYPE_PTROB_P (argtype)) 
              {
                if (complain & tf_error)
                  pedwarn (location, OPT_Wpointer_arith,
			   (code == PREINCREMENT_EXPR
                              || code == POSTINCREMENT_EXPR)
			   ? G_("ISO C++ forbids incrementing a pointer "
				"of type %qT")
			   : G_("ISO C++ forbids decrementing a pointer "
				"of type %qT"),
			   argtype);
                else
                  return error_mark_node;
              }
	    else if (!verify_type_context (location, TCTX_POINTER_ARITH,
					   TREE_TYPE (argtype),
					   !(complain & tf_error)))
	      return error_mark_node;

	    inc = cxx_sizeof_nowarn (TREE_TYPE (argtype));
	  }
	else
	  inc = VECTOR_TYPE_P (argtype)
	    ? build_one_cst (argtype)
	    : integer_one_node;

	inc = cp_convert (argtype, inc, complain);

	/* If 'arg' is an Objective-C PROPERTY_REF expression, then we
	   need to ask Objective-C to build the increment or decrement
	   expression for it.  */
	if (objc_is_property_ref (arg))
	  return objc_build_incr_expr_for_property_ref (input_location, code, 
							arg, inc);	

	/* Complain about anything else that is not a true lvalue.  */
	if (!lvalue_or_else (arg, ((code == PREINCREMENT_EXPR
				    || code == POSTINCREMENT_EXPR)
				   ? lv_increment : lv_decrement),
                             complain))
	  return error_mark_node;

	/* [depr.volatile.type] "Postfix ++ and -- expressions and
	   prefix ++ and -- expressions of volatile-qualified arithmetic
	   and pointer types are deprecated."  */
	if (TREE_THIS_VOLATILE (arg) || CP_TYPE_VOLATILE_P (TREE_TYPE (arg)))
	  warning_at (location, OPT_Wvolatile,
		      "%qs expression of %<volatile%>-qualified type is "
		      "deprecated",
		      ((code == PREINCREMENT_EXPR
			|| code == POSTINCREMENT_EXPR)
		       ? "++" : "--"));

	/* Forbid using -- or ++ in C++17 on `bool'.  */
	if (TREE_CODE (declared_type) == BOOLEAN_TYPE)
	  {
	    if (code == POSTDECREMENT_EXPR || code == PREDECREMENT_EXPR)
	      {
                if (complain & tf_error)
		  error_at (location,
			    "use of an operand of type %qT in %<operator--%> "
			    "is forbidden", boolean_type_node);
		return error_mark_node;
	      }
	    else
	      {
		if (cxx_dialect >= cxx17)
		  {
		    if (complain & tf_error)
		      error_at (location,
				"use of an operand of type %qT in "
				"%<operator++%> is forbidden in C++17",
				boolean_type_node);
		    return error_mark_node;
		  }
		/* Otherwise, [depr.incr.bool] says this is deprecated.  */
		else
		  warning_at (location, OPT_Wdeprecated,
			      "use of an operand of type %qT "
			      "in %<operator++%> is deprecated",
			      boolean_type_node);
	      }
	    val = boolean_increment (code, arg);
	  }
	else if (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR)
	  /* An rvalue has no cv-qualifiers.  */
	  val = build2 (code, cv_unqualified (TREE_TYPE (arg)), arg, inc);
	else
	  val = build2 (code, TREE_TYPE (arg), arg, inc);

	TREE_SIDE_EFFECTS (val) = 1;
	return val;
      }

    case ADDR_EXPR:
      /* Note that this operation never does default_conversion
	 regardless of NOCONVERT.  */
      return cp_build_addr_expr (arg, complain);

    default:
      break;
    }

  if (!errstring)
    {
      if (argtype == 0)
	argtype = TREE_TYPE (arg);
      return build1 (code, argtype, arg);
    }

  if (complain & tf_error)
    error_at (location, "%s", errstring);
  return error_mark_node;
}

/* Hook for the c-common bits that build a unary op.  */
tree
build_unary_op (location_t /*location*/,
		enum tree_code code, tree xarg, bool noconvert)
{
  return cp_build_unary_op (code, xarg, noconvert, tf_warning_or_error);
}

/* Adjust LVALUE, an MODIFY_EXPR, PREINCREMENT_EXPR or PREDECREMENT_EXPR,
   so that it is a valid lvalue even for GENERIC by replacing
   (lhs = rhs) with ((lhs = rhs), lhs)
   (--lhs) with ((--lhs), lhs)
   (++lhs) with ((++lhs), lhs)
   and if lhs has side-effects, calling cp_stabilize_reference on it, so
   that it can be evaluated multiple times.  */

tree
genericize_compound_lvalue (tree lvalue)
{
  if (TREE_SIDE_EFFECTS (TREE_OPERAND (lvalue, 0)))
    lvalue = build2 (TREE_CODE (lvalue), TREE_TYPE (lvalue),
		     cp_stabilize_reference (TREE_OPERAND (lvalue, 0)),
		     TREE_OPERAND (lvalue, 1));
  return build2 (COMPOUND_EXPR, TREE_TYPE (TREE_OPERAND (lvalue, 0)),
		 lvalue, TREE_OPERAND (lvalue, 0));
}

/* Apply unary lvalue-demanding operator CODE to the expression ARG
   for certain kinds of expressions which are not really lvalues
   but which we can accept as lvalues.

   If ARG is not a kind of expression we can handle, return
   NULL_TREE.  */

tree
unary_complex_lvalue (enum tree_code code, tree arg)
{
  /* Inside a template, making these kinds of adjustments is
     pointless; we are only concerned with the type of the
     expression.  */
  if (processing_template_decl)
    return NULL_TREE;

  /* Handle (a, b) used as an "lvalue".  */
  if (TREE_CODE (arg) == COMPOUND_EXPR)
    {
      tree real_result = cp_build_unary_op (code, TREE_OPERAND (arg, 1), false,
                                            tf_warning_or_error);
      return build2 (COMPOUND_EXPR, TREE_TYPE (real_result),
		     TREE_OPERAND (arg, 0), real_result);
    }

  /* Handle (a ? b : c) used as an "lvalue".  */
  if (TREE_CODE (arg) == COND_EXPR
      || TREE_CODE (arg) == MIN_EXPR || TREE_CODE (arg) == MAX_EXPR)
    return rationalize_conditional_expr (code, arg, tf_warning_or_error);

  /* Handle (a = b), (++a), and (--a) used as an "lvalue".  */
  if (TREE_CODE (arg) == MODIFY_EXPR
      || TREE_CODE (arg) == PREINCREMENT_EXPR
      || TREE_CODE (arg) == PREDECREMENT_EXPR)
    return unary_complex_lvalue (code, genericize_compound_lvalue (arg));

  if (code != ADDR_EXPR)
    return NULL_TREE;

  /* Handle (a = b) used as an "lvalue" for `&'.  */
  if (TREE_CODE (arg) == MODIFY_EXPR
      || TREE_CODE (arg) == INIT_EXPR)
    {
      tree real_result = cp_build_unary_op (code, TREE_OPERAND (arg, 0), false,
                                            tf_warning_or_error);
      arg = build2 (COMPOUND_EXPR, TREE_TYPE (real_result),
		    arg, real_result);
      suppress_warning (arg /* What warning? */);
      return arg;
    }

  if (FUNC_OR_METHOD_TYPE_P (TREE_TYPE (arg))
      || TREE_CODE (arg) == OFFSET_REF)
    return NULL_TREE;

  /* We permit compiler to make function calls returning
     objects of aggregate type look like lvalues.  */
  {
    tree targ = arg;

    if (TREE_CODE (targ) == SAVE_EXPR)
      targ = TREE_OPERAND (targ, 0);

    if (TREE_CODE (targ) == CALL_EXPR && MAYBE_CLASS_TYPE_P (TREE_TYPE (targ)))
      {
	if (TREE_CODE (arg) == SAVE_EXPR)
	  targ = arg;
	else
	  targ = build_cplus_new (TREE_TYPE (arg), arg, tf_warning_or_error);
	return build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (arg)), targ);
      }

    if (TREE_CODE (arg) == SAVE_EXPR && INDIRECT_REF_P (targ))
      return build3 (SAVE_EXPR, build_pointer_type (TREE_TYPE (arg)),
		     TREE_OPERAND (targ, 0), current_function_decl, NULL);
  }

  /* Don't let anything else be handled specially.  */
  return NULL_TREE;
}

/* Mark EXP saying that we need to be able to take the
   address of it; it should not be allocated in a register.
   Value is true if successful.  ARRAY_REF_P is true if this
   is for ARRAY_REF construction - in that case we don't want
   to look through VIEW_CONVERT_EXPR from VECTOR_TYPE to ARRAY_TYPE,
   it is fine to use ARRAY_REFs for vector subscripts on vector
   register variables.

   C++: we do not allow `current_class_ptr' to be addressable.  */

bool
cxx_mark_addressable (tree exp, bool array_ref_p)
{
  tree x = exp;

  while (1)
    switch (TREE_CODE (x))
      {
      case VIEW_CONVERT_EXPR:
	if (array_ref_p
	    && TREE_CODE (TREE_TYPE (x)) == ARRAY_TYPE
	    && VECTOR_TYPE_P (TREE_TYPE (TREE_OPERAND (x, 0))))
	  return true;
	x = TREE_OPERAND (x, 0);
	break;

      case COMPONENT_REF:
	if (bitfield_p (x))
	  error ("attempt to take address of bit-field");
	/* FALLTHRU */
      case ADDR_EXPR:
      case ARRAY_REF:
      case REALPART_EXPR:
      case IMAGPART_EXPR:
	x = TREE_OPERAND (x, 0);
	break;

      case PARM_DECL:
	if (x == current_class_ptr)
	  {
	    error ("cannot take the address of %<this%>, which is an rvalue expression");
	    TREE_ADDRESSABLE (x) = 1; /* so compiler doesn't die later.  */
	    return true;
	  }
	/* Fall through.  */

      case VAR_DECL:
	/* Caller should not be trying to mark initialized
	   constant fields addressable.  */
	gcc_assert (DECL_LANG_SPECIFIC (x) == 0
		    || DECL_IN_AGGR_P (x) == 0
		    || TREE_STATIC (x)
		    || DECL_EXTERNAL (x));
	/* Fall through.  */

      case RESULT_DECL:
	if (DECL_REGISTER (x) && !TREE_ADDRESSABLE (x)
	    && !DECL_ARTIFICIAL (x))
	  {
	    if (VAR_P (x) && DECL_HARD_REGISTER (x))
	      {
		error
		  ("address of explicit register variable %qD requested", x);
		return false;
	      }
	    else if (extra_warnings)
	      warning
		(OPT_Wextra, "address requested for %qD, which is declared %<register%>", x);
	  }
	TREE_ADDRESSABLE (x) = 1;
	return true;

      case CONST_DECL:
      case FUNCTION_DECL:
	TREE_ADDRESSABLE (x) = 1;
	return true;

      case CONSTRUCTOR:
	TREE_ADDRESSABLE (x) = 1;
	return true;

      case TARGET_EXPR:
	TREE_ADDRESSABLE (x) = 1;
	cxx_mark_addressable (TREE_OPERAND (x, 0));
	return true;

      default:
	return true;
    }
}

/* Build and return a conditional expression IFEXP ? OP1 : OP2.  */

tree
build_x_conditional_expr (location_t loc, tree ifexp, tree op1, tree op2, 
                          tsubst_flags_t complain)
{
  tree orig_ifexp = ifexp;
  tree orig_op1 = op1;
  tree orig_op2 = op2;
  tree expr;

  if (processing_template_decl)
    {
      /* The standard says that the expression is type-dependent if
	 IFEXP is type-dependent, even though the eventual type of the
	 expression doesn't dependent on IFEXP.  */
      if (type_dependent_expression_p (ifexp)
	  /* As a GNU extension, the middle operand may be omitted.  */
	  || (op1 && type_dependent_expression_p (op1))
	  || type_dependent_expression_p (op2))
	return build_min_nt_loc (loc, COND_EXPR, ifexp, op1, op2);
      ifexp = build_non_dependent_expr (ifexp);
      if (op1)
	op1 = build_non_dependent_expr (op1);
      op2 = build_non_dependent_expr (op2);
    }

  expr = build_conditional_expr (loc, ifexp, op1, op2, complain);
  if (processing_template_decl && expr != error_mark_node)
    {
      tree min = build_min_non_dep (COND_EXPR, expr,
				    orig_ifexp, orig_op1, orig_op2);
      expr = convert_from_reference (min);
    }
  return expr;
}

/* Given a list of expressions, return a compound expression
   that performs them all and returns the value of the last of them.  */

tree
build_x_compound_expr_from_list (tree list, expr_list_kind exp,
				 tsubst_flags_t complain)
{
  tree expr = TREE_VALUE (list);

  if (BRACE_ENCLOSED_INITIALIZER_P (expr)
      && !CONSTRUCTOR_IS_DIRECT_INIT (expr))
    {
      if (complain & tf_error)
	pedwarn (cp_expr_loc_or_input_loc (expr), 0,
		 "list-initializer for non-class type must not "
		 "be parenthesized");
      else
	return error_mark_node;
    }

  if (TREE_CHAIN (list))
    {
      if (complain & tf_error)
	switch (exp)
	  {
	  case ELK_INIT:
	    permerror (input_location, "expression list treated as compound "
				       "expression in initializer");
	    break;
	  case ELK_MEM_INIT:
	    permerror (input_location, "expression list treated as compound "
				       "expression in mem-initializer");
	    break;
	  case ELK_FUNC_CAST:
	    permerror (input_location, "expression list treated as compound "
				       "expression in functional cast");
	    break;
	  default:
	    gcc_unreachable ();
	  }
      else
	return error_mark_node;

      for (list = TREE_CHAIN (list); list; list = TREE_CHAIN (list))
	expr = build_x_compound_expr (EXPR_LOCATION (TREE_VALUE (list)),
				      expr, TREE_VALUE (list), complain);
    }

  return expr;
}

/* Like build_x_compound_expr_from_list, but using a VEC.  */

tree
build_x_compound_expr_from_vec (vec<tree, va_gc> *vec, const char *msg,
				tsubst_flags_t complain)
{
  if (vec_safe_is_empty (vec))
    return NULL_TREE;
  else if (vec->length () == 1)
    return (*vec)[0];
  else
    {
      tree expr;
      unsigned int ix;
      tree t;

      if (msg != NULL)
	{
	  if (complain & tf_error)
	    permerror (input_location,
		       "%s expression list treated as compound expression",
		       msg);
	  else
	    return error_mark_node;
	}

      expr = (*vec)[0];
      for (ix = 1; vec->iterate (ix, &t); ++ix)
	expr = build_x_compound_expr (EXPR_LOCATION (t), expr,
				      t, complain);

      return expr;
    }
}

/* Handle overloading of the ',' operator when needed.  */

tree
build_x_compound_expr (location_t loc, tree op1, tree op2,
		       tsubst_flags_t complain)
{
  tree result;
  tree orig_op1 = op1;
  tree orig_op2 = op2;
  tree overload = NULL_TREE;

  if (processing_template_decl)
    {
      if (type_dependent_expression_p (op1)
	  || type_dependent_expression_p (op2))
	{
	  result = build_min_nt_loc (loc, COMPOUND_EXPR, op1, op2);
	  maybe_save_operator_binding (result);
	  return result;
	}
      op1 = build_non_dependent_expr (op1);
      op2 = build_non_dependent_expr (op2);
    }

  result = build_new_op (loc, COMPOUND_EXPR, LOOKUP_NORMAL, op1, op2,
			 NULL_TREE, &overload, complain);
  if (!result)
    result = cp_build_compound_expr (op1, op2, complain);

  if (processing_template_decl && result != error_mark_node)
    {
      if (overload != NULL_TREE)
	return (build_min_non_dep_op_overload
		(COMPOUND_EXPR, result, overload, orig_op1, orig_op2));

      return build_min_non_dep (COMPOUND_EXPR, result, orig_op1, orig_op2);
    }

  return result;
}

/* Like cp_build_compound_expr, but for the c-common bits.  */

tree
build_compound_expr (location_t /*loc*/, tree lhs, tree rhs)
{
  return cp_build_compound_expr (lhs, rhs, tf_warning_or_error);
}

/* Build a compound expression.  */

tree
cp_build_compound_expr (tree lhs, tree rhs, tsubst_flags_t complain)
{
  lhs = convert_to_void (lhs, ICV_LEFT_OF_COMMA, complain);

  if (lhs == error_mark_node || rhs == error_mark_node)
    return error_mark_node;

  if (TREE_CODE (rhs) == TARGET_EXPR)
    {
      /* If the rhs is a TARGET_EXPR, then build the compound
	 expression inside the target_expr's initializer. This
	 helps the compiler to eliminate unnecessary temporaries.  */
      tree init = TREE_OPERAND (rhs, 1);

      init = build2 (COMPOUND_EXPR, TREE_TYPE (init), lhs, init);
      TREE_OPERAND (rhs, 1) = init;

      return rhs;
    }

  if (type_unknown_p (rhs))
    {
      if (complain & tf_error)
	error_at (cp_expr_loc_or_input_loc (rhs),
		  "no context to resolve type of %qE", rhs);
      return error_mark_node;
    }
  
  return build2 (COMPOUND_EXPR, TREE_TYPE (rhs), lhs, rhs);
}

/* Issue a diagnostic message if casting from SRC_TYPE to DEST_TYPE
   casts away constness.  CAST gives the type of cast.  Returns true
   if the cast is ill-formed, false if it is well-formed.

   ??? This function warns for casting away any qualifier not just
   const.  We would like to specify exactly what qualifiers are casted
   away.
*/

static bool
check_for_casting_away_constness (location_t loc, tree src_type,
				  tree dest_type, enum tree_code cast,
				  tsubst_flags_t complain)
{
  /* C-style casts are allowed to cast away constness.  With
     WARN_CAST_QUAL, we still want to issue a warning.  */
  if (cast == CAST_EXPR && !warn_cast_qual)
    return false;
  
  if (!casts_away_constness (src_type, dest_type, complain))
    return false;

  switch (cast)
    {
    case CAST_EXPR:
      if (complain & tf_warning)
	warning_at (loc, OPT_Wcast_qual,
		    "cast from type %qT to type %qT casts away qualifiers",
		    src_type, dest_type);
      return false;

    case STATIC_CAST_EXPR:
      if (complain & tf_error)
	error_at (loc, "%<static_cast%> from type %qT to type %qT casts "
		  "away qualifiers",
		  src_type, dest_type);
      return true;

    case REINTERPRET_CAST_EXPR:
      if (complain & tf_error)
	error_at (loc, "%<reinterpret_cast%> from type %qT to type %qT "
		  "casts away qualifiers",
		  src_type, dest_type);
      return true;

    default:
      gcc_unreachable();
    }
}

/* Warns if the cast from expression EXPR to type TYPE is useless.  */
void
maybe_warn_about_useless_cast (location_t loc, tree type, tree expr,
			       tsubst_flags_t complain)
{
  if (warn_useless_cast
      && complain & tf_warning)
    {
      if ((TYPE_REF_P (type)
	   && (TYPE_REF_IS_RVALUE (type)
	       ? xvalue_p (expr) : lvalue_p (expr))
	   && same_type_p (TREE_TYPE (expr), TREE_TYPE (type)))
	  || same_type_p (TREE_TYPE (expr), type))
	warning_at (loc, OPT_Wuseless_cast,
		    "useless cast to type %q#T", type);
    }
}

/* Warns if the cast ignores cv-qualifiers on TYPE.  */
static void
maybe_warn_about_cast_ignoring_quals (location_t loc, tree type,
				      tsubst_flags_t complain)
{
  if (warn_ignored_qualifiers
      && complain & tf_warning
      && !CLASS_TYPE_P (type)
      && (cp_type_quals (type) & (TYPE_QUAL_CONST|TYPE_QUAL_VOLATILE)))
    warning_at (loc, OPT_Wignored_qualifiers,
		"type qualifiers ignored on cast result type");
}

/* Convert EXPR (an expression with pointer-to-member type) to TYPE
   (another pointer-to-member type in the same hierarchy) and return
   the converted expression.  If ALLOW_INVERSE_P is permitted, a
   pointer-to-derived may be converted to pointer-to-base; otherwise,
   only the other direction is permitted.  If C_CAST_P is true, this
   conversion is taking place as part of a C-style cast.  */

tree
convert_ptrmem (tree type, tree expr, bool allow_inverse_p,
		bool c_cast_p, tsubst_flags_t complain)
{
  if (same_type_p (type, TREE_TYPE (expr)))
    return expr;

  if (TYPE_PTRDATAMEM_P (type))
    {
      tree obase = TYPE_PTRMEM_CLASS_TYPE (TREE_TYPE (expr));
      tree nbase = TYPE_PTRMEM_CLASS_TYPE (type);
      tree delta = (get_delta_difference
		    (obase, nbase,
		     allow_inverse_p, c_cast_p, complain));

      if (delta == error_mark_node)
	return error_mark_node;

      if (!same_type_p (obase, nbase))
	{
	  if (TREE_CODE (expr) == PTRMEM_CST)
	    expr = cplus_expand_constant (expr);

	  tree cond = cp_build_binary_op (input_location, EQ_EXPR, expr,
					  build_int_cst (TREE_TYPE (expr), -1),
					  complain);
	  tree op1 = build_nop (ptrdiff_type_node, expr);
	  tree op2 = cp_build_binary_op (input_location, PLUS_EXPR, op1, delta,
					 complain);

	  expr = fold_build3_loc (input_location,
				  COND_EXPR, ptrdiff_type_node, cond, op1, op2);
	}

      return build_nop (type, expr);
    }
  else
    return build_ptrmemfunc (TYPE_PTRMEMFUNC_FN_TYPE (type), expr,
			     allow_inverse_p, c_cast_p, complain);
}

/* Perform a static_cast from EXPR to TYPE.  When C_CAST_P is true,
   this static_cast is being attempted as one of the possible casts
   allowed by a C-style cast.  (In that case, accessibility of base
   classes is not considered, and it is OK to cast away
   constness.)  Return the result of the cast.  *VALID_P is set to
   indicate whether or not the cast was valid.  */

static tree
build_static_cast_1 (location_t loc, tree type, tree expr, bool c_cast_p,
		     bool *valid_p, tsubst_flags_t complain)
{
  tree intype;
  tree result;
  cp_lvalue_kind clk;

  /* Assume the cast is valid.  */
  *valid_p = true;

  intype = unlowered_expr_type (expr);

  /* Save casted types in the function's used types hash table.  */
  used_types_insert (type);

  /* A prvalue of non-class type is cv-unqualified.  */
  if (!CLASS_TYPE_P (type))
    type = cv_unqualified (type);

  /* [expr.static.cast]

     An lvalue of type "cv1 B", where B is a class type, can be cast
     to type "reference to cv2 D", where D is a class derived (clause
     _class.derived_) from B, if a valid standard conversion from
     "pointer to D" to "pointer to B" exists (_conv.ptr_), cv2 is the
     same cv-qualification as, or greater cv-qualification than, cv1,
     and B is not a virtual base class of D.  */
  /* We check this case before checking the validity of "TYPE t =
     EXPR;" below because for this case:

       struct B {};
       struct D : public B { D(const B&); };
       extern B& b;
       void f() { static_cast<const D&>(b); }

     we want to avoid constructing a new D.  The standard is not
     completely clear about this issue, but our interpretation is
     consistent with other compilers.  */
  if (TYPE_REF_P (type)
      && CLASS_TYPE_P (TREE_TYPE (type))
      && CLASS_TYPE_P (intype)
      && (TYPE_REF_IS_RVALUE (type) || lvalue_p (expr))
      && DERIVED_FROM_P (intype, TREE_TYPE (type))
      && can_convert (build_pointer_type (TYPE_MAIN_VARIANT (intype)),
		      build_pointer_type (TYPE_MAIN_VARIANT
					  (TREE_TYPE (type))),
		      complain)
      && (c_cast_p
	  || at_least_as_qualified_p (TREE_TYPE (type), intype)))
    {
      tree base;

      if (processing_template_decl)
	return expr;

      /* There is a standard conversion from "D*" to "B*" even if "B"
	 is ambiguous or inaccessible.  If this is really a
	 static_cast, then we check both for inaccessibility and
	 ambiguity.  However, if this is a static_cast being performed
	 because the user wrote a C-style cast, then accessibility is
	 not considered.  */
      base = lookup_base (TREE_TYPE (type), intype,
			  c_cast_p ? ba_unique : ba_check,
			  NULL, complain);
      expr = cp_build_addr_expr (expr, complain);

      if (sanitize_flags_p (SANITIZE_VPTR))
	{
	  tree ubsan_check
	    = cp_ubsan_maybe_instrument_downcast (loc, type,
						  intype, expr);
	  if (ubsan_check)
	    expr = ubsan_check;
	}

      /* Convert from "B*" to "D*".  This function will check that "B"
	 is not a virtual base of "D".  Even if we don't have a guarantee
	 that expr is NULL, if the static_cast is to a reference type,
	 it is UB if it would be NULL, so omit the non-NULL check.  */
      expr = build_base_path (MINUS_EXPR, expr, base,
			      /*nonnull=*/flag_delete_null_pointer_checks,
			      complain);

      /* Convert the pointer to a reference -- but then remember that
	 there are no expressions with reference type in C++.

         We call rvalue so that there's an actual tree code
         (NON_LVALUE_EXPR) for the static_cast; otherwise, if the operand
         is a variable with the same type, the conversion would get folded
         away, leaving just the variable and causing lvalue_kind to give
         the wrong answer.  */
      expr = cp_fold_convert (type, expr);

      /* When -fsanitize=null, make sure to diagnose reference binding to
	 NULL even when the reference is converted to pointer later on.  */
      if (sanitize_flags_p (SANITIZE_NULL)
	  && TREE_CODE (expr) == COND_EXPR
	  && TREE_OPERAND (expr, 2)
	  && TREE_CODE (TREE_OPERAND (expr, 2)) == INTEGER_CST
	  && TREE_TYPE (TREE_OPERAND (expr, 2)) == type)
	ubsan_maybe_instrument_reference (&TREE_OPERAND (expr, 2));

      return convert_from_reference (rvalue (expr));
    }

  /* "A glvalue of type cv1 T1 can be cast to type rvalue reference to
     cv2 T2 if cv2 T2 is reference-compatible with cv1 T1 (8.5.3)."  */
  if (TYPE_REF_P (type)
      && TYPE_REF_IS_RVALUE (type)
      && (clk = real_lvalue_p (expr))
      && reference_compatible_p (TREE_TYPE (type), intype)
      && (c_cast_p || at_least_as_qualified_p (TREE_TYPE (type), intype)))
    {
      if (processing_template_decl)
	return expr;
      if (clk == clk_ordinary)
	{
	  /* Handle the (non-bit-field) lvalue case here by casting to
	     lvalue reference and then changing it to an rvalue reference.
	     Casting an xvalue to rvalue reference will be handled by the
	     main code path.  */
	  tree lref = cp_build_reference_type (TREE_TYPE (type), false);
	  result = (perform_direct_initialization_if_possible
		    (lref, expr, c_cast_p, complain));
	  result = build1 (NON_LVALUE_EXPR, type, result);
	  return convert_from_reference (result);
	}
      else
	/* For a bit-field or packed field, bind to a temporary.  */
	expr = rvalue (expr);
    }

  /* Resolve overloaded address here rather than once in
     implicit_conversion and again in the inverse code below.  */
  if (TYPE_PTRMEMFUNC_P (type) && type_unknown_p (expr))
    {
      expr = instantiate_type (type, expr, complain);
      intype = TREE_TYPE (expr);
    }

  /* [expr.static.cast]

     Any expression can be explicitly converted to type cv void.  */
  if (VOID_TYPE_P (type))
    return convert_to_void (expr, ICV_CAST, complain);

  /* [class.abstract]
     An abstract class shall not be used ... as the type of an explicit
     conversion.  */
  if (abstract_virtuals_error_sfinae (ACU_CAST, type, complain))
    return error_mark_node;

  /* [expr.static.cast]

     An expression e can be explicitly converted to a type T using a
     static_cast of the form static_cast<T>(e) if the declaration T
     t(e);" is well-formed, for some invented temporary variable
     t.  */
  result = perform_direct_initialization_if_possible (type, expr,
						      c_cast_p, complain);
  /* P1975 allows static_cast<Aggr>(42), as well as static_cast<T[5]>(42),
     which initialize the first element of the aggregate.  We need to handle
     the array case specifically.  */
  if (result == NULL_TREE
      && cxx_dialect >= cxx20
      && TREE_CODE (type) == ARRAY_TYPE)
    {
      /* Create { EXPR } and perform direct-initialization from it.  */
      tree e = build_constructor_single (init_list_type_node, NULL_TREE, expr);
      CONSTRUCTOR_IS_DIRECT_INIT (e) = true;
      CONSTRUCTOR_IS_PAREN_INIT (e) = true;
      result = perform_direct_initialization_if_possible (type, e, c_cast_p,
							  complain);
    }
  if (result)
    {
      if (processing_template_decl)
	return expr;

      result = convert_from_reference (result);

      /* [expr.static.cast]

	 If T is a reference type, the result is an lvalue; otherwise,
	 the result is an rvalue.  */
      if (!TYPE_REF_P (type))
	{
	  result = rvalue (result);

	  if (result == expr && SCALAR_TYPE_P (type))
	    /* Leave some record of the cast.  */
	    result = build_nop (type, expr);
	}
      return result;
    }

  /* [expr.static.cast]

     The inverse of any standard conversion sequence (clause _conv_),
     other than the lvalue-to-rvalue (_conv.lval_), array-to-pointer
     (_conv.array_), function-to-pointer (_conv.func_), and boolean
     (_conv.bool_) conversions, can be performed explicitly using
     static_cast subject to the restriction that the explicit
     conversion does not cast away constness (_expr.const.cast_), and
     the following additional rules for specific cases:  */
  /* For reference, the conversions not excluded are: integral
     promotions, floating-point promotion, integral conversions,
     floating-point conversions, floating-integral conversions,
     pointer conversions, and pointer to member conversions.  */
  /* DR 128

     A value of integral _or enumeration_ type can be explicitly
     converted to an enumeration type.  */
  /* The effect of all that is that any conversion between any two
     types which are integral, floating, or enumeration types can be
     performed.  */
  if ((INTEGRAL_OR_ENUMERATION_TYPE_P (type)
       || SCALAR_FLOAT_TYPE_P (type))
      && (INTEGRAL_OR_ENUMERATION_TYPE_P (intype)
	  || SCALAR_FLOAT_TYPE_P (intype)))
    {
      if (processing_template_decl)
	return expr;
      return ocp_convert (type, expr, CONV_C_CAST, LOOKUP_NORMAL, complain);
    }

  if (TYPE_PTR_P (type) && TYPE_PTR_P (intype)
      && CLASS_TYPE_P (TREE_TYPE (type))
      && CLASS_TYPE_P (TREE_TYPE (intype))
      && can_convert (build_pointer_type (TYPE_MAIN_VARIANT
					  (TREE_TYPE (intype))),
		      build_pointer_type (TYPE_MAIN_VARIANT
					  (TREE_TYPE (type))),
		      complain))
    {
      tree base;

      if (processing_template_decl)
	return expr;

      if (!c_cast_p
	  && check_for_casting_away_constness (loc, intype, type,
					       STATIC_CAST_EXPR,
					       complain))
	return error_mark_node;
      base = lookup_base (TREE_TYPE (type), TREE_TYPE (intype),
			  c_cast_p ? ba_unique : ba_check,
			  NULL, complain);
      expr = build_base_path (MINUS_EXPR, expr, base, /*nonnull=*/false,
			      complain);

      if (sanitize_flags_p (SANITIZE_VPTR))
	{
	  tree ubsan_check
	    = cp_ubsan_maybe_instrument_downcast (loc, type,
						  intype, expr);
	  if (ubsan_check)
	    expr = ubsan_check;
	}

      return cp_fold_convert (type, expr);
    }

  if ((TYPE_PTRDATAMEM_P (type) && TYPE_PTRDATAMEM_P (intype))
      || (TYPE_PTRMEMFUNC_P (type) && TYPE_PTRMEMFUNC_P (intype)))
    {
      tree c1;
      tree c2;
      tree t1;
      tree t2;

      c1 = TYPE_PTRMEM_CLASS_TYPE (intype);
      c2 = TYPE_PTRMEM_CLASS_TYPE (type);

      if (TYPE_PTRDATAMEM_P (type))
	{
	  t1 = (build_ptrmem_type
		(c1,
		 TYPE_MAIN_VARIANT (TYPE_PTRMEM_POINTED_TO_TYPE (intype))));
	  t2 = (build_ptrmem_type
		(c2,
		 TYPE_MAIN_VARIANT (TYPE_PTRMEM_POINTED_TO_TYPE (type))));
	}
      else
	{
	  t1 = intype;
	  t2 = type;
	}
      if (can_convert (t1, t2, complain) || can_convert (t2, t1, complain))
	{
	  if (!c_cast_p
	      && check_for_casting_away_constness (loc, intype, type,
						   STATIC_CAST_EXPR,
						   complain))
	    return error_mark_node;
	  if (processing_template_decl)
	    return expr;
	  return convert_ptrmem (type, expr, /*allow_inverse_p=*/1,
				 c_cast_p, complain);
	}
    }

  /* [expr.static.cast]

     An rvalue of type "pointer to cv void" can be explicitly
     converted to a pointer to object type.  A value of type pointer
     to object converted to "pointer to cv void" and back to the
     original pointer type will have its original value.  */
  if (TYPE_PTR_P (intype)
      && VOID_TYPE_P (TREE_TYPE (intype))
      && TYPE_PTROB_P (type))
    {
      if (!c_cast_p
	  && check_for_casting_away_constness (loc, intype, type,
					       STATIC_CAST_EXPR,
					       complain))
	return error_mark_node;
      if (processing_template_decl)
	return expr;
      return build_nop (type, expr);
    }

  *valid_p = false;
  return error_mark_node;
}

/* Return an expression representing static_cast<TYPE>(EXPR).  */

tree
build_static_cast (location_t loc, tree type, tree oexpr,
		   tsubst_flags_t complain)
{
  tree expr = oexpr;
  tree result;
  bool valid_p;

  if (type == error_mark_node || expr == error_mark_node)
    return error_mark_node;

  bool dependent = (dependent_type_p (type)
		    || type_dependent_expression_p (expr));
  if (dependent)
    {
    tmpl:
      expr = build_min (STATIC_CAST_EXPR, type, oexpr);
      /* We don't know if it will or will not have side effects.  */
      TREE_SIDE_EFFECTS (expr) = 1;
      result = convert_from_reference (expr);
      protected_set_expr_location (result, loc);
      return result;
    }
  else if (processing_template_decl)
    expr = build_non_dependent_expr (expr);

  /* build_c_cast puts on a NOP_EXPR to make the result not an lvalue.
     Strip such NOP_EXPRs if VALUE is being used in non-lvalue context.  */
  if (!TYPE_REF_P (type)
      && TREE_CODE (expr) == NOP_EXPR
      && TREE_TYPE (expr) == TREE_TYPE (TREE_OPERAND (expr, 0)))
    expr = TREE_OPERAND (expr, 0);

  result = build_static_cast_1 (loc, type, expr, /*c_cast_p=*/false,
				&valid_p, complain);
  if (valid_p)
    {
      if (result != error_mark_node)
	{
	  maybe_warn_about_useless_cast (loc, type, expr, complain);
	  maybe_warn_about_cast_ignoring_quals (loc, type, complain);
	}
      if (processing_template_decl)
	goto tmpl;
      protected_set_expr_location (result, loc);
      return result;
    }

  if (complain & tf_error)
    {
      error_at (loc, "invalid %<static_cast%> from type %qT to type %qT",
		TREE_TYPE (expr), type);
      if ((TYPE_PTR_P (type) || TYPE_REF_P (type))
	  && CLASS_TYPE_P (TREE_TYPE (type))
	    && !COMPLETE_TYPE_P (TREE_TYPE (type)))
	inform (DECL_SOURCE_LOCATION (TYPE_MAIN_DECL (TREE_TYPE (type))),
		"class type %qT is incomplete", TREE_TYPE (type));
      tree expr_type = TREE_TYPE (expr);
      if (TYPE_PTR_P (expr_type))
	expr_type = TREE_TYPE (expr_type);
      if (CLASS_TYPE_P (expr_type) && !COMPLETE_TYPE_P (expr_type))
	inform (DECL_SOURCE_LOCATION (TYPE_MAIN_DECL (expr_type)),
		"class type %qT is incomplete", expr_type);
    }
  return error_mark_node;
}

/* EXPR is an expression with member function or pointer-to-member
   function type.  TYPE is a pointer type.  Converting EXPR to TYPE is
   not permitted by ISO C++, but we accept it in some modes.  If we
   are not in one of those modes, issue a diagnostic.  Return the
   converted expression.  */

tree
convert_member_func_to_ptr (tree type, tree expr, tsubst_flags_t complain)
{
  tree intype;
  tree decl;

  intype = TREE_TYPE (expr);
  gcc_assert (TYPE_PTRMEMFUNC_P (intype)
	      || TREE_CODE (intype) == METHOD_TYPE);

  if (!(complain & tf_warning_or_error))
    return error_mark_node;

  if (pedantic || warn_pmf2ptr)
    pedwarn (input_location, pedantic ? OPT_Wpedantic : OPT_Wpmf_conversions,
	     "converting from %qH to %qI", intype, type);

  if (TREE_CODE (intype) == METHOD_TYPE)
    expr = build_addr_func (expr, complain);
  else if (TREE_CODE (expr) == PTRMEM_CST)
    expr = build_address (PTRMEM_CST_MEMBER (expr));
  else
    {
      decl = maybe_dummy_object (TYPE_PTRMEM_CLASS_TYPE (intype), 0);
      decl = build_address (decl);
      expr = get_member_function_from_ptrfunc (&decl, expr, complain);
    }

  if (expr == error_mark_node)
    return error_mark_node;

  return build_nop (type, expr);
}

/* Build a NOP_EXPR to TYPE, but mark it as a reinterpret_cast so that
   constexpr evaluation knows to reject it.  */

static tree
build_nop_reinterpret (tree type, tree expr)
{
  tree ret = build_nop (type, expr);
  if (ret != expr)
    REINTERPRET_CAST_P (ret) = true;
  return ret;
}

/* Return a representation for a reinterpret_cast from EXPR to TYPE.
   If C_CAST_P is true, this reinterpret cast is being done as part of
   a C-style cast.  If VALID_P is non-NULL, *VALID_P is set to
   indicate whether or not reinterpret_cast was valid.  */

static tree
build_reinterpret_cast_1 (location_t loc, tree type, tree expr,
			  bool c_cast_p, bool *valid_p,
			  tsubst_flags_t complain)
{
  tree intype;

  /* Assume the cast is invalid.  */
  if (valid_p)
    *valid_p = true;

  if (type == error_mark_node || error_operand_p (expr))
    return error_mark_node;

  intype = TREE_TYPE (expr);

  /* Save casted types in the function's used types hash table.  */
  used_types_insert (type);

  /* A prvalue of non-class type is cv-unqualified.  */
  if (!CLASS_TYPE_P (type))
    type = cv_unqualified (type);

  /* [expr.reinterpret.cast]
     A glvalue of type T1, designating an object x, can be cast to the type
     "reference to T2" if an expression of type "pointer to T1" can be
     explicitly converted to the type "pointer to T2" using a reinterpret_cast.
     The result is that of *reinterpret_cast<T2 *>(p) where p is a pointer to x
     of type "pointer to T1". No temporary is created, no copy is made, and no
     constructors (11.4.4) or conversion functions (11.4.7) are called.  */
  if (TYPE_REF_P (type))
    {
      if (!glvalue_p (expr))
	{
          if (complain & tf_error)
	    error_at (loc, "invalid cast of a prvalue expression of type "
		      "%qT to type %qT",
		      intype, type);
	  return error_mark_node;
	}

      /* Warn about a reinterpret_cast from "A*" to "B&" if "A" and
	 "B" are related class types; the reinterpret_cast does not
	 adjust the pointer.  */
      if (TYPE_PTR_P (intype)
          && (complain & tf_warning)
	  && (comptypes (TREE_TYPE (intype), TREE_TYPE (type),
			 COMPARE_BASE | COMPARE_DERIVED)))
	warning_at (loc, 0, "casting %qT to %qT does not dereference pointer",
		    intype, type);

      expr = cp_build_addr_expr (expr, complain);

      if (warn_strict_aliasing > 2)
	cp_strict_aliasing_warning (EXPR_LOCATION (expr), type, expr);

      if (expr != error_mark_node)
	expr = build_reinterpret_cast_1
	  (loc, build_pointer_type (TREE_TYPE (type)), expr, c_cast_p,
	   valid_p, complain);
      if (expr != error_mark_node)
	/* cp_build_indirect_ref isn't right for rvalue refs.  */
	expr = convert_from_reference (fold_convert (type, expr));
      return expr;
    }

  /* As a G++ extension, we consider conversions from member
     functions, and pointers to member functions to
     pointer-to-function and pointer-to-void types.  If
     -Wno-pmf-conversions has not been specified,
     convert_member_func_to_ptr will issue an error message.  */
  if ((TYPE_PTRMEMFUNC_P (intype)
       || TREE_CODE (intype) == METHOD_TYPE)
      && TYPE_PTR_P (type)
      && (TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE
	  || VOID_TYPE_P (TREE_TYPE (type))))
    return convert_member_func_to_ptr (type, expr, complain);

  /* If the cast is not to a reference type, the lvalue-to-rvalue,
     array-to-pointer, and function-to-pointer conversions are
     performed.  */
  expr = decay_conversion (expr, complain);

  /* build_c_cast puts on a NOP_EXPR to make the result not an lvalue.
     Strip such NOP_EXPRs if VALUE is being used in non-lvalue context.  */
  if (TREE_CODE (expr) == NOP_EXPR
      && TREE_TYPE (expr) == TREE_TYPE (TREE_OPERAND (expr, 0)))
    expr = TREE_OPERAND (expr, 0);

  if (error_operand_p (expr))
    return error_mark_node;

  intype = TREE_TYPE (expr);

  /* [expr.reinterpret.cast]
     A pointer can be converted to any integral type large enough to
     hold it. ... A value of type std::nullptr_t can be converted to
     an integral type; the conversion has the same meaning and
     validity as a conversion of (void*)0 to the integral type.  */
  if (CP_INTEGRAL_TYPE_P (type)
      && (TYPE_PTR_P (intype) || NULLPTR_TYPE_P (intype)))
    {
      if (TYPE_PRECISION (type) < TYPE_PRECISION (intype))
        {
          if (complain & tf_error)
            permerror (loc, "cast from %qH to %qI loses precision",
                       intype, type);
          else
            return error_mark_node;
        }
      if (NULLPTR_TYPE_P (intype))
        return build_int_cst (type, 0);
    }
  /* [expr.reinterpret.cast]
     A value of integral or enumeration type can be explicitly
     converted to a pointer.  */
  else if (TYPE_PTR_P (type) && INTEGRAL_OR_ENUMERATION_TYPE_P (intype))
    /* OK */
    ;
  else if ((INTEGRAL_OR_ENUMERATION_TYPE_P (type)
	    || TYPE_PTR_OR_PTRMEM_P (type))
	   && same_type_p (type, intype))
    /* DR 799 */
    return rvalue (expr);
  else if (TYPE_PTRFN_P (type) && TYPE_PTRFN_P (intype))
    {
      if ((complain & tf_warning)
	  && !cxx_safe_function_type_cast_p (TREE_TYPE (type),
					     TREE_TYPE (intype)))
	warning_at (loc, OPT_Wcast_function_type,
		    "cast between incompatible function types"
		    " from %qH to %qI", intype, type);
      return build_nop_reinterpret (type, expr);
    }
  else if (TYPE_PTRMEMFUNC_P (type) && TYPE_PTRMEMFUNC_P (intype))
    {
      if ((complain & tf_warning)
	  && !cxx_safe_function_type_cast_p
		(TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE_RAW (type)),
		 TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE_RAW (intype))))
	warning_at (loc, OPT_Wcast_function_type,
		    "cast between incompatible pointer to member types"
		    " from %qH to %qI", intype, type);
      return build_nop_reinterpret (type, expr);
    }
  else if ((TYPE_PTRDATAMEM_P (type) && TYPE_PTRDATAMEM_P (intype))
	   || (TYPE_PTROBV_P (type) && TYPE_PTROBV_P (intype)))
    {
      if (!c_cast_p
	  && check_for_casting_away_constness (loc, intype, type,
					       REINTERPRET_CAST_EXPR,
					       complain))
	return error_mark_node;
      /* Warn about possible alignment problems.  */
      if ((STRICT_ALIGNMENT || warn_cast_align == 2)
	  && (complain & tf_warning)
	  && !VOID_TYPE_P (type)
	  && TREE_CODE (TREE_TYPE (intype)) != FUNCTION_TYPE
	  && COMPLETE_TYPE_P (TREE_TYPE (type))
	  && COMPLETE_TYPE_P (TREE_TYPE (intype))
	  && min_align_of_type (TREE_TYPE (type))
	     > min_align_of_type (TREE_TYPE (intype)))
	warning_at (loc, OPT_Wcast_align, "cast from %qH to %qI "
		    "increases required alignment of target type",
		    intype, type);

      if (warn_strict_aliasing <= 2)
	/* strict_aliasing_warning STRIP_NOPs its expr.  */
	cp_strict_aliasing_warning (EXPR_LOCATION (expr), type, expr);

      return build_nop_reinterpret (type, expr);
    }
  else if ((TYPE_PTRFN_P (type) && TYPE_PTROBV_P (intype))
	   || (TYPE_PTRFN_P (intype) && TYPE_PTROBV_P (type)))
    {
      if (complain & tf_warning)
	/* C++11 5.2.10 p8 says that "Converting a function pointer to an
	   object pointer type or vice versa is conditionally-supported."  */
	warning_at (loc, OPT_Wconditionally_supported,
		    "casting between pointer-to-function and "
		    "pointer-to-object is conditionally-supported");
      return build_nop_reinterpret (type, expr);
    }
  else if (gnu_vector_type_p (type) && scalarish_type_p (intype))
    return convert_to_vector (type, rvalue (expr));
  else if (gnu_vector_type_p (intype)
	   && INTEGRAL_OR_ENUMERATION_TYPE_P (type))
    return convert_to_integer_nofold (type, expr);
  else
    {
      if (valid_p)
	*valid_p = false;
      if (complain & tf_error)
        error_at (loc, "invalid cast from type %qT to type %qT",
		  intype, type);
      return error_mark_node;
    }

  expr = cp_convert (type, expr, complain);
  if (TREE_CODE (expr) == NOP_EXPR)
    /* Mark any nop_expr that created as a reintepret_cast.  */
    REINTERPRET_CAST_P (expr) = true;
  return expr;
}

tree
build_reinterpret_cast (location_t loc, tree type, tree expr,
			tsubst_flags_t complain)
{
  tree r;

  if (type == error_mark_node || expr == error_mark_node)
    return error_mark_node;

  if (processing_template_decl)
    {
      tree t = build_min (REINTERPRET_CAST_EXPR, type, expr);

      if (!TREE_SIDE_EFFECTS (t)
	  && type_dependent_expression_p (expr))
	/* There might turn out to be side effects inside expr.  */
	TREE_SIDE_EFFECTS (t) = 1;
      r = convert_from_reference (t);
      protected_set_expr_location (r, loc);
      return r;
    }

  r = build_reinterpret_cast_1 (loc, type, expr, /*c_cast_p=*/false,
				/*valid_p=*/NULL, complain);
  if (r != error_mark_node)
    {
      maybe_warn_about_useless_cast (loc, type, expr, complain);
      maybe_warn_about_cast_ignoring_quals (loc, type, complain);
    }
  protected_set_expr_location (r, loc);
  return r;
}

/* Perform a const_cast from EXPR to TYPE.  If the cast is valid,
   return an appropriate expression.  Otherwise, return
   error_mark_node.  If the cast is not valid, and COMPLAIN is true,
   then a diagnostic will be issued.  If VALID_P is non-NULL, we are
   performing a C-style cast, its value upon return will indicate
   whether or not the conversion succeeded.  */

static tree
build_const_cast_1 (location_t loc, tree dst_type, tree expr,
		    tsubst_flags_t complain, bool *valid_p)
{
  tree src_type;
  tree reference_type;

  /* Callers are responsible for handling error_mark_node as a
     destination type.  */
  gcc_assert (dst_type != error_mark_node);
  /* In a template, callers should be building syntactic
     representations of casts, not using this machinery.  */
  gcc_assert (!processing_template_decl);

  /* Assume the conversion is invalid.  */
  if (valid_p)
    *valid_p = false;

  if (!INDIRECT_TYPE_P (dst_type) && !TYPE_PTRDATAMEM_P (dst_type))
    {
      if (complain & tf_error)
	error_at (loc, "invalid use of %<const_cast%> with type %qT, "
		  "which is not a pointer, reference, "
		  "nor a pointer-to-data-member type", dst_type);
      return error_mark_node;
    }

  if (TREE_CODE (TREE_TYPE (dst_type)) == FUNCTION_TYPE)
    {
      if (complain & tf_error)
	error_at (loc, "invalid use of %<const_cast%> with type %qT, "
		  "which is a pointer or reference to a function type",
		  dst_type);
       return error_mark_node;
    }

  /* A prvalue of non-class type is cv-unqualified.  */
  dst_type = cv_unqualified (dst_type);

  /* Save casted types in the function's used types hash table.  */
  used_types_insert (dst_type);

  src_type = TREE_TYPE (expr);
  /* Expressions do not really have reference types.  */
  if (TYPE_REF_P (src_type))
    src_type = TREE_TYPE (src_type);

  /* [expr.const.cast]

     For two object types T1 and T2, if a pointer to T1 can be explicitly
     converted to the type "pointer to T2" using a const_cast, then the
     following conversions can also be made:

     -- an lvalue of type T1 can be explicitly converted to an lvalue of
     type T2 using the cast const_cast<T2&>;

     -- a glvalue of type T1 can be explicitly converted to an xvalue of
     type T2 using the cast const_cast<T2&&>; and

     -- if T1 is a class type, a prvalue of type T1 can be explicitly
     converted to an xvalue of type T2 using the cast const_cast<T2&&>.  */

  if (TYPE_REF_P (dst_type))
    {
      reference_type = dst_type;
      if (!TYPE_REF_IS_RVALUE (dst_type)
	  ? lvalue_p (expr)
	  : obvalue_p (expr))
	/* OK.  */;
      else
	{
	  if (complain & tf_error)
	    error_at (loc, "invalid %<const_cast%> of an rvalue of type %qT "
		      "to type %qT",
		      src_type, dst_type);
 	  return error_mark_node;
	}
      dst_type = build_pointer_type (TREE_TYPE (dst_type));
      src_type = build_pointer_type (src_type);
    }
  else
    {
      reference_type = NULL_TREE;
      /* If the destination type is not a reference type, the
	 lvalue-to-rvalue, array-to-pointer, and function-to-pointer
	 conversions are performed.  */
      src_type = type_decays_to (src_type);
      if (src_type == error_mark_node)
	return error_mark_node;
    }

  if (TYPE_PTR_P (src_type) || TYPE_PTRDATAMEM_P (src_type))
    {
      if (comp_ptr_ttypes_const (dst_type, src_type, bounds_none))
	{
	  if (valid_p)
	    {
	      *valid_p = true;
	      /* This cast is actually a C-style cast.  Issue a warning if
		 the user is making a potentially unsafe cast.  */
	      check_for_casting_away_constness (loc, src_type, dst_type,
						CAST_EXPR, complain);
	      /* ??? comp_ptr_ttypes_const ignores TYPE_ALIGN.  */
	      if ((STRICT_ALIGNMENT || warn_cast_align == 2)
		  && (complain & tf_warning)
		  && min_align_of_type (TREE_TYPE (dst_type))
		     > min_align_of_type (TREE_TYPE (src_type)))
		warning_at (loc, OPT_Wcast_align, "cast from %qH to %qI "
			    "increases required alignment of target type",
			    src_type, dst_type);
	    }
	  if (reference_type)
	    {
	      expr = cp_build_addr_expr (expr, complain);
	      if (expr == error_mark_node)
		return error_mark_node;
	      expr = build_nop (reference_type, expr);
	      return convert_from_reference (expr);
	    }
	  else
	    {
	      expr = decay_conversion (expr, complain);
	      if (expr == error_mark_node)
		return error_mark_node;

	      /* build_c_cast puts on a NOP_EXPR to make the result not an
		 lvalue.  Strip such NOP_EXPRs if VALUE is being used in
		 non-lvalue context.  */
	      if (TREE_CODE (expr) == NOP_EXPR
		  && TREE_TYPE (expr) == TREE_TYPE (TREE_OPERAND (expr, 0)))
		expr = TREE_OPERAND (expr, 0);
	      return build_nop (dst_type, expr);
	    }
	}
      else if (valid_p
	       && !at_least_as_qualified_p (TREE_TYPE (dst_type),
					    TREE_TYPE (src_type)))
	check_for_casting_away_constness (loc, src_type, dst_type,
					  CAST_EXPR, complain);
    }

  if (complain & tf_error)
    error_at (loc, "invalid %<const_cast%> from type %qT to type %qT",
	      src_type, dst_type);
  return error_mark_node;
}

tree
build_const_cast (location_t loc, tree type, tree expr,
		  tsubst_flags_t complain)
{
  tree r;

  if (type == error_mark_node || error_operand_p (expr))
    return error_mark_node;

  if (processing_template_decl)
    {
      tree t = build_min (CONST_CAST_EXPR, type, expr);

      if (!TREE_SIDE_EFFECTS (t)
	  && type_dependent_expression_p (expr))
	/* There might turn out to be side effects inside expr.  */
	TREE_SIDE_EFFECTS (t) = 1;
      r = convert_from_reference (t);
      protected_set_expr_location (r, loc);
      return r;
    }

  r = build_const_cast_1 (loc, type, expr, complain, /*valid_p=*/NULL);
  if (r != error_mark_node)
    {
      maybe_warn_about_useless_cast (loc, type, expr, complain);
      maybe_warn_about_cast_ignoring_quals (loc, type, complain);
    }
  protected_set_expr_location (r, loc);
  return r;
}

/* Like cp_build_c_cast, but for the c-common bits.  */

tree
build_c_cast (location_t loc, tree type, tree expr)
{
  return cp_build_c_cast (loc, type, expr, tf_warning_or_error);
}

/* Like the "build_c_cast" used for c-common, but using cp_expr to
   preserve location information even for tree nodes that don't
   support it.  */

cp_expr
build_c_cast (location_t loc, tree type, cp_expr expr)
{
  cp_expr result = cp_build_c_cast (loc, type, expr, tf_warning_or_error);
  result.set_location (loc);
  return result;
}

/* Build an expression representing an explicit C-style cast to type
   TYPE of expression EXPR.  */

tree
cp_build_c_cast (location_t loc, tree type, tree expr,
		 tsubst_flags_t complain)
{
  tree value = expr;
  tree result;
  bool valid_p;

  if (type == error_mark_node || error_operand_p (expr))
    return error_mark_node;

  if (processing_template_decl)
    {
      tree t = build_min (CAST_EXPR, type,
			  tree_cons (NULL_TREE, value, NULL_TREE));
      /* We don't know if it will or will not have side effects.  */
      TREE_SIDE_EFFECTS (t) = 1;
      return convert_from_reference (t);
    }

  /* Casts to a (pointer to a) specific ObjC class (or 'id' or
     'Class') should always be retained, because this information aids
     in method lookup.  */
  if (objc_is_object_ptr (type)
      && objc_is_object_ptr (TREE_TYPE (expr)))
    return build_nop (type, expr);

  /* build_c_cast puts on a NOP_EXPR to make the result not an lvalue.
     Strip such NOP_EXPRs if VALUE is being used in non-lvalue context.  */
  if (!TYPE_REF_P (type)
      && TREE_CODE (value) == NOP_EXPR
      && TREE_TYPE (value) == TREE_TYPE (TREE_OPERAND (value, 0)))
    value = TREE_OPERAND (value, 0);

  if (TREE_CODE (type) == ARRAY_TYPE)
    {
      /* Allow casting from T1* to T2[] because Cfront allows it.
	 NIHCL uses it. It is not valid ISO C++ however.  */
      if (TYPE_PTR_P (TREE_TYPE (expr)))
	{
          if (complain & tf_error)
            permerror (loc, "ISO C++ forbids casting to an array type %qT",
		       type);
          else
            return error_mark_node;
	  type = build_pointer_type (TREE_TYPE (type));
	}
      else
	{
          if (complain & tf_error)
            error_at (loc, "ISO C++ forbids casting to an array type %qT",
		      type);
	  return error_mark_node;
	}
    }

  if (FUNC_OR_METHOD_TYPE_P (type))
    {
      if (complain & tf_error)
        error_at (loc, "invalid cast to function type %qT", type);
      return error_mark_node;
    }

  if (TYPE_PTR_P (type)
      && TREE_CODE (TREE_TYPE (value)) == INTEGER_TYPE
      /* Casting to an integer of smaller size is an error detected elsewhere.  */
      && TYPE_PRECISION (type) > TYPE_PRECISION (TREE_TYPE (value))
      /* Don't warn about converting any constant.  */
      && !TREE_CONSTANT (value))
    warning_at (loc, OPT_Wint_to_pointer_cast, 
		"cast to pointer from integer of different size");

  /* A C-style cast can be a const_cast.  */
  result = build_const_cast_1 (loc, type, value, complain & tf_warning,
			       &valid_p);
  if (valid_p)
    {
      if (result != error_mark_node)
	{
	  maybe_warn_about_useless_cast (loc, type, value, complain);
	  maybe_warn_about_cast_ignoring_quals (loc, type, complain);
	}
      return result;
    }

  /* Or a static cast.  */
  result = build_static_cast_1 (loc, type, value, /*c_cast_p=*/true,
				&valid_p, complain);
  /* Or a reinterpret_cast.  */
  if (!valid_p)
    result = build_reinterpret_cast_1 (loc, type, value, /*c_cast_p=*/true,
				       &valid_p, complain);
  /* The static_cast or reinterpret_cast may be followed by a
     const_cast.  */
  if (valid_p
      /* A valid cast may result in errors if, for example, a
	 conversion to an ambiguous base class is required.  */
      && !error_operand_p (result))
    {
      tree result_type;

      maybe_warn_about_useless_cast (loc, type, value, complain);
      maybe_warn_about_cast_ignoring_quals (loc, type, complain);

      /* Non-class rvalues always have cv-unqualified type.  */
      if (!CLASS_TYPE_P (type))
	type = TYPE_MAIN_VARIANT (type);
      result_type = TREE_TYPE (result);
      if (!CLASS_TYPE_P (result_type) && !TYPE_REF_P (type))
	result_type = TYPE_MAIN_VARIANT (result_type);
      /* If the type of RESULT does not match TYPE, perform a
	 const_cast to make it match.  If the static_cast or
	 reinterpret_cast succeeded, we will differ by at most
	 cv-qualification, so the follow-on const_cast is guaranteed
	 to succeed.  */
      if (!same_type_p (non_reference (type), non_reference (result_type)))
	{
	  result = build_const_cast_1 (loc, type, result, false, &valid_p);
	  gcc_assert (valid_p);
	}
      return result;
    }

  return error_mark_node;
}

/* For use from the C common bits.  */
tree
build_modify_expr (location_t location,
		   tree lhs, tree /*lhs_origtype*/,
		   enum tree_code modifycode, 
		   location_t /*rhs_location*/, tree rhs,
		   tree /*rhs_origtype*/)
{
  return cp_build_modify_expr (location, lhs, modifycode, rhs,
			       tf_warning_or_error);
}

/* Build an assignment expression of lvalue LHS from value RHS.
   MODIFYCODE is the code for a binary operator that we use
   to combine the old value of LHS with RHS to get the new value.
   Or else MODIFYCODE is NOP_EXPR meaning do a simple assignment.

   C++: If MODIFYCODE is INIT_EXPR, then leave references unbashed.  */

tree
cp_build_modify_expr (location_t loc, tree lhs, enum tree_code modifycode,
		      tree rhs, tsubst_flags_t complain)
{
  lhs = mark_lvalue_use_nonread (lhs);

  tree result = NULL_TREE;
  tree newrhs = rhs;
  tree lhstype = TREE_TYPE (lhs);
  tree olhs = lhs;
  tree olhstype = lhstype;
  bool plain_assign = (modifycode == NOP_EXPR);
  bool compound_side_effects_p = false;
  tree preeval = NULL_TREE;

  /* Avoid duplicate error messages from operands that had errors.  */
  if (error_operand_p (lhs) || error_operand_p (rhs))
    return error_mark_node;

  while (TREE_CODE (lhs) == COMPOUND_EXPR)
    {
      if (TREE_SIDE_EFFECTS (TREE_OPERAND (lhs, 0)))
	compound_side_effects_p = true;
      lhs = TREE_OPERAND (lhs, 1);
    }

  /* Handle control structure constructs used as "lvalues".  Note that we
     leave COMPOUND_EXPR on the LHS because it is sequenced after the RHS.  */
  switch (TREE_CODE (lhs))
    {
      /* Handle --foo = 5; as these are valid constructs in C++.  */
    case PREDECREMENT_EXPR:
    case PREINCREMENT_EXPR:
      if (compound_side_effects_p)
	newrhs = rhs = stabilize_expr (rhs, &preeval);
      lhs = genericize_compound_lvalue (lhs);
    maybe_add_compound:
      /* If we had (bar, --foo) = 5; or (bar, (baz, --foo)) = 5;
	 and looked through the COMPOUND_EXPRs, readd them now around
	 the resulting lhs.  */
      if (TREE_CODE (olhs) == COMPOUND_EXPR)
	{
	  lhs = build2 (COMPOUND_EXPR, lhstype, TREE_OPERAND (olhs, 0), lhs);
	  tree *ptr = &TREE_OPERAND (lhs, 1);
	  for (olhs = TREE_OPERAND (olhs, 1);
	       TREE_CODE (olhs) == COMPOUND_EXPR;
	       olhs = TREE_OPERAND (olhs, 1))
	    {
	      *ptr = build2 (COMPOUND_EXPR, lhstype,
			     TREE_OPERAND (olhs, 0), *ptr);
	      ptr = &TREE_OPERAND (*ptr, 1);
	    }
	}
      break;

    case MODIFY_EXPR:
      if (compound_side_effects_p)
	newrhs = rhs = stabilize_expr (rhs, &preeval);
      lhs = genericize_compound_lvalue (lhs);
      goto maybe_add_compound;

    case MIN_EXPR:
    case MAX_EXPR:
      /* MIN_EXPR and MAX_EXPR are currently only permitted as lvalues,
	 when neither operand has side-effects.  */
      if (!lvalue_or_else (lhs, lv_assign, complain))
	return error_mark_node;

      gcc_assert (!TREE_SIDE_EFFECTS (TREE_OPERAND (lhs, 0))
		  && !TREE_SIDE_EFFECTS (TREE_OPERAND (lhs, 1)));

      lhs = build3 (COND_EXPR, TREE_TYPE (lhs),
		    build2 (TREE_CODE (lhs) == MIN_EXPR ? LE_EXPR : GE_EXPR,
			    boolean_type_node,
			    TREE_OPERAND (lhs, 0),
			    TREE_OPERAND (lhs, 1)),
		    TREE_OPERAND (lhs, 0),
		    TREE_OPERAND (lhs, 1));
      gcc_fallthrough ();

      /* Handle (a ? b : c) used as an "lvalue".  */
    case COND_EXPR:
      {
	/* Produce (a ? (b = rhs) : (c = rhs))
	   except that the RHS goes through a save-expr
	   so the code to compute it is only emitted once.  */
	if (VOID_TYPE_P (TREE_TYPE (rhs)))
	  {
	    if (complain & tf_error)
	      error_at (cp_expr_loc_or_loc (rhs, loc),
			"void value not ignored as it ought to be");
	    return error_mark_node;
	  }

	rhs = stabilize_expr (rhs, &preeval);

	/* Check this here to avoid odd errors when trying to convert
	   a throw to the type of the COND_EXPR.  */
	if (!lvalue_or_else (lhs, lv_assign, complain))
	  return error_mark_node;

	tree op1 = TREE_OPERAND (lhs, 1);
	if (TREE_CODE (op1) != THROW_EXPR)
	  op1 = cp_build_modify_expr (loc, op1, modifycode, rhs, complain);
	/* When sanitizing undefined behavior, even when rhs doesn't need
	   stabilization at this point, the sanitization might add extra
	   SAVE_EXPRs in there and so make sure there is no tree sharing
	   in the rhs, otherwise those SAVE_EXPRs will have initialization
	   only in one of the two branches.  */
	if (sanitize_flags_p (SANITIZE_UNDEFINED
			      | SANITIZE_UNDEFINED_NONDEFAULT))
	  rhs = unshare_expr (rhs);
	tree op2 = TREE_OPERAND (lhs, 2);
	if (TREE_CODE (op2) != THROW_EXPR)
	  op2 = cp_build_modify_expr (loc, op2, modifycode, rhs, complain);
	tree cond = build_conditional_expr (input_location,
					    TREE_OPERAND (lhs, 0), op1, op2,
					    complain);

	if (cond == error_mark_node)
	  return cond;
	/* If we had (e, (a ? b : c)) = d; or (e, (f, (a ? b : c))) = d;
	   and looked through the COMPOUND_EXPRs, readd them now around
	   the resulting cond before adding the preevaluated rhs.  */
	if (TREE_CODE (olhs) == COMPOUND_EXPR)
	  {
	    cond = build2 (COMPOUND_EXPR, TREE_TYPE (cond),
			   TREE_OPERAND (olhs, 0), cond);
	    tree *ptr = &TREE_OPERAND (cond, 1);
	    for (olhs = TREE_OPERAND (olhs, 1);
		 TREE_CODE (olhs) == COMPOUND_EXPR;
		 olhs = TREE_OPERAND (olhs, 1))
	      {
		*ptr = build2 (COMPOUND_EXPR, TREE_TYPE (cond),
			       TREE_OPERAND (olhs, 0), *ptr);
		ptr = &TREE_OPERAND (*ptr, 1);
	      }
	  }
	/* Make sure the code to compute the rhs comes out
	   before the split.  */
	result = cond;
	goto ret;
      }

    default:
      lhs = olhs;
      break;
    }

  if (modifycode == INIT_EXPR)
    {
      if (BRACE_ENCLOSED_INITIALIZER_P (rhs))
	/* Do the default thing.  */;
      else if (TREE_CODE (rhs) == CONSTRUCTOR)
	{
	  /* Compound literal.  */
	  if (! same_type_p (TREE_TYPE (rhs), lhstype))
	    /* Call convert to generate an error; see PR 11063.  */
	    rhs = convert (lhstype, rhs);
	  result = build2 (INIT_EXPR, lhstype, lhs, rhs);
	  TREE_SIDE_EFFECTS (result) = 1;
	  goto ret;
	}
      else if (! MAYBE_CLASS_TYPE_P (lhstype))
	/* Do the default thing.  */;
      else
	{
	  releasing_vec rhs_vec = make_tree_vector_single (rhs);
	  result = build_special_member_call (lhs, complete_ctor_identifier,
					      &rhs_vec, lhstype, LOOKUP_NORMAL,
                                              complain);
	  if (result == NULL_TREE)
	    return error_mark_node;
	  goto ret;
	}
    }
  else
    {
      lhs = require_complete_type_sfinae (lhs, complain);
      if (lhs == error_mark_node)
	return error_mark_node;

      if (modifycode == NOP_EXPR)
	{
	  if (c_dialect_objc ())
	    {
	      result = objc_maybe_build_modify_expr (lhs, rhs);
	      if (result)
		goto ret;
	    }

	  /* `operator=' is not an inheritable operator.  */
	  if (! MAYBE_CLASS_TYPE_P (lhstype))
	    /* Do the default thing.  */;
	  else
	    {
	      result = build_new_op (input_location, MODIFY_EXPR,
				     LOOKUP_NORMAL, lhs, rhs,
				     make_node (NOP_EXPR), /*overload=*/NULL,
				     complain);
	      if (result == NULL_TREE)
		return error_mark_node;
	      goto ret;
	    }
	  lhstype = olhstype;
	}
      else
	{
	  tree init = NULL_TREE;

	  /* A binary op has been requested.  Combine the old LHS
	     value with the RHS producing the value we should actually
	     store into the LHS.  */
	  gcc_assert (!((TYPE_REF_P (lhstype)
			 && MAYBE_CLASS_TYPE_P (TREE_TYPE (lhstype)))
			|| MAYBE_CLASS_TYPE_P (lhstype)));

	  /* An expression of the form E1 op= E2.  [expr.ass] says:
	     "Such expressions are deprecated if E1 has volatile-qualified
	     type."  We warn here rather than in cp_genericize_r because
	     for compound assignments we are supposed to warn even if the
	     assignment is a discarded-value expression.  */
	  if (TREE_THIS_VOLATILE (lhs) || CP_TYPE_VOLATILE_P (lhstype))
	    warning_at (loc, OPT_Wvolatile,
			"compound assignment with %<volatile%>-qualified left "
			"operand is deprecated");
	  /* Preevaluate the RHS to make sure its evaluation is complete
	     before the lvalue-to-rvalue conversion of the LHS:

	     [expr.ass] With respect to an indeterminately-sequenced
	     function call, the operation of a compound assignment is a
	     single evaluation. [ Note: Therefore, a function call shall
	     not intervene between the lvalue-to-rvalue conversion and the
	     side effect associated with any single compound assignment
	     operator. -- end note ]  */
	  lhs = cp_stabilize_reference (lhs);
	  rhs = decay_conversion (rhs, complain);
	  if (rhs == error_mark_node)
	    return error_mark_node;
	  rhs = stabilize_expr (rhs, &init);
	  newrhs = cp_build_binary_op (loc, modifycode, lhs, rhs, complain);
	  if (newrhs == error_mark_node)
	    {
	      if (complain & tf_error)
		inform (loc, "  in evaluation of %<%Q(%#T, %#T)%>",
			modifycode, TREE_TYPE (lhs), TREE_TYPE (rhs));
	      return error_mark_node;
	    }

	  if (init)
	    newrhs = build2 (COMPOUND_EXPR, TREE_TYPE (newrhs), init, newrhs);

	  /* Now it looks like a plain assignment.  */
	  modifycode = NOP_EXPR;
	  if (c_dialect_objc ())
	    {
	      result = objc_maybe_build_modify_expr (lhs, newrhs);
	      if (result)
		goto ret;
	    }
	}
      gcc_assert (!TYPE_REF_P (lhstype));
      gcc_assert (!TYPE_REF_P (TREE_TYPE (newrhs)));
    }

  /* The left-hand side must be an lvalue.  */
  if (!lvalue_or_else (lhs, lv_assign, complain))
    return error_mark_node;

  /* Warn about modifying something that is `const'.  Don't warn if
     this is initialization.  */
  if (modifycode != INIT_EXPR
      && (TREE_READONLY (lhs) || CP_TYPE_CONST_P (lhstype)
	  /* Functions are not modifiable, even though they are
	     lvalues.  */
	  || FUNC_OR_METHOD_TYPE_P (TREE_TYPE (lhs))
	  /* If it's an aggregate and any field is const, then it is
	     effectively const.  */
	  || (CLASS_TYPE_P (lhstype)
	      && C_TYPE_FIELDS_READONLY (lhstype))))
    {
      if (complain & tf_error)
	cxx_readonly_error (loc, lhs, lv_assign);
      return error_mark_node;
    }

  /* If storing into a structure or union member, it may have been given a
     lowered bitfield type.  We need to convert to the declared type first,
     so retrieve it now.  */

  olhstype = unlowered_expr_type (lhs);

  /* Convert new value to destination type.  */

  if (TREE_CODE (lhstype) == ARRAY_TYPE)
    {
      int from_array;

      if (BRACE_ENCLOSED_INITIALIZER_P (newrhs))
	{
	  if (modifycode != INIT_EXPR)
	    {
	      if (complain & tf_error)
		error_at (loc,
			  "assigning to an array from an initializer list");
	      return error_mark_node;
	    }
	  if (check_array_initializer (lhs, lhstype, newrhs))
	    return error_mark_node;
	  newrhs = digest_init (lhstype, newrhs, complain);
	  if (newrhs == error_mark_node)
	    return error_mark_node;
	}

      /* C++11 8.5/17: "If the destination type is an array of characters,
	 an array of char16_t, an array of char32_t, or an array of wchar_t,
	 and the initializer is a string literal...".  */
      else if ((TREE_CODE (tree_strip_any_location_wrapper (newrhs))
		== STRING_CST)
	       && char_type_p (TREE_TYPE (TYPE_MAIN_VARIANT (lhstype)))
	       && modifycode == INIT_EXPR)
	{
	  newrhs = digest_init (lhstype, newrhs, complain);
	  if (newrhs == error_mark_node)
	    return error_mark_node;
	}

      else if (!same_or_base_type_p (TYPE_MAIN_VARIANT (lhstype),
				     TYPE_MAIN_VARIANT (TREE_TYPE (newrhs))))
	{
	  if (complain & tf_error)
	    error_at (loc, "incompatible types in assignment of %qT to %qT",
		      TREE_TYPE (rhs), lhstype);
	  return error_mark_node;
	}

      /* Allow array assignment in compiler-generated code.  */
      else if (!current_function_decl
	       || !DECL_DEFAULTED_FN (current_function_decl))
	{
          /* This routine is used for both initialization and assignment.
             Make sure the diagnostic message differentiates the context.  */
	  if (complain & tf_error)
	    {
	      if (modifycode == INIT_EXPR)
		error_at (loc, "array used as initializer");
	      else
		error_at (loc, "invalid array assignment");
	    }
	  return error_mark_node;
	}

      from_array = TREE_CODE (TREE_TYPE (newrhs)) == ARRAY_TYPE
		   ? 1 + (modifycode != INIT_EXPR): 0;
      result = build_vec_init (lhs, NULL_TREE, newrhs,
			       /*explicit_value_init_p=*/false,
			       from_array, complain);
      goto ret;
    }

  if (modifycode == INIT_EXPR)
    /* Calls with INIT_EXPR are all direct-initialization, so don't set
       LOOKUP_ONLYCONVERTING.  */
    newrhs = convert_for_initialization (lhs, olhstype, newrhs, LOOKUP_NORMAL,
					 ICR_INIT, NULL_TREE, 0,
					 complain | tf_no_cleanup);
  else
    newrhs = convert_for_assignment (olhstype, newrhs, ICR_ASSIGN,
				     NULL_TREE, 0, complain, LOOKUP_IMPLICIT);

  if (!same_type_p (lhstype, olhstype))
    newrhs = cp_convert_and_check (lhstype, newrhs, complain);

  if (modifycode != INIT_EXPR)
    {
      if (TREE_CODE (newrhs) == CALL_EXPR
	  && TYPE_NEEDS_CONSTRUCTING (lhstype))
	newrhs = build_cplus_new (lhstype, newrhs, complain);

      /* Can't initialize directly from a TARGET_EXPR, since that would
	 cause the lhs to be constructed twice, and possibly result in
	 accidental self-initialization.  So we force the TARGET_EXPR to be
	 expanded without a target.  */
      if (TREE_CODE (newrhs) == TARGET_EXPR)
	newrhs = build2 (COMPOUND_EXPR, TREE_TYPE (newrhs), newrhs,
			 TREE_OPERAND (newrhs, 0));
    }

  if (newrhs == error_mark_node)
    return error_mark_node;

  if (c_dialect_objc () && flag_objc_gc)
    {
      result = objc_generate_write_barrier (lhs, modifycode, newrhs);

      if (result)
	goto ret;
    }

  result = build2_loc (loc, modifycode == NOP_EXPR ? MODIFY_EXPR : INIT_EXPR,
		       lhstype, lhs, newrhs);

  TREE_SIDE_EFFECTS (result) = 1;
  if (!plain_assign)
    suppress_warning (result, OPT_Wparentheses);

 ret:
  if (preeval)
    result = build2 (COMPOUND_EXPR, TREE_TYPE (result), preeval, result);
  return result;
}

cp_expr
build_x_modify_expr (location_t loc, tree lhs, enum tree_code modifycode,
		     tree rhs, tsubst_flags_t complain)
{
  tree orig_lhs = lhs;
  tree orig_rhs = rhs;
  tree overload = NULL_TREE;

  if (lhs == error_mark_node || rhs == error_mark_node)
    return cp_expr (error_mark_node, loc);

  if (processing_template_decl)
    {
      if (modifycode == NOP_EXPR
	  || type_dependent_expression_p (lhs)
	  || type_dependent_expression_p (rhs))
	{
	  tree op = build_min_nt_loc (loc, modifycode, NULL_TREE, NULL_TREE);
	  tree rval = build_min_nt_loc (loc, MODOP_EXPR, lhs, op, rhs);
	  maybe_save_operator_binding (rval);
	  return rval;
	}

      lhs = build_non_dependent_expr (lhs);
      rhs = build_non_dependent_expr (rhs);
    }

  if (modifycode != NOP_EXPR)
    {
      tree op = build_nt (modifycode, NULL_TREE, NULL_TREE);
      tree rval = build_new_op (loc, MODIFY_EXPR, LOOKUP_NORMAL,
				lhs, rhs, op, &overload, complain);
      if (rval)
	{
	  if (rval == error_mark_node)
	    return rval;
	  suppress_warning (rval /* What warning? */);
	  if (processing_template_decl)
	    {
	      if (overload != NULL_TREE)
		return (build_min_non_dep_op_overload
			(MODIFY_EXPR, rval, overload, orig_lhs, orig_rhs));

	      return (build_min_non_dep
		      (MODOP_EXPR, rval, orig_lhs, op, orig_rhs));
	    }
	  return rval;
	}
    }
  return cp_build_modify_expr (loc, lhs, modifycode, rhs, complain);
}

/* Helper function for get_delta_difference which assumes FROM is a base
   class of TO.  Returns a delta for the conversion of pointer-to-member
   of FROM to pointer-to-member of TO.  If the conversion is invalid and 
   tf_error is not set in COMPLAIN returns error_mark_node, otherwise
   returns zero.  If FROM is not a base class of TO, returns NULL_TREE.
   If C_CAST_P is true, this conversion is taking place as part of a 
   C-style cast.  */

static tree
get_delta_difference_1 (tree from, tree to, bool c_cast_p,
			tsubst_flags_t complain)
{
  tree binfo;
  base_kind kind;

  binfo = lookup_base (to, from, c_cast_p ? ba_unique : ba_check,
		       &kind, complain);

  if (binfo == error_mark_node)
    {
      if (!(complain & tf_error))
	return error_mark_node;

      inform (input_location, "   in pointer to member function conversion");
      return size_zero_node;
    }
  else if (binfo)
    {
      if (kind != bk_via_virtual)
	return BINFO_OFFSET (binfo);
      else
	/* FROM is a virtual base class of TO.  Issue an error or warning
	   depending on whether or not this is a reinterpret cast.  */
	{
	  if (!(complain & tf_error))
	    return error_mark_node;

	  error ("pointer to member conversion via virtual base %qT",
		 BINFO_TYPE (binfo_from_vbase (binfo)));

	  return size_zero_node;
	}
      }
  else
    return NULL_TREE;
}

/* Get difference in deltas for different pointer to member function
   types.  If the conversion is invalid and tf_error is not set in
   COMPLAIN, returns error_mark_node, otherwise returns an integer
   constant of type PTRDIFF_TYPE_NODE and its value is zero if the
   conversion is invalid.  If ALLOW_INVERSE_P is true, then allow reverse
   conversions as well.  If C_CAST_P is true this conversion is taking
   place as part of a C-style cast.

   Note that the naming of FROM and TO is kind of backwards; the return
   value is what we add to a TO in order to get a FROM.  They are named
   this way because we call this function to find out how to convert from
   a pointer to member of FROM to a pointer to member of TO.  */

static tree
get_delta_difference (tree from, tree to,
		      bool allow_inverse_p,
		      bool c_cast_p, tsubst_flags_t complain)
{
  tree result;

  if (same_type_ignoring_top_level_qualifiers_p (from, to))
    /* Pointer to member of incomplete class is permitted*/
    result = size_zero_node;
  else
    result = get_delta_difference_1 (from, to, c_cast_p, complain);

  if (result == error_mark_node)
    return error_mark_node;

  if (!result)
  {
    if (!allow_inverse_p)
      {
	if (!(complain & tf_error))
	  return error_mark_node;

	error_not_base_type (from, to);
	inform (input_location, "   in pointer to member conversion");
      	result = size_zero_node;
      }
    else
      {
	result = get_delta_difference_1 (to, from, c_cast_p, complain);

	if (result == error_mark_node)
	  return error_mark_node;

	if (result)
	  result = size_diffop_loc (input_location,
				    size_zero_node, result);
	else
	  {
	    if (!(complain & tf_error))
	      return error_mark_node;

	    error_not_base_type (from, to);
	    inform (input_location, "   in pointer to member conversion");
	    result = size_zero_node;
	  }
      }
  }

  return convert_to_integer (ptrdiff_type_node, result);
}

/* Return a constructor for the pointer-to-member-function TYPE using
   the other components as specified.  */

tree
build_ptrmemfunc1 (tree type, tree delta, tree pfn)
{
  tree u = NULL_TREE;
  tree delta_field;
  tree pfn_field;
  vec<constructor_elt, va_gc> *v;

  /* Pull the FIELD_DECLs out of the type.  */
  pfn_field = TYPE_FIELDS (type);
  delta_field = DECL_CHAIN (pfn_field);

  /* Make sure DELTA has the type we want.  */
  delta = convert_and_check (input_location, delta_type_node, delta);

  /* Convert to the correct target type if necessary.  */
  pfn = fold_convert (TREE_TYPE (pfn_field), pfn);

  /* Finish creating the initializer.  */
  vec_alloc (v, 2);
  CONSTRUCTOR_APPEND_ELT(v, pfn_field, pfn);
  CONSTRUCTOR_APPEND_ELT(v, delta_field, delta);
  u = build_constructor (type, v);
  TREE_CONSTANT (u) = TREE_CONSTANT (pfn) & TREE_CONSTANT (delta);
  TREE_STATIC (u) = (TREE_CONSTANT (u)
		     && (initializer_constant_valid_p (pfn, TREE_TYPE (pfn))
			 != NULL_TREE)
		     && (initializer_constant_valid_p (delta, TREE_TYPE (delta))
			 != NULL_TREE));
  return u;
}

/* Build a constructor for a pointer to member function.  It can be
   used to initialize global variables, local variable, or used
   as a value in expressions.  TYPE is the POINTER to METHOD_TYPE we
   want to be.

   If FORCE is nonzero, then force this conversion, even if
   we would rather not do it.  Usually set when using an explicit
   cast.  A C-style cast is being processed iff C_CAST_P is true.

   Return error_mark_node, if something goes wrong.  */

tree
build_ptrmemfunc (tree type, tree pfn, int force, bool c_cast_p,
		  tsubst_flags_t complain)
{
  tree fn;
  tree pfn_type;
  tree to_type;

  if (error_operand_p (pfn))
    return error_mark_node;

  pfn_type = TREE_TYPE (pfn);
  to_type = build_ptrmemfunc_type (type);

  /* Handle multiple conversions of pointer to member functions.  */
  if (TYPE_PTRMEMFUNC_P (pfn_type))
    {
      tree delta = NULL_TREE;
      tree npfn = NULL_TREE;
      tree n;

      if (!force
	  && !can_convert_arg (to_type, TREE_TYPE (pfn), pfn,
			       LOOKUP_NORMAL, complain))
	{
	  if (complain & tf_error)
	    error ("invalid conversion to type %qT from type %qT",
		   to_type, pfn_type);
	  else
	    return error_mark_node;
	}

      n = get_delta_difference (TYPE_PTRMEMFUNC_OBJECT_TYPE (pfn_type),
				TYPE_PTRMEMFUNC_OBJECT_TYPE (to_type),
				force,
				c_cast_p, complain);
      if (n == error_mark_node)
	return error_mark_node;

      /* We don't have to do any conversion to convert a
	 pointer-to-member to its own type.  But, we don't want to
	 just return a PTRMEM_CST if there's an explicit cast; that
	 cast should make the expression an invalid template argument.  */
      if (TREE_CODE (pfn) != PTRMEM_CST)
	{
	  if (same_type_p (to_type, pfn_type))
	    return pfn;
	  else if (integer_zerop (n) && TREE_CODE (pfn) != CONSTRUCTOR)
	    return build_reinterpret_cast (input_location, to_type, pfn, 
                                           complain);
	}

      if (TREE_SIDE_EFFECTS (pfn))
	pfn = save_expr (pfn);

      /* Obtain the function pointer and the current DELTA.  */
      if (TREE_CODE (pfn) == PTRMEM_CST)
	expand_ptrmemfunc_cst (pfn, &delta, &npfn);
      else
	{
	  npfn = build_ptrmemfunc_access_expr (pfn, pfn_identifier);
	  delta = build_ptrmemfunc_access_expr (pfn, delta_identifier);
	}

      /* Just adjust the DELTA field.  */
      gcc_assert  (same_type_ignoring_top_level_qualifiers_p
		   (TREE_TYPE (delta), ptrdiff_type_node));
      if (!integer_zerop (n))
	{
	  if (TARGET_PTRMEMFUNC_VBIT_LOCATION == ptrmemfunc_vbit_in_delta)
	    n = cp_build_binary_op (input_location,
				    LSHIFT_EXPR, n, integer_one_node,
				    complain);
	  delta = cp_build_binary_op (input_location,
				      PLUS_EXPR, delta, n, complain);
	}
      return build_ptrmemfunc1 (to_type, delta, npfn);
    }

  /* Handle null pointer to member function conversions.  */
  if (null_ptr_cst_p (pfn))
    {
      pfn = cp_build_c_cast (input_location, type, pfn, complain);
      return build_ptrmemfunc1 (to_type,
				integer_zero_node,
				pfn);
    }

  if (type_unknown_p (pfn))
    return instantiate_type (type, pfn, complain);

  fn = TREE_OPERAND (pfn, 0);
  gcc_assert (TREE_CODE (fn) == FUNCTION_DECL
	      /* In a template, we will have preserved the
		 OFFSET_REF.  */
	      || (processing_template_decl && TREE_CODE (fn) == OFFSET_REF));
  return make_ptrmem_cst (to_type, fn);
}

/* Return the DELTA, IDX, PFN, and DELTA2 values for the PTRMEM_CST
   given by CST.

   ??? There is no consistency as to the types returned for the above
   values.  Some code acts as if it were a sizetype and some as if it were
   integer_type_node.  */

void
expand_ptrmemfunc_cst (tree cst, tree *delta, tree *pfn)
{
  tree type = TREE_TYPE (cst);
  tree fn = PTRMEM_CST_MEMBER (cst);
  tree ptr_class, fn_class;

  gcc_assert (TREE_CODE (fn) == FUNCTION_DECL);

  /* The class that the function belongs to.  */
  fn_class = DECL_CONTEXT (fn);

  /* The class that we're creating a pointer to member of.  */
  ptr_class = TYPE_PTRMEMFUNC_OBJECT_TYPE (type);

  /* First, calculate the adjustment to the function's class.  */
  *delta = get_delta_difference (fn_class, ptr_class, /*force=*/0,
				 /*c_cast_p=*/0, tf_warning_or_error);

  if (!DECL_VIRTUAL_P (fn))
    *pfn = convert (TYPE_PTRMEMFUNC_FN_TYPE (type),
		    build_addr_func (fn, tf_warning_or_error));
  else
    {
      /* If we're dealing with a virtual function, we have to adjust 'this'
	 again, to point to the base which provides the vtable entry for
	 fn; the call will do the opposite adjustment.  */
      tree orig_class = DECL_CONTEXT (fn);
      tree binfo = binfo_or_else (orig_class, fn_class);
      *delta = fold_build2 (PLUS_EXPR, TREE_TYPE (*delta),
			    *delta, BINFO_OFFSET (binfo));

      /* We set PFN to the vtable offset at which the function can be
	 found, plus one (unless ptrmemfunc_vbit_in_delta, in which
	 case delta is shifted left, and then incremented).  */
      *pfn = DECL_VINDEX (fn);
      *pfn = fold_build2 (MULT_EXPR, integer_type_node, *pfn,
			  TYPE_SIZE_UNIT (vtable_entry_type));

      switch (TARGET_PTRMEMFUNC_VBIT_LOCATION)
	{
	case ptrmemfunc_vbit_in_pfn:
	  *pfn = fold_build2 (PLUS_EXPR, integer_type_node, *pfn,
			      integer_one_node);
	  break;

	case ptrmemfunc_vbit_in_delta:
	  *delta = fold_build2 (LSHIFT_EXPR, TREE_TYPE (*delta),
				*delta, integer_one_node);
	  *delta = fold_build2 (PLUS_EXPR, TREE_TYPE (*delta),
				*delta, integer_one_node);
	  break;

	default:
	  gcc_unreachable ();
	}

      *pfn = fold_convert (TYPE_PTRMEMFUNC_FN_TYPE (type), *pfn);
    }
}

/* Return an expression for PFN from the pointer-to-member function
   given by T.  */

static tree
pfn_from_ptrmemfunc (tree t)
{
  if (TREE_CODE (t) == PTRMEM_CST)
    {
      tree delta;
      tree pfn;

      expand_ptrmemfunc_cst (t, &delta, &pfn);
      if (pfn)
	return pfn;
    }

  return build_ptrmemfunc_access_expr (t, pfn_identifier);
}

/* Return an expression for DELTA from the pointer-to-member function
   given by T.  */

static tree
delta_from_ptrmemfunc (tree t)
{
  if (TREE_CODE (t) == PTRMEM_CST)
    {
      tree delta;
      tree pfn;

      expand_ptrmemfunc_cst (t, &delta, &pfn);
      if (delta)
	return delta;
    }

  return build_ptrmemfunc_access_expr (t, delta_identifier);
}

/* Convert value RHS to type TYPE as preparation for an assignment to
   an lvalue of type TYPE.  ERRTYPE indicates what kind of error the
   implicit conversion is.  If FNDECL is non-NULL, we are doing the
   conversion in order to pass the PARMNUMth argument of FNDECL.
   If FNDECL is NULL, we are doing the conversion in function pointer
   argument passing, conversion in initialization, etc. */

static tree
convert_for_assignment (tree type, tree rhs,
			impl_conv_rhs errtype, tree fndecl, int parmnum,
			tsubst_flags_t complain, int flags)
{
  tree rhstype;
  enum tree_code coder;

  location_t rhs_loc = EXPR_LOC_OR_LOC (rhs, input_location);
  bool has_loc = EXPR_LOCATION (rhs) != UNKNOWN_LOCATION;
  /* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue,
     but preserve location wrappers.  */
  if (TREE_CODE (rhs) == NON_LVALUE_EXPR
      && !location_wrapper_p (rhs))
    rhs = TREE_OPERAND (rhs, 0);

  /* Handle [dcl.init.list] direct-list-initialization from
     single element of enumeration with a fixed underlying type.  */
  if (is_direct_enum_init (type, rhs))
    {
      tree elt = CONSTRUCTOR_ELT (rhs, 0)->value;
      if (check_narrowing (ENUM_UNDERLYING_TYPE (type), elt, complain))
	{
	  warning_sentinel w (warn_useless_cast);
	  warning_sentinel w2 (warn_ignored_qualifiers);
	  rhs = cp_build_c_cast (rhs_loc, type, elt, complain);
	}
      else
	rhs = error_mark_node;
    }

  rhstype = TREE_TYPE (rhs);
  coder = TREE_CODE (rhstype);

  if (VECTOR_TYPE_P (type) && coder == VECTOR_TYPE
      && vector_types_convertible_p (type, rhstype, true))
    {
      rhs = mark_rvalue_use (rhs);
      return convert (type, rhs);
    }

  if (rhs == error_mark_node || rhstype == error_mark_node)
    return error_mark_node;
  if (TREE_CODE (rhs) == TREE_LIST && TREE_VALUE (rhs) == error_mark_node)
    return error_mark_node;

  /* The RHS of an assignment cannot have void type.  */
  if (coder == VOID_TYPE)
    {
      if (complain & tf_error)
	error_at (rhs_loc, "void value not ignored as it ought to be");
      return error_mark_node;
    }

  if (c_dialect_objc ())
    {
      int parmno;
      tree selector;
      tree rname = fndecl;

      switch (errtype)
        {
	  case ICR_ASSIGN:
	    parmno = -1;
	    break;
	  case ICR_INIT:
	    parmno = -2;
	    break;
	  default:
	    selector = objc_message_selector ();
	    parmno = parmnum;
	    if (selector && parmno > 1)
	      {
		rname = selector;
		parmno -= 1;
	      }
	}

      if (objc_compare_types (type, rhstype, parmno, rname))
	{
	  rhs = mark_rvalue_use (rhs);
	  return convert (type, rhs);
	}
    }

  /* [expr.ass]

     The expression is implicitly converted (clause _conv_) to the
     cv-unqualified type of the left operand.

     We allow bad conversions here because by the time we get to this point
     we are committed to doing the conversion.  If we end up doing a bad
     conversion, convert_like will complain.  */
  if (!can_convert_arg_bad (type, rhstype, rhs, flags, complain))
    {
      /* When -Wno-pmf-conversions is use, we just silently allow
	 conversions from pointers-to-members to plain pointers.  If
	 the conversion doesn't work, cp_convert will complain.  */
      if (!warn_pmf2ptr
	  && TYPE_PTR_P (type)
	  && TYPE_PTRMEMFUNC_P (rhstype))
	rhs = cp_convert (strip_top_quals (type), rhs, complain);
      else
	{
	  if (complain & tf_error)
	    {
	      /* If the right-hand side has unknown type, then it is an
		 overloaded function.  Call instantiate_type to get error
		 messages.  */
	      if (rhstype == unknown_type_node)
		{
		  tree r = instantiate_type (type, rhs, tf_warning_or_error);
		  /* -fpermissive might allow this; recurse.  */
		  if (!seen_error ())
		    return convert_for_assignment (type, r, errtype, fndecl,
						   parmnum, complain, flags);
		}
	      else if (fndecl)
		complain_about_bad_argument (rhs_loc,
					     rhstype, type,
					     fndecl, parmnum);
	      else
		{
		  range_label_for_type_mismatch label (rhstype, type);
		  gcc_rich_location richloc (rhs_loc, has_loc ? &label : NULL);
		  switch (errtype)
		    {
		    case ICR_DEFAULT_ARGUMENT:
		      error_at (&richloc,
				"cannot convert %qH to %qI in default argument",
				rhstype, type);
		      break;
		    case ICR_ARGPASS:
		      error_at (&richloc,
				"cannot convert %qH to %qI in argument passing",
				rhstype, type);
		      break;
		    case ICR_CONVERTING:
		      error_at (&richloc, "cannot convert %qH to %qI",
				rhstype, type);
		      break;
		    case ICR_INIT:
		      error_at (&richloc,
				"cannot convert %qH to %qI in initialization",
				rhstype, type);
		      break;
		    case ICR_RETURN:
		      error_at (&richloc, "cannot convert %qH to %qI in return",
				rhstype, type);
		      break;
		    case ICR_ASSIGN:
		      error_at (&richloc,
				"cannot convert %qH to %qI in assignment",
				rhstype, type);
		      break;
		    default:
		      gcc_unreachable();
		  }
		}
	      if (TYPE_PTR_P (rhstype)
		  && TYPE_PTR_P (type)
		  && CLASS_TYPE_P (TREE_TYPE (rhstype))
		  && CLASS_TYPE_P (TREE_TYPE (type))
		  && !COMPLETE_TYPE_P (TREE_TYPE (rhstype)))
		inform (DECL_SOURCE_LOCATION (TYPE_MAIN_DECL
					      (TREE_TYPE (rhstype))),
			"class type %qT is incomplete", TREE_TYPE (rhstype));
	    }
	  return error_mark_node;
	}
    }
  if (warn_suggest_attribute_format)
    {
      const enum tree_code codel = TREE_CODE (type);
      if ((codel == POINTER_TYPE || codel == REFERENCE_TYPE)
	  && coder == codel
	  && check_missing_format_attribute (type, rhstype)
	  && (complain & tf_warning))
	switch (errtype)
	  {
	    case ICR_ARGPASS:
	    case ICR_DEFAULT_ARGUMENT:
	      if (fndecl)
		warning (OPT_Wsuggest_attribute_format,
			 "parameter %qP of %qD might be a candidate "
			 "for a format attribute", parmnum, fndecl);
	      else
		warning (OPT_Wsuggest_attribute_format,
			 "parameter might be a candidate "
			 "for a format attribute");
	      break;
	    case ICR_CONVERTING:
	      warning (OPT_Wsuggest_attribute_format,
		       "target of conversion might be a candidate "
		       "for a format attribute");
	      break;
	    case ICR_INIT:
	      warning (OPT_Wsuggest_attribute_format,
		       "target of initialization might be a candidate "
		       "for a format attribute");
	      break;
	    case ICR_RETURN:
	      warning (OPT_Wsuggest_attribute_format,
		       "return type might be a candidate "
		       "for a format attribute");
	      break;
	    case ICR_ASSIGN:
	      warning (OPT_Wsuggest_attribute_format,
		       "left-hand side of assignment might be a candidate "
		       "for a format attribute");
	      break;
	    default:
	      gcc_unreachable();
	  }
    }

  /* If -Wparentheses, warn about a = b = c when a has type bool and b
     does not.  */
  if (warn_parentheses
      && TREE_CODE (type) == BOOLEAN_TYPE
      && TREE_CODE (rhs) == MODIFY_EXPR
      && !warning_suppressed_p (rhs, OPT_Wparentheses)
      && TREE_CODE (TREE_TYPE (rhs)) != BOOLEAN_TYPE
      && (complain & tf_warning)
      && warning_at (rhs_loc, OPT_Wparentheses,
		     "suggest parentheses around assignment used as "
		     "truth value"))
    suppress_warning (rhs, OPT_Wparentheses);

  if (complain & tf_warning)
    warn_for_address_or_pointer_of_packed_member (type, rhs);

  return perform_implicit_conversion_flags (strip_top_quals (type), rhs,
					    complain, flags);
}

/* Convert RHS to be of type TYPE.
   If EXP is nonzero, it is the target of the initialization.
   ERRTYPE indicates what kind of error the implicit conversion is.

   Two major differences between the behavior of
   `convert_for_assignment' and `convert_for_initialization'
   are that references are bashed in the former, while
   copied in the latter, and aggregates are assigned in
   the former (operator=) while initialized in the
   latter (X(X&)).

   If using constructor make sure no conversion operator exists, if one does
   exist, an ambiguity exists.  */

tree
convert_for_initialization (tree exp, tree type, tree rhs, int flags,
			    impl_conv_rhs errtype, tree fndecl, int parmnum,
                            tsubst_flags_t complain)
{
  enum tree_code codel = TREE_CODE (type);
  tree rhstype;
  enum tree_code coder;

  /* build_c_cast puts on a NOP_EXPR to make the result not an lvalue.
     Strip such NOP_EXPRs, since RHS is used in non-lvalue context.  */
  if (TREE_CODE (rhs) == NOP_EXPR
      && TREE_TYPE (rhs) == TREE_TYPE (TREE_OPERAND (rhs, 0))
      && codel != REFERENCE_TYPE)
    rhs = TREE_OPERAND (rhs, 0);

  if (type == error_mark_node
      || rhs == error_mark_node
      || (TREE_CODE (rhs) == TREE_LIST && TREE_VALUE (rhs) == error_mark_node))
    return error_mark_node;

  if (MAYBE_CLASS_TYPE_P (non_reference (type)))
    ;
  else if ((TREE_CODE (TREE_TYPE (rhs)) == ARRAY_TYPE
	    && TREE_CODE (type) != ARRAY_TYPE
	    && (!TYPE_REF_P (type)
		|| TREE_CODE (TREE_TYPE (type)) != ARRAY_TYPE))
	   || (TREE_CODE (TREE_TYPE (rhs)) == FUNCTION_TYPE
	       && !TYPE_REFFN_P (type))
	   || TREE_CODE (TREE_TYPE (rhs)) == METHOD_TYPE)
    rhs = decay_conversion (rhs, complain);

  rhstype = TREE_TYPE (rhs);
  coder = TREE_CODE (rhstype);

  if (coder == ERROR_MARK)
    return error_mark_node;

  /* We accept references to incomplete types, so we can
     return here before checking if RHS is of complete type.  */

  if (codel == REFERENCE_TYPE)
    {
      auto_diagnostic_group d;
      /* This should eventually happen in convert_arguments.  */
      int savew = 0, savee = 0;

      if (fndecl)
	savew = warningcount + werrorcount, savee = errorcount;
      rhs = initialize_reference (type, rhs, flags, complain);

      if (fndecl
	  && (warningcount + werrorcount > savew || errorcount > savee))
	inform (get_fndecl_argument_location (fndecl, parmnum),
		"in passing argument %P of %qD", parmnum, fndecl);
      return rhs;
    }

  if (exp != 0)
    exp = require_complete_type_sfinae (exp, complain);
  if (exp == error_mark_node)
    return error_mark_node;

  type = complete_type (type);

  if (DIRECT_INIT_EXPR_P (type, rhs))
    /* Don't try to do copy-initialization if we already have
       direct-initialization.  */
    return rhs;

  if (MAYBE_CLASS_TYPE_P (type))
    return perform_implicit_conversion_flags (type, rhs, complain, flags);

  return convert_for_assignment (type, rhs, errtype, fndecl, parmnum,
				 complain, flags);
}

/* If RETVAL is the address of, or a reference to, a local variable or
   temporary give an appropriate warning and return true.  */

static bool
maybe_warn_about_returning_address_of_local (tree retval, location_t loc)
{
  tree valtype = TREE_TYPE (DECL_RESULT (current_function_decl));
  tree whats_returned = fold_for_warn (retval);
  if (!loc)
    loc = cp_expr_loc_or_input_loc (retval);

  for (;;)
    {
      if (TREE_CODE (whats_returned) == COMPOUND_EXPR)
	whats_returned = TREE_OPERAND (whats_returned, 1);
      else if (CONVERT_EXPR_P (whats_returned)
	       || TREE_CODE (whats_returned) == NON_LVALUE_EXPR)
	whats_returned = TREE_OPERAND (whats_returned, 0);
      else
	break;
    }

  if (TREE_CODE (whats_returned) == TARGET_EXPR
      && is_std_init_list (TREE_TYPE (whats_returned)))
    {
      tree init = TARGET_EXPR_INITIAL (whats_returned);
      if (TREE_CODE (init) == CONSTRUCTOR)
	/* Pull out the array address.  */
	whats_returned = CONSTRUCTOR_ELT (init, 0)->value;
      else if (TREE_CODE (init) == INDIRECT_REF)
	/* The source of a trivial copy looks like *(T*)&var.  */
	whats_returned = TREE_OPERAND (init, 0);
      else
	return false;
      STRIP_NOPS (whats_returned);
    }

  /* As a special case, we handle a call to std::move or std::forward.  */
  if (TREE_CODE (whats_returned) == CALL_EXPR
      && (is_std_move_p (whats_returned)
	  || is_std_forward_p (whats_returned)))
    {
      tree arg = CALL_EXPR_ARG (whats_returned, 0);
      return maybe_warn_about_returning_address_of_local (arg, loc);
    }

  if (TREE_CODE (whats_returned) != ADDR_EXPR)
    return false;
  whats_returned = TREE_OPERAND (whats_returned, 0);

  while (TREE_CODE (whats_returned) == COMPONENT_REF
	 || TREE_CODE (whats_returned) == ARRAY_REF)
    whats_returned = TREE_OPERAND (whats_returned, 0);

  if (TREE_CODE (whats_returned) == AGGR_INIT_EXPR
      || TREE_CODE (whats_returned) == TARGET_EXPR)
    {
      if (TYPE_REF_P (valtype))
	warning_at (loc, OPT_Wreturn_local_addr,
		    "returning reference to temporary");
      else if (is_std_init_list (valtype))
	warning_at (loc, OPT_Winit_list_lifetime,
		    "returning temporary %<initializer_list%> does not extend "
		    "the lifetime of the underlying array");
      return true;
    }

  STRIP_ANY_LOCATION_WRAPPER (whats_returned);

  if (DECL_P (whats_returned)
      && DECL_NAME (whats_returned)
      && DECL_FUNCTION_SCOPE_P (whats_returned)
      && !is_capture_proxy (whats_returned)
      && !(TREE_STATIC (whats_returned)
	   || TREE_PUBLIC (whats_returned)))
    {
      if (VAR_P (whats_returned)
	  && DECL_DECOMPOSITION_P (whats_returned)
	  && DECL_DECOMP_BASE (whats_returned)
	  && DECL_HAS_VALUE_EXPR_P (whats_returned))
	{
	  /* When returning address of a structured binding, if the structured
	     binding is not a reference, continue normally, if it is a
	     reference, recurse on the initializer of the structured
	     binding.  */
	  tree base = DECL_DECOMP_BASE (whats_returned);
	  if (TYPE_REF_P (TREE_TYPE (base)))
	    {
	      if (tree init = DECL_INITIAL (base))
		return maybe_warn_about_returning_address_of_local (init, loc);
	      else
		return false;
	    }
	}
      bool w = false;
      auto_diagnostic_group d;
      if (TYPE_REF_P (valtype))
	w = warning_at (loc, OPT_Wreturn_local_addr,
			"reference to local variable %qD returned",
			whats_returned);
      else if (is_std_init_list (valtype))
	w = warning_at (loc, OPT_Winit_list_lifetime,
			"returning local %<initializer_list%> variable %qD "
			"does not extend the lifetime of the underlying array",
			whats_returned);
      else if (POINTER_TYPE_P (valtype)
	       && TREE_CODE (whats_returned) == LABEL_DECL)
	w = warning_at (loc, OPT_Wreturn_local_addr,
			"address of label %qD returned",
			whats_returned);
      else if (POINTER_TYPE_P (valtype))
	w = warning_at (loc, OPT_Wreturn_local_addr,
			"address of local variable %qD returned",
			whats_returned);
      if (w)
	inform (DECL_SOURCE_LOCATION (whats_returned),
		"declared here");
      return true;
    }

  return false;
}

/* Returns true if DECL is in the std namespace.  */

bool
decl_in_std_namespace_p (tree decl)
{
  while (decl)
    {
      decl = decl_namespace_context (decl);
      if (DECL_NAMESPACE_STD_P (decl))
	return true;
      /* Allow inline namespaces inside of std namespace, e.g. with
	 --enable-symvers=gnu-versioned-namespace std::forward would be
	 actually std::_8::forward.  */
      if (!DECL_NAMESPACE_INLINE_P (decl))
	return false;
      decl = CP_DECL_CONTEXT (decl);
    }
  return false;
}

/* Returns true if FN, a CALL_EXPR, is a call to std::forward.  */

static bool
is_std_forward_p (tree fn)
{
  /* std::forward only takes one argument.  */
  if (call_expr_nargs (fn) != 1)
    return false;

  tree fndecl = cp_get_callee_fndecl_nofold (fn);
  if (!decl_in_std_namespace_p (fndecl))
    return false;

  tree name = DECL_NAME (fndecl);
  return name && id_equal (name, "forward");
}

/* Returns true if FN, a CALL_EXPR, is a call to std::move.  */

static bool
is_std_move_p (tree fn)
{
  /* std::move only takes one argument.  */
  if (call_expr_nargs (fn) != 1)
    return false;

  tree fndecl = cp_get_callee_fndecl_nofold (fn);
  if (!decl_in_std_namespace_p (fndecl))
    return false;

  tree name = DECL_NAME (fndecl);
  return name && id_equal (name, "move");
}

/* Returns true if RETVAL is a good candidate for the NRVO as per
   [class.copy.elision].  FUNCTYPE is the type the function is declared
   to return.  */

static bool
can_do_nrvo_p (tree retval, tree functype)
{
  if (functype == error_mark_node)
    return false;
  if (retval)
    STRIP_ANY_LOCATION_WRAPPER (retval);
  tree result = DECL_RESULT (current_function_decl);
  return (retval != NULL_TREE
	  && !processing_template_decl
	  /* Must be a local, automatic variable.  */
	  && VAR_P (retval)
	  && DECL_CONTEXT (retval) == current_function_decl
	  && !TREE_STATIC (retval)
	  /* And not a lambda or anonymous union proxy.  */
	  && !DECL_HAS_VALUE_EXPR_P (retval)
	  && (DECL_ALIGN (retval) <= DECL_ALIGN (result))
	  /* The cv-unqualified type of the returned value must be the
	     same as the cv-unqualified return type of the
	     function.  */
	  && same_type_p ((TYPE_MAIN_VARIANT (TREE_TYPE (retval))),
			  (TYPE_MAIN_VARIANT (functype)))
	  /* And the returned value must be non-volatile.  */
	  && !TYPE_VOLATILE (TREE_TYPE (retval)));
}

/* If we should treat RETVAL, an expression being returned, as if it were
   designated by an rvalue, returns it adjusted accordingly; otherwise, returns
   NULL_TREE.  See [class.copy.elision].  RETURN_P is true if this is a return
   context (rather than throw).  */

tree
treat_lvalue_as_rvalue_p (tree expr, bool return_p)
{
  if (cxx_dialect == cxx98)
    return NULL_TREE;

  tree retval = expr;
  STRIP_ANY_LOCATION_WRAPPER (retval);
  if (REFERENCE_REF_P (retval))
    retval = TREE_OPERAND (retval, 0);

  /* An implicitly movable entity is a variable of automatic storage duration
     that is either a non-volatile object or (C++20) an rvalue reference to a
     non-volatile object type.  */
  if (!(((VAR_P (retval) && !DECL_HAS_VALUE_EXPR_P (retval))
	 || TREE_CODE (retval) == PARM_DECL)
	&& !TREE_STATIC (retval)
	&& !CP_TYPE_VOLATILE_P (non_reference (TREE_TYPE (retval)))
	&& (TREE_CODE (TREE_TYPE (retval)) != REFERENCE_TYPE
	    || (cxx_dialect >= cxx20
		&& TYPE_REF_IS_RVALUE (TREE_TYPE (retval))))))
    return NULL_TREE;

  /* If the expression in a return or co_return statement is a (possibly
     parenthesized) id-expression that names an implicitly movable entity
     declared in the body or parameter-declaration-clause of the innermost
     enclosing function or lambda-expression, */
  if (DECL_CONTEXT (retval) != current_function_decl)
    return NULL_TREE;
  if (return_p)
    return set_implicit_rvalue_p (move (expr));

  /* if the operand of a throw-expression is a (possibly parenthesized)
     id-expression that names an implicitly movable entity whose scope does not
     extend beyond the compound-statement of the innermost try-block or
     function-try-block (if any) whose compound-statement or ctor-initializer
     encloses the throw-expression, */

  /* C++20 added move on throw of parms.  */
  if (TREE_CODE (retval) == PARM_DECL && cxx_dialect < cxx20)
    return NULL_TREE;

  for (cp_binding_level *b = current_binding_level;
       ; b = b->level_chain)
    {
      for (tree decl = b->names; decl; decl = TREE_CHAIN (decl))
	if (decl == retval)
	  return set_implicit_rvalue_p (move (expr));
      if (b->kind == sk_function_parms || b->kind == sk_try)
	return NULL_TREE;
    }
}

/* Warn about wrong usage of std::move in a return statement.  RETVAL
   is the expression we are returning; FUNCTYPE is the type the function
   is declared to return.  */

static void
maybe_warn_pessimizing_move (tree retval, tree functype)
{
  if (!(warn_pessimizing_move || warn_redundant_move))
    return;

  location_t loc = cp_expr_loc_or_input_loc (retval);

  /* C++98 doesn't know move.  */
  if (cxx_dialect < cxx11)
    return;

  /* Wait until instantiation time, since we can't gauge if we should do
     the NRVO until then.  */
  if (processing_template_decl)
    return;

  /* This is only interesting for class types.  */
  if (!CLASS_TYPE_P (functype))
    return;

  /* We're looking for *std::move<T&> ((T &) &arg).  */
  if (REFERENCE_REF_P (retval)
      && TREE_CODE (TREE_OPERAND (retval, 0)) == CALL_EXPR)
    {
      tree fn = TREE_OPERAND (retval, 0);
      if (is_std_move_p (fn))
	{
	  tree arg = CALL_EXPR_ARG (fn, 0);
	  tree moved;
	  if (TREE_CODE (arg) != NOP_EXPR)
	    return;
	  arg = TREE_OPERAND (arg, 0);
	  if (TREE_CODE (arg) != ADDR_EXPR)
	    return;
	  arg = TREE_OPERAND (arg, 0);
	  arg = convert_from_reference (arg);
	  /* Warn if we could do copy elision were it not for the move.  */
	  if (can_do_nrvo_p (arg, functype))
	    {
	      auto_diagnostic_group d;
	      if (warning_at (loc, OPT_Wpessimizing_move,
			      "moving a local object in a return statement "
			      "prevents copy elision"))
		inform (loc, "remove %<std::move%> call");
	    }
	  /* Warn if the move is redundant.  It is redundant when we would
	     do maybe-rvalue overload resolution even without std::move.  */
	  else if (warn_redundant_move
		   && (moved = treat_lvalue_as_rvalue_p (arg, /*return*/true)))
	    {
	      /* Make sure that the overload resolution would actually succeed
		 if we removed the std::move call.  */
	      tree t = convert_for_initialization (NULL_TREE, functype,
						   moved,
						   (LOOKUP_NORMAL
						    | LOOKUP_ONLYCONVERTING
						    | LOOKUP_PREFER_RVALUE),
						   ICR_RETURN, NULL_TREE, 0,
						   tf_none);
	      /* If this worked, implicit rvalue would work, so the call to
		 std::move is redundant.  */
	      if (t != error_mark_node)
		{
		  auto_diagnostic_group d;
		  if (warning_at (loc, OPT_Wredundant_move,
				  "redundant move in return statement"))
		    inform (loc, "remove %<std::move%> call");
		}
	    }
	}
    }
}

/* Check that returning RETVAL from the current function is valid.
   Return an expression explicitly showing all conversions required to
   change RETVAL into the function return type, and to assign it to
   the DECL_RESULT for the function.  Set *NO_WARNING to true if
   code reaches end of non-void function warning shouldn't be issued
   on this RETURN_EXPR.  */

tree
check_return_expr (tree retval, bool *no_warning)
{
  tree result;
  /* The type actually returned by the function.  */
  tree valtype;
  /* The type the function is declared to return, or void if
     the declared type is incomplete.  */
  tree functype;
  int fn_returns_value_p;
  location_t loc = cp_expr_loc_or_input_loc (retval);

  *no_warning = false;

  /* A `volatile' function is one that isn't supposed to return, ever.
     (This is a G++ extension, used to get better code for functions
     that call the `volatile' function.)  */
  if (TREE_THIS_VOLATILE (current_function_decl))
    warning (0, "function declared %<noreturn%> has a %<return%> statement");

  /* Check for various simple errors.  */
  if (DECL_DESTRUCTOR_P (current_function_decl))
    {
      if (retval)
	error_at (loc, "returning a value from a destructor");
      return NULL_TREE;
    }
  else if (DECL_CONSTRUCTOR_P (current_function_decl))
    {
      if (in_function_try_handler)
	/* If a return statement appears in a handler of the
	   function-try-block of a constructor, the program is ill-formed.  */
	error ("cannot return from a handler of a function-try-block of a constructor");
      else if (retval)
	/* You can't return a value from a constructor.  */
	error_at (loc, "returning a value from a constructor");
      return NULL_TREE;
    }

  const tree saved_retval = retval;

  if (processing_template_decl)
    {
      current_function_returns_value = 1;

      if (check_for_bare_parameter_packs (retval))
	return error_mark_node;

      /* If one of the types might be void, we can't tell whether we're
	 returning a value.  */
      if ((WILDCARD_TYPE_P (TREE_TYPE (DECL_RESULT (current_function_decl)))
	   && !FNDECL_USED_AUTO (current_function_decl))
	  || (retval != NULL_TREE
	      && (TREE_TYPE (retval) == NULL_TREE
		  || WILDCARD_TYPE_P (TREE_TYPE (retval)))))
	goto dependent;
    }

  functype = TREE_TYPE (TREE_TYPE (current_function_decl));

  /* Deduce auto return type from a return statement.  */
  if (FNDECL_USED_AUTO (current_function_decl))
    {
      tree pattern = DECL_SAVED_AUTO_RETURN_TYPE (current_function_decl);
      tree auto_node;
      tree type;

      if (!retval && !is_auto (pattern))
	{
	  /* Give a helpful error message.  */
	  error ("return-statement with no value, in function returning %qT",
		 pattern);
	  inform (input_location, "only plain %<auto%> return type can be "
		  "deduced to %<void%>");
	  type = error_mark_node;
	}
      else if (retval && BRACE_ENCLOSED_INITIALIZER_P (retval))
	{
	  error ("returning initializer list");
	  type = error_mark_node;
	}
      else
	{
	  if (!retval)
	    retval = void_node;
	  auto_node = type_uses_auto (pattern);
	  type = do_auto_deduction (pattern, retval, auto_node,
				    tf_warning_or_error, adc_return_type);
	}

      if (type == error_mark_node)
	/* Leave it.  */;
      else if (functype == pattern)
	apply_deduced_return_type (current_function_decl, type);
      else if (!same_type_p (type, functype))
	{
	  if (LAMBDA_FUNCTION_P (current_function_decl))
	    error_at (loc, "inconsistent types %qT and %qT deduced for "
		      "lambda return type", functype, type);
	  else
	    error_at (loc, "inconsistent deduction for auto return type: "
		      "%qT and then %qT", functype, type);
	}
      functype = type;
    }

  result = DECL_RESULT (current_function_decl);
  valtype = TREE_TYPE (result);
  gcc_assert (valtype != NULL_TREE);
  fn_returns_value_p = !VOID_TYPE_P (valtype);

  /* Check for a return statement with no return value in a function
     that's supposed to return a value.  */
  if (!retval && fn_returns_value_p)
    {
      if (functype != error_mark_node)
	permerror (input_location, "return-statement with no value, in "
		   "function returning %qT", valtype);
      /* Remember that this function did return.  */
      current_function_returns_value = 1;
      /* And signal caller that TREE_NO_WARNING should be set on the
	 RETURN_EXPR to avoid control reaches end of non-void function
	 warnings in tree-cfg.c.  */
      *no_warning = true;
    }
  /* Check for a return statement with a value in a function that
     isn't supposed to return a value.  */
  else if (retval && !fn_returns_value_p)
    {
      if (VOID_TYPE_P (TREE_TYPE (retval)))
	/* You can return a `void' value from a function of `void'
	   type.  In that case, we have to evaluate the expression for
	   its side-effects.  */
	finish_expr_stmt (retval);
      else if (retval != error_mark_node)
	permerror (loc, "return-statement with a value, in function "
		   "returning %qT", valtype);
      current_function_returns_null = 1;

      /* There's really no value to return, after all.  */
      return NULL_TREE;
    }
  else if (!retval)
    /* Remember that this function can sometimes return without a
       value.  */
    current_function_returns_null = 1;
  else
    /* Remember that this function did return a value.  */
    current_function_returns_value = 1;

  /* Check for erroneous operands -- but after giving ourselves a
     chance to provide an error about returning a value from a void
     function.  */
  if (error_operand_p (retval))
    {
      current_function_return_value = error_mark_node;
      return error_mark_node;
    }

  /* Only operator new(...) throw(), can return NULL [expr.new/13].  */
  if (IDENTIFIER_NEW_OP_P (DECL_NAME (current_function_decl))
      && !TYPE_NOTHROW_P (TREE_TYPE (current_function_decl))
      && ! flag_check_new
      && retval && null_ptr_cst_p (retval))
    warning (0, "%<operator new%> must not return NULL unless it is "
	     "declared %<throw()%> (or %<-fcheck-new%> is in effect)");

  /* Effective C++ rule 15.  See also start_function.  */
  if (warn_ecpp
      && DECL_NAME (current_function_decl) == assign_op_identifier
      && !type_dependent_expression_p (retval))
    {
      bool warn = true;

      /* The function return type must be a reference to the current
	class.  */
      if (TYPE_REF_P (valtype)
	  && same_type_ignoring_top_level_qualifiers_p
	      (TREE_TYPE (valtype), TREE_TYPE (current_class_ref)))
	{
	  /* Returning '*this' is obviously OK.  */
	  if (retval == current_class_ref)
	    warn = false;
	  /* If we are calling a function whose return type is the same of
	     the current class reference, it is ok.  */
	  else if (INDIRECT_REF_P (retval)
		   && TREE_CODE (TREE_OPERAND (retval, 0)) == CALL_EXPR)
	    warn = false;
	}

      if (warn)
	warning_at (loc, OPT_Weffc__,
		    "%<operator=%> should return a reference to %<*this%>");
    }

  if (dependent_type_p (functype)
      || type_dependent_expression_p (retval))
    {
    dependent:
      /* We should not have changed the return value.  */
      gcc_assert (retval == saved_retval);
      /* We don't know if this is an lvalue or rvalue use, but
	 either way we can mark it as read.  */
      mark_exp_read (retval);
      return retval;
    }

  /* The fabled Named Return Value optimization, as per [class.copy]/15:

     [...]      For  a function with a class return type, if the expression
     in the return statement is the name of a local  object,  and  the  cv-
     unqualified  type  of  the  local  object  is the same as the function
     return type, an implementation is permitted to omit creating the  tem-
     porary  object  to  hold  the function return value [...]

     So, if this is a value-returning function that always returns the same
     local variable, remember it.

     It might be nice to be more flexible, and choose the first suitable
     variable even if the function sometimes returns something else, but
     then we run the risk of clobbering the variable we chose if the other
     returned expression uses the chosen variable somehow.  And people expect
     this restriction, anyway.  (jason 2000-11-19)

     See finish_function and finalize_nrv for the rest of this optimization.  */
  if (retval)
    {
      retval = maybe_undo_parenthesized_ref (retval);
      STRIP_ANY_LOCATION_WRAPPER (retval);
    }

  bool named_return_value_okay_p = can_do_nrvo_p (retval, functype);
  if (fn_returns_value_p && flag_elide_constructors)
    {
      if (named_return_value_okay_p
          && (current_function_return_value == NULL_TREE
              || current_function_return_value == retval))
	current_function_return_value = retval;
      else
	current_function_return_value = error_mark_node;
    }

  /* We don't need to do any conversions when there's nothing being
     returned.  */
  if (!retval)
    return NULL_TREE;

  if (!named_return_value_okay_p)
    maybe_warn_pessimizing_move (retval, functype);

  /* Do any required conversions.  */
  if (retval == result || DECL_CONSTRUCTOR_P (current_function_decl))
    /* No conversions are required.  */
    ;
  else
    {
      int flags = LOOKUP_NORMAL | LOOKUP_ONLYCONVERTING;

      /* The functype's return type will have been set to void, if it
	 was an incomplete type.  Just treat this as 'return;' */
      if (VOID_TYPE_P (functype))
	return error_mark_node;

      if (processing_template_decl)
	retval = build_non_dependent_expr (retval);

      /* Under C++11 [12.8/32 class.copy], a returned lvalue is sometimes
	 treated as an rvalue for the purposes of overload resolution to
	 favor move constructors over copy constructors.

         Note that these conditions are similar to, but not as strict as,
	 the conditions for the named return value optimization.  */
      bool converted = false;
      tree moved;
      /* This is only interesting for class type.  */
      if (CLASS_TYPE_P (functype)
	  && (moved = treat_lvalue_as_rvalue_p (retval, /*return*/true)))
	{
	  if (cxx_dialect < cxx20)
	    {
	      moved = convert_for_initialization
		(NULL_TREE, functype, moved, flags|LOOKUP_PREFER_RVALUE,
		 ICR_RETURN, NULL_TREE, 0, tf_none);
	      if (moved != error_mark_node)
		{
		  retval = moved;
		  converted = true;
		}
	    }
	  else
	    /* In C++20 we just treat the return value as an rvalue that
	       can bind to lvalue refs.  */
	    retval = moved;
	}

      /* The call in a (lambda) thunk needs no conversions.  */
      if (TREE_CODE (retval) == CALL_EXPR
	  && call_from_lambda_thunk_p (retval))
	converted = true;

      /* First convert the value to the function's return type, then
	 to the type of return value's location to handle the
	 case that functype is smaller than the valtype.  */
      if (!converted)
	retval = convert_for_initialization
	  (NULL_TREE, functype, retval, flags, ICR_RETURN, NULL_TREE, 0,
	   tf_warning_or_error);
      retval = convert (valtype, retval);

      /* If the conversion failed, treat this just like `return;'.  */
      if (retval == error_mark_node)
	return retval;
      /* We can't initialize a register from a AGGR_INIT_EXPR.  */
      else if (! cfun->returns_struct
	       && TREE_CODE (retval) == TARGET_EXPR
	       && TREE_CODE (TREE_OPERAND (retval, 1)) == AGGR_INIT_EXPR)
	retval = build2 (COMPOUND_EXPR, TREE_TYPE (retval), retval,
			 TREE_OPERAND (retval, 0));
      else if (!processing_template_decl
	       && maybe_warn_about_returning_address_of_local (retval, loc)
	       && INDIRECT_TYPE_P (valtype))
	retval = build2 (COMPOUND_EXPR, TREE_TYPE (retval), retval,
			 build_zero_cst (TREE_TYPE (retval)));
    }

  if (processing_template_decl)
    return saved_retval;

  /* Actually copy the value returned into the appropriate location.  */
  if (retval && retval != result)
    retval = build2 (INIT_EXPR, TREE_TYPE (result), result, retval);

  if (tree set = maybe_set_retval_sentinel ())
    retval = build2 (COMPOUND_EXPR, void_type_node, retval, set);

  return retval;
}


/* Returns nonzero if the pointer-type FROM can be converted to the
   pointer-type TO via a qualification conversion.  If CONSTP is -1,
   then we return nonzero if the pointers are similar, and the
   cv-qualification signature of FROM is a proper subset of that of TO.

   If CONSTP is positive, then all outer pointers have been
   const-qualified.  */

static bool
comp_ptr_ttypes_real (tree to, tree from, int constp)
{
  bool to_more_cv_qualified = false;
  bool is_opaque_pointer = false;

  for (; ; to = TREE_TYPE (to), from = TREE_TYPE (from))
    {
      if (TREE_CODE (to) != TREE_CODE (from))
	return false;

      if (TREE_CODE (from) == OFFSET_TYPE
	  && !same_type_p (TYPE_OFFSET_BASETYPE (from),
			   TYPE_OFFSET_BASETYPE (to)))
	return false;

      /* Const and volatile mean something different for function and
	 array types, so the usual checks are not appropriate.  We'll
	 check the array type elements in further iterations.  */
      if (!FUNC_OR_METHOD_TYPE_P (to) && TREE_CODE (to) != ARRAY_TYPE)
	{
	  if (!at_least_as_qualified_p (to, from))
	    return false;

	  if (!at_least_as_qualified_p (from, to))
	    {
	      if (constp == 0)
		return false;
	      to_more_cv_qualified = true;
	    }

	  if (constp > 0)
	    constp &= TYPE_READONLY (to);
	}

      if (VECTOR_TYPE_P (to))
	is_opaque_pointer = vector_targets_convertible_p (to, from);

      /* P0388R4 allows a conversion from int[N] to int[] but not the
	 other way round.  When both arrays have bounds but they do
	 not match, then no conversion is possible.  */
      if (TREE_CODE (to) == ARRAY_TYPE
	  && !comp_array_types (to, from, bounds_first, /*strict=*/false))
	return false;

      if (!TYPE_PTR_P (to)
	  && !TYPE_PTRDATAMEM_P (to)
	  /* CWG 330 says we need to look through arrays.  */
	  && TREE_CODE (to) != ARRAY_TYPE)
	return ((constp >= 0 || to_more_cv_qualified)
		&& (is_opaque_pointer
		    || same_type_ignoring_top_level_qualifiers_p (to, from)));
    }
}

/* When comparing, say, char ** to char const **, this function takes
   the 'char *' and 'char const *'.  Do not pass non-pointer/reference
   types to this function.  */

int
comp_ptr_ttypes (tree to, tree from)
{
  return comp_ptr_ttypes_real (to, from, 1);
}

/* Returns true iff FNTYPE is a non-class type that involves
   error_mark_node.  We can get FUNCTION_TYPE with buried error_mark_node
   if a parameter type is ill-formed.  */

bool
error_type_p (const_tree type)
{
  tree t;

  switch (TREE_CODE (type))
    {
    case ERROR_MARK:
      return true;

    case POINTER_TYPE:
    case REFERENCE_TYPE:
    case OFFSET_TYPE:
      return error_type_p (TREE_TYPE (type));

    case FUNCTION_TYPE:
    case METHOD_TYPE:
      if (error_type_p (TREE_TYPE (type)))
	return true;
      for (t = TYPE_ARG_TYPES (type); t; t = TREE_CHAIN (t))
	if (error_type_p (TREE_VALUE (t)))
	  return true;
      return false;

    case RECORD_TYPE:
      if (TYPE_PTRMEMFUNC_P (type))
	return error_type_p (TYPE_PTRMEMFUNC_FN_TYPE (type));
      return false;

    default:
      return false;
    }
}

/* Returns true if to and from are (possibly multi-level) pointers to the same
   type or inheritance-related types, regardless of cv-quals.  */

bool
ptr_reasonably_similar (const_tree to, const_tree from)
{
  for (; ; to = TREE_TYPE (to), from = TREE_TYPE (from))
    {
      /* Any target type is similar enough to void.  */
      if (VOID_TYPE_P (to))
	return !error_type_p (from);
      if (VOID_TYPE_P (from))
	return !error_type_p (to);

      if (TREE_CODE (to) != TREE_CODE (from))
	return false;

      if (TREE_CODE (from) == OFFSET_TYPE
	  && comptypes (TYPE_OFFSET_BASETYPE (to),
			TYPE_OFFSET_BASETYPE (from),
			COMPARE_BASE | COMPARE_DERIVED))
	continue;

      if (VECTOR_TYPE_P (to)
	  && vector_types_convertible_p (to, from, false))
	return true;

      if (TREE_CODE (to) == INTEGER_TYPE
	  && TYPE_PRECISION (to) == TYPE_PRECISION (from))
	return true;

      if (TREE_CODE (to) == FUNCTION_TYPE)
	return !error_type_p (to) && !error_type_p (from);

      if (!TYPE_PTR_P (to))
	{
	  /* When either type is incomplete avoid DERIVED_FROM_P,
	     which may call complete_type (c++/57942).  */
	  bool b = !COMPLETE_TYPE_P (to) || !COMPLETE_TYPE_P (from);
	  return comptypes
	    (TYPE_MAIN_VARIANT (to), TYPE_MAIN_VARIANT (from),
	     b ? COMPARE_STRICT : COMPARE_BASE | COMPARE_DERIVED);
	}
    }
}

/* Return true if TO and FROM (both of which are POINTER_TYPEs or
   pointer-to-member types) are the same, ignoring cv-qualification at
   all levels.  CB says how we should behave when comparing array bounds.  */

bool
comp_ptr_ttypes_const (tree to, tree from, compare_bounds_t cb)
{
  bool is_opaque_pointer = false;

  for (; ; to = TREE_TYPE (to), from = TREE_TYPE (from))
    {
      if (TREE_CODE (to) != TREE_CODE (from))
	return false;

      if (TREE_CODE (from) == OFFSET_TYPE
	  && same_type_p (TYPE_OFFSET_BASETYPE (from),
			  TYPE_OFFSET_BASETYPE (to)))
	  continue;

      if (VECTOR_TYPE_P (to))
	is_opaque_pointer = vector_targets_convertible_p (to, from);

      if (TREE_CODE (to) == ARRAY_TYPE
	  /* Ignore cv-qualification, but if we see e.g. int[3] and int[4],
	     we must fail.  */
	  && !comp_array_types (to, from, cb, /*strict=*/false))
	return false;

      /* CWG 330 says we need to look through arrays.  */
      if (!TYPE_PTR_P (to) && TREE_CODE (to) != ARRAY_TYPE)
	return (is_opaque_pointer
		|| same_type_ignoring_top_level_qualifiers_p (to, from));
    }
}

/* Returns the type qualifiers for this type, including the qualifiers on the
   elements for an array type.  */

int
cp_type_quals (const_tree type)
{
  int quals;
  /* This CONST_CAST is okay because strip_array_types returns its
     argument unmodified and we assign it to a const_tree.  */
  type = strip_array_types (CONST_CAST_TREE (type));
  if (type == error_mark_node
      /* Quals on a FUNCTION_TYPE are memfn quals.  */
      || TREE_CODE (type) == FUNCTION_TYPE)
    return TYPE_UNQUALIFIED;
  quals = TYPE_QUALS (type);
  /* METHOD and REFERENCE_TYPEs should never have quals.  */
  gcc_assert ((TREE_CODE (type) != METHOD_TYPE
	       && !TYPE_REF_P (type))
	      || ((quals & (TYPE_QUAL_CONST|TYPE_QUAL_VOLATILE))
		  == TYPE_UNQUALIFIED));
  return quals;
}

/* Returns the function-ref-qualifier for TYPE */

cp_ref_qualifier
type_memfn_rqual (const_tree type)
{
  gcc_assert (FUNC_OR_METHOD_TYPE_P (type));

  if (!FUNCTION_REF_QUALIFIED (type))
    return REF_QUAL_NONE;
  else if (FUNCTION_RVALUE_QUALIFIED (type))
    return REF_QUAL_RVALUE;
  else
    return REF_QUAL_LVALUE;
}

/* Returns the function-cv-quals for TYPE, which must be a FUNCTION_TYPE or
   METHOD_TYPE.  */

int
type_memfn_quals (const_tree type)
{
  if (TREE_CODE (type) == FUNCTION_TYPE)
    return TYPE_QUALS (type);
  else if (TREE_CODE (type) == METHOD_TYPE)
    return cp_type_quals (class_of_this_parm (type));
  else
    gcc_unreachable ();
}

/* Returns the FUNCTION_TYPE TYPE with its function-cv-quals changed to
   MEMFN_QUALS and its ref-qualifier to RQUAL. */

tree
apply_memfn_quals (tree type, cp_cv_quals memfn_quals, cp_ref_qualifier rqual)
{
  /* Could handle METHOD_TYPE here if necessary.  */
  gcc_assert (TREE_CODE (type) == FUNCTION_TYPE);
  if (TYPE_QUALS (type) == memfn_quals
      && type_memfn_rqual (type) == rqual)
    return type;

  /* This should really have a different TYPE_MAIN_VARIANT, but that gets
     complex.  */
  tree result = build_qualified_type (type, memfn_quals);
  return build_ref_qualified_type (result, rqual);
}

/* Returns nonzero if TYPE is const or volatile.  */

bool
cv_qualified_p (const_tree type)
{
  int quals = cp_type_quals (type);
  return (quals & (TYPE_QUAL_CONST|TYPE_QUAL_VOLATILE)) != 0;
}

/* Returns nonzero if the TYPE contains a mutable member.  */

bool
cp_has_mutable_p (const_tree type)
{
  /* This CONST_CAST is okay because strip_array_types returns its
     argument unmodified and we assign it to a const_tree.  */
  type = strip_array_types (CONST_CAST_TREE(type));

  return CLASS_TYPE_P (type) && CLASSTYPE_HAS_MUTABLE (type);
}

/* Set TREE_READONLY and TREE_VOLATILE on DECL as indicated by the
   TYPE_QUALS.  For a VAR_DECL, this may be an optimistic
   approximation.  In particular, consider:

     int f();
     struct S { int i; };
     const S s = { f(); }

   Here, we will make "s" as TREE_READONLY (because it is declared
   "const") -- only to reverse ourselves upon seeing that the
   initializer is non-constant.  */

void
cp_apply_type_quals_to_decl (int type_quals, tree decl)
{
  tree type = TREE_TYPE (decl);

  if (type == error_mark_node)
    return;

  if (TREE_CODE (decl) == TYPE_DECL)
    return;

  gcc_assert (!(TREE_CODE (type) == FUNCTION_TYPE
		&& type_quals != TYPE_UNQUALIFIED));

  /* Avoid setting TREE_READONLY incorrectly.  */
  /* We used to check TYPE_NEEDS_CONSTRUCTING here, but now a constexpr
     constructor can produce constant init, so rely on cp_finish_decl to
     clear TREE_READONLY if the variable has non-constant init.  */

  /* If the type has (or might have) a mutable component, that component
     might be modified.  */
  if (TYPE_HAS_MUTABLE_P (type) || !COMPLETE_TYPE_P (type))
    type_quals &= ~TYPE_QUAL_CONST;

  c_apply_type_quals_to_decl (type_quals, decl);
}

/* Subroutine of casts_away_constness.  Make T1 and T2 point at
   exemplar types such that casting T1 to T2 is casting away constness
   if and only if there is no implicit conversion from T1 to T2.  */

static void
casts_away_constness_r (tree *t1, tree *t2, tsubst_flags_t complain)
{
  int quals1;
  int quals2;

  /* [expr.const.cast]

     For multi-level pointer to members and multi-level mixed pointers
     and pointers to members (conv.qual), the "member" aspect of a
     pointer to member level is ignored when determining if a const
     cv-qualifier has been cast away.  */
  /* [expr.const.cast]

     For  two  pointer types:

	    X1 is T1cv1,1 * ... cv1,N *   where T1 is not a pointer type
	    X2 is T2cv2,1 * ... cv2,M *   where T2 is not a pointer type
	    K is min(N,M)

     casting from X1 to X2 casts away constness if, for a non-pointer
     type T there does not exist an implicit conversion (clause
     _conv_) from:

	    Tcv1,(N-K+1) * cv1,(N-K+2) * ... cv1,N *

     to

	    Tcv2,(M-K+1) * cv2,(M-K+2) * ... cv2,M *.  */
  if ((!TYPE_PTR_P (*t1) && !TYPE_PTRDATAMEM_P (*t1))
      || (!TYPE_PTR_P (*t2) && !TYPE_PTRDATAMEM_P (*t2)))
    {
      *t1 = cp_build_qualified_type (void_type_node,
				     cp_type_quals (*t1));
      *t2 = cp_build_qualified_type (void_type_node,
				     cp_type_quals (*t2));
      return;
    }

  quals1 = cp_type_quals (*t1);
  quals2 = cp_type_quals (*t2);

  if (TYPE_PTRDATAMEM_P (*t1))
    *t1 = TYPE_PTRMEM_POINTED_TO_TYPE (*t1);
  else
    *t1 = TREE_TYPE (*t1);
  if (TYPE_PTRDATAMEM_P (*t2))
    *t2 = TYPE_PTRMEM_POINTED_TO_TYPE (*t2);
  else
    *t2 = TREE_TYPE (*t2);

  casts_away_constness_r (t1, t2, complain);
  *t1 = build_pointer_type (*t1);
  *t2 = build_pointer_type (*t2);
  *t1 = cp_build_qualified_type (*t1, quals1);
  *t2 = cp_build_qualified_type (*t2, quals2);
}

/* Returns nonzero if casting from TYPE1 to TYPE2 casts away
   constness.  

   ??? This function returns non-zero if casting away qualifiers not
   just const.  We would like to return to the caller exactly which
   qualifiers are casted away to give more accurate diagnostics.
*/

static bool
casts_away_constness (tree t1, tree t2, tsubst_flags_t complain)
{
  if (TYPE_REF_P (t2))
    {
      /* [expr.const.cast]

	 Casting from an lvalue of type T1 to an lvalue of type T2
	 using a reference cast casts away constness if a cast from an
	 rvalue of type "pointer to T1" to the type "pointer to T2"
	 casts away constness.  */
      t1 = (TYPE_REF_P (t1) ? TREE_TYPE (t1) : t1);
      return casts_away_constness (build_pointer_type (t1),
				   build_pointer_type (TREE_TYPE (t2)),
				   complain);
    }

  if (TYPE_PTRDATAMEM_P (t1) && TYPE_PTRDATAMEM_P (t2))
    /* [expr.const.cast]

       Casting from an rvalue of type "pointer to data member of X
       of type T1" to the type "pointer to data member of Y of type
       T2" casts away constness if a cast from an rvalue of type
       "pointer to T1" to the type "pointer to T2" casts away
       constness.  */
    return casts_away_constness
      (build_pointer_type (TYPE_PTRMEM_POINTED_TO_TYPE (t1)),
       build_pointer_type (TYPE_PTRMEM_POINTED_TO_TYPE (t2)),
       complain);

  /* Casting away constness is only something that makes sense for
     pointer or reference types.  */
  if (!TYPE_PTR_P (t1) || !TYPE_PTR_P (t2))
    return false;

  /* Top-level qualifiers don't matter.  */
  t1 = TYPE_MAIN_VARIANT (t1);
  t2 = TYPE_MAIN_VARIANT (t2);
  casts_away_constness_r (&t1, &t2, complain);
  if (!can_convert (t2, t1, complain))
    return true;

  return false;
}

/* If T is a REFERENCE_TYPE return the type to which T refers.
   Otherwise, return T itself.  */

tree
non_reference (tree t)
{
  if (t && TYPE_REF_P (t))
    t = TREE_TYPE (t);
  return t;
}


/* Return nonzero if REF is an lvalue valid for this language;
   otherwise, print an error message and return zero.  USE says
   how the lvalue is being used and so selects the error message.  */

int
lvalue_or_else (tree ref, enum lvalue_use use, tsubst_flags_t complain)
{
  cp_lvalue_kind kind = lvalue_kind (ref);

  if (kind == clk_none)
    {
      if (complain & tf_error)
	lvalue_error (cp_expr_loc_or_input_loc (ref), use);
      return 0;
    }
  else if (kind & (clk_rvalueref|clk_class))
    {
      if (!(complain & tf_error))
	return 0;
      /* Make this a permerror because we used to accept it.  */
      permerror (cp_expr_loc_or_input_loc (ref),
		 "using rvalue as lvalue");
    }
  return 1;
}

/* Return true if a user-defined literal operator is a raw operator.  */

bool
check_raw_literal_operator (const_tree decl)
{
  tree argtypes = TYPE_ARG_TYPES (TREE_TYPE (decl));
  tree argtype;
  int arity;
  bool maybe_raw_p = false;

  /* Count the number and type of arguments and check for ellipsis.  */
  for (argtype = argtypes, arity = 0;
       argtype && argtype != void_list_node;
       ++arity, argtype = TREE_CHAIN (argtype))
    {
      tree t = TREE_VALUE (argtype);

      if (same_type_p (t, const_string_type_node))
	maybe_raw_p = true;
    }
  if (!argtype)
    return false; /* Found ellipsis.  */

  if (!maybe_raw_p || arity != 1)
    return false;

  return true;
}


/* Return true if a user-defined literal operator has one of the allowed
   argument types.  */

bool
check_literal_operator_args (const_tree decl,
			     bool *long_long_unsigned_p, bool *long_double_p)
{
  tree argtypes = TYPE_ARG_TYPES (TREE_TYPE (decl));

  *long_long_unsigned_p = false;
  *long_double_p = false;
  if (processing_template_decl || processing_specialization)
    return argtypes == void_list_node;
  else
    {
      tree argtype;
      int arity;
      int max_arity = 2;

      /* Count the number and type of arguments and check for ellipsis.  */
      for (argtype = argtypes, arity = 0;
	   argtype && argtype != void_list_node;
	   argtype = TREE_CHAIN (argtype))
	{
	  tree t = TREE_VALUE (argtype);
	  ++arity;

	  if (TYPE_PTR_P (t))
	    {
	      bool maybe_raw_p = false;
	      t = TREE_TYPE (t);
	      if (cp_type_quals (t) != TYPE_QUAL_CONST)
		return false;
	      t = TYPE_MAIN_VARIANT (t);
	      if ((maybe_raw_p = same_type_p (t, char_type_node))
		  || same_type_p (t, wchar_type_node)
		  || same_type_p (t, char8_type_node)
		  || same_type_p (t, char16_type_node)
		  || same_type_p (t, char32_type_node))
		{
		  argtype = TREE_CHAIN (argtype);
		  if (!argtype)
		    return false;
		  t = TREE_VALUE (argtype);
		  if (maybe_raw_p && argtype == void_list_node)
		    return true;
		  else if (same_type_p (t, size_type_node))
		    {
		      ++arity;
		      continue;
		    }
		  else
		    return false;
		}
	    }
	  else if (same_type_p (t, long_long_unsigned_type_node))
	    {
	      max_arity = 1;
	      *long_long_unsigned_p = true;
	    }
	  else if (same_type_p (t, long_double_type_node))
	    {
	      max_arity = 1;
	      *long_double_p = true;
	    }
	  else if (same_type_p (t, char_type_node))
	    max_arity = 1;
	  else if (same_type_p (t, wchar_type_node))
	    max_arity = 1;
	  else if (same_type_p (t, char8_type_node))
	    max_arity = 1;
	  else if (same_type_p (t, char16_type_node))
	    max_arity = 1;
	  else if (same_type_p (t, char32_type_node))
	    max_arity = 1;
	  else
	    return false;
	}
      if (!argtype)
	return false; /* Found ellipsis.  */

      if (arity != max_arity)
	return false;

      return true;
    }
}

/* Always returns false since unlike C90, C++ has no concept of implicit
   function declarations.  */

bool
c_decl_implicit (const_tree)
{
  return false;
}
