/* Language-level data type conversion for GNU C++.
   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 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.c, convert_to_integer[_maybe_fold].
     In c-typeck.c, build_binary_op_nodefault (boolean ops),
	and c_common_truthvalue_conversion.
     In expr.c: expand_expr, for operands of a MULT_EXPR.
     In fold-const.c: fold.
     In tree.c: 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_sfinae (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)
{
  bool nowarn = TREE_NO_WARNING (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 (nowarn && TREE_CODE (expr) == TREE_CODE (conv))
    TREE_NO_WARNING (conv) = nowarn;

  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_sfinae (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 && !TREE_NO_WARNING (expr))
	  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.c.)
               - automatic dereferencing of references, since the user cannot
                 control it. (See also warn_if_unused_value() in c-common.c.)  */
            if (warn_unused_value
		&& implicit != ICV_CAST
                && (complain & tf_warning)
                && !TREE_NO_WARNING (expr)
                && !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);
  {
    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
	  && !TREE_NO_WARNING (expr)
	  && !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 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.c 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.c 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 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;
}
