/* Utility routines for data type conversion for GCC.
   Copyright (C) 1987-2024 Free Software Foundation, Inc.

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


/* These routines are somewhat language-independent utility function
   intended to be called by the language-specific convert () functions.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "target.h"
#include "tree.h"
#include "diagnostic-core.h"
#include "fold-const.h"
#include "stor-layout.h"
#include "convert.h"
#include "langhooks.h"
#include "builtins.h"
#include "ubsan.h"
#include "stringpool.h"
#include "attribs.h"
#include "asan.h"
#include "selftest.h"

#define maybe_fold_build1_loc(FOLD_P, LOC, CODE, TYPE, EXPR) \
  ((FOLD_P) ? fold_build1_loc (LOC, CODE, TYPE, EXPR)	     \
   : build1_loc (LOC, CODE, TYPE, EXPR))
#define maybe_fold_build2_loc(FOLD_P, LOC, CODE, TYPE, EXPR1, EXPR2) \
  ((FOLD_P) ? fold_build2_loc (LOC, CODE, TYPE, EXPR1, EXPR2)	     \
   : build2_loc (LOC, CODE, TYPE, EXPR1, EXPR2))

/* Convert EXPR to some pointer or reference type TYPE.
   EXPR must be pointer, reference, integer, enumeral, or literal zero;
   in other cases error is called.  If FOLD_P is true, try to fold the
   expression.  */

static tree
convert_to_pointer_1 (tree type, tree expr, bool fold_p)
{
  location_t loc = EXPR_LOCATION (expr);
  if (TREE_TYPE (expr) == type)
    return expr;

  switch (TREE_CODE (TREE_TYPE (expr)))
    {
    case POINTER_TYPE:
    case REFERENCE_TYPE:
      {
        /* If the pointers point to different address spaces, conversion needs
	   to be done via a ADDR_SPACE_CONVERT_EXPR instead of a NOP_EXPR.  */
	addr_space_t to_as = TYPE_ADDR_SPACE (TREE_TYPE (type));
	addr_space_t from_as = TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (expr)));

	if (to_as == from_as)
	  return maybe_fold_build1_loc (fold_p, loc, NOP_EXPR, type, expr);
	else
	  return maybe_fold_build1_loc (fold_p, loc, ADDR_SPACE_CONVERT_EXPR,
					type, expr);
      }

    case INTEGER_TYPE:
    case ENUMERAL_TYPE:
    case BOOLEAN_TYPE:
    case BITINT_TYPE:
      {
	/* If the input precision differs from the target pointer type
	   precision, first convert the input expression to an integer type of
	   the target precision.  Some targets, e.g. VMS, need several pointer
	   sizes to coexist so the latter isn't necessarily POINTER_SIZE.  */
	unsigned int pprec = TYPE_PRECISION (type);
	unsigned int eprec = TYPE_PRECISION (TREE_TYPE (expr));

	if (eprec != pprec)
	  expr
	    = maybe_fold_build1_loc (fold_p, loc, NOP_EXPR,
				     lang_hooks.types.type_for_size (pprec, 0),
				     expr);
      }
      return maybe_fold_build1_loc (fold_p, loc, CONVERT_EXPR, type, expr);

    default:
      error ("cannot convert to a pointer type");
      return error_mark_node;
    }
}

/* Subroutine of the various convert_to_*_maybe_fold routines.

   If a location wrapper has been folded to a constant (presumably of
   a different type), re-wrap the new constant with a location wrapper.  */

tree
preserve_any_location_wrapper (tree result, tree orig_expr)
{
  if (CONSTANT_CLASS_P (result) && location_wrapper_p (orig_expr))
    {
      if (result == TREE_OPERAND (orig_expr, 0))
	return orig_expr;
      else
	return maybe_wrap_with_location (result, EXPR_LOCATION (orig_expr));
    }

  return result;
}

/* A wrapper around convert_to_pointer_1 that always folds the
   expression.  */

tree
convert_to_pointer (tree type, tree expr)
{
  return convert_to_pointer_1 (type, expr, true);
}

/* A wrapper around convert_to_pointer_1 that only folds the
   expression if DOFOLD, or if it is CONSTANT_CLASS_OR_WRAPPER_P.  */

tree
convert_to_pointer_maybe_fold (tree type, tree expr, bool dofold)
{
  tree result
    = convert_to_pointer_1 (type, expr,
			    dofold || CONSTANT_CLASS_OR_WRAPPER_P (expr));
  return preserve_any_location_wrapper (result, expr);
}

/* Convert EXPR to some floating-point type TYPE.

   EXPR must be float, fixed-point, integer, or enumeral;
   in other cases error is called.  If FOLD_P is true, try to fold
   the expression.  */

static tree
convert_to_real_1 (tree type, tree expr, bool fold_p)
{
  enum built_in_function fcode = builtin_mathfn_code (expr);
  tree itype = TREE_TYPE (expr);
  location_t loc = EXPR_LOCATION (expr);

  if (TREE_CODE (expr) == COMPOUND_EXPR)
    {
      tree t = convert_to_real_1 (type, TREE_OPERAND (expr, 1), fold_p);
      if (t == TREE_OPERAND (expr, 1))
	return expr;
      return build2_loc (EXPR_LOCATION (expr), COMPOUND_EXPR, TREE_TYPE (t),
			 TREE_OPERAND (expr, 0), t);
    }    

  /* Disable until we figure out how to decide whether the functions are
     present in runtime.  */
  /* Convert (float)sqrt((double)x) where x is float into sqrtf(x) */
  if (optimize
      && (TYPE_MODE (type) == TYPE_MODE (double_type_node)
          || TYPE_MODE (type) == TYPE_MODE (float_type_node)))
    {
      switch (fcode)
        {
#define CASE_MATHFN(FN) case BUILT_IN_##FN: case BUILT_IN_##FN##L:
	  CASE_MATHFN (COSH)
	  CASE_MATHFN (EXP)
	  CASE_MATHFN (EXP10)
	  CASE_MATHFN (EXP2)
 	  CASE_MATHFN (EXPM1)
	  CASE_MATHFN (GAMMA)
	  CASE_MATHFN (J0)
	  CASE_MATHFN (J1)
	  CASE_MATHFN (LGAMMA)
	  CASE_MATHFN (POW10)
	  CASE_MATHFN (SINH)
	  CASE_MATHFN (TGAMMA)
	  CASE_MATHFN (Y0)
	  CASE_MATHFN (Y1)
	    /* The above functions may set errno differently with float
	       input or output so this transformation is not safe with
	       -fmath-errno.  */
	    if (flag_errno_math)
	      break;
	    gcc_fallthrough ();
	  CASE_MATHFN (ACOS)
	  CASE_MATHFN (ACOSH)
	  CASE_MATHFN (ASIN)
 	  CASE_MATHFN (ASINH)
 	  CASE_MATHFN (ATAN)
	  CASE_MATHFN (ATANH)
 	  CASE_MATHFN (CBRT)
 	  CASE_MATHFN (COS)
 	  CASE_MATHFN (ERF)
 	  CASE_MATHFN (ERFC)
	  CASE_MATHFN (LOG)
	  CASE_MATHFN (LOG10)
	  CASE_MATHFN (LOG2)
 	  CASE_MATHFN (LOG1P)
 	  CASE_MATHFN (SIN)
 	  CASE_MATHFN (TAN)
 	  CASE_MATHFN (TANH)
	    /* The above functions are not safe to do this conversion.  */
	    if (!flag_unsafe_math_optimizations)
	      break;
	    gcc_fallthrough ();
	  CASE_MATHFN (SQRT)
	  CASE_MATHFN (FABS)
	  CASE_MATHFN (LOGB)
#undef CASE_MATHFN
	    if (call_expr_nargs (expr) != 1
		|| !SCALAR_FLOAT_TYPE_P (TREE_TYPE (CALL_EXPR_ARG (expr, 0))))
	      break;
	    {
	      tree arg0 = strip_float_extensions (CALL_EXPR_ARG (expr, 0));
	      tree newtype = type;

	      /* We have (outertype)sqrt((innertype)x).  Choose the wider mode
		 from the both as the safe type for operation.  */
	      if (TYPE_PRECISION (TREE_TYPE (arg0)) > TYPE_PRECISION (type))
		newtype = TREE_TYPE (arg0);

	      /* We consider to convert

		     (T1) sqrtT2 ((T2) exprT3)
		 to
		     (T1) sqrtT4 ((T4) exprT3)

		  , where T1 is TYPE, T2 is ITYPE, T3 is TREE_TYPE (ARG0),
		 and T4 is NEWTYPE.  All those types are of floating-point types.
		 T4 (NEWTYPE) should be narrower than T2 (ITYPE). This conversion
		 is safe only if P1 >= P2*2+2, where P1 and P2 are precisions of
		 T2 and T4.  See the following URL for a reference:
		 http://stackoverflow.com/questions/9235456/determining-
                 floating-point-square-root
		 */
	      if ((fcode == BUILT_IN_SQRT || fcode == BUILT_IN_SQRTL)
		  && !flag_unsafe_math_optimizations)
		{
		  /* The following conversion is unsafe even the precision condition
		     below is satisfied:

		     (float) sqrtl ((long double) double_val) -> (float) sqrt (double_val)
		    */
		  if (TYPE_MODE (type) != TYPE_MODE (newtype))
		    break;

		  int p1 = REAL_MODE_FORMAT (TYPE_MODE (itype))->p;
		  int p2 = REAL_MODE_FORMAT (TYPE_MODE (newtype))->p;
		  if (p1 < p2 * 2 + 2)
		    break;
		}

	      /* Be careful about integer to fp conversions.
		 These may overflow still.  */
	      if (FLOAT_TYPE_P (TREE_TYPE (arg0))
		  && TYPE_PRECISION (newtype) < TYPE_PRECISION (itype)
		  && (TYPE_MODE (newtype) == TYPE_MODE (double_type_node)
		      || TYPE_MODE (newtype) == TYPE_MODE (float_type_node)))
		{
		  tree fn = mathfn_built_in (newtype, fcode);
		  if (fn)
		    {
		      tree arg = convert_to_real_1 (newtype, arg0, fold_p);
		      expr = build_call_expr (fn, 1, arg);
		      if (newtype == type)
			return expr;
		    }
		}
	    }
	default:
	  break;
	}
    }

  /* Propagate the cast into the operation.  */
  if (itype != type && FLOAT_TYPE_P (type))
    switch (TREE_CODE (expr))
      {
	/* Convert (float)-x into -(float)x.  This is safe for
	   round-to-nearest rounding mode when the inner type is float.  */
	case ABS_EXPR:
	case NEGATE_EXPR:
	  if (!flag_rounding_math
	      && FLOAT_TYPE_P (itype)
	      && element_precision (type) < element_precision (itype))
	    {
	      tree arg = convert_to_real_1 (type, TREE_OPERAND (expr, 0),
					    fold_p);
	      return build1 (TREE_CODE (expr), type, arg);
	    }
	  break;
	default:
	  break;
      }

  switch (TREE_CODE (TREE_TYPE (expr)))
    {
    case REAL_TYPE:
      /* Ignore the conversion if we don't need to store intermediate
	 results and neither type is a decimal float.  */
      return build1_loc (loc,
			 (flag_float_store
			  || DECIMAL_FLOAT_TYPE_P (type)
			  || DECIMAL_FLOAT_TYPE_P (itype))
			 ? CONVERT_EXPR : NOP_EXPR, type, expr);

    case INTEGER_TYPE:
    case ENUMERAL_TYPE:
    case BOOLEAN_TYPE:
    case BITINT_TYPE:
      return build1 (FLOAT_EXPR, type, expr);

    case FIXED_POINT_TYPE:
      return build1 (FIXED_CONVERT_EXPR, type, expr);

    case COMPLEX_TYPE:
      return convert (type,
		      maybe_fold_build1_loc (fold_p, loc, REALPART_EXPR,
					     TREE_TYPE (TREE_TYPE (expr)),
					     expr));

    case POINTER_TYPE:
    case REFERENCE_TYPE:
      error ("pointer value used where a floating-point was expected");
      return error_mark_node;

    case VECTOR_TYPE:
      error ("vector value used where a floating-point was expected");
      return error_mark_node;

    default:
      error ("aggregate value used where a floating-point was expected");
      return error_mark_node;
    }
}

/* A wrapper around convert_to_real_1 that always folds the
   expression.  */

tree
convert_to_real (tree type, tree expr)
{
  return convert_to_real_1 (type, expr, true);
}

/* A wrapper around convert_to_real_1 that only folds the
   expression if DOFOLD, or if it is CONSTANT_CLASS_OR_WRAPPER_P.  */

tree
convert_to_real_maybe_fold (tree type, tree expr, bool dofold)
{
  tree result
    = convert_to_real_1 (type, expr,
			 dofold || CONSTANT_CLASS_OR_WRAPPER_P (expr));
  return preserve_any_location_wrapper (result, expr);
}

/* Try to narrow EX_FORM ARG0 ARG1 in narrowed arg types producing a
   result in TYPE.  */

static tree
do_narrow (location_t loc,
	   enum tree_code ex_form, tree type, tree arg0, tree arg1,
	   tree expr, unsigned inprec, unsigned outprec, bool dofold)
{
  /* Do the arithmetic in type TYPEX,
     then convert result to TYPE.  */
  tree typex = type;

  /* Can't do arithmetic in enumeral types
     so use an integer type that will hold the values.  */
  if (TREE_CODE (typex) == ENUMERAL_TYPE)
    typex = lang_hooks.types.type_for_size (TYPE_PRECISION (typex),
					    TYPE_UNSIGNED (typex));

  /* The type demotion below might cause doing unsigned arithmetic
     instead of signed, and thus hide overflow bugs.  */
  if ((ex_form == PLUS_EXPR || ex_form == MINUS_EXPR)
      && !TYPE_UNSIGNED (typex)
      && sanitize_flags_p (SANITIZE_SI_OVERFLOW))
    return NULL_TREE;

  /* Similarly for multiplication, but in that case it can be
     problematic even if typex is unsigned type - 0xffff * 0xffff
     overflows in int.  */
  if (ex_form == MULT_EXPR
      && !TYPE_OVERFLOW_WRAPS (TREE_TYPE (expr))
      && sanitize_flags_p (SANITIZE_SI_OVERFLOW))
    return NULL_TREE;

  /* But now perhaps TYPEX is as wide as INPREC.
     In that case, do nothing special here.
     (Otherwise would recurse infinitely in convert.  */
  if (TYPE_PRECISION (typex) != inprec)
    {
      /* Don't do unsigned arithmetic where signed was wanted,
	 or vice versa.
	 Exception: if both of the original operands were
	 unsigned then we can safely do the work as unsigned.
	 Exception: shift operations take their type solely
	 from the first argument.
	 Exception: the LSHIFT_EXPR case above requires that
	 we perform this operation unsigned lest we produce
	 signed-overflow undefinedness.
	 And we may need to do it as unsigned
	 if we truncate to the original size.  */
      if (TYPE_UNSIGNED (TREE_TYPE (expr))
	  || (TYPE_UNSIGNED (TREE_TYPE (arg0))
	      && (TYPE_UNSIGNED (TREE_TYPE (arg1))
		  || ex_form == LSHIFT_EXPR
		  || ex_form == RSHIFT_EXPR
		  || ex_form == LROTATE_EXPR
		  || ex_form == RROTATE_EXPR))
	  || ex_form == LSHIFT_EXPR
	  /* If we have !flag_wrapv, and either ARG0 or
	     ARG1 is of a signed type, we have to do
	     PLUS_EXPR, MINUS_EXPR or MULT_EXPR in an unsigned
	     type in case the operation in outprec precision
	     could overflow.  Otherwise, we would introduce
	     signed-overflow undefinedness.  */
	  || ((!(INTEGRAL_TYPE_P (TREE_TYPE (arg0))
		 && TYPE_OVERFLOW_WRAPS (TREE_TYPE (arg0)))
	       || !(INTEGRAL_TYPE_P (TREE_TYPE (arg1))
		    && TYPE_OVERFLOW_WRAPS (TREE_TYPE (arg1))))
	      && ((TYPE_PRECISION (TREE_TYPE (arg0)) * 2u
		   > outprec)
		  || (TYPE_PRECISION (TREE_TYPE (arg1)) * 2u
		      > outprec))
	      && (ex_form == PLUS_EXPR
		  || ex_form == MINUS_EXPR
		  || ex_form == MULT_EXPR)))
	{
	  if (!TYPE_UNSIGNED (typex))
	    typex = unsigned_type_for (typex);
	}
      else
	{
	  if (TYPE_UNSIGNED (typex))
	    typex = signed_type_for (typex);
	}
      /* We should do away with all this once we have a proper
	 type promotion/demotion pass, see PR45397.  */
      expr = maybe_fold_build2_loc (dofold, loc, ex_form, typex,
				    convert (typex, arg0),
				    convert (typex, arg1));
      return convert (type, expr);
    }
  
  return NULL_TREE;
}

/* Convert EXPR to some integer (or enum) type TYPE.

   EXPR must be pointer, integer, discrete (enum, char, or bool), float,
   fixed-point or vector; in other cases error is called.

   If DOFOLD is TRUE, we try to simplify newly-created patterns by folding.

   The result of this is always supposed to be a newly created tree node
   not in use in any existing structure.  */

static tree
convert_to_integer_1 (tree type, tree expr, bool dofold)
{
  enum tree_code ex_form = TREE_CODE (expr);
  tree intype = TREE_TYPE (expr);
  unsigned int inprec = element_precision (intype);
  unsigned int outprec = element_precision (type);
  location_t loc = EXPR_LOCATION (expr);

  /* An INTEGER_TYPE cannot be incomplete, but an ENUMERAL_TYPE can
     be.  Consider `enum E = { a, b = (enum E) 3 };'.  */
  if (!COMPLETE_TYPE_P (type))
    {
      error ("conversion to incomplete type");
      return error_mark_node;
    }

  if (ex_form == COMPOUND_EXPR)
    {
      tree t = convert_to_integer_1 (type, TREE_OPERAND (expr, 1), dofold);
      if (t == TREE_OPERAND (expr, 1))
	return expr;
      return build2_loc (EXPR_LOCATION (expr), COMPOUND_EXPR, TREE_TYPE (t),
			 TREE_OPERAND (expr, 0), t);
    }    

  /* Convert e.g. (long)round(d) -> lround(d).  */
  /* If we're converting to char, we may encounter differing behavior
     between converting from double->char vs double->long->char.
     We're in "undefined" territory but we prefer to be conservative,
     so only proceed in "unsafe" math mode.  */
  if (optimize
      && (flag_unsafe_math_optimizations
	  || (long_integer_type_node
	      && outprec >= TYPE_PRECISION (long_integer_type_node))))
    {
      tree s_expr = strip_float_extensions (expr);
      tree s_intype = TREE_TYPE (s_expr);
      const enum built_in_function fcode = builtin_mathfn_code (s_expr);
      tree fn = 0;

      switch (fcode)
        {
	CASE_FLT_FN (BUILT_IN_CEIL):
	CASE_FLT_FN_FLOATN_NX (BUILT_IN_CEIL):
	  /* Only convert in ISO C99 mode.  */
	  if (!targetm.libc_has_function (function_c99_misc, intype))
	    break;
	  if (outprec < TYPE_PRECISION (integer_type_node)
	      || (outprec == TYPE_PRECISION (integer_type_node)
		  && !TYPE_UNSIGNED (type)))
	    fn = mathfn_built_in (s_intype, BUILT_IN_ICEIL);
	  else if (outprec == TYPE_PRECISION (long_integer_type_node)
		   && !TYPE_UNSIGNED (type))
	    fn = mathfn_built_in (s_intype, BUILT_IN_LCEIL);
	  else if (outprec == TYPE_PRECISION (long_long_integer_type_node)
		   && !TYPE_UNSIGNED (type))
	    fn = mathfn_built_in (s_intype, BUILT_IN_LLCEIL);
	  break;

	CASE_FLT_FN (BUILT_IN_FLOOR):
	CASE_FLT_FN_FLOATN_NX (BUILT_IN_FLOOR):
	  /* Only convert in ISO C99 mode.  */
	  if (!targetm.libc_has_function (function_c99_misc, intype))
	    break;
	  if (outprec < TYPE_PRECISION (integer_type_node)
	      || (outprec == TYPE_PRECISION (integer_type_node)
		  && !TYPE_UNSIGNED (type)))
	    fn = mathfn_built_in (s_intype, BUILT_IN_IFLOOR);
	  else if (outprec == TYPE_PRECISION (long_integer_type_node)
		   && !TYPE_UNSIGNED (type))
	    fn = mathfn_built_in (s_intype, BUILT_IN_LFLOOR);
	  else if (outprec == TYPE_PRECISION (long_long_integer_type_node)
		   && !TYPE_UNSIGNED (type))
	    fn = mathfn_built_in (s_intype, BUILT_IN_LLFLOOR);
	  break;

	CASE_FLT_FN (BUILT_IN_ROUND):
	CASE_FLT_FN_FLOATN_NX (BUILT_IN_ROUND):
	  /* Only convert in ISO C99 mode and with -fno-math-errno.  */
	  if (!targetm.libc_has_function (function_c99_misc, intype)
	      || flag_errno_math)
	    break;
	  if (outprec < TYPE_PRECISION (integer_type_node)
	      || (outprec == TYPE_PRECISION (integer_type_node)
		  && !TYPE_UNSIGNED (type)))
	    fn = mathfn_built_in (s_intype, BUILT_IN_IROUND);
	  else if (outprec == TYPE_PRECISION (long_integer_type_node)
		   && !TYPE_UNSIGNED (type))
	    fn = mathfn_built_in (s_intype, BUILT_IN_LROUND);
	  else if (outprec == TYPE_PRECISION (long_long_integer_type_node)
		   && !TYPE_UNSIGNED (type))
	    fn = mathfn_built_in (s_intype, BUILT_IN_LLROUND);
	  break;

	CASE_FLT_FN (BUILT_IN_NEARBYINT):
	CASE_FLT_FN_FLOATN_NX (BUILT_IN_NEARBYINT):
	  /* Only convert nearbyint* if we can ignore math exceptions.  */
	  if (flag_trapping_math)
	    break;
	  gcc_fallthrough ();
	CASE_FLT_FN (BUILT_IN_RINT):
	CASE_FLT_FN_FLOATN_NX (BUILT_IN_RINT):
	  /* Only convert in ISO C99 mode and with -fno-math-errno.  */
	  if (!targetm.libc_has_function (function_c99_misc, intype)
	      || flag_errno_math)
	    break;
	  if (outprec < TYPE_PRECISION (integer_type_node)
	      || (outprec == TYPE_PRECISION (integer_type_node)
		  && !TYPE_UNSIGNED (type)))
	    fn = mathfn_built_in (s_intype, BUILT_IN_IRINT);
	  else if (outprec == TYPE_PRECISION (long_integer_type_node)
		   && !TYPE_UNSIGNED (type))
	    fn = mathfn_built_in (s_intype, BUILT_IN_LRINT);
	  else if (outprec == TYPE_PRECISION (long_long_integer_type_node)
		   && !TYPE_UNSIGNED (type))
	    fn = mathfn_built_in (s_intype, BUILT_IN_LLRINT);
	  break;

	CASE_FLT_FN (BUILT_IN_TRUNC):
	CASE_FLT_FN_FLOATN_NX (BUILT_IN_TRUNC):
	  if (call_expr_nargs (s_expr) != 1
	      || !SCALAR_FLOAT_TYPE_P (TREE_TYPE (CALL_EXPR_ARG (s_expr, 0)))
	      || (!flag_fp_int_builtin_inexact && flag_trapping_math))
	    break;
	  return convert_to_integer_1 (type, CALL_EXPR_ARG (s_expr, 0),
				       dofold);

	default:
	  break;
	}

      if (fn
	  && call_expr_nargs (s_expr) == 1
	  && SCALAR_FLOAT_TYPE_P (TREE_TYPE (CALL_EXPR_ARG (s_expr, 0))))
	{
	  tree newexpr = build_call_expr (fn, 1, CALL_EXPR_ARG (s_expr, 0));
	  return convert_to_integer_1 (type, newexpr, dofold);
	}
    }

  /* Convert (int)logb(d) -> ilogb(d).  */
  if (optimize
      && flag_unsafe_math_optimizations
      && !flag_trapping_math && !flag_errno_math && flag_finite_math_only
      && integer_type_node
      && (outprec > TYPE_PRECISION (integer_type_node)
	  || (outprec == TYPE_PRECISION (integer_type_node)
	      && !TYPE_UNSIGNED (type))))
    {
      tree s_expr = strip_float_extensions (expr);
      tree s_intype = TREE_TYPE (s_expr);
      const enum built_in_function fcode = builtin_mathfn_code (s_expr);
      tree fn = 0;

      switch (fcode)
	{
	CASE_FLT_FN (BUILT_IN_LOGB):
	  fn = mathfn_built_in (s_intype, BUILT_IN_ILOGB);
	  break;

	default:
	  break;
	}

      if (fn
	  && call_expr_nargs (s_expr) == 1
	  && SCALAR_FLOAT_TYPE_P (TREE_TYPE (CALL_EXPR_ARG (s_expr, 0))))
        {
	  tree newexpr = build_call_expr (fn, 1, CALL_EXPR_ARG (s_expr, 0));
	  return convert_to_integer_1 (type, newexpr, dofold);
	}
    }

  switch (TREE_CODE (intype))
    {
    case POINTER_TYPE:
    case REFERENCE_TYPE:
      if (integer_zerop (expr)
	  && !TREE_OVERFLOW (tree_strip_any_location_wrapper (expr)))
	return build_int_cst (type, 0);

      /* Convert to an unsigned integer of the correct width first, and from
	 there widen/truncate to the required type.  Some targets support the
	 coexistence of multiple valid pointer sizes, so fetch the one we need
	 from the type.  */
      if (!dofold)
	return build1 (CONVERT_EXPR, type, expr);
      expr = fold_build1 (CONVERT_EXPR,
			  lang_hooks.types.type_for_size
			    (TYPE_PRECISION (intype), 0),
			  expr);
      return fold_convert (type, expr);

    case INTEGER_TYPE:
    case ENUMERAL_TYPE:
    case BOOLEAN_TYPE:
    case OFFSET_TYPE:
    case BITINT_TYPE:
      /* If this is a logical operation, which just returns 0 or 1, we can
	 change the type of the expression.  */

      if (TREE_CODE_CLASS (ex_form) == tcc_comparison)
	{
	  expr = copy_node (expr);
	  TREE_TYPE (expr) = type;
	  return expr;
	}

      /* If we are widening the type, put in an explicit conversion.
	 Similarly if we are not changing the width.  After this, we know
	 we are truncating EXPR.  */

      else if (outprec >= inprec)
	{
	  enum tree_code code;

	  /* If the precision of the EXPR's type is K bits and the
	     destination mode has more bits, and the sign is changing,
	     it is not safe to use a NOP_EXPR.  For example, suppose
	     that EXPR's type is a 3-bit unsigned integer type, the
	     TYPE is a 3-bit signed integer type, and the machine mode
	     for the types is 8-bit QImode.  In that case, the
	     conversion necessitates an explicit sign-extension.  In
	     the signed-to-unsigned case the high-order bits have to
	     be cleared.  */
	  if (TYPE_UNSIGNED (type) != TYPE_UNSIGNED (TREE_TYPE (expr))
	      && !type_has_mode_precision_p (TREE_TYPE (expr)))
	    code = CONVERT_EXPR;
	  else
	    code = NOP_EXPR;

	  return maybe_fold_build1_loc (dofold, loc, code, type, expr);
	}

      /* If TYPE is an enumeral type or a type with a precision less
	 than the number of bits in its mode, do the conversion to the
	 type corresponding to its mode, then do a nop conversion
	 to TYPE.  */
      else if (TREE_CODE (type) == ENUMERAL_TYPE
	       || (TREE_CODE (type) != BITINT_TYPE
		   && maybe_ne (outprec,
				GET_MODE_PRECISION (TYPE_MODE (type)))))
	{
	  expr
	    = convert_to_integer_1 (lang_hooks.types.type_for_mode
				    (TYPE_MODE (type), TYPE_UNSIGNED (type)),
				    expr, dofold);
	  return maybe_fold_build1_loc (dofold, loc, NOP_EXPR, type, expr);
	}

      /* Here detect when we can distribute the truncation down past some
	 arithmetic.  For example, if adding two longs and converting to an
	 int, we can equally well convert both to ints and then add.
	 For the operations handled here, such truncation distribution
	 is always safe.
	 It is desirable in these cases:
	 1) when truncating down to full-word from a larger size
	 2) when truncating takes no work.
	 3) when at least one operand of the arithmetic has been extended
	 (as by C's default conversions).  In this case we need two conversions
	 if we do the arithmetic as already requested, so we might as well
	 truncate both and then combine.  Perhaps that way we need only one.

	 Note that in general we cannot do the arithmetic in a type
	 shorter than the desired result of conversion, even if the operands
	 are both extended from a shorter type, because they might overflow
	 if combined in that type.  The exceptions to this--the times when
	 two narrow values can be combined in their narrow type even to
	 make a wider result--are handled by "shorten" in build_binary_op.  */

      if (dofold)
	switch (ex_form)
	  {
	  case RSHIFT_EXPR:
	    /* We can pass truncation down through right shifting
	       when the shift count is a nonpositive constant.  */
	    if (TREE_CODE (TREE_OPERAND (expr, 1)) == INTEGER_CST
		&& tree_int_cst_sgn (TREE_OPERAND (expr, 1)) <= 0)
	      goto trunc1;
	    break;

	  case LSHIFT_EXPR:
	    /* We can pass truncation down through left shifting
	       when the shift count is a nonnegative constant and
	       the target type is unsigned.  */
	    if (TREE_CODE (TREE_OPERAND (expr, 1)) == INTEGER_CST
		&& tree_int_cst_sgn (TREE_OPERAND (expr, 1)) >= 0
		&& TYPE_UNSIGNED (type)
		&& TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)
	      {
		/* If shift count is less than the width of the truncated type,
		   really shift.  */
		if (wi::to_widest (TREE_OPERAND (expr, 1))
		    < TYPE_PRECISION (type))
		  /* In this case, shifting is like multiplication.  */
		  goto trunc1;
		else
		  {
		    /* If it is >= that width, result is zero.
		       Handling this with trunc1 would give the wrong result:
		       (int) ((long long) a << 32) is well defined (as 0)
		       but (int) a << 32 is undefined and would get a
		       warning.  */

		    tree t = build_int_cst (type, 0);

		    /* If the original expression had side-effects, we must
		       preserve it.  */
		    if (TREE_SIDE_EFFECTS (expr))
		      return build2 (COMPOUND_EXPR, type, expr, t);
		    else
		      return t;
		  }
	      }
	    break;

	  case TRUNC_DIV_EXPR:
	    {
	      tree arg0 = get_unwidened (TREE_OPERAND (expr, 0), NULL_TREE);
	      tree arg1 = get_unwidened (TREE_OPERAND (expr, 1), NULL_TREE);

	      /* Don't distribute unless the output precision is at least as
		 big as the actual inputs and it has the same signedness.  */
	      if (outprec >= TYPE_PRECISION (TREE_TYPE (arg0))
		  && outprec >= TYPE_PRECISION (TREE_TYPE (arg1))
		  /* If signedness of arg0 and arg1 don't match,
		     we can't necessarily find a type to compare them in.  */
		  && (TYPE_UNSIGNED (TREE_TYPE (arg0))
		      == TYPE_UNSIGNED (TREE_TYPE (arg1)))
		  /* Do not change the sign of the division.  */
		  && (TYPE_UNSIGNED (TREE_TYPE (expr))
		      == TYPE_UNSIGNED (TREE_TYPE (arg0)))
		  /* Either require unsigned division or a division by
		     a constant that is not -1.  */
		  && (TYPE_UNSIGNED (TREE_TYPE (arg0))
		      || (TREE_CODE (arg1) == INTEGER_CST
			  && !integer_all_onesp (arg1))))
		{
		  tree tem = do_narrow (loc, ex_form, type, arg0, arg1,
					expr, inprec, outprec, dofold);
		  if (tem)
		    return tem;
		}
	      break;
	    }

	  case MAX_EXPR:
	  case MIN_EXPR:
	  case MULT_EXPR:
	    {
	      tree arg0 = get_unwidened (TREE_OPERAND (expr, 0), type);
	      tree arg1 = get_unwidened (TREE_OPERAND (expr, 1), type);

	      /* Don't distribute unless the output precision is at least as
		 big as the actual inputs.  Otherwise, the comparison of the
		 truncated values will be wrong.  */
	      if (outprec >= TYPE_PRECISION (TREE_TYPE (arg0))
		  && outprec >= TYPE_PRECISION (TREE_TYPE (arg1))
		  /* If signedness of arg0 and arg1 don't match,
		     we can't necessarily find a type to compare them in.  */
		  && (TYPE_UNSIGNED (TREE_TYPE (arg0))
		      == TYPE_UNSIGNED (TREE_TYPE (arg1))))
		goto trunc1;
	      break;
	    }

	  case PLUS_EXPR:
	  case MINUS_EXPR:
	  case BIT_AND_EXPR:
	  case BIT_IOR_EXPR:
	  case BIT_XOR_EXPR:
	  trunc1:
	    {
	      tree arg0 = get_unwidened (TREE_OPERAND (expr, 0), type);
	      tree arg1 = get_unwidened (TREE_OPERAND (expr, 1), type);

	      /* Do not try to narrow operands of pointer subtraction;
		 that will interfere with other folding.  */
	      if (ex_form == MINUS_EXPR
		  && CONVERT_EXPR_P (arg0)
		  && CONVERT_EXPR_P (arg1)
		  && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (arg0, 0)))
		  && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (arg1, 0))))
		break;

	      tree tem = do_narrow (loc, ex_form, type, arg0, arg1,
				    expr, inprec, outprec, dofold);
	      if (tem)
		return tem;
	    }
	    break;

	  case NEGATE_EXPR:
	    /* Using unsigned arithmetic for signed types may hide overflow
	       bugs.  */
	    if (!TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (expr, 0)))
		&& sanitize_flags_p (SANITIZE_SI_OVERFLOW))
	      break;
	    /* Fall through.  */
	  case BIT_NOT_EXPR:
	    /* This is not correct for ABS_EXPR,
	       since we must test the sign before truncation.  */
	    {
	      /* Do the arithmetic in type TYPEX,
		 then convert result to TYPE.  */
	      tree typex = type;

	      /* Can't do arithmetic in enumeral types
		 so use an integer type that will hold the values.  */
	      if (TREE_CODE (typex) == ENUMERAL_TYPE)
		typex
		  = lang_hooks.types.type_for_size (TYPE_PRECISION (typex),
						    TYPE_UNSIGNED (typex));

	      if (!TYPE_UNSIGNED (typex))
		typex = unsigned_type_for (typex);
	      return convert (type,
			      fold_build1 (ex_form, typex,
					   convert (typex,
						    TREE_OPERAND (expr, 0))));
	    }

	  CASE_CONVERT:
	    {
	      tree argtype = TREE_TYPE (TREE_OPERAND (expr, 0));
	      /* Don't introduce a "can't convert between vector values
		 of different size" error.  */
	      if (TREE_CODE (argtype) == VECTOR_TYPE
		  && maybe_ne (GET_MODE_SIZE (TYPE_MODE (argtype)),
			       GET_MODE_SIZE (TYPE_MODE (type))))
		break;
	    }
	    /* If truncating after truncating, might as well do all at once.
	       If truncating after extending, we may get rid of wasted work.  */
	    return convert (type, get_unwidened (TREE_OPERAND (expr, 0), type));

	  case COND_EXPR:
	    /* It is sometimes worthwhile to push the narrowing down through
	       the conditional and never loses.  A COND_EXPR may have a throw
	       as one operand, which then has void type.  Just leave void
	       operands as they are.  */
	    return
	      fold_build3 (COND_EXPR, type, TREE_OPERAND (expr, 0),
			   VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (expr, 1)))
			   ? TREE_OPERAND (expr, 1)
			   : convert (type, TREE_OPERAND (expr, 1)),
			   VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (expr, 2)))
			   ? TREE_OPERAND (expr, 2)
			   : convert (type, TREE_OPERAND (expr, 2)));

	  default:
	    break;
	  }

      /* When parsing long initializers, we might end up with a lot of casts.
	 Shortcut this.  */
      if (TREE_CODE (tree_strip_any_location_wrapper (expr)) == INTEGER_CST)
	return fold_convert (type, expr);
      return build1 (CONVERT_EXPR, type, expr);

    case REAL_TYPE:
      if (sanitize_flags_p (SANITIZE_FLOAT_CAST)
	  && current_function_decl != NULL_TREE)
	{
	  expr = save_expr (expr);
	  tree check = ubsan_instrument_float_cast (loc, type, expr);
	  expr = build1 (FIX_TRUNC_EXPR, type, expr);
	  if (check == NULL_TREE)
	    return expr;
	  return maybe_fold_build2_loc (dofold, loc, COMPOUND_EXPR,
					TREE_TYPE (expr), check, expr);
	}
      else
	return build1 (FIX_TRUNC_EXPR, type, expr);

    case FIXED_POINT_TYPE:
      return build1 (FIXED_CONVERT_EXPR, type, expr);

    case COMPLEX_TYPE:
      expr = maybe_fold_build1_loc (dofold, loc, REALPART_EXPR,
				    TREE_TYPE (TREE_TYPE (expr)), expr);
      return convert (type, expr);

    case VECTOR_TYPE:
      if (!tree_int_cst_equal (TYPE_SIZE (type), TYPE_SIZE (TREE_TYPE (expr))))
	{
	  error ("cannot convert a vector of type %qT"
		 " to type %qT which has different size",
		 TREE_TYPE (expr), type);
	  return error_mark_node;
	}
      return build1 (VIEW_CONVERT_EXPR, type, expr);

    default:
      error ("aggregate value used where an integer was expected");
      return error_mark_node;
    }
}

/* Convert EXPR to some integer (or enum) type TYPE.

   EXPR must be pointer, integer, discrete (enum, char, or bool), float,
   fixed-point or vector; in other cases error is called.

   The result of this is always supposed to be a newly created tree node
   not in use in any existing structure.  */

tree
convert_to_integer (tree type, tree expr)
{
  return convert_to_integer_1 (type, expr, true);
}

/* A wrapper around convert_to_complex_1 that only folds the
   expression if DOFOLD, or if it is CONSTANT_CLASS_OR_WRAPPER_P.  */

tree
convert_to_integer_maybe_fold (tree type, tree expr, bool dofold)
{
  tree result
    = convert_to_integer_1 (type, expr,
			    dofold || CONSTANT_CLASS_OR_WRAPPER_P (expr));
  return preserve_any_location_wrapper (result, expr);
}

/* Convert EXPR to the complex type TYPE in the usual ways.  If FOLD_P is
   true, try to fold the expression.  */

static tree
convert_to_complex_1 (tree type, tree expr, bool fold_p)
{
  location_t loc = EXPR_LOCATION (expr);
  tree subtype = TREE_TYPE (type);

  switch (TREE_CODE (TREE_TYPE (expr)))
    {
    case REAL_TYPE:
    case FIXED_POINT_TYPE:
    case INTEGER_TYPE:
    case ENUMERAL_TYPE:
    case BOOLEAN_TYPE:
    case BITINT_TYPE:
      {
	tree real = convert (subtype, expr);
	tree imag = convert (subtype, integer_zero_node);
	if (error_operand_p (real) || error_operand_p (imag))
	  return error_mark_node;
	return build2 (COMPLEX_EXPR, type, real, imag);
      }

    case COMPLEX_TYPE:
      {
	tree elt_type = TREE_TYPE (TREE_TYPE (expr));

	if (TYPE_MAIN_VARIANT (elt_type) == TYPE_MAIN_VARIANT (subtype))
	  return expr;
	else if (TREE_CODE (expr) == COMPOUND_EXPR)
	  {
	    tree t = convert_to_complex_1 (type, TREE_OPERAND (expr, 1),
					   fold_p);
	    if (t == TREE_OPERAND (expr, 1))
	      return expr;
	    return build2_loc (EXPR_LOCATION (expr), COMPOUND_EXPR,
			       TREE_TYPE (t), TREE_OPERAND (expr, 0), t);
	  }
	else if (TREE_CODE (expr) == COMPLEX_EXPR)
	  return maybe_fold_build2_loc (fold_p, loc, COMPLEX_EXPR, type,
					convert (subtype,
						 TREE_OPERAND (expr, 0)),
					convert (subtype,
						 TREE_OPERAND (expr, 1)));
	else
	  {
	    expr = save_expr (expr);
	    tree realp = maybe_fold_build1_loc (fold_p, loc, REALPART_EXPR,
						TREE_TYPE (TREE_TYPE (expr)),
						expr);
	    tree imagp = maybe_fold_build1_loc (fold_p, loc, IMAGPART_EXPR,
						TREE_TYPE (TREE_TYPE (expr)),
						expr);
	    return maybe_fold_build2_loc (fold_p, loc, COMPLEX_EXPR, type,
					  convert (subtype, realp),
					  convert (subtype, imagp));
	  }
      }

    case POINTER_TYPE:
    case REFERENCE_TYPE:
      error ("pointer value used where a complex was expected");
      return error_mark_node;

    default:
      error ("aggregate value used where a complex was expected");
      return error_mark_node;
    }
}

/* A wrapper around convert_to_complex_1 that always folds the
   expression.  */

tree
convert_to_complex (tree type, tree expr)
{
  return convert_to_complex_1 (type, expr, true);
}

/* A wrapper around convert_to_complex_1 that only folds the
   expression if DOFOLD, or if it is CONSTANT_CLASS_OR_WRAPPER_P.  */

tree
convert_to_complex_maybe_fold (tree type, tree expr, bool dofold)
{
  tree result
    = convert_to_complex_1 (type, expr,
			    dofold || CONSTANT_CLASS_OR_WRAPPER_P (expr));
  return preserve_any_location_wrapper (result, expr);
}

/* Convert EXPR to the vector type TYPE in the usual ways.  */

tree
convert_to_vector (tree type, tree expr)
{
  switch (TREE_CODE (TREE_TYPE (expr)))
    {
    case INTEGER_TYPE:
    case VECTOR_TYPE:
      if (!tree_int_cst_equal (TYPE_SIZE (type), TYPE_SIZE (TREE_TYPE (expr))))
	{
	  error ("cannot convert a value of type %qT"
		 " to vector type %qT which has different size",
		 TREE_TYPE (expr), type);
	  return error_mark_node;
	}
      return build1 (VIEW_CONVERT_EXPR, type, expr);

    default:
      error ("cannot convert value to a vector");
      return error_mark_node;
    }
}

/* Convert EXPR to some fixed-point type TYPE.

   EXPR must be fixed-point, float, integer, or enumeral;
   in other cases error is called.  */

tree
convert_to_fixed (tree type, tree expr)
{
  if (integer_zerop (expr))
    {
      tree fixed_zero_node = build_fixed (type, FCONST0 (TYPE_MODE (type)));
      return fixed_zero_node;
    }
  else if (integer_onep (expr) && ALL_SCALAR_ACCUM_MODE_P (TYPE_MODE (type)))
    {
      tree fixed_one_node = build_fixed (type, FCONST1 (TYPE_MODE (type)));
      return fixed_one_node;
    }

  switch (TREE_CODE (TREE_TYPE (expr)))
    {
    case FIXED_POINT_TYPE:
    case INTEGER_TYPE:
    case ENUMERAL_TYPE:
    case BOOLEAN_TYPE:
    case REAL_TYPE:
      return build1 (FIXED_CONVERT_EXPR, type, expr);

    case COMPLEX_TYPE:
      return convert (type,
		      fold_build1 (REALPART_EXPR,
				   TREE_TYPE (TREE_TYPE (expr)), expr));

    default:
      error ("aggregate value used where a fixed-point was expected");
      return error_mark_node;
    }
}

#if CHECKING_P

namespace selftest {

/* Selftests for conversions.  */

static void
test_convert_to_integer_maybe_fold (tree orig_type, tree new_type)
{
  /* Calling convert_to_integer_maybe_fold on an INTEGER_CST.  */

  tree orig_cst = build_int_cst (orig_type, 42);

  /* Verify that convert_to_integer_maybe_fold on a constant returns a new
     constant of the new type, unless the types are the same, in which
     case verify it's a no-op.  */
  {
    tree result = convert_to_integer_maybe_fold (new_type,
						 orig_cst, false);
    if (orig_type != new_type)
      {
	ASSERT_EQ (TREE_TYPE (result), new_type);
	ASSERT_EQ (TREE_CODE (result), INTEGER_CST);
      }
    else
      ASSERT_EQ (result, orig_cst);
  }

  /* Calling convert_to_integer_maybe_fold on a location wrapper around
     an INTEGER_CST.

     Verify that convert_to_integer_maybe_fold on a location wrapper
     around a constant returns a new location wrapper around an equivalent
     constant, both of the new type, unless the types are the same,
     in which case the original wrapper should be returned.   */
  {
    const location_t loc = BUILTINS_LOCATION;
    tree wrapped_orig_cst = maybe_wrap_with_location (orig_cst, loc);
    tree result
      = convert_to_integer_maybe_fold (new_type, wrapped_orig_cst, false);
    ASSERT_EQ (TREE_TYPE (result), new_type);
    ASSERT_EQ (EXPR_LOCATION (result), loc);
    ASSERT_TRUE (location_wrapper_p (result));
    ASSERT_EQ (TREE_TYPE (TREE_OPERAND (result, 0)), new_type);
    ASSERT_EQ (TREE_CODE (TREE_OPERAND (result, 0)), INTEGER_CST);

    if (orig_type == new_type)
      ASSERT_EQ (result, wrapped_orig_cst);
  }
}

/* Verify that convert_to_integer_maybe_fold preserves locations.  */

static void
test_convert_to_integer_maybe_fold ()
{
  /* char -> long.  */
  test_convert_to_integer_maybe_fold (char_type_node, long_integer_type_node);

  /* char -> char.  */
  test_convert_to_integer_maybe_fold (char_type_node, char_type_node);

  /* long -> char.  */
  test_convert_to_integer_maybe_fold (char_type_node, long_integer_type_node);

  /* long -> long.  */
  test_convert_to_integer_maybe_fold (long_integer_type_node,
				      long_integer_type_node);
}

/* Run all of the selftests within this file.  */

void
convert_cc_tests ()
{
  test_convert_to_integer_maybe_fold ();
}

} // namespace selftest

#endif /* CHECKING_P */
