/* Utility routines for data type conversion for GCC.
   Copyright (C) 1987-2020 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:
      {
	/* 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 convert_to_pointer_1 (type, integer_zero_node, fold_p);
    }
}

/* 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)
	      && TYPE_PRECISION (type) < TYPE_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:
      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 convert_to_real_1 (type, integer_zero_node, fold_p);

    default:
      error ("aggregate value used where a floating-point was expected");
      return convert_to_real_1 (type, integer_zero_node, fold_p);
    }
}

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

  /* 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))
	    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))
	    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)
	      || 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)
	      || 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))))
	    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:
      /* 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
	       || 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 (tree_int_cst_lt (TREE_OPERAND (expr, 1), TYPE_SIZE (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;

	      if (outprec >= BITS_PER_WORD
		  || targetm.truly_noop_truncation (outprec, inprec)
		  || inprec > TYPE_PRECISION (TREE_TYPE (arg0))
		  || inprec > TYPE_PRECISION (TREE_TYPE (arg1)))
		{
		  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 convert (type, integer_zero_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:
      return build2 (COMPLEX_EXPR, type, convert (subtype, expr),
		     convert (subtype, integer_zero_node));

    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 convert_to_complex_1 (type, integer_zero_node, fold_p);

    default:
      error ("aggregate value used where a complex was expected");
      return convert_to_complex_1 (type, integer_zero_node, fold_p);
    }
}

/* 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_c_tests ()
{
  test_convert_to_integer_maybe_fold ();
}

} // namespace selftest

#endif /* CHECKING_P */
