/* Language-level data type conversion for GNU C++.
   Copyright (C) 1987-2022 Free Software Foundation, Inc.
   Hacked by Michael Tiemann (tiemann@cygnus.com)

This file is part of GCC.

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

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

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


/* This file contains the functions for converting C++ expressions
   to different data types.  The only entry point is `convert'.
   Every language front end must have a `convert' function
   but what kind of conversions it does will depend on the language.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "target.h"
#include "cp-tree.h"
#include "stor-layout.h"
#include "flags.h"
#include "intl.h"
#include "convert.h"
#include "stringpool.h"
#include "attribs.h"
#include "escaped_string.h"

static tree convert_to_pointer_force (tree, tree, tsubst_flags_t);
static tree build_type_conversion (tree, tree);
static tree build_up_reference (tree, tree, int, tree, tsubst_flags_t);
static void diagnose_ref_binding (location_t, tree, tree, tree);

/* Change of width--truncation and extension of integers or reals--
   is represented with NOP_EXPR.  Proper functioning of many things
   assumes that no other conversions can be NOP_EXPRs.

   Conversion between integer and pointer is represented with CONVERT_EXPR.
   Converting integer to real uses FLOAT_EXPR
   and real to integer uses FIX_TRUNC_EXPR.

   Here is a list of all the functions that assume that widening and
   narrowing is always done with a NOP_EXPR:
     In convert.cc, convert_to_integer[_maybe_fold].
     In c-typeck.cc, build_binary_op_nodefault (boolean ops),
	and c_common_truthvalue_conversion.
     In expr.cc: expand_expr, for operands of a MULT_EXPR.
     In fold-const.cc: fold.
     In tree.cc: get_narrower and get_unwidened.

   C++: in multiple-inheritance, converting between pointers may involve
   adjusting them by a delta stored within the class definition.  */

/* Subroutines of `convert'.  */

/* if converting pointer to pointer
     if dealing with classes, check for derived->base or vice versa
     else if dealing with method pointers, delegate
     else convert blindly
   else if converting class, pass off to build_type_conversion
   else try C-style pointer conversion.  */

static tree
cp_convert_to_pointer (tree type, tree expr, bool dofold,
		       tsubst_flags_t complain)
{
  tree intype = TREE_TYPE (expr);
  enum tree_code form;
  tree rval;
  location_t loc = cp_expr_loc_or_input_loc (expr);

  if (intype == error_mark_node)
    return error_mark_node;

  if (MAYBE_CLASS_TYPE_P (intype))
    {
      intype = complete_type (intype);
      if (!COMPLETE_TYPE_P (intype))
	{
	  if (complain & tf_error)
	    error_at (loc, "cannot convert from incomplete type %qH to %qI",
		      intype, type);
	  return error_mark_node;
	}

      rval = build_type_conversion (type, expr);
      if (rval)
	{
	  if ((complain & tf_error)
	      && rval == error_mark_node)
	    error_at (loc, "conversion of %qE from %qH to %qI is ambiguous",
		      expr, intype, type);
	  return rval;
	}
    }

  /* Handle anachronistic conversions from (::*)() to cv void* or (*)().  */
  if (TYPE_PTR_P (type)
      && (TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE
	  || VOID_TYPE_P (TREE_TYPE (type))))
    {
      if (TYPE_PTRMEMFUNC_P (intype)
	  || TREE_CODE (intype) == METHOD_TYPE)
	return convert_member_func_to_ptr (type, expr, complain);
      if (TYPE_PTR_P (TREE_TYPE (expr)))
	return build_nop (type, expr);
      intype = TREE_TYPE (expr);
    }

  if (expr == error_mark_node)
    return error_mark_node;

  form = TREE_CODE (intype);

  if (INDIRECT_TYPE_P (intype))
    {
      intype = TYPE_MAIN_VARIANT (intype);

      if (TYPE_MAIN_VARIANT (type) != intype
	  && TYPE_PTR_P (type)
	  && TREE_CODE (TREE_TYPE (type)) == RECORD_TYPE
	  && MAYBE_CLASS_TYPE_P (TREE_TYPE (type))
	  && MAYBE_CLASS_TYPE_P (TREE_TYPE (intype))
	  && TREE_CODE (TREE_TYPE (intype)) == RECORD_TYPE)
	{
	  enum tree_code code = PLUS_EXPR;
	  tree binfo;
	  tree intype_class;
	  tree type_class;
	  bool same_p;

	  intype_class = TREE_TYPE (intype);
	  type_class = TREE_TYPE (type);

	  same_p = same_type_p (TYPE_MAIN_VARIANT (intype_class),
				TYPE_MAIN_VARIANT (type_class));
	  binfo = NULL_TREE;
	  /* Try derived to base conversion.  */
	  if (!same_p)
	    binfo = lookup_base (intype_class, type_class, ba_check,
				 NULL, complain);
	  if (!same_p && !binfo)
	    {
	      /* Try base to derived conversion.  */
	      binfo = lookup_base (type_class, intype_class, ba_check,
				   NULL, complain);
	      code = MINUS_EXPR;
	    }
	  if (binfo == error_mark_node)
	    return error_mark_node;
	  if (binfo || same_p)
	    {
	      if (binfo)
		expr = build_base_path (code, expr, binfo, 0, complain);
	      /* Add any qualifier conversions.  */
	      return build_nop (type, expr);
	    }
	}

      if (TYPE_PTRMEMFUNC_P (type))
	{
	  if (complain & tf_error)
	    error_at (loc, "cannot convert %qE from type %qH to type %qI",
		      expr, intype, type);
	  return error_mark_node;
	}

      return build_nop (type, expr);
    }
  else if ((TYPE_PTRDATAMEM_P (type) && TYPE_PTRDATAMEM_P (intype))
	   || (TYPE_PTRMEMFUNC_P (type) && TYPE_PTRMEMFUNC_P (intype)))
    return convert_ptrmem (type, expr, /*allow_inverse_p=*/false,
			   /*c_cast_p=*/false, complain);
  else if (TYPE_PTRMEMFUNC_P (intype))
    {
      if (!warn_pmf2ptr)
	{
	  if (TREE_CODE (expr) == PTRMEM_CST)
	    return cp_convert_to_pointer (type, PTRMEM_CST_MEMBER (expr),
					  dofold, complain);
	  else if (TREE_CODE (expr) == OFFSET_REF)
	    {
	      tree object = TREE_OPERAND (expr, 0);
	      return get_member_function_from_ptrfunc (&object,
						       TREE_OPERAND (expr, 1),
						       complain);
	    }
	}
      if (complain & tf_error)
	error_at (loc, "cannot convert %qE from type %qH to type %qI",
		  expr, intype, type);
      return error_mark_node;
    }

  if (null_ptr_cst_p (expr))
    {
      if (TYPE_PTRMEMFUNC_P (type))
	return build_ptrmemfunc (TYPE_PTRMEMFUNC_FN_TYPE (type), expr, 0,
				 /*c_cast_p=*/false, complain);

      if (complain & tf_warning)
	maybe_warn_zero_as_null_pointer_constant (expr, loc);

      /* A NULL pointer-to-data-member is represented by -1, not by
	 zero.  */
      tree val = (TYPE_PTRDATAMEM_P (type)
		  ? build_int_cst_type (type, -1)
		  : build_int_cst (type, 0));

      return (TREE_SIDE_EFFECTS (expr)
	      ? build2 (COMPOUND_EXPR, type, expr, val) : val);
    }
  else if (TYPE_PTRMEM_P (type) && INTEGRAL_CODE_P (form))
    {
      if (complain & tf_error)
	error_at (loc, "invalid conversion from %qH to %qI", intype, type);
      return error_mark_node;
    }

  if (INTEGRAL_CODE_P (form))
    {
      if (TYPE_PRECISION (intype) == POINTER_SIZE)
	return build1 (CONVERT_EXPR, type, expr);
      expr = cp_convert (c_common_type_for_size (TYPE_PRECISION (type), 0), expr,
			 complain);
      /* Modes may be different but sizes should be the same.  There
	 is supposed to be some integral type that is the same width
	 as a pointer.  */
      gcc_assert (GET_MODE_SIZE (SCALAR_INT_TYPE_MODE (TREE_TYPE (expr)))
		  == GET_MODE_SIZE (SCALAR_INT_TYPE_MODE (type)));

      /* FIXME needed because convert_to_pointer_maybe_fold still folds
	 conversion of constants.  */
      if (!dofold)
	return build1 (CONVERT_EXPR, type, expr);

      return convert_to_pointer_maybe_fold (type, expr, dofold);
    }

  if (type_unknown_p (expr))
    return instantiate_type (type, expr, complain);

  if (complain & tf_error)
    error_at (loc, "cannot convert %qE from type %qH to type %qI",
	      expr, intype, type);
  return error_mark_node;
}

/* Like convert, except permit conversions to take place which
   are not normally allowed due to access restrictions
   (such as conversion from sub-type to private super-type).  */

static tree
convert_to_pointer_force (tree type, tree expr, tsubst_flags_t complain)
{
  tree intype = TREE_TYPE (expr);
  enum tree_code form = TREE_CODE (intype);

  if (form == POINTER_TYPE)
    {
      intype = TYPE_MAIN_VARIANT (intype);

      if (TYPE_MAIN_VARIANT (type) != intype
	  && TREE_CODE (TREE_TYPE (type)) == RECORD_TYPE
	  && MAYBE_CLASS_TYPE_P (TREE_TYPE (type))
	  && MAYBE_CLASS_TYPE_P (TREE_TYPE (intype))
	  && TREE_CODE (TREE_TYPE (intype)) == RECORD_TYPE)
	{
	  enum tree_code code = PLUS_EXPR;
	  tree binfo;

	  binfo = lookup_base (TREE_TYPE (intype), TREE_TYPE (type),
			       ba_unique, NULL, complain);
	  if (!binfo)
	    {
	      binfo = lookup_base (TREE_TYPE (type), TREE_TYPE (intype),
				   ba_unique, NULL, complain);
	      code = MINUS_EXPR;
	    }
	  if (binfo == error_mark_node)
	    return error_mark_node;
	  if (binfo)
	    {
	      expr = build_base_path (code, expr, binfo, 0, complain);
	      if (expr == error_mark_node)
		 return error_mark_node;
	      /* Add any qualifier conversions.  */
	      if (!same_type_p (TREE_TYPE (TREE_TYPE (expr)),
				TREE_TYPE (type)))
		expr = build_nop (type, expr);
	      return expr;
	    }
	}
    }

  return cp_convert_to_pointer (type, expr, /*fold*/false, complain);
}

/* We are passing something to a function which requires a reference.
   The type we are interested in is in TYPE. The initial
   value we have to begin with is in ARG.

   FLAGS controls how we manage access checking.
   DIRECT_BIND in FLAGS controls how any temporaries are generated.
     If DIRECT_BIND is set, DECL is the reference we're binding to.  */

static tree
build_up_reference (tree type, tree arg, int flags, tree decl,
		    tsubst_flags_t complain)
{
  tree rval;
  tree argtype = TREE_TYPE (arg);
  tree target_type = TREE_TYPE (type);

  gcc_assert (TYPE_REF_P (type));

  if ((flags & DIRECT_BIND) && ! lvalue_p (arg))
    {
      /* Create a new temporary variable.  We can't just use a TARGET_EXPR
	 here because it needs to live as long as DECL.  */
      tree targ = arg;

      arg = make_temporary_var_for_ref_to_temp (decl, target_type);

      /* Process the initializer for the declaration.  */
      DECL_INITIAL (arg) = targ;
      cp_finish_decl (arg, targ, /*init_const_expr_p=*/false, NULL_TREE,
		      LOOKUP_ONLYCONVERTING|DIRECT_BIND);
    }
  else if (!(flags & DIRECT_BIND) && ! obvalue_p (arg))
    return get_target_expr (arg, complain);

  /* If we had a way to wrap this up, and say, if we ever needed its
     address, transform all occurrences of the register, into a memory
     reference we could win better.  */
  rval = cp_build_addr_expr (arg, complain);
  if (rval == error_mark_node)
    return error_mark_node;

  if ((flags & LOOKUP_PROTECT)
      && TYPE_MAIN_VARIANT (argtype) != TYPE_MAIN_VARIANT (target_type)
      && MAYBE_CLASS_TYPE_P (argtype)
      && MAYBE_CLASS_TYPE_P (target_type))
    {
      /* We go through lookup_base for the access control.  */
      tree binfo = lookup_base (argtype, target_type, ba_check,
				NULL, complain);
      if (binfo == error_mark_node)
	return error_mark_node;
      if (binfo == NULL_TREE)
	return error_not_base_type (target_type, argtype);
      rval = build_base_path (PLUS_EXPR, rval, binfo, 1, complain);
    }
  else
    rval
      = convert_to_pointer_force (build_pointer_type (target_type),
				  rval, complain);
  return build_nop (type, rval);
}

/* Subroutine of convert_to_reference. REFTYPE is the target reference type.
   INTYPE is the original rvalue type and DECL is an optional _DECL node
   for diagnostics.

   [dcl.init.ref] says that if an rvalue is used to
   initialize a reference, then the reference must be to a
   non-volatile const type.  */

static void
diagnose_ref_binding (location_t loc, tree reftype, tree intype, tree decl)
{
  tree ttl = TREE_TYPE (reftype);

  if (!TYPE_REF_IS_RVALUE (reftype)
      && !CP_TYPE_CONST_NON_VOLATILE_P (ttl))
    {
      const char *msg;

      if (CP_TYPE_VOLATILE_P (ttl) && decl)
	msg = G_("initialization of volatile reference type %q#T from "
	         "rvalue of type %qT");
      else if (CP_TYPE_VOLATILE_P (ttl))
	msg = G_("conversion to volatile reference type %q#T "
	         "from rvalue of type %qT");
      else if (decl)
	msg = G_("initialization of non-const reference type %q#T from "
	         "rvalue of type %qT");
      else
	msg = G_("conversion to non-const reference type %q#T from "
	         "rvalue of type %qT");

      permerror (loc, msg, reftype, intype);
    }
}

/* For C++: Only need to do one-level references, but cannot
   get tripped up on signed/unsigned differences.

   DECL is either NULL_TREE or the _DECL node for a reference that is being
   initialized.  It can be error_mark_node if we don't know the _DECL but
   we know it's an initialization.  */

tree
convert_to_reference (tree reftype, tree expr, int convtype,
		      int flags, tree decl, tsubst_flags_t complain)
{
  tree type = TYPE_MAIN_VARIANT (TREE_TYPE (reftype));
  tree intype;
  tree rval = NULL_TREE;
  tree rval_as_conversion = NULL_TREE;
  bool can_convert_intype_to_type;
  location_t loc = cp_expr_loc_or_input_loc (expr);

  if (TREE_CODE (type) == FUNCTION_TYPE
      && TREE_TYPE (expr) == unknown_type_node)
    expr = instantiate_type (type, expr, complain);

  if (expr == error_mark_node)
    return error_mark_node;

  intype = TREE_TYPE (expr);

  gcc_assert (!TYPE_REF_P (intype));
  gcc_assert (TYPE_REF_P (reftype));

  intype = TYPE_MAIN_VARIANT (intype);

  can_convert_intype_to_type = can_convert_standard (type, intype, complain);

  if (!can_convert_intype_to_type
      && (convtype & CONV_IMPLICIT) && MAYBE_CLASS_TYPE_P (intype)
      && ! (flags & LOOKUP_NO_CONVERSION))
    {
      /* Look for a user-defined conversion to lvalue that we can use.  */

      rval_as_conversion
	= build_type_conversion (reftype, expr);

      if (rval_as_conversion && rval_as_conversion != error_mark_node
	  && lvalue_p (rval_as_conversion))
	{
	  expr = rval_as_conversion;
	  rval_as_conversion = NULL_TREE;
	  intype = type;
	  can_convert_intype_to_type = 1;
	}
    }

  if (((convtype & CONV_STATIC)
       && can_convert_standard (intype, type, complain))
      || ((convtype & CONV_IMPLICIT) && can_convert_intype_to_type))
    {
      {
	tree ttl = TREE_TYPE (reftype);
	tree ttr = lvalue_type (expr);

	if ((complain & tf_error)
	    && ! lvalue_p (expr))
	  diagnose_ref_binding (loc, reftype, intype, decl);

	if (! (convtype & CONV_CONST)
	    && !at_least_as_qualified_p (ttl, ttr))
	  {
	    if (complain & tf_error)
	      permerror (loc, "conversion from %qH to %qI discards qualifiers",
			 ttr, reftype);
	    else
	      return error_mark_node;
	  }
      }

      return build_up_reference (reftype, expr, flags, decl, complain);
    }
  else if ((convtype & CONV_REINTERPRET) && obvalue_p (expr))
    {
      /* When casting an lvalue to a reference type, just convert into
	 a pointer to the new type and deference it.  This is allowed
	 by San Diego WP section 5.2.9 paragraph 12, though perhaps it
	 should be done directly (jason).  (int &)ri ---> *(int*)&ri */

      /* B* bp; A& ar = (A&)bp; is valid, but it's probably not what they
	 meant.  */
      if ((complain & tf_warning)
	  && TYPE_PTR_P (intype)
	  && (comptypes (TREE_TYPE (intype), type,
			 COMPARE_BASE | COMPARE_DERIVED)))
	warning_at (loc, 0, "casting %qT to %qT does not dereference pointer",
		    intype, reftype);

      rval = cp_build_addr_expr (expr, complain);
      if (rval != error_mark_node)
	rval = convert_force (build_pointer_type (TREE_TYPE (reftype)),
			      rval, 0, complain);
      if (rval != error_mark_node)
	rval = build1 (NOP_EXPR, reftype, rval);
    }
  else
    {
      rval = convert_for_initialization (NULL_TREE, type, expr, flags,
					 ICR_CONVERTING, 0, 0, complain);
      if (rval == NULL_TREE || rval == error_mark_node)
	return rval;
      if (complain & tf_error)
	diagnose_ref_binding (loc, reftype, intype, decl);
      rval = build_up_reference (reftype, rval, flags, decl, complain);
    }

  if (rval)
    {
      /* If we found a way to convert earlier, then use it.  */
      return rval;
    }

  if (complain & tf_error)
    error_at (loc, "cannot convert type %qH to type %qI", intype, reftype);

  return error_mark_node;
}

/* We are using a reference VAL for its value. Bash that reference all the
   way down to its lowest form.  */

tree
convert_from_reference (tree val)
{
  if (TREE_TYPE (val)
      && TYPE_REF_P (TREE_TYPE (val)))
    {
      tree t = TREE_TYPE (TREE_TYPE (val));
      tree ref = build1 (INDIRECT_REF, t, val);

      mark_exp_read (val);
       /* 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 (val));
      val = ref;
    }

  return val;
}

/* Really perform an lvalue-to-rvalue conversion, including copying an
   argument of class type into a temporary.  */

tree
force_rvalue (tree expr, tsubst_flags_t complain)
{
  tree type = TREE_TYPE (expr);
  if (MAYBE_CLASS_TYPE_P (type) && TREE_CODE (expr) != TARGET_EXPR)
    {
      releasing_vec args (make_tree_vector_single (expr));
      expr = build_special_member_call (NULL_TREE, complete_ctor_identifier,
					&args, type, LOOKUP_NORMAL, complain);
      expr = build_cplus_new (type, expr, complain);
    }
  else
    expr = decay_conversion (expr, complain);

  return expr;
}


/* If EXPR and ORIG are INTEGER_CSTs, return a version of EXPR that has
   TREE_OVERFLOW set only if it is set in ORIG.  Otherwise, return EXPR
   unchanged.  */

static tree
ignore_overflows (tree expr, tree orig)
{
  tree stripped_expr = tree_strip_any_location_wrapper (expr);
  tree stripped_orig = tree_strip_any_location_wrapper (orig);

  if (TREE_CODE (stripped_expr) == INTEGER_CST
      && TREE_CODE (stripped_orig) == INTEGER_CST
      && TREE_OVERFLOW (stripped_expr) != TREE_OVERFLOW (stripped_orig))
    {
      gcc_assert (!TREE_OVERFLOW (stripped_orig));
      /* Ensure constant sharing.  */
      stripped_expr = wide_int_to_tree (TREE_TYPE (stripped_expr),
					wi::to_wide (stripped_expr));
    }

  return preserve_any_location_wrapper (stripped_expr, expr);
}

/* Fold away simple conversions, but make sure TREE_OVERFLOW is set
   properly and propagate TREE_NO_WARNING if folding EXPR results
   in the same expression code.  */

tree
cp_fold_convert (tree type, tree expr)
{
  tree conv;
  if (TREE_TYPE (expr) == type)
    conv = expr;
  else if (TREE_CODE (expr) == PTRMEM_CST
	   && same_type_p (TYPE_PTRMEM_CLASS_TYPE (type),
			   PTRMEM_CST_CLASS (expr)))
    {
      /* Avoid wrapping a PTRMEM_CST in NOP_EXPR.  */
      conv = copy_node (expr);
      TREE_TYPE (conv) = type;
    }
  else if (TYPE_PTRMEM_P (type))
    {
      conv = convert_ptrmem (type, expr, true, false,
			     tf_warning_or_error);
      conv = cp_fully_fold (conv);
    }
  else
    {
      conv = fold_convert (type, expr);
      conv = ignore_overflows (conv, expr);
    }

  if (TREE_CODE (expr) == TREE_CODE (conv))
    copy_warning (conv, expr);

  return conv;
}

/* C++ conversions, preference to static cast conversions.  */

tree
cp_convert (tree type, tree expr, tsubst_flags_t complain)
{
  return ocp_convert (type, expr, CONV_OLD_CONVERT, LOOKUP_NORMAL, complain);
}

/* C++ equivalent of convert_and_check but using cp_convert as the
   conversion function.

   Convert EXPR to TYPE, warning about conversion problems with constants.
   Invoke this function on every expression that is converted implicitly,
   i.e. because of language rules and not because of an explicit cast.  */

tree
cp_convert_and_check (tree type, tree expr, tsubst_flags_t complain)
{
  tree result;

  if (TREE_TYPE (expr) == type)
    return expr;
  if (expr == error_mark_node)
    return expr;
  result = cp_convert (type, expr, complain);

  if ((complain & tf_warning)
      && c_inhibit_evaluation_warnings == 0)
    {
      tree folded = cp_fully_fold (expr);
      tree folded_result;
      if (folded == expr)
	folded_result = result;
      else
	{
	  /* Avoid bogus -Wparentheses warnings.  */
	  warning_sentinel w (warn_parentheses);
	  warning_sentinel c (warn_int_in_bool_context);
	  folded_result = cp_convert (type, folded, tf_none);
	}
      folded_result = fold_simple (folded_result);
      if (!TREE_OVERFLOW_P (folded)
	  && folded_result != error_mark_node)
	warnings_for_convert_and_check (cp_expr_loc_or_input_loc (expr),
					type, folded, folded_result);
    }

  return result;
}

/* Conversion...

   FLAGS indicates how we should behave.  */

tree
ocp_convert (tree type, tree expr, int convtype, int flags,
	     tsubst_flags_t complain)
{
  tree e = expr;
  enum tree_code code = TREE_CODE (type);
  const char *invalid_conv_diag;
  tree e1;
  location_t loc = cp_expr_loc_or_input_loc (expr);
  bool dofold = (convtype & CONV_FOLD);

  if (error_operand_p (e) || type == error_mark_node)
    return error_mark_node;

  if (TREE_CODE (e) == COMPOUND_EXPR)
    {
      e = ocp_convert (type, TREE_OPERAND (e, 1), convtype, flags, complain);
      if (e == error_mark_node)
	return error_mark_node;
      if (e == TREE_OPERAND (expr, 1))
	return expr;
      return build2_loc (EXPR_LOCATION (expr), COMPOUND_EXPR, TREE_TYPE (e),
			 TREE_OPERAND (expr, 0), e);
    }

  complete_type (type);
  complete_type (TREE_TYPE (expr));

  if ((invalid_conv_diag
       = targetm.invalid_conversion (TREE_TYPE (expr), type)))
    {
      if (complain & tf_error)
	error (invalid_conv_diag);
      return error_mark_node;
    }

  /* FIXME remove when moving to c_fully_fold model.  */
  if (!CLASS_TYPE_P (type))
    {
      e = mark_rvalue_use (e);
      tree v = scalar_constant_value (e);
      if (!error_operand_p (v))
	e = v;
    }
  if (error_operand_p (e))
    return error_mark_node;

  if (NULLPTR_TYPE_P (type) && null_ptr_cst_p (e))
    {
      if (complain & tf_warning)
	maybe_warn_zero_as_null_pointer_constant (e, loc);

      if (!TREE_SIDE_EFFECTS (e))
	return nullptr_node;
    }

  if (MAYBE_CLASS_TYPE_P (type) && (convtype & CONV_FORCE_TEMP))
    /* We need a new temporary; don't take this shortcut.  */;
  else if (same_type_ignoring_top_level_qualifiers_p (type, TREE_TYPE (e)))
    {
      tree etype = TREE_TYPE (e);
      if (same_type_p (type, etype))
	/* The call to fold will not always remove the NOP_EXPR as
	   might be expected, since if one of the types is a typedef;
	   the comparison in fold is just equality of pointers, not a
	   call to comptypes.  We don't call fold in this case because
	   that can result in infinite recursion; fold will call
	   convert, which will call ocp_convert, etc.  */
	return e;
      /* For complex data types, we need to perform componentwise
	 conversion.  */
      else if (TREE_CODE (type) == COMPLEX_TYPE)
	return convert_to_complex_maybe_fold (type, e, dofold);
      else if (VECTOR_TYPE_P (type))
	return convert_to_vector (type, rvalue (e));
      else if (TREE_CODE (e) == TARGET_EXPR)
	{
	  /* Don't build a NOP_EXPR of class type.  Instead, change the
	     type of the temporary.  */
	  gcc_assert (same_type_ignoring_top_level_qualifiers_p (type, etype));
	  TREE_TYPE (e) = TREE_TYPE (TARGET_EXPR_SLOT (e)) = type;
	  return e;
	}
      else if (TREE_CODE (e) == CONSTRUCTOR)
	{
	  gcc_assert (same_type_ignoring_top_level_qualifiers_p (type, etype));
	  TREE_TYPE (e) = type;
	  return e;
	}
      else
	{
	  /* We shouldn't be treating objects of ADDRESSABLE type as
	     rvalues.  */
	  gcc_assert (!TREE_ADDRESSABLE (type));
	  return build_nop (type, e);
	}
    }

  e1 = targetm.convert_to_type (type, e);
  if (e1)
    return e1;

  if (code == VOID_TYPE && (convtype & CONV_STATIC))
    {
      e = convert_to_void (e, ICV_CAST, complain);
      return e;
    }

  if (INTEGRAL_CODE_P (code))
    {
      tree intype = TREE_TYPE (e);
      tree converted;

      if (TREE_CODE (type) == ENUMERAL_TYPE)
	{
	  /* enum = enum, enum = int, enum = float, (enum)pointer are all
	     errors.  */
	  if (((INTEGRAL_OR_ENUMERATION_TYPE_P (intype)
		|| TREE_CODE (intype) == REAL_TYPE)
	       && ! (convtype & CONV_STATIC))
	      || TYPE_PTR_P (intype))
	    {
	      if (complain & tf_error)
		permerror (loc, "conversion from %q#T to %q#T", intype, type);
	      else
		return error_mark_node;
	    }

	  /* [expr.static.cast]

	     8. A value of integral or enumeration type can be explicitly
	     converted to an enumeration type. The value is unchanged if
	     the original value is within the range of the enumeration
	     values. Otherwise, the resulting enumeration value is
	     unspecified.  */
	  tree val = fold_for_warn (e);
	  if ((complain & tf_warning)
	      && TREE_CODE (val) == INTEGER_CST
	      && ENUM_UNDERLYING_TYPE (type)
	      && !int_fits_type_p (val, ENUM_UNDERLYING_TYPE (type)))
	    warning_at (loc, OPT_Wconversion, 
			"the result of the conversion is unspecified because "
			"%qE is outside the range of type %qT",
			expr, type);
	}
      if (MAYBE_CLASS_TYPE_P (intype))
	{
	  tree rval;
	  rval = build_type_conversion (type, e);
	  if (rval)
	    return rval;
	  if (complain & tf_error)
	    error_at (loc, "%q#T used where a %qT was expected", intype, type);
	  return error_mark_node;
	}
      if (code == BOOLEAN_TYPE)
	{
	  if (VOID_TYPE_P (intype))
	    {
	      if (complain & tf_error)
		error_at (loc,
			  "could not convert %qE from %<void%> to %<bool%>",
			  expr);
	      return error_mark_node;
	    }

	  if (VECTOR_TYPE_P (intype) && !gnu_vector_type_p (intype))
	    {
	      if (complain & tf_error)
		error_at (loc, "could not convert %qE from %qH to %qI", expr,
			  TREE_TYPE (expr), type);
	      return error_mark_node;
	    }

	  /* We can't implicitly convert a scoped enum to bool, so convert
	     to the underlying type first.  */
	  if (SCOPED_ENUM_P (intype) && (convtype & CONV_STATIC))
	    e = build_nop (ENUM_UNDERLYING_TYPE (intype), e);
	  if (complain & tf_warning)
	    return cp_truthvalue_conversion (e, complain);
	  else
	    {
	      /* Prevent bogus -Wint-in-bool-context warnings coming
		 from c_common_truthvalue_conversion down the line.  */
	      warning_sentinel w (warn_int_in_bool_context);
	      warning_sentinel c (warn_sign_compare);
	      return cp_truthvalue_conversion (e, complain);
	    }
	}

      converted = convert_to_integer_maybe_fold (type, e, dofold);

      /* Ignore any integer overflow caused by the conversion.  */
      return ignore_overflows (converted, e);
    }
  if (INDIRECT_TYPE_P (type) || TYPE_PTRMEM_P (type))
    return cp_convert_to_pointer (type, e, dofold, complain);
  if (code == VECTOR_TYPE)
    {
      tree in_vtype = TREE_TYPE (e);
      if (MAYBE_CLASS_TYPE_P (in_vtype))
	{
	  tree ret_val;
	  ret_val = build_type_conversion (type, e);
	  if (ret_val)
	    return ret_val;
	  if (complain & tf_error)
	    error_at (loc, "%q#T used where a %qT was expected",
		      in_vtype, type);
	  return error_mark_node;
	}
      return convert_to_vector (type, rvalue (e));
    }
  if (code == REAL_TYPE || code == COMPLEX_TYPE)
    {
      if (MAYBE_CLASS_TYPE_P (TREE_TYPE (e)))
	{
	  tree rval;
	  rval = build_type_conversion (type, e);
	  if (rval)
	    return rval;
	  else if (complain & tf_error)
	    error_at (loc,
		      "%q#T used where a floating-point value was expected",
		      TREE_TYPE (e));
	}
      if (code == REAL_TYPE)
	return convert_to_real_maybe_fold (type, e, dofold);
      else if (code == COMPLEX_TYPE)
	return convert_to_complex_maybe_fold (type, e, dofold);
    }

  /* New C++ semantics:  since assignment is now based on
     memberwise copying,  if the rhs type is derived from the
     lhs type, then we may still do a conversion.  */
  if (RECORD_OR_UNION_CODE_P (code))
    {
      tree dtype = TREE_TYPE (e);
      tree ctor = NULL_TREE;

      dtype = TYPE_MAIN_VARIANT (dtype);

      /* Conversion between aggregate types.  New C++ semantics allow
	 objects of derived type to be cast to objects of base type.
	 Old semantics only allowed this between pointers.

	 There may be some ambiguity between using a constructor
	 vs. using a type conversion operator when both apply.  */

      ctor = e;

      if (abstract_virtuals_error (NULL_TREE, type, complain))
	return error_mark_node;

      if (BRACE_ENCLOSED_INITIALIZER_P (ctor))
	ctor = perform_implicit_conversion (type, ctor, complain);
      else if ((flags & LOOKUP_ONLYCONVERTING)
	       && ! (CLASS_TYPE_P (dtype) && DERIVED_FROM_P (type, dtype)))
	/* For copy-initialization, first we create a temp of the proper type
	   with a user-defined conversion sequence, then we direct-initialize
	   the target with the temp (see [dcl.init]).  */
	ctor = build_user_type_conversion (type, ctor, flags, complain);
      else
	{
	  releasing_vec ctor_vec (make_tree_vector_single (ctor));
	  ctor = build_special_member_call (NULL_TREE,
					    complete_ctor_identifier,
					    &ctor_vec,
					    type, flags, complain);
	}
      if (ctor)
	return build_cplus_new (type, ctor, complain);
    }

  if (complain & tf_error)
    {
      /* If the conversion failed and expr was an invalid use of pointer to
	 member function, try to report a meaningful error.  */
      if (invalid_nonstatic_memfn_p (loc, expr, complain))
	/* We displayed the error message.  */;
      else
	error_at (loc, "conversion from %qH to non-scalar type %qI requested",
		  TREE_TYPE (expr), type);
    }
  return error_mark_node;
}

/* If CALL is a call, return the callee; otherwise null.  */

tree
cp_get_callee (tree call)
{
  if (call == NULL_TREE)
    return call;
  else if (TREE_CODE (call) == CALL_EXPR)
    return CALL_EXPR_FN (call);
  else if (TREE_CODE (call) == AGGR_INIT_EXPR)
    return AGGR_INIT_EXPR_FN (call);
  return NULL_TREE;
}

/* FN is the callee of a CALL_EXPR or AGGR_INIT_EXPR; return the FUNCTION_DECL
   if we can.  */

tree
cp_get_fndecl_from_callee (tree fn, bool fold /* = true */)
{
  if (fn == NULL_TREE)
    return fn;
  if (TREE_CODE (fn) == FUNCTION_DECL)
    return fn;
  tree type = TREE_TYPE (fn);
  if (type == NULL_TREE || !INDIRECT_TYPE_P (type))
    return NULL_TREE;
  if (fold)
    fn = maybe_constant_init (fn);
  STRIP_NOPS (fn);
  if (TREE_CODE (fn) == ADDR_EXPR
      || TREE_CODE (fn) == FDESC_EXPR)
    fn = TREE_OPERAND (fn, 0);
  if (TREE_CODE (fn) == FUNCTION_DECL)
    return fn;
  return NULL_TREE;
}

/* Like get_callee_fndecl, but handles AGGR_INIT_EXPR as well and uses the
   constexpr machinery.  */

tree
cp_get_callee_fndecl (tree call)
{
  return cp_get_fndecl_from_callee (cp_get_callee (call));
}

/* As above, but not using the constexpr machinery.  */

tree
cp_get_callee_fndecl_nofold (tree call)
{
  return cp_get_fndecl_from_callee (cp_get_callee (call), false);
}

/* Subroutine of convert_to_void.  Warn if we're discarding something with
   attribute [[nodiscard]].  */

static void
maybe_warn_nodiscard (tree expr, impl_conv_void implicit)
{
  if (!warn_unused_result || c_inhibit_evaluation_warnings)
    return;

  tree call = expr;
  if (TREE_CODE (expr) == TARGET_EXPR)
    call = TARGET_EXPR_INITIAL (expr);
  location_t loc = cp_expr_loc_or_input_loc (call);
  tree callee = cp_get_callee (call);
  if (!callee)
    return;

  tree type = TREE_TYPE (callee);
  if (TYPE_PTRMEMFUNC_P (type))
    type = TYPE_PTRMEMFUNC_FN_TYPE (type);
  if (INDIRECT_TYPE_P (type))
    type = TREE_TYPE (type);

  tree rettype = TREE_TYPE (type);
  tree fn = cp_get_fndecl_from_callee (callee);
  tree attr;
  if (implicit != ICV_CAST && fn
      && (attr = lookup_attribute ("nodiscard", DECL_ATTRIBUTES (fn))))
    {
      escaped_string msg;
      tree args = TREE_VALUE (attr);
      if (args)
	msg.escape (TREE_STRING_POINTER (TREE_VALUE (args)));
      const char *format
	= (msg
	   ? G_("ignoring return value of %qD, "
		"declared with attribute %<nodiscard%>: %<%s%>")
	   : G_("ignoring return value of %qD, "
		"declared with attribute %<nodiscard%>%s"));
      const char *raw_msg = msg ? (const char *) msg : "";
      auto_diagnostic_group d;
      if (warning_at (loc, OPT_Wunused_result, format, fn, raw_msg))
	inform (DECL_SOURCE_LOCATION (fn), "declared here");
    }
  else if (implicit != ICV_CAST
	   && (attr = lookup_attribute ("nodiscard", TYPE_ATTRIBUTES (rettype))))
    {
      escaped_string msg;
      tree args = TREE_VALUE (attr);
      if (args)
	msg.escape (TREE_STRING_POINTER (TREE_VALUE (args)));
      const char *format
	= (msg
	   ? G_("ignoring returned value of type %qT, "
		"declared with attribute %<nodiscard%>: %<%s%>")
	   : G_("ignoring returned value of type %qT, "
		"declared with attribute %<nodiscard%>%s"));
      const char *raw_msg = msg ? (const char *) msg : "";
      auto_diagnostic_group d;
      if (warning_at (loc, OPT_Wunused_result, format, rettype, raw_msg))
	{
	  if (fn)
	    inform (DECL_SOURCE_LOCATION (fn),
		    "in call to %qD, declared here", fn);
	  inform (DECL_SOURCE_LOCATION (TYPE_NAME (rettype)),
		  "%qT declared here", rettype);
	}
    }
  else if (TREE_CODE (expr) == TARGET_EXPR
	   && lookup_attribute ("warn_unused_result", TYPE_ATTRIBUTES (type)))
    {
      /* The TARGET_EXPR confuses do_warn_unused_result into thinking that the
	 result is used, so handle that case here.  */
      if (fn)
	{
	  auto_diagnostic_group d;
	  if (warning_at (loc, OPT_Wunused_result,
			  "ignoring return value of %qD, "
			  "declared with attribute %<warn_unused_result%>",
			  fn))
	    inform (DECL_SOURCE_LOCATION (fn), "declared here");
	}
      else
	warning_at (loc, OPT_Wunused_result,
		    "ignoring return value of function "
		    "declared with attribute %<warn_unused_result%>");
    }
}

/* When an expression is used in a void context, its value is discarded and
   no lvalue-rvalue and similar conversions happen [expr.static.cast/4,
   stmt.expr/1, expr.comma/1].  This permits dereferencing an incomplete type
   in a void context. The C++ standard does not define what an `access' to an
   object is, but there is reason to believe that it is the lvalue to rvalue
   conversion -- if it were not, `*&*p = 1' would violate [expr]/4 in that it
   accesses `*p' not to calculate the value to be stored. But, dcl.type.cv/8
   indicates that volatile semantics should be the same between C and C++
   where ever possible. C leaves it implementation defined as to what
   constitutes an access to a volatile. So, we interpret `*vp' as a read of
   the volatile object `vp' points to, unless that is an incomplete type. For
   volatile references we do not do this interpretation, because that would
   make it impossible to ignore the reference return value from functions. We
   issue warnings in the confusing cases.

   The IMPLICIT is ICV_CAST when the user is explicitly converting an expression
   to void via a cast. If an expression is being implicitly converted, IMPLICIT
   indicates the context of the implicit conversion.  */

tree
convert_to_void (tree expr, impl_conv_void implicit, tsubst_flags_t complain)
{
  location_t loc = cp_expr_loc_or_input_loc (expr);

  if (expr == error_mark_node
      || TREE_TYPE (expr) == error_mark_node)
    return error_mark_node;

  expr = maybe_undo_parenthesized_ref (expr);

  expr = mark_discarded_use (expr);
  if (implicit == ICV_CAST)
    /* An explicit cast to void avoids all -Wunused-but-set* warnings.  */
    mark_exp_read (expr);

  if (!TREE_TYPE (expr))
    return expr;
  if (invalid_nonstatic_memfn_p (loc, expr, complain))
    return error_mark_node;
  if (TREE_CODE (expr) == PSEUDO_DTOR_EXPR)
    {
      if (complain & tf_error)
        error_at (loc, "pseudo-destructor is not called");
      return error_mark_node;
    }

  /* Explicitly evaluate void-converted concept checks since their
     satisfaction may produce ill-formed programs.  */
   if (concept_check_p (expr))
     expr = evaluate_concept_check (expr);

  if (VOID_TYPE_P (TREE_TYPE (expr)))
    return expr;
  switch (TREE_CODE (expr))
    {
    case COND_EXPR:
      {
	/* The two parts of a cond expr might be separate lvalues.  */
	tree op1 = TREE_OPERAND (expr,1);
	tree op2 = TREE_OPERAND (expr,2);
	bool side_effects = ((op1 && TREE_SIDE_EFFECTS (op1))
			     || TREE_SIDE_EFFECTS (op2));
	tree new_op1, new_op2;
	new_op1 = NULL_TREE;
	if (implicit != ICV_CAST && !side_effects)
	  {
	    if (op1)
	      new_op1 = convert_to_void (op1, ICV_SECOND_OF_COND, complain);
	    new_op2 = convert_to_void (op2, ICV_THIRD_OF_COND, complain);
	  }
	else
	  {
	    if (op1)
	      new_op1 = convert_to_void (op1, ICV_CAST, complain);
	    new_op2 = convert_to_void (op2, ICV_CAST, complain);
	  }

	expr = build3_loc (loc, COND_EXPR, TREE_TYPE (new_op2),
			   TREE_OPERAND (expr, 0), new_op1, new_op2);
	break;
      }

    case COMPOUND_EXPR:
      {
	/* The second part of a compound expr contains the value.  */
	tree op1 = TREE_OPERAND (expr,1);
	tree new_op1;
	if (implicit != ICV_CAST && !warning_suppressed_p (expr /* What warning? */))
	  new_op1 = convert_to_void (op1, ICV_RIGHT_OF_COMMA, complain);
	else
	  new_op1 = convert_to_void (op1, ICV_CAST, complain);

	if (new_op1 != op1)
	  {
	    tree t = build2_loc (loc, COMPOUND_EXPR, TREE_TYPE (new_op1),
				 TREE_OPERAND (expr, 0), new_op1);
	    expr = t;
	  }

	break;
      }

    case NON_LVALUE_EXPR:
    case NOP_EXPR:
      /* These have already decayed to rvalue.  */
      break;

    case CALL_EXPR:   /* We have a special meaning for volatile void fn().  */
      /* cdtors may return this or void, depending on
	 targetm.cxx.cdtor_returns_this, but this shouldn't affect our
	 decisions here: neither nodiscard warnings (nodiscard dtors
	 are nonsensical and ctors have a different behavior with that
	 attribute that is handled in the TARGET_EXPR case), nor should
	 any constexpr or template instantiations be affected by an ABI
	 property that is, or at least ought to be transparent to the
	 language.  */
      if (tree fn = cp_get_callee_fndecl_nofold (expr))
	if (DECL_CONSTRUCTOR_P (fn) || DECL_DESTRUCTOR_P (fn))
	  return expr;

      if (complain & tf_warning)
	maybe_warn_nodiscard (expr, implicit);
      break;

    case INDIRECT_REF:
      {
	tree type = TREE_TYPE (expr);
	int is_reference = TYPE_REF_P (TREE_TYPE (TREE_OPERAND (expr, 0)));
	int is_volatile = TYPE_VOLATILE (type);
	int is_complete = COMPLETE_TYPE_P (complete_type (type));

	/* Can't load the value if we don't know the type.  */
	if (is_volatile && !is_complete)
          {
            if (complain & tf_warning)
	      switch (implicit)
		{
	      	  case ICV_CAST:
		    warning_at (loc, 0, "conversion to void will not access "
				"object of incomplete type %qT", type);
		    break;
		  case ICV_SECOND_OF_COND:
		    warning_at (loc, 0, "indirection will not access object of "
				"incomplete type %qT in second operand "
				"of conditional expression", type);
		    break;
		  case ICV_THIRD_OF_COND:
		    warning_at (loc, 0, "indirection will not access object of "
				"incomplete type %qT in third operand "
				"of conditional expression", type);
		    break;
		  case ICV_RIGHT_OF_COMMA:
		    warning_at (loc, 0, "indirection will not access object of "
				"incomplete type %qT in right operand of "
				"comma operator", type);
		    break;
		  case ICV_LEFT_OF_COMMA:
		    warning_at (loc, 0, "indirection will not access object of "
				"incomplete type %qT in left operand of "
				"comma operator", type);
		    break;
		  case ICV_STATEMENT:
		    warning_at (loc, 0, "indirection will not access object of "
				"incomplete type %qT in statement", type);
		     break;
		  case ICV_THIRD_IN_FOR:
		    warning_at (loc, 0, "indirection will not access object of "
				"incomplete type %qT in for increment "
				"expression", type);
		    break;
		  default:
		    gcc_unreachable ();
		}
          }
	/* Don't load the value if this is an implicit dereference, or if
	   the type needs to be handled by ctors/dtors.  */
	else if (is_volatile && is_reference)
          {
            if (complain & tf_warning)
	      switch (implicit)
		{
	      	  case ICV_CAST:
		    warning_at (loc, 0, "conversion to void will not access "
				"object of type %qT", type);
		    break;
		  case ICV_SECOND_OF_COND:
		    warning_at (loc, 0, "implicit dereference will not access "
				"object of type %qT in second operand of "
				"conditional expression", type);
		    break;
		  case ICV_THIRD_OF_COND:
		    warning_at (loc, 0, "implicit dereference will not access "
				"object of type %qT in third operand of "
				"conditional expression", type);
		    break;
		  case ICV_RIGHT_OF_COMMA:
		    warning_at (loc, 0, "implicit dereference will not access "
				"object of type %qT in right operand of "
				"comma operator", type);
		    break;
		  case ICV_LEFT_OF_COMMA:
		    warning_at (loc, 0, "implicit dereference will not access "
				"object of type %qT in left operand of comma "
				"operator", type);
		    break;
		  case ICV_STATEMENT:
		    warning_at (loc, 0, "implicit dereference will not access "
				"object of type %qT in statement",  type);
		     break;
		  case ICV_THIRD_IN_FOR:
		    warning_at (loc, 0, "implicit dereference will not access "
				"object of type %qT in for increment expression",
				type);
		    break;
		  default:
		    gcc_unreachable ();
		}
          }
	else if (is_volatile && TREE_ADDRESSABLE (type))
	  {
	    if (complain & tf_warning)
	      switch (implicit)
		{
	      	  case ICV_CAST:
		    warning_at (loc, 0, "conversion to void will not access "
				"object of non-trivially-copyable type %qT",
				type);
		    break;
		  case ICV_SECOND_OF_COND:
		    warning_at (loc, 0, "indirection will not access object of "
				"non-trivially-copyable type %qT in second "
				"operand of conditional expression", type);
		    break;
		  case ICV_THIRD_OF_COND:
		    warning_at (loc, 0, "indirection will not access object of "
		  	      	"non-trivially-copyable type %qT in third "
				"operand of conditional expression", type);
		    break;
		  case ICV_RIGHT_OF_COMMA:
		    warning_at (loc, 0, "indirection will not access object of "
		    		"non-trivially-copyable type %qT in right "
				"operand of comma operator", type);
		    break;
		  case ICV_LEFT_OF_COMMA:
		    warning_at (loc, 0, "indirection will not access object of "
		    		"non-trivially-copyable type %qT in left "
				"operand of comma operator", type);
		    break;
		  case ICV_STATEMENT:
		    warning_at (loc, 0, "indirection will not access object of "
		     		"non-trivially-copyable type %qT in statement",
				type);
		     break;
		  case ICV_THIRD_IN_FOR:
		    warning_at (loc, 0, "indirection will not access object of "
		    		"non-trivially-copyable type %qT in for "
				"increment expression", type);
		    break;
		  default:
		    gcc_unreachable ();
		}
	  }
	if (is_reference || !is_volatile || !is_complete || TREE_ADDRESSABLE (type))
          {
            /* Emit a warning (if enabled) when the "effect-less" INDIRECT_REF
               operation is stripped off. Note that we don't warn about
               - an expression with TREE_NO_WARNING set. (For an example of
                 such expressions, see build_over_call in call.cc.)
               - automatic dereferencing of references, since the user cannot
                 control it. (See also warn_if_unused_value() in c-common.cc.)  */
            if (warn_unused_value
		&& implicit != ICV_CAST
                && (complain & tf_warning)
                && !warning_suppressed_p (expr, OPT_Wunused_value)
                && !is_reference)
              warning_at (loc, OPT_Wunused_value, "value computed is not used");
            expr = TREE_OPERAND (expr, 0);
	    if (TREE_CODE (expr) == CALL_EXPR
		&& (complain & tf_warning))
	      maybe_warn_nodiscard (expr, implicit);
          }

	break;
      }

    case VAR_DECL:
      {
	/* External variables might be incomplete.  */
	tree type = TREE_TYPE (expr);
	int is_complete = COMPLETE_TYPE_P (complete_type (type));

	if (TYPE_VOLATILE (type) && !is_complete && (complain & tf_warning))
	  switch (implicit)
	    {
	      case ICV_CAST:
		warning_at (loc, 0, "conversion to void will not access "
			    "object %qE of incomplete type %qT", expr, type);
		break;
	      case ICV_SECOND_OF_COND:
	        warning_at (loc, 0, "variable %qE of incomplete type %qT will "
			    "not be accessed in second operand of "
			    "conditional expression", expr, type);
		break;
	      case ICV_THIRD_OF_COND:
	        warning_at (loc, 0, "variable %qE of incomplete type %qT will "
			    "not be accessed in third operand of "
			    "conditional expression", expr, type);
		break;
	      case ICV_RIGHT_OF_COMMA:
	        warning_at (loc, 0, "variable %qE of incomplete type %qT will "
			    "not be accessed in right operand of comma operator",
			    expr, type);
		break;
	      case ICV_LEFT_OF_COMMA:
	        warning_at (loc, 0, "variable %qE of incomplete type %qT will "
			    "not be accessed in left operand of comma operator",
			    expr, type);
		break;
	      case ICV_STATEMENT:
	        warning_at (loc, 0, "variable %qE of incomplete type %qT will "
			    "not be accessed in statement", expr, type);
		break;
	      case ICV_THIRD_IN_FOR:
	        warning_at (loc, 0, "variable %qE of incomplete type %qT will "
			    "not be accessed in for increment expression",
			    expr, type);
		break;
	      default:
	        gcc_unreachable ();
	    }

	break;
      }

    case TARGET_EXPR:
      /* Don't bother with the temporary object returned from a function if
	 we don't use it, don't need to destroy it, and won't abort in
	 assign_temp.  We'll still
	 allocate space for it in expand_call or declare_return_variable,
	 but we don't need to track it through all the tree phases.  */
      if (TARGET_EXPR_IMPLICIT_P (expr)
	  && !TREE_ADDRESSABLE (TREE_TYPE (expr)))
	{
	  tree init = TARGET_EXPR_INITIAL (expr);
	  if (TREE_CODE (init) == AGGR_INIT_EXPR
	      && !AGGR_INIT_VIA_CTOR_P (init))
	    {
	      tree fn = AGGR_INIT_EXPR_FN (init);
	      expr = build_call_array_loc (input_location,
					   TREE_TYPE (TREE_TYPE
						      (TREE_TYPE (fn))),
					   fn,
					   aggr_init_expr_nargs (init),
					   AGGR_INIT_EXPR_ARGP (init));
	    }
	}
      if (complain & tf_warning)
	maybe_warn_nodiscard (expr, implicit);
      break;

    default:;
    }
  expr = resolve_nondeduced_context (expr, complain);
  if (!mark_single_function (expr, complain))
    return error_mark_node;

  {
    tree probe = expr;

    if (TREE_CODE (probe) == ADDR_EXPR)
      probe = TREE_OPERAND (expr, 0);
    if (type_unknown_p (probe))
      {
	/* [over.over] enumerates the places where we can take the address
	   of an overloaded function, and this is not one of them.  */
	if (complain & tf_error)
	  switch (implicit)
	    {
	      case ICV_CAST:
		error_at (loc, "conversion to void "
			  "cannot resolve address of overloaded function");
		break;
	      case ICV_SECOND_OF_COND:
		error_at (loc, "second operand of conditional expression "
			  "cannot resolve address of overloaded function");
		break;
	      case ICV_THIRD_OF_COND:
		error_at (loc, "third operand of conditional expression "
			  "cannot resolve address of overloaded function");
		break;
	      case ICV_RIGHT_OF_COMMA:
		error_at (loc, "right operand of comma operator "
			  "cannot resolve address of overloaded function");
		break;
	      case ICV_LEFT_OF_COMMA:
		error_at (loc, "left operand of comma operator "
			  "cannot resolve address of overloaded function");
		break;
	      case ICV_STATEMENT:
		error_at (loc, "statement "
			  "cannot resolve address of overloaded function");
		break;
	      case ICV_THIRD_IN_FOR:
		error_at (loc, "for increment expression "
			  "cannot resolve address of overloaded function");
		break;
	    }
	else
	  return error_mark_node;
	expr = void_node;
      }
    else if (implicit != ICV_CAST && probe == expr && is_overloaded_fn (probe))
      {
	/* Only warn when there is no &.  */
	if (complain & tf_warning)
	  switch (implicit)
	    {
	      case ICV_SECOND_OF_COND:
	        warning_at (loc, OPT_Waddress,
			    "second operand of conditional expression "
			    "is a reference, not call, to function %qE", expr);
		break;
	      case ICV_THIRD_OF_COND:
	        warning_at (loc, OPT_Waddress,
			    "third operand of conditional expression "
			    "is a reference, not call, to function %qE", expr);
		break;
	      case ICV_RIGHT_OF_COMMA:
		warning_at (loc, OPT_Waddress,
			    "right operand of comma operator "
			    "is a reference, not call, to function %qE", expr);
		break;
	      case ICV_LEFT_OF_COMMA:
	        warning_at (loc, OPT_Waddress,
			    "left operand of comma operator "
			    "is a reference, not call, to function %qE", expr);
		break;
	      case ICV_STATEMENT:
	        warning_at (loc, OPT_Waddress,
			    "statement is a reference, not call, to function %qE",
			    expr);
		break;
	      case ICV_THIRD_IN_FOR:
	        warning_at (loc, OPT_Waddress,
			    "for increment expression "
			    "is a reference, not call, to function %qE", expr);
		break;
	      default:
	        gcc_unreachable ();
	    }

	if (TREE_CODE (expr) == COMPONENT_REF)
	  expr = TREE_OPERAND (expr, 0);
      }
  }

  if (expr != error_mark_node && !VOID_TYPE_P (TREE_TYPE (expr)))
    {
      if (implicit != ICV_CAST
	  && warn_unused_value
	  && !warning_suppressed_p (expr, OPT_Wunused_value)
	  && !processing_template_decl
	  && !cp_unevaluated_operand
	  && (complain & tf_warning))
	{
	  /* The middle end does not warn about expressions that have
	     been explicitly cast to void, so we must do so here.  */
	  if (!TREE_SIDE_EFFECTS (expr))
	    {
	      switch (implicit)
		{
		  case ICV_SECOND_OF_COND:
		    warning_at (loc, OPT_Wunused_value,
				"second operand of conditional expression "
				"has no effect");
		    break;
		  case ICV_THIRD_OF_COND:
		    warning_at (loc, OPT_Wunused_value,
				"third operand of conditional expression "
				"has no effect");
		    break;
		  case ICV_RIGHT_OF_COMMA:
		    warning_at (loc, OPT_Wunused_value,
				"right operand of comma operator has no effect");
		    break;
		  case ICV_LEFT_OF_COMMA:
		    warning_at (loc, OPT_Wunused_value,
				"left operand of comma operator has no effect");
		    break;
		  case ICV_STATEMENT:
		    warning_at (loc, OPT_Wunused_value,
				"statement has no effect");
		    break;
		  case ICV_THIRD_IN_FOR:
		    warning_at (loc, OPT_Wunused_value,
				"for increment expression has no effect");
		    break;
		  default:
		    gcc_unreachable ();
		}
	    }
	  else
	    {
	      tree e = expr;
	      /* We might like to warn about (say) "(int) f()", as the
		 cast has no effect, but the compiler itself will
		 generate implicit conversions under some
		 circumstances.  (For example a block copy will be
		 turned into a call to "__builtin_memcpy", with a
		 conversion of the return value to an appropriate
		 type.)  So, to avoid false positives, we strip
		 conversions.  Do not use STRIP_NOPs because it will
		 not strip conversions to "void", as that is not a
		 mode-preserving conversion.  */
	      while (TREE_CODE (e) == NOP_EXPR)
		e = TREE_OPERAND (e, 0);

	      enum tree_code code = TREE_CODE (e);
	      enum tree_code_class tclass = TREE_CODE_CLASS (code);
	      if (tclass == tcc_comparison
		  || tclass == tcc_unary
		  || tclass == tcc_binary
		  || code == VEC_PERM_EXPR
		  || code == VEC_COND_EXPR)
		warn_if_unused_value (e, loc);
	    }
	}
      expr = build1 (CONVERT_EXPR, void_type_node, expr);
    }
  if (! TREE_SIDE_EFFECTS (expr))
    expr = void_node;
  return expr;
}

/* Create an expression whose value is that of EXPR,
   converted to type TYPE.  The TREE_TYPE of the value
   is always TYPE.  This function implements all reasonable
   conversions; callers should filter out those that are
   not permitted by the language being compiled.

   Most of this routine is from build_reinterpret_cast.

   The back end cannot call cp_convert (what was convert) because
   conversions to/from basetypes may involve memory references
   (vbases) and adding or subtracting small values (multiple
   inheritance), but it calls convert from the constant folding code
   on subtrees of already built trees after it has ripped them apart.

   Also, if we ever support range variables, we'll probably also have to
   do a little bit more work.  */

tree
convert (tree type, tree expr)
{
  tree intype;

  if (type == error_mark_node || expr == error_mark_node)
    return error_mark_node;

  intype = TREE_TYPE (expr);

  if (INDIRECT_TYPE_P (type) && INDIRECT_TYPE_P (intype))
    return build_nop (type, expr);

  return ocp_convert (type, expr, CONV_BACKEND_CONVERT,
		      LOOKUP_NORMAL|LOOKUP_NO_CONVERSION,
		      tf_warning_or_error);
}

/* Like convert, but in a static initializer (called from
   convert_and_check).  */

tree
convert_init (tree type, tree expr)
{
  return convert (type, expr);
}

/* Like cp_convert, except permit conversions to take place which
   are not normally allowed due to access restrictions
   (such as conversion from sub-type to private super-type).  */

tree
convert_force (tree type, tree expr, int convtype, tsubst_flags_t complain)
{
  tree e = expr;
  enum tree_code code = TREE_CODE (type);

  if (code == REFERENCE_TYPE)
    return convert_to_reference (type, e, CONV_C_CAST, 0,
				 NULL_TREE, complain);

  if (code == POINTER_TYPE)
    return convert_to_pointer_force (type, e, complain);

  /* From typeck.cc convert_for_assignment */
  if (((TYPE_PTR_P (TREE_TYPE (e)) && TREE_CODE (e) == ADDR_EXPR
	&& TREE_CODE (TREE_TYPE (TREE_TYPE (e))) == METHOD_TYPE)
       || integer_zerop (e)
       || TYPE_PTRMEMFUNC_P (TREE_TYPE (e)))
      && TYPE_PTRMEMFUNC_P (type))
    /* compatible pointer to member functions.  */
    return build_ptrmemfunc (TYPE_PTRMEMFUNC_FN_TYPE (type), e, 1,
			     /*c_cast_p=*/1, complain);

  return ocp_convert (type, e, CONV_C_CAST|convtype, LOOKUP_NORMAL, complain);
}

/* Convert an aggregate EXPR to type XTYPE.  If a conversion
   exists, return the attempted conversion.  This may
   return ERROR_MARK_NODE if the conversion is not
   allowed (references private members, etc).
   If no conversion exists, NULL_TREE is returned.

   FIXME: Ambiguity checking is wrong.  Should choose one by the implicit
   object parameter, or by the second standard conversion sequence if
   that doesn't do it.  This will probably wait for an overloading rewrite.
   (jason 8/9/95)  */

static tree
build_type_conversion (tree xtype, tree expr)
{
  /* C++: check to see if we can convert this aggregate type
     into the required type.  */
  return build_user_type_conversion (xtype, expr, LOOKUP_NORMAL,
				     tf_warning_or_error);
}

/* Convert the given EXPR to one of a group of types suitable for use in an
   expression.  DESIRES is a combination of various WANT_* flags (q.v.)
   which indicates which types are suitable.  If COMPLAIN is true, complain
   about ambiguity; otherwise, the caller will deal with it.  */

tree
build_expr_type_conversion (int desires, tree expr, bool complain)
{
  tree basetype = TREE_TYPE (expr);
  tree conv = NULL_TREE;
  tree winner = NULL_TREE;

  if (null_node_p (expr)
      && (desires & WANT_INT)
      && !(desires & WANT_NULL))
    {
      location_t loc =
	expansion_point_location_if_in_system_header (input_location);

      warning_at (loc, OPT_Wconversion_null,
		  "converting NULL to non-pointer type");
    }

  if (basetype == error_mark_node)
    return error_mark_node;

  if (! MAYBE_CLASS_TYPE_P (basetype))
    switch (TREE_CODE (basetype))
      {
      case INTEGER_TYPE:
	if ((desires & WANT_NULL) && null_ptr_cst_p (expr))
	  return expr;
	/* fall through.  */

      case BOOLEAN_TYPE:
	return (desires & WANT_INT) ? expr : NULL_TREE;
      case ENUMERAL_TYPE:
	return (desires & WANT_ENUM) ? expr : NULL_TREE;
      case REAL_TYPE:
	return (desires & WANT_FLOAT) ? expr : NULL_TREE;
      case POINTER_TYPE:
	return (desires & WANT_POINTER) ? expr : NULL_TREE;

      case FUNCTION_TYPE:
      case ARRAY_TYPE:
	return (desires & WANT_POINTER) ? decay_conversion (expr,
							    tf_warning_or_error)
					: NULL_TREE;

      case VECTOR_TYPE:
	if (!gnu_vector_type_p (basetype))
	  return NULL_TREE;
	/* FALLTHROUGH */
      case COMPLEX_TYPE:
	if ((desires & WANT_VECTOR_OR_COMPLEX) == 0)
	  return NULL_TREE;
	switch (TREE_CODE (TREE_TYPE (basetype)))
	  {
	  case INTEGER_TYPE:
	  case BOOLEAN_TYPE:
	    return (desires & WANT_INT) ? expr : NULL_TREE;
	  case ENUMERAL_TYPE:
	    return (desires & WANT_ENUM) ? expr : NULL_TREE;
	  case REAL_TYPE:
	    return (desires & WANT_FLOAT) ? expr : NULL_TREE;
	  default:
	    return NULL_TREE;
	  }

      default:
	return NULL_TREE;
      }

  /* The code for conversions from class type is currently only used for
     delete expressions.  Other expressions are handled by build_new_op.  */
  if (!complete_type_or_maybe_complain (basetype, expr, complain))
    return error_mark_node;
  if (!TYPE_HAS_CONVERSION (basetype))
    return NULL_TREE;

  for (conv = lookup_conversions (basetype); conv; conv = TREE_CHAIN (conv))
    {
      int win = 0;
      tree candidate;
      tree cand = TREE_VALUE (conv);
      cand = OVL_FIRST (cand);

      if (winner && winner == cand)
	continue;

      if (DECL_NONCONVERTING_P (cand))
	continue;

      candidate = non_reference (TREE_TYPE (TREE_TYPE (cand)));

      switch (TREE_CODE (candidate))
	{
	case BOOLEAN_TYPE:
	case INTEGER_TYPE:
	  win = (desires & WANT_INT); break;
	case ENUMERAL_TYPE:
	  win = (desires & WANT_ENUM); break;
	case REAL_TYPE:
	  win = (desires & WANT_FLOAT); break;
	case POINTER_TYPE:
	  win = (desires & WANT_POINTER); break;

	case COMPLEX_TYPE:
	case VECTOR_TYPE:
	  if ((desires & WANT_VECTOR_OR_COMPLEX) == 0)
	    break;
	  switch (TREE_CODE (TREE_TYPE (candidate)))
	    {
	    case BOOLEAN_TYPE:
	    case INTEGER_TYPE:
	      win = (desires & WANT_INT); break;
	    case ENUMERAL_TYPE:
	      win = (desires & WANT_ENUM); break;
	    case REAL_TYPE:
	      win = (desires & WANT_FLOAT); break;
	    default:
	      break;
	    }
	  break;

	default:
	  /* A wildcard could be instantiated to match any desired
	     type, but we can't deduce the template argument.  */
	  if (WILDCARD_TYPE_P (candidate))
	    win = true;
	  break;
	}

      if (win)
	{
	  if (TREE_CODE (cand) == TEMPLATE_DECL)
	    {
	      if (complain)
		error ("default type conversion cannot deduce template"
		       " argument for %qD", cand);
	      return error_mark_node;
	    }

	  if (winner)
	    {
	      tree winner_type
		= non_reference (TREE_TYPE (TREE_TYPE (winner)));

	      if (!same_type_ignoring_top_level_qualifiers_p (winner_type,
							      candidate))
		{
		  if (complain)
		    {
		      error ("ambiguous default type conversion from %qT",
			     basetype);
		      inform (input_location,
			      "  candidate conversions include %qD and %qD",
			      winner, cand);
		    }
		  return error_mark_node;
		}
	    }

	  winner = cand;
	}
    }

  if (winner)
    {
      tree type = non_reference (TREE_TYPE (TREE_TYPE (winner)));
      return build_user_type_conversion (type, expr, LOOKUP_NORMAL,
					 tf_warning_or_error);
    }

  return NULL_TREE;
}

/* Implements integral promotion (4.1) and float->double promotion.  */

tree
type_promotes_to (tree type)
{
  tree promoted_type;

  if (type == error_mark_node)
    return error_mark_node;

  type = TYPE_MAIN_VARIANT (type);

  /* Check for promotions of target-defined types first.  */
  promoted_type = targetm.promoted_type (type);
  if (promoted_type)
    return promoted_type;

  /* bool always promotes to int (not unsigned), even if it's the same
     size.  */
  if (TREE_CODE (type) == BOOLEAN_TYPE)
    type = integer_type_node;

  /* Normally convert enums to int, but convert wide enums to something
     wider.  Scoped enums don't promote, but pretend they do for backward
     ABI bug compatibility wrt varargs.  */
  else if (TREE_CODE (type) == ENUMERAL_TYPE
	   || type == char8_type_node
	   || type == char16_type_node
	   || type == char32_type_node
	   || type == wchar_type_node)
    {
      tree prom = type;

      if (TREE_CODE (type) == ENUMERAL_TYPE)
	{
	  prom = ENUM_UNDERLYING_TYPE (prom);
	  if (!ENUM_IS_SCOPED (type)
	      && ENUM_FIXED_UNDERLYING_TYPE_P (type))
	    {
	      /* ISO C++17, 7.6/4.  A prvalue of an unscoped enumeration type
		 whose underlying type is fixed (10.2) can be converted to a
		 prvalue of its underlying type. Moreover, if integral promotion
		 can be applied to its underlying type, a prvalue of an unscoped
		 enumeration type whose underlying type is fixed can also be 
		 converted to a prvalue of the promoted underlying type.  */
	      return type_promotes_to (prom);
	    }
	}

      int precision = MAX (TYPE_PRECISION (type),
			   TYPE_PRECISION (integer_type_node));
      tree totype = c_common_type_for_size (precision, 0);
      if (TYPE_UNSIGNED (prom)
	  && ! int_fits_type_p (TYPE_MAX_VALUE (prom), totype))
	prom = c_common_type_for_size (precision, 1);
      else
	prom = totype;
      if (SCOPED_ENUM_P (type))
	{
	  if (abi_version_crosses (6)
	      && TYPE_MODE (prom) != TYPE_MODE (type))
	    warning (OPT_Wabi, "scoped enum %qT passed through %<...%> as "
		     "%qT before %<-fabi-version=6%>, %qT after",
		     type, prom, ENUM_UNDERLYING_TYPE (type));
	  if (!abi_version_at_least (6))
	    type = prom;
	}
      else
	type = prom;
    }
  else if (c_promoting_integer_type_p (type))
    {
      /* Retain unsignedness if really not getting bigger.  */
      if (TYPE_UNSIGNED (type)
	  && TYPE_PRECISION (type) == TYPE_PRECISION (integer_type_node))
	type = unsigned_type_node;
      else
	type = integer_type_node;
    }
  else if (type == float_type_node)
    type = double_type_node;

  return type;
}

/* The routines below this point are carefully written to conform to
   the standard.  They use the same terminology, and follow the rules
   closely.  Although they are used only in pt.cc at the moment, they
   should presumably be used everywhere in the future.  */

/* True iff EXPR can be converted to TYPE via a qualification conversion.
   Callers should check for identical types before calling this function.  */

bool
can_convert_qual (tree type, tree expr)
{
  tree expr_type = TREE_TYPE (expr);
  gcc_assert (!same_type_p (type, expr_type));

  /* A function pointer conversion also counts as a Qualification Adjustment
     under [over.ics.scs].  */
  if (fnptr_conv_p (type, expr_type))
    return true;

  if (TYPE_PTR_P (type) && TYPE_PTR_P (expr_type))
    return comp_ptr_ttypes (TREE_TYPE (type), TREE_TYPE (expr_type));
  else if (TYPE_PTRMEM_P (type) && TYPE_PTRMEM_P (expr_type))
    return (same_type_p (TYPE_PTRMEM_CLASS_TYPE (type),
			 TYPE_PTRMEM_CLASS_TYPE (expr_type))
	    && comp_ptr_ttypes (TYPE_PTRMEM_POINTED_TO_TYPE (type),
				TYPE_PTRMEM_POINTED_TO_TYPE (expr_type)));
  else
    return false;
}

/* Attempt to perform qualification conversions on EXPR to convert it
   to TYPE.  Return the resulting expression, or error_mark_node if
   the conversion was impossible.  Since this is only used by
   convert_nontype_argument, we fold the conversion.  */

tree
perform_qualification_conversions (tree type, tree expr)
{
  tree expr_type;

  expr_type = TREE_TYPE (expr);

  if (same_type_p (type, expr_type))
    return expr;
  else if (can_convert_qual (type, expr))
    return cp_fold_convert (type, expr);
  else
    return error_mark_node;
}

/* True iff T is a transaction-safe function type.  */

bool
tx_safe_fn_type_p (tree t)
{
  if (!FUNC_OR_METHOD_TYPE_P (t))
    return false;
  return !!lookup_attribute ("transaction_safe", TYPE_ATTRIBUTES (t));
}

/* Return the transaction-unsafe variant of transaction-safe function type
   T.  */

tree
tx_unsafe_fn_variant (tree t)
{
  gcc_assert (tx_safe_fn_type_p (t));
  tree attrs = remove_attribute ("transaction_safe",
				 TYPE_ATTRIBUTES (t));
  return cp_build_type_attribute_variant (t, attrs);
}

/* Return true iff FROM can convert to TO by a transaction-safety
   conversion.  */

static bool
can_convert_tx_safety (tree to, tree from)
{
  return (flag_tm && tx_safe_fn_type_p (from)
	  && same_type_p (to, tx_unsafe_fn_variant (from)));
}

/* Return true iff FROM can convert to TO by dropping noexcept.
   This is just a subroutine of fnptr_conv_p.  */

static bool
noexcept_conv_p (tree to, tree from)
{
  if (!flag_noexcept_type)
    return false;

  if (TREE_CODE (to) != TREE_CODE (from))
    return false;
  if (!FUNC_OR_METHOD_TYPE_P (from))
    return false;
  if (!type_throw_all_p (to)
      || type_throw_all_p (from))
    return false;
  tree v = build_exception_variant (from, NULL_TREE);
  return same_type_p (to, v);
}

/* Return true iff FROM can convert to TO by a function pointer conversion.  */

bool
fnptr_conv_p (tree to, tree from)
{
  tree t = to;
  tree f = from;
  if (TYPE_PTRMEMFUNC_P (t)
      && TYPE_PTRMEMFUNC_P (f))
    {
      t = TYPE_PTRMEMFUNC_FN_TYPE (t);
      f = TYPE_PTRMEMFUNC_FN_TYPE (f);
    }
  if (INDIRECT_TYPE_P (t)
      && INDIRECT_TYPE_P (f))
    {
      t = TREE_TYPE (t);
      f = TREE_TYPE (f);
    }

  return (noexcept_conv_p (t, f)
	  || can_convert_tx_safety (t, f));
}

/* Return FN with any NOP_EXPRs stripped that represent function pointer
   conversions or conversions to the same type.  */

tree
strip_fnptr_conv (tree fn)
{
  while (TREE_CODE (fn) == NOP_EXPR)
    {
      tree op = TREE_OPERAND (fn, 0);
      tree ft = TREE_TYPE (fn);
      tree ot = TREE_TYPE (op);
      if (same_type_p (ft, ot)
	  || fnptr_conv_p (ft, ot))
	fn = op;
      else
	break;
    }
  return fn;
}
