LCOV - code coverage report
Current view: top level - gcc - convert.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 92.1 % 555 511
Test Date: 2026-02-28 14:20:25 Functions: 89.5 % 19 17
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* Utility routines for data type conversion for GCC.
       2              :    Copyright (C) 1987-2026 Free Software Foundation, Inc.
       3              : 
       4              : This file is part of GCC.
       5              : 
       6              : GCC is free software; you can redistribute it and/or modify it under
       7              : the terms of the GNU General Public License as published by the Free
       8              : Software Foundation; either version 3, or (at your option) any later
       9              : version.
      10              : 
      11              : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
      12              : WARRANTY; without even the implied warranty of MERCHANTABILITY or
      13              : FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      14              : for more details.
      15              : 
      16              : You should have received a copy of the GNU General Public License
      17              : along with GCC; see the file COPYING3.  If not see
      18              : <http://www.gnu.org/licenses/>.  */
      19              : 
      20              : 
      21              : /* These routines are somewhat language-independent utility function
      22              :    intended to be called by the language-specific convert () functions.  */
      23              : 
      24              : #include "config.h"
      25              : #include "system.h"
      26              : #include "coretypes.h"
      27              : #include "target.h"
      28              : #include "tree.h"
      29              : #include "diagnostic-core.h"
      30              : #include "fold-const.h"
      31              : #include "stor-layout.h"
      32              : #include "convert.h"
      33              : #include "langhooks.h"
      34              : #include "builtins.h"
      35              : #include "ubsan.h"
      36              : #include "stringpool.h"
      37              : #include "attribs.h"
      38              : #include "asan.h"
      39              : #include "selftest.h"
      40              : 
      41              : #define maybe_fold_build1_loc(FOLD_P, LOC, CODE, TYPE, EXPR) \
      42              :   ((FOLD_P) ? fold_build1_loc (LOC, CODE, TYPE, EXPR)        \
      43              :    : build1_loc (LOC, CODE, TYPE, EXPR))
      44              : #define maybe_fold_build2_loc(FOLD_P, LOC, CODE, TYPE, EXPR1, EXPR2) \
      45              :   ((FOLD_P) ? fold_build2_loc (LOC, CODE, TYPE, EXPR1, EXPR2)        \
      46              :    : build2_loc (LOC, CODE, TYPE, EXPR1, EXPR2))
      47              : 
      48              : /* Convert EXPR to some pointer or reference type TYPE.
      49              :    EXPR must be pointer, reference, integer, enumeral, or literal zero;
      50              :    in other cases error is called.  If FOLD_P is true, try to fold the
      51              :    expression.  */
      52              : 
      53              : static tree
      54      7159331 : convert_to_pointer_1 (tree type, tree expr, bool fold_p)
      55              : {
      56      7159331 :   location_t loc = EXPR_LOCATION (expr);
      57      7159331 :   if (TREE_TYPE (expr) == type)
      58              :     return expr;
      59              : 
      60      7159331 :   switch (TREE_CODE (TREE_TYPE (expr)))
      61              :     {
      62      6590809 :     case POINTER_TYPE:
      63      6590809 :     case REFERENCE_TYPE:
      64      6590809 :       {
      65              :         /* If the pointers point to different address spaces, conversion needs
      66              :            to be done via a ADDR_SPACE_CONVERT_EXPR instead of a NOP_EXPR.  */
      67      6590809 :         addr_space_t to_as = TYPE_ADDR_SPACE (TREE_TYPE (type));
      68      6590809 :         addr_space_t from_as = TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (expr)));
      69              : 
      70      6590809 :         if (to_as == from_as)
      71      6590809 :           return maybe_fold_build1_loc (fold_p, loc, NOP_EXPR, type, expr);
      72              :         else
      73            0 :           return maybe_fold_build1_loc (fold_p, loc, ADDR_SPACE_CONVERT_EXPR,
      74              :                                         type, expr);
      75              :       }
      76              : 
      77       568504 :     case INTEGER_TYPE:
      78       568504 :     case ENUMERAL_TYPE:
      79       568504 :     case BOOLEAN_TYPE:
      80       568504 :     case BITINT_TYPE:
      81       568504 :       {
      82              :         /* If the input precision differs from the target pointer type
      83              :            precision, first convert the input expression to an integer type of
      84              :            the target precision.  Some targets, e.g. VMS, need several pointer
      85              :            sizes to coexist so the latter isn't necessarily POINTER_SIZE.  */
      86       568504 :         unsigned int pprec = TYPE_PRECISION (type);
      87       568504 :         unsigned int eprec = TYPE_PRECISION (TREE_TYPE (expr));
      88              : 
      89       568504 :         if (eprec != pprec)
      90       506706 :           expr
      91       506706 :             = maybe_fold_build1_loc (fold_p, loc, NOP_EXPR,
      92              :                                      lang_hooks.types.type_for_size (pprec, 0),
      93              :                                      expr);
      94              :       }
      95       568504 :       return maybe_fold_build1_loc (fold_p, loc, CONVERT_EXPR, type, expr);
      96              : 
      97           18 :     default:
      98           18 :       error ("cannot convert to a pointer type");
      99           18 :       return error_mark_node;
     100              :     }
     101              : }
     102              : 
     103              : /* Subroutine of the various convert_to_*_maybe_fold routines.
     104              : 
     105              :    If a location wrapper has been folded to a constant (presumably of
     106              :    a different type), re-wrap the new constant with a location wrapper.  */
     107              : 
     108              : tree
     109    523709044 : preserve_any_location_wrapper (tree result, tree orig_expr)
     110              : {
     111    523709044 :   if (CONSTANT_CLASS_P (result) && location_wrapper_p (orig_expr))
     112              :     {
     113     60497244 :       if (result == TREE_OPERAND (orig_expr, 0))
     114              :         return orig_expr;
     115              :       else
     116     30249501 :         return maybe_wrap_with_location (result, EXPR_LOCATION (orig_expr));
     117              :     }
     118              : 
     119              :   return result;
     120              : }
     121              : 
     122              : /* A wrapper around convert_to_pointer_1 that always folds the
     123              :    expression.  */
     124              : 
     125              : tree
     126      7159331 : convert_to_pointer (tree type, tree expr)
     127              : {
     128      7159331 :   return convert_to_pointer_1 (type, expr, true);
     129              : }
     130              : 
     131              : /* A wrapper around convert_to_pointer_1 that only folds the
     132              :    expression if DOFOLD, or if it is CONSTANT_CLASS_OR_WRAPPER_P.  */
     133              : 
     134              : tree
     135            0 : convert_to_pointer_maybe_fold (tree type, tree expr, bool dofold)
     136              : {
     137            0 :   tree result
     138            0 :     = convert_to_pointer_1 (type, expr,
     139            0 :                             dofold || CONSTANT_CLASS_OR_WRAPPER_P (expr));
     140            0 :   return preserve_any_location_wrapper (result, expr);
     141              : }
     142              : 
     143              : /* Convert EXPR to some floating-point type TYPE.
     144              : 
     145              :    EXPR must be float, fixed-point, integer, or enumeral;
     146              :    in other cases error is called.  If FOLD_P is true, try to fold
     147              :    the expression.  */
     148              : 
     149              : static tree
     150     20014852 : convert_to_real_1 (tree type, tree expr, bool fold_p)
     151              : {
     152     20014852 :   enum built_in_function fcode = builtin_mathfn_code (expr);
     153     20014852 :   tree itype = TREE_TYPE (expr);
     154     20014852 :   location_t loc = EXPR_LOCATION (expr);
     155              : 
     156     20014852 :   if (TREE_CODE (expr) == COMPOUND_EXPR)
     157              :     {
     158          451 :       tree t = convert_to_real_1 (type, TREE_OPERAND (expr, 1), fold_p);
     159          451 :       if (t == TREE_OPERAND (expr, 1))
     160              :         return expr;
     161          451 :       return build2_loc (EXPR_LOCATION (expr), COMPOUND_EXPR, TREE_TYPE (t),
     162          902 :                          TREE_OPERAND (expr, 0), t);
     163              :     }
     164              : 
     165              :   /* Disable until we figure out how to decide whether the functions are
     166              :      present in runtime.  */
     167              :   /* Convert (float)sqrt((double)x) where x is float into sqrtf(x) */
     168     20014401 :   if (optimize
     169     20014401 :       && (TYPE_MODE (type) == TYPE_MODE (double_type_node)
     170     18005383 :           || TYPE_MODE (type) == TYPE_MODE (float_type_node)))
     171              :     {
     172     11022342 :       switch (fcode)
     173              :         {
     174              : #define CASE_MATHFN(FN) case BUILT_IN_##FN: case BUILT_IN_##FN##L:
     175         9175 :           CASE_MATHFN (COSH)
     176         9175 :           CASE_MATHFN (EXP)
     177         9175 :           CASE_MATHFN (EXP10)
     178         9175 :           CASE_MATHFN (EXP2)
     179         9175 :           CASE_MATHFN (EXPM1)
     180         9175 :           CASE_MATHFN (GAMMA)
     181         9175 :           CASE_MATHFN (J0)
     182         9175 :           CASE_MATHFN (J1)
     183         9175 :           CASE_MATHFN (LGAMMA)
     184         9175 :           CASE_MATHFN (POW10)
     185         9175 :           CASE_MATHFN (SINH)
     186         9175 :           CASE_MATHFN (TGAMMA)
     187         9175 :           CASE_MATHFN (Y0)
     188         9175 :           CASE_MATHFN (Y1)
     189              :             /* The above functions may set errno differently with float
     190              :                input or output so this transformation is not safe with
     191              :                -fmath-errno.  */
     192         9175 :             if (flag_errno_math)
     193              :               break;
     194        22816 :             gcc_fallthrough ();
     195        22816 :           CASE_MATHFN (ACOS)
     196        22816 :           CASE_MATHFN (ACOSH)
     197        22816 :           CASE_MATHFN (ASIN)
     198        22816 :           CASE_MATHFN (ASINH)
     199        22816 :           CASE_MATHFN (ATAN)
     200        22816 :           CASE_MATHFN (ATANH)
     201        22816 :           CASE_MATHFN (CBRT)
     202        22816 :           CASE_MATHFN (COS)
     203        22816 :           CASE_MATHFN (ERF)
     204        22816 :           CASE_MATHFN (ERFC)
     205        22816 :           CASE_MATHFN (LOG)
     206        22816 :           CASE_MATHFN (LOG10)
     207        22816 :           CASE_MATHFN (LOG2)
     208        22816 :           CASE_MATHFN (LOG1P)
     209        22816 :           CASE_MATHFN (SIN)
     210        22816 :           CASE_MATHFN (TAN)
     211        22816 :           CASE_MATHFN (TANH)
     212              :             /* The above functions are not safe to do this conversion.  */
     213        22816 :             if (!flag_unsafe_math_optimizations)
     214              :               break;
     215         5667 :             gcc_fallthrough ();
     216         5667 :           CASE_MATHFN (SQRT)
     217         5667 :           CASE_MATHFN (FABS)
     218         5667 :           CASE_MATHFN (LOGB)
     219              : #undef CASE_MATHFN
     220         5667 :             if (call_expr_nargs (expr) != 1
     221        11334 :                 || !SCALAR_FLOAT_TYPE_P (TREE_TYPE (CALL_EXPR_ARG (expr, 0))))
     222              :               break;
     223         5567 :             {
     224         5567 :               tree arg0 = strip_float_extensions (CALL_EXPR_ARG (expr, 0));
     225         5567 :               tree newtype = type;
     226              : 
     227              :               /* We have (outertype)sqrt((innertype)x).  Choose the wider mode
     228              :                  from the both as the safe type for operation.  */
     229         5567 :               if (TYPE_PRECISION (TREE_TYPE (arg0)) > TYPE_PRECISION (type))
     230            5 :                 newtype = TREE_TYPE (arg0);
     231              : 
     232              :               /* We consider to convert
     233              : 
     234              :                      (T1) sqrtT2 ((T2) exprT3)
     235              :                  to
     236              :                      (T1) sqrtT4 ((T4) exprT3)
     237              : 
     238              :                   , where T1 is TYPE, T2 is ITYPE, T3 is TREE_TYPE (ARG0),
     239              :                  and T4 is NEWTYPE.  All those types are of floating-point types.
     240              :                  T4 (NEWTYPE) should be narrower than T2 (ITYPE). This conversion
     241              :                  is safe only if P1 >= P2*2+2, where P1 and P2 are precisions of
     242              :                  T2 and T4.  See the following URL for a reference:
     243              :                  http://stackoverflow.com/questions/9235456/determining-
     244              :                  floating-point-square-root
     245              :                  */
     246         5567 :               if ((fcode == BUILT_IN_SQRT || fcode == BUILT_IN_SQRTL)
     247         1341 :                   && !flag_unsafe_math_optimizations)
     248              :                 {
     249              :                   /* The following conversion is unsafe even the precision condition
     250              :                      below is satisfied:
     251              : 
     252              :                      (float) sqrtl ((long double) double_val) -> (float) sqrt (double_val)
     253              :                     */
     254         1279 :                   if (TYPE_MODE (type) != TYPE_MODE (newtype))
     255              :                     break;
     256              : 
     257         1278 :                   int p1 = REAL_MODE_FORMAT (TYPE_MODE (itype))->p;
     258         1278 :                   int p2 = REAL_MODE_FORMAT (TYPE_MODE (newtype))->p;
     259         1278 :                   if (p1 < p2 * 2 + 2)
     260              :                     break;
     261              :                 }
     262              : 
     263              :               /* Be careful about integer to fp conversions.
     264              :                  These may overflow still.  */
     265         4299 :               if (FLOAT_TYPE_P (TREE_TYPE (arg0))
     266         4299 :                   && TYPE_PRECISION (newtype) < TYPE_PRECISION (itype)
     267         5692 :                   && (TYPE_MODE (newtype) == TYPE_MODE (double_type_node)
     268          943 :                       || TYPE_MODE (newtype) == TYPE_MODE (float_type_node)))
     269              :                 {
     270         1393 :                   tree fn = mathfn_built_in (newtype, fcode);
     271         1393 :                   if (fn)
     272              :                     {
     273         1393 :                       tree arg = convert_to_real_1 (newtype, arg0, fold_p);
     274         1393 :                       expr = build_call_expr (fn, 1, arg);
     275         1393 :                       if (newtype == type)
     276              :                         return expr;
     277              :                     }
     278              :                 }
     279              :             }
     280              :         default:
     281              :           break;
     282              :         }
     283              :     }
     284              : 
     285              :   /* Propagate the cast into the operation.  */
     286     20013008 :   if (itype != type && FLOAT_TYPE_P (type))
     287     19988016 :     switch (TREE_CODE (expr))
     288              :       {
     289              :         /* Convert (float)-x into -(float)x.  This is safe for
     290              :            round-to-nearest rounding mode when the inner type is float.  */
     291        67807 :         case ABS_EXPR:
     292        67807 :         case NEGATE_EXPR:
     293        67807 :           if (!flag_rounding_math
     294        67806 :               && FLOAT_TYPE_P (itype)
     295        97856 :               && element_precision (type) < element_precision (itype))
     296              :             {
     297         3905 :               tree arg = convert_to_real_1 (type, TREE_OPERAND (expr, 0),
     298              :                                             fold_p);
     299         3905 :               return build1 (TREE_CODE (expr), type, arg);
     300              :             }
     301              :           break;
     302              :         default:
     303              :           break;
     304              :       }
     305              : 
     306     20009103 :   switch (TREE_CODE (TREE_TYPE (expr)))
     307              :     {
     308      3328072 :     case REAL_TYPE:
     309              :       /* Ignore the conversion if we don't need to store intermediate
     310              :          results and neither type is a decimal float.  */
     311      3328072 :       return build1_loc (loc,
     312      3328072 :                          (flag_float_store
     313      3327963 :                           || DECIMAL_FLOAT_TYPE_P (type)
     314      3310589 :                           || DECIMAL_FLOAT_TYPE_P (itype))
     315      3328072 :                          ? CONVERT_EXPR : NOP_EXPR, type, expr);
     316              : 
     317     16678940 :     case INTEGER_TYPE:
     318     16678940 :     case ENUMERAL_TYPE:
     319     16678940 :     case BOOLEAN_TYPE:
     320     16678940 :     case BITINT_TYPE:
     321     16678940 :       return build1 (FLOAT_EXPR, type, expr);
     322              : 
     323            0 :     case FIXED_POINT_TYPE:
     324            0 :       return build1 (FIXED_CONVERT_EXPR, type, expr);
     325              : 
     326         2064 :     case COMPLEX_TYPE:
     327         4128 :       return convert (type,
     328         2064 :                       maybe_fold_build1_loc (fold_p, loc, REALPART_EXPR,
     329              :                                              TREE_TYPE (TREE_TYPE (expr)),
     330         2064 :                                              expr));
     331              : 
     332            4 :     case POINTER_TYPE:
     333            4 :     case REFERENCE_TYPE:
     334            4 :       error ("pointer value used where a floating-point was expected");
     335            4 :       return error_mark_node;
     336              : 
     337           11 :     case VECTOR_TYPE:
     338           11 :       error ("vector value used where a floating-point was expected");
     339           11 :       return error_mark_node;
     340              : 
     341           12 :     default:
     342           12 :       error ("aggregate value used where a floating-point was expected");
     343           12 :       return error_mark_node;
     344              :     }
     345              : }
     346              : 
     347              : /* A wrapper around convert_to_real_1 that always folds the
     348              :    expression.  */
     349              : 
     350              : tree
     351      1070527 : convert_to_real (tree type, tree expr)
     352              : {
     353      1070527 :   return convert_to_real_1 (type, expr, true);
     354              : }
     355              : 
     356              : /* A wrapper around convert_to_real_1 that only folds the
     357              :    expression if DOFOLD, or if it is CONSTANT_CLASS_OR_WRAPPER_P.  */
     358              : 
     359              : tree
     360     18938576 : convert_to_real_maybe_fold (tree type, tree expr, bool dofold)
     361              : {
     362     18938576 :   tree result
     363     18938576 :     = convert_to_real_1 (type, expr,
     364     18938576 :                          dofold || CONSTANT_CLASS_OR_WRAPPER_P (expr));
     365     18938576 :   return preserve_any_location_wrapper (result, expr);
     366              : }
     367              : 
     368              : /* Try to narrow EX_FORM ARG0 ARG1 in narrowed arg types producing a
     369              :    result in TYPE.  */
     370              : 
     371              : static tree
     372       716761 : do_narrow (location_t loc,
     373              :            enum tree_code ex_form, tree type, tree arg0, tree arg1,
     374              :            tree expr, unsigned inprec, unsigned outprec, bool dofold)
     375              : {
     376              :   /* Do the arithmetic in type TYPEX,
     377              :      then convert result to TYPE.  */
     378       716761 :   tree typex = type;
     379              : 
     380              :   /* Can't do arithmetic in enumeral types
     381              :      so use an integer type that will hold the values.  */
     382       716761 :   if (TREE_CODE (typex) == ENUMERAL_TYPE)
     383            0 :     typex = lang_hooks.types.type_for_size (TYPE_PRECISION (typex),
     384            0 :                                             TYPE_UNSIGNED (typex));
     385              : 
     386              :   /* The type demotion below might cause doing unsigned arithmetic
     387              :      instead of signed, and thus hide overflow bugs.  */
     388       716761 :   if ((ex_form == PLUS_EXPR || ex_form == MINUS_EXPR)
     389       358087 :       && !TYPE_UNSIGNED (typex)
     390       964832 :       && sanitize_flags_p (SANITIZE_SI_OVERFLOW))
     391              :     return NULL_TREE;
     392              : 
     393              :   /* Similarly for multiplication, but in that case it can be
     394              :      problematic even if typex is unsigned type - 0xffff * 0xffff
     395              :      overflows in int.  */
     396       716648 :   if (ex_form == MULT_EXPR
     397         3904 :       && !TYPE_OVERFLOW_WRAPS (TREE_TYPE (expr))
     398       719098 :       && sanitize_flags_p (SANITIZE_SI_OVERFLOW))
     399              :     return NULL_TREE;
     400              : 
     401              :   /* But now perhaps TYPEX is as wide as INPREC.
     402              :      In that case, do nothing special here.
     403              :      (Otherwise would recurse infinitely in convert.  */
     404       716609 :   if (TYPE_PRECISION (typex) != inprec)
     405              :     {
     406              :       /* Don't do unsigned arithmetic where signed was wanted,
     407              :          or vice versa.
     408              :          Exception: if both of the original operands were
     409              :          unsigned then we can safely do the work as unsigned.
     410              :          Exception: shift operations take their type solely
     411              :          from the first argument.
     412              :          Exception: the LSHIFT_EXPR case above requires that
     413              :          we perform this operation unsigned lest we produce
     414              :          signed-overflow undefinedness.
     415              :          And we may need to do it as unsigned
     416              :          if we truncate to the original size.  */
     417       716609 :       if (TYPE_UNSIGNED (TREE_TYPE (expr))
     418       182837 :           || (TYPE_UNSIGNED (TREE_TYPE (arg0))
     419        87214 :               && (TYPE_UNSIGNED (TREE_TYPE (arg1))
     420              :                   || ex_form == LSHIFT_EXPR
     421        72406 :                   || ex_form == RSHIFT_EXPR
     422              :                   || ex_form == LROTATE_EXPR
     423        71749 :                   || ex_form == RROTATE_EXPR))
     424       167372 :           || ex_form == LSHIFT_EXPR
     425              :           /* If we have !flag_wrapv, and either ARG0 or
     426              :              ARG1 is of a signed type, we have to do
     427              :              PLUS_EXPR, MINUS_EXPR or MULT_EXPR in an unsigned
     428              :              type in case the operation in outprec precision
     429              :              could overflow.  Otherwise, we would introduce
     430              :              signed-overflow undefinedness.  */
     431       883610 :           || ((!(INTEGRAL_TYPE_P (TREE_TYPE (arg0))
     432       167001 :                  && TYPE_OVERFLOW_WRAPS (TREE_TYPE (arg0)))
     433        72704 :                || !(INTEGRAL_TYPE_P (TREE_TYPE (arg1))
     434        72704 :                     && TYPE_OVERFLOW_WRAPS (TREE_TYPE (arg1))))
     435       166027 :               && ((TYPE_PRECISION (TREE_TYPE (arg0)) * 2u
     436              :                    > outprec)
     437         9794 :                   || (TYPE_PRECISION (TREE_TYPE (arg1)) * 2u
     438              :                       > outprec))
     439       165929 :               && (ex_form == PLUS_EXPR
     440              :                   || ex_form == MINUS_EXPR
     441              :                   || ex_form == MULT_EXPR)))
     442              :         {
     443       676312 :           if (!TYPE_UNSIGNED (typex))
     444       332540 :             typex = unsigned_type_for (typex);
     445              :         }
     446              :       else
     447              :         {
     448        40297 :           if (TYPE_UNSIGNED (typex))
     449        29450 :             typex = signed_type_for (typex);
     450              :         }
     451              :       /* We should do away with all this once we have a proper
     452              :          type promotion/demotion pass, see PR45397.  */
     453       716609 :       expr = maybe_fold_build2_loc (dofold, loc, ex_form, typex,
     454              :                                     convert (typex, arg0),
     455              :                                     convert (typex, arg1));
     456       716609 :       return convert (type, expr);
     457              :     }
     458              : 
     459              :   return NULL_TREE;
     460              : }
     461              : 
     462              : /* Convert EXPR to some integer (or enum) type TYPE.
     463              : 
     464              :    EXPR must be pointer, integer, discrete (enum, char, or bool), float,
     465              :    fixed-point or vector; in other cases error is called.
     466              : 
     467              :    If DOFOLD is TRUE, we try to simplify newly-created patterns by folding.
     468              : 
     469              :    The result of this is always supposed to be a newly created tree node
     470              :    not in use in any existing structure.  */
     471              : 
     472              : static tree
     473    270482877 : convert_to_integer_1 (tree type, tree expr, bool dofold)
     474              : {
     475    270482877 :   enum tree_code ex_form = TREE_CODE (expr);
     476    270482877 :   tree intype = TREE_TYPE (expr);
     477    270482877 :   unsigned int inprec = element_precision (intype);
     478    270482877 :   unsigned int outprec = element_precision (type);
     479    270482877 :   location_t loc = EXPR_LOCATION (expr);
     480              : 
     481              :   /* An INTEGER_TYPE cannot be incomplete, but an ENUMERAL_TYPE can
     482              :      be.  Consider `enum E = { a, b = (enum E) 3 };'.  */
     483    270482877 :   if (!COMPLETE_TYPE_P (type))
     484              :     {
     485            4 :       error ("conversion to incomplete type");
     486            4 :       return error_mark_node;
     487              :     }
     488              : 
     489    270482873 :   if (ex_form == COMPOUND_EXPR)
     490              :     {
     491        48206 :       tree t = convert_to_integer_1 (type, TREE_OPERAND (expr, 1), dofold);
     492        48206 :       if (t == TREE_OPERAND (expr, 1))
     493              :         return expr;
     494        45333 :       return build2_loc (EXPR_LOCATION (expr), COMPOUND_EXPR, TREE_TYPE (t),
     495        90666 :                          TREE_OPERAND (expr, 0), t);
     496              :     }
     497              : 
     498              :   /* Convert e.g. (long)round(d) -> lround(d).  */
     499              :   /* If we're converting to char, we may encounter differing behavior
     500              :      between converting from double->char vs double->long->char.
     501              :      We're in "undefined" territory but we prefer to be conservative,
     502              :      so only proceed in "unsafe" math mode.  */
     503    270434667 :   if (optimize
     504    270434667 :       && (flag_unsafe_math_optimizations
     505    257082976 :           || (long_integer_type_node
     506    257082976 :               && outprec >= TYPE_PRECISION (long_integer_type_node))))
     507              :     {
     508    104009252 :       tree s_expr = strip_float_extensions (expr);
     509    104009252 :       tree s_intype = TREE_TYPE (s_expr);
     510    104009252 :       const enum built_in_function fcode = builtin_mathfn_code (s_expr);
     511    104009252 :       tree fn = 0;
     512              : 
     513    104009252 :       switch (fcode)
     514              :         {
     515        37689 :         CASE_FLT_FN (BUILT_IN_CEIL):
     516        37689 :         CASE_FLT_FN_FLOATN_NX (BUILT_IN_CEIL):
     517              :           /* Only convert in ISO C99 mode.  */
     518        37689 :           if (!targetm.libc_has_function (function_c99_misc, intype))
     519              :             break;
     520        37689 :           if (outprec < TYPE_PRECISION (integer_type_node)
     521        37689 :               || (outprec == TYPE_PRECISION (integer_type_node)
     522           71 :                   && !TYPE_UNSIGNED (type)))
     523           22 :             fn = mathfn_built_in (s_intype, BUILT_IN_ICEIL);
     524        37667 :           else if (outprec == TYPE_PRECISION (long_integer_type_node)
     525        37667 :                    && !TYPE_UNSIGNED (type))
     526           81 :             fn = mathfn_built_in (s_intype, BUILT_IN_LCEIL);
     527        37586 :           else if (outprec == TYPE_PRECISION (long_long_integer_type_node)
     528        37586 :                    && !TYPE_UNSIGNED (type))
     529            0 :             fn = mathfn_built_in (s_intype, BUILT_IN_LLCEIL);
     530              :           break;
     531              : 
     532        37292 :         CASE_FLT_FN (BUILT_IN_FLOOR):
     533        37292 :         CASE_FLT_FN_FLOATN_NX (BUILT_IN_FLOOR):
     534              :           /* Only convert in ISO C99 mode.  */
     535        37292 :           if (!targetm.libc_has_function (function_c99_misc, intype))
     536              :             break;
     537        37292 :           if (outprec < TYPE_PRECISION (integer_type_node)
     538        37292 :               || (outprec == TYPE_PRECISION (integer_type_node)
     539           63 :                   && !TYPE_UNSIGNED (type)))
     540           21 :             fn = mathfn_built_in (s_intype, BUILT_IN_IFLOOR);
     541        37271 :           else if (outprec == TYPE_PRECISION (long_integer_type_node)
     542        37271 :                    && !TYPE_UNSIGNED (type))
     543           82 :             fn = mathfn_built_in (s_intype, BUILT_IN_LFLOOR);
     544        37189 :           else if (outprec == TYPE_PRECISION (long_long_integer_type_node)
     545        37189 :                    && !TYPE_UNSIGNED (type))
     546            0 :             fn = mathfn_built_in (s_intype, BUILT_IN_LLFLOOR);
     547              :           break;
     548              : 
     549          107 :         CASE_FLT_FN (BUILT_IN_ROUND):
     550          107 :         CASE_FLT_FN_FLOATN_NX (BUILT_IN_ROUND):
     551              :           /* Only convert in ISO C99 mode and with -fno-math-errno.  */
     552          107 :           if (!targetm.libc_has_function (function_c99_misc, intype)
     553          107 :               || flag_errno_math)
     554              :             break;
     555          104 :           if (outprec < TYPE_PRECISION (integer_type_node)
     556          104 :               || (outprec == TYPE_PRECISION (integer_type_node)
     557           24 :                   && !TYPE_UNSIGNED (type)))
     558           25 :             fn = mathfn_built_in (s_intype, BUILT_IN_IROUND);
     559           79 :           else if (outprec == TYPE_PRECISION (long_integer_type_node)
     560           79 :                    && !TYPE_UNSIGNED (type))
     561           74 :             fn = mathfn_built_in (s_intype, BUILT_IN_LROUND);
     562            5 :           else if (outprec == TYPE_PRECISION (long_long_integer_type_node)
     563            5 :                    && !TYPE_UNSIGNED (type))
     564            0 :             fn = mathfn_built_in (s_intype, BUILT_IN_LLROUND);
     565              :           break;
     566              : 
     567           95 :         CASE_FLT_FN (BUILT_IN_NEARBYINT):
     568           95 :         CASE_FLT_FN_FLOATN_NX (BUILT_IN_NEARBYINT):
     569              :           /* Only convert nearbyint* if we can ignore math exceptions.  */
     570           95 :           if (flag_trapping_math)
     571              :             break;
     572          175 :           gcc_fallthrough ();
     573          175 :         CASE_FLT_FN (BUILT_IN_RINT):
     574          175 :         CASE_FLT_FN_FLOATN_NX (BUILT_IN_RINT):
     575              :           /* Only convert in ISO C99 mode and with -fno-math-errno.  */
     576          175 :           if (!targetm.libc_has_function (function_c99_misc, intype)
     577          175 :               || flag_errno_math)
     578              :             break;
     579          175 :           if (outprec < TYPE_PRECISION (integer_type_node)
     580          175 :               || (outprec == TYPE_PRECISION (integer_type_node)
     581           25 :                   && !TYPE_UNSIGNED (type)))
     582           25 :             fn = mathfn_built_in (s_intype, BUILT_IN_IRINT);
     583          150 :           else if (outprec == TYPE_PRECISION (long_integer_type_node)
     584          150 :                    && !TYPE_UNSIGNED (type))
     585          150 :             fn = mathfn_built_in (s_intype, BUILT_IN_LRINT);
     586            0 :           else if (outprec == TYPE_PRECISION (long_long_integer_type_node)
     587            0 :                    && !TYPE_UNSIGNED (type))
     588            0 :             fn = mathfn_built_in (s_intype, BUILT_IN_LLRINT);
     589              :           break;
     590              : 
     591           14 :         CASE_FLT_FN (BUILT_IN_TRUNC):
     592           14 :         CASE_FLT_FN_FLOATN_NX (BUILT_IN_TRUNC):
     593           14 :           if (call_expr_nargs (s_expr) != 1
     594           14 :               || !SCALAR_FLOAT_TYPE_P (TREE_TYPE (CALL_EXPR_ARG (s_expr, 0)))
     595           26 :               || (!flag_fp_int_builtin_inexact && flag_trapping_math))
     596              :             break;
     597            6 :           return convert_to_integer_1 (type, CALL_EXPR_ARG (s_expr, 0),
     598            6 :                                        dofold);
     599              : 
     600              :         default:
     601              :           break;
     602              :         }
     603              : 
     604          480 :       if (fn
     605          480 :           && call_expr_nargs (s_expr) == 1
     606          960 :           && SCALAR_FLOAT_TYPE_P (TREE_TYPE (CALL_EXPR_ARG (s_expr, 0))))
     607              :         {
     608          470 :           tree newexpr = build_call_expr (fn, 1, CALL_EXPR_ARG (s_expr, 0));
     609          470 :           return convert_to_integer_1 (type, newexpr, dofold);
     610              :         }
     611              :     }
     612              : 
     613              :   /* Convert (int)logb(d) -> ilogb(d).  */
     614    270434191 :   if (optimize
     615    257812732 :       && flag_unsafe_math_optimizations
     616       729761 :       && !flag_trapping_math && !flag_errno_math && flag_finite_math_only
     617       729607 :       && integer_type_node
     618    271163798 :       && (outprec > TYPE_PRECISION (integer_type_node)
     619       417991 :           || (outprec == TYPE_PRECISION (integer_type_node)
     620       214534 :               && !TYPE_UNSIGNED (type))))
     621              :     {
     622       380289 :       tree s_expr = strip_float_extensions (expr);
     623       380289 :       tree s_intype = TREE_TYPE (s_expr);
     624       380289 :       const enum built_in_function fcode = builtin_mathfn_code (s_expr);
     625       380289 :       tree fn = 0;
     626              : 
     627       380289 :       switch (fcode)
     628              :         {
     629            5 :         CASE_FLT_FN (BUILT_IN_LOGB):
     630            5 :           fn = mathfn_built_in (s_intype, BUILT_IN_ILOGB);
     631            5 :           break;
     632              : 
     633              :         default:
     634              :           break;
     635              :         }
     636              : 
     637            5 :       if (fn
     638            5 :           && call_expr_nargs (s_expr) == 1
     639           10 :           && SCALAR_FLOAT_TYPE_P (TREE_TYPE (CALL_EXPR_ARG (s_expr, 0))))
     640              :         {
     641            3 :           tree newexpr = build_call_expr (fn, 1, CALL_EXPR_ARG (s_expr, 0));
     642            3 :           return convert_to_integer_1 (type, newexpr, dofold);
     643              :         }
     644              :     }
     645              : 
     646    270434188 :   switch (TREE_CODE (intype))
     647              :     {
     648       929400 :     case POINTER_TYPE:
     649       929400 :     case REFERENCE_TYPE:
     650       929400 :       if (integer_zerop (expr)
     651       929400 :           && !TREE_OVERFLOW (tree_strip_any_location_wrapper (expr)))
     652        19656 :         return build_int_cst (type, 0);
     653              : 
     654              :       /* Convert to an unsigned integer of the correct width first, and from
     655              :          there widen/truncate to the required type.  Some targets support the
     656              :          coexistence of multiple valid pointer sizes, so fetch the one we need
     657              :          from the type.  */
     658       909744 :       if (!dofold)
     659       193533 :         return build1 (CONVERT_EXPR, type, expr);
     660       716211 :       expr = fold_build1 (CONVERT_EXPR,
     661              :                           lang_hooks.types.type_for_size
     662              :                             (TYPE_PRECISION (intype), 0),
     663              :                           expr);
     664       716211 :       return fold_convert (type, expr);
     665              : 
     666    269008929 :     case INTEGER_TYPE:
     667    269008929 :     case ENUMERAL_TYPE:
     668    269008929 :     case BOOLEAN_TYPE:
     669    269008929 :     case OFFSET_TYPE:
     670    269008929 :     case BITINT_TYPE:
     671              :       /* If this is a logical operation, which just returns 0 or 1, we can
     672              :          change the type of the expression.  */
     673              : 
     674    269008929 :       if (TREE_CODE_CLASS (ex_form) == tcc_comparison)
     675              :         {
     676      3285954 :           expr = copy_node (expr);
     677      3285954 :           TREE_TYPE (expr) = type;
     678      3285954 :           return expr;
     679              :         }
     680              : 
     681              :       /* If we are widening the type, put in an explicit conversion.
     682              :          Similarly if we are not changing the width.  After this, we know
     683              :          we are truncating EXPR.  */
     684              : 
     685    265722975 :       else if (outprec >= inprec)
     686              :         {
     687    230832745 :           enum tree_code code;
     688              : 
     689              :           /* If the precision of the EXPR's type is K bits and the
     690              :              destination mode has more bits, and the sign is changing,
     691              :              it is not safe to use a NOP_EXPR.  For example, suppose
     692              :              that EXPR's type is a 3-bit unsigned integer type, the
     693              :              TYPE is a 3-bit signed integer type, and the machine mode
     694              :              for the types is 8-bit QImode.  In that case, the
     695              :              conversion necessitates an explicit sign-extension.  In
     696              :              the signed-to-unsigned case the high-order bits have to
     697              :              be cleared.  */
     698    230832745 :           if (TYPE_UNSIGNED (type) != TYPE_UNSIGNED (TREE_TYPE (expr))
     699    230832745 :               && !type_has_mode_precision_p (TREE_TYPE (expr)))
     700              :             code = CONVERT_EXPR;
     701              :           else
     702              :             code = NOP_EXPR;
     703              : 
     704    230832745 :           return maybe_fold_build1_loc (dofold, loc, code, type, expr);
     705              :         }
     706              : 
     707              :       /* If TYPE is an enumeral type or a type with a precision less
     708              :          than the number of bits in its mode, do the conversion to the
     709              :          type corresponding to its mode, then do a nop conversion
     710              :          to TYPE.  */
     711     34890230 :       else if (TREE_CODE (type) == ENUMERAL_TYPE
     712     34890230 :                || (TREE_CODE (type) != BITINT_TYPE
     713     34712834 :                    && maybe_ne (outprec,
     714     34712834 :                                 GET_MODE_PRECISION (TYPE_MODE (type)))))
     715              :         {
     716      4556945 :           expr
     717      4556945 :             = convert_to_integer_1 (lang_hooks.types.type_for_mode
     718      4556945 :                                     (TYPE_MODE (type), TYPE_UNSIGNED (type)),
     719              :                                     expr, dofold);
     720      4556945 :           return maybe_fold_build1_loc (dofold, loc, NOP_EXPR, type, expr);
     721              :         }
     722              : 
     723              :       /* Here detect when we can distribute the truncation down past some
     724              :          arithmetic.  For example, if adding two longs and converting to an
     725              :          int, we can equally well convert both to ints and then add.
     726              :          For the operations handled here, such truncation distribution
     727              :          is always safe.
     728              :          It is desirable in these cases:
     729              :          1) when truncating down to full-word from a larger size
     730              :          2) when truncating takes no work.
     731              :          3) when at least one operand of the arithmetic has been extended
     732              :          (as by C's default conversions).  In this case we need two conversions
     733              :          if we do the arithmetic as already requested, so we might as well
     734              :          truncate both and then combine.  Perhaps that way we need only one.
     735              : 
     736              :          Note that in general we cannot do the arithmetic in a type
     737              :          shorter than the desired result of conversion, even if the operands
     738              :          are both extended from a shorter type, because they might overflow
     739              :          if combined in that type.  The exceptions to this--the times when
     740              :          two narrow values can be combined in their narrow type even to
     741              :          make a wider result--are handled by "shorten" in build_binary_op.  */
     742              : 
     743     30333285 :       if (dofold)
     744     24523432 :         switch (ex_form)
     745              :           {
     746       167723 :           case RSHIFT_EXPR:
     747              :             /* We can pass truncation down through right shifting
     748              :                when the shift count is a nonpositive constant.  */
     749       167723 :             if (TREE_CODE (TREE_OPERAND (expr, 1)) == INTEGER_CST
     750       167723 :                 && tree_int_cst_sgn (TREE_OPERAND (expr, 1)) <= 0)
     751           55 :               goto trunc1;
     752              :             break;
     753              : 
     754        16683 :           case LSHIFT_EXPR:
     755              :             /* We can pass truncation down through left shifting
     756              :                when the shift count is a nonnegative constant and
     757              :                the target type is unsigned.  */
     758        16683 :             if (TREE_CODE (TREE_OPERAND (expr, 1)) == INTEGER_CST
     759         4094 :                 && tree_int_cst_sgn (TREE_OPERAND (expr, 1)) >= 0
     760         4062 :                 && TYPE_UNSIGNED (type)
     761        18286 :                 && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)
     762              :               {
     763              :                 /* If shift count is less than the width of the truncated type,
     764              :                    really shift.  */
     765         1603 :                 if (wi::to_widest (TREE_OPERAND (expr, 1))
     766         3206 :                     < TYPE_PRECISION (type))
     767              :                   /* In this case, shifting is like multiplication.  */
     768         1580 :                   goto trunc1;
     769              :                 else
     770              :                   {
     771              :                     /* If it is >= that width, result is zero.
     772              :                        Handling this with trunc1 would give the wrong result:
     773              :                        (int) ((long long) a << 32) is well defined (as 0)
     774              :                        but (int) a << 32 is undefined and would get a
     775              :                        warning.  */
     776              : 
     777           23 :                     tree t = build_int_cst (type, 0);
     778              : 
     779              :                     /* If the original expression had side-effects, we must
     780              :                        preserve it.  */
     781           23 :                     if (TREE_SIDE_EFFECTS (expr))
     782            0 :                       return build2 (COMPOUND_EXPR, type, expr, t);
     783              :                     else
     784              :                       return t;
     785              :                   }
     786              :               }
     787              :             break;
     788              : 
     789        23732 :           case TRUNC_DIV_EXPR:
     790        23732 :             {
     791        23732 :               tree arg0 = get_unwidened (TREE_OPERAND (expr, 0), NULL_TREE);
     792        23732 :               tree arg1 = get_unwidened (TREE_OPERAND (expr, 1), NULL_TREE);
     793              : 
     794              :               /* Don't distribute unless the output precision is at least as
     795              :                  big as the actual inputs and it has the same signedness.  */
     796        23732 :               if (outprec >= TYPE_PRECISION (TREE_TYPE (arg0))
     797        12679 :                   && outprec >= TYPE_PRECISION (TREE_TYPE (arg1))
     798              :                   /* If signedness of arg0 and arg1 don't match,
     799              :                      we can't necessarily find a type to compare them in.  */
     800          511 :                   && (TYPE_UNSIGNED (TREE_TYPE (arg0))
     801          511 :                       == TYPE_UNSIGNED (TREE_TYPE (arg1)))
     802              :                   /* Do not change the sign of the division.  */
     803          345 :                   && (TYPE_UNSIGNED (TREE_TYPE (expr))
     804          345 :                       == TYPE_UNSIGNED (TREE_TYPE (arg0)))
     805              :                   /* Either require unsigned division or a division by
     806              :                      a constant that is not -1.  */
     807        24036 :                   && (TYPE_UNSIGNED (TREE_TYPE (arg0))
     808          282 :                       || (TREE_CODE (arg1) == INTEGER_CST
     809          161 :                           && !integer_all_onesp (arg1))))
     810              :                 {
     811          183 :                   tree tem = do_narrow (loc, ex_form, type, arg0, arg1,
     812              :                                         expr, inprec, outprec, dofold);
     813          183 :                   if (tem)
     814              :                     return tem;
     815              :                 }
     816              :               break;
     817              :             }
     818              : 
     819        44179 :           case MAX_EXPR:
     820        44179 :           case MIN_EXPR:
     821        44179 :           case MULT_EXPR:
     822        44179 :             {
     823        44179 :               tree arg0 = get_unwidened (TREE_OPERAND (expr, 0), type);
     824        44179 :               tree arg1 = get_unwidened (TREE_OPERAND (expr, 1), type);
     825              : 
     826              :               /* Don't distribute unless the output precision is at least as
     827              :                  big as the actual inputs.  Otherwise, the comparison of the
     828              :                  truncated values will be wrong.  */
     829        44179 :               if (outprec >= TYPE_PRECISION (TREE_TYPE (arg0))
     830        23782 :                   && outprec >= TYPE_PRECISION (TREE_TYPE (arg1))
     831              :                   /* If signedness of arg0 and arg1 don't match,
     832              :                      we can't necessarily find a type to compare them in.  */
     833        48934 :                   && (TYPE_UNSIGNED (TREE_TYPE (arg0))
     834         4755 :                       == TYPE_UNSIGNED (TREE_TYPE (arg1))))
     835         4311 :                 goto trunc1;
     836              :               break;
     837              :             }
     838              : 
     839       716598 :           case PLUS_EXPR:
     840       716598 :           case MINUS_EXPR:
     841       716598 :           case BIT_AND_EXPR:
     842       716598 :           case BIT_IOR_EXPR:
     843       716598 :           case BIT_XOR_EXPR:
     844       716598 :           trunc1:
     845       716598 :             {
     846       716598 :               tree arg0 = get_unwidened (TREE_OPERAND (expr, 0), type);
     847       716598 :               tree arg1 = get_unwidened (TREE_OPERAND (expr, 1), type);
     848              : 
     849              :               /* Do not try to narrow operands of pointer subtraction;
     850              :                  that will interfere with other folding.  */
     851       716598 :               if (ex_form == MINUS_EXPR
     852         5918 :                   && CONVERT_EXPR_P (arg0)
     853          138 :                   && CONVERT_EXPR_P (arg1)
     854           55 :                   && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (arg0, 0)))
     855       716618 :                   && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (arg1, 0))))
     856              :                 break;
     857              : 
     858       716578 :               tree tem = do_narrow (loc, ex_form, type, arg0, arg1,
     859              :                                     expr, inprec, outprec, dofold);
     860       716578 :               if (tem)
     861              :                 return tem;
     862              :             }
     863              :             break;
     864              : 
     865        72278 :           case NEGATE_EXPR:
     866              :             /* Using unsigned arithmetic for signed types may hide overflow
     867              :                bugs.  */
     868        72278 :             if (!TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (expr, 0)))
     869        72278 :                 && sanitize_flags_p (SANITIZE_SI_OVERFLOW))
     870              :               break;
     871              :             /* Fall through.  */
     872       170643 :           case BIT_NOT_EXPR:
     873              :             /* This is not correct for ABS_EXPR,
     874              :                since we must test the sign before truncation.  */
     875       170643 :             {
     876              :               /* Do the arithmetic in type TYPEX,
     877              :                  then convert result to TYPE.  */
     878       170643 :               tree typex = type;
     879              : 
     880              :               /* Can't do arithmetic in enumeral types
     881              :                  so use an integer type that will hold the values.  */
     882       170643 :               if (TREE_CODE (typex) == ENUMERAL_TYPE)
     883            0 :                 typex
     884            0 :                   = lang_hooks.types.type_for_size (TYPE_PRECISION (typex),
     885            0 :                                                     TYPE_UNSIGNED (typex));
     886              : 
     887       170643 :               if (!TYPE_UNSIGNED (typex))
     888        71384 :                 typex = unsigned_type_for (typex);
     889       170643 :               return convert (type,
     890       170643 :                               fold_build1 (ex_form, typex,
     891              :                                            convert (typex,
     892       170643 :                                                     TREE_OPERAND (expr, 0))));
     893              :             }
     894              : 
     895      2570787 :           CASE_CONVERT:
     896      2570787 :             {
     897      2570787 :               tree argtype = TREE_TYPE (TREE_OPERAND (expr, 0));
     898              :               /* Don't introduce a "can't convert between vector values
     899              :                  of different size" error.  */
     900      2570787 :               if (TREE_CODE (argtype) == VECTOR_TYPE
     901      2570787 :                   && maybe_ne (GET_MODE_SIZE (TYPE_MODE (argtype)),
     902            0 :                                GET_MODE_SIZE (TYPE_MODE (type))))
     903              :                 break;
     904              :             }
     905              :             /* If truncating after truncating, might as well do all at once.
     906              :                If truncating after extending, we may get rid of wasted work.  */
     907      2570787 :             return convert (type, get_unwidened (TREE_OPERAND (expr, 0), type));
     908              : 
     909       117620 :           case COND_EXPR:
     910              :             /* It is sometimes worthwhile to push the narrowing down through
     911              :                the conditional and never loses.  A COND_EXPR may have a throw
     912              :                as one operand, which then has void type.  Just leave void
     913              :                operands as they are.  */
     914       117620 :             return
     915       117620 :               fold_build3 (COND_EXPR, type, TREE_OPERAND (expr, 0),
     916              :                            VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (expr, 1)))
     917              :                            ? TREE_OPERAND (expr, 1)
     918              :                            : convert (type, TREE_OPERAND (expr, 1)),
     919              :                            VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (expr, 2)))
     920              :                            ? TREE_OPERAND (expr, 2)
     921              :                            : convert (type, TREE_OPERAND (expr, 2)));
     922              : 
     923              :           default:
     924              :             break;
     925              :           }
     926              : 
     927              :       /* When parsing long initializers, we might end up with a lot of casts.
     928              :          Shortcut this.  */
     929     26757603 :       if (TREE_CODE (tree_strip_any_location_wrapper (expr)) == INTEGER_CST)
     930     17987838 :         return fold_convert (type, expr);
     931      8769765 :       return build1 (CONVERT_EXPR, type, expr);
     932              : 
     933       452661 :     case REAL_TYPE:
     934       452661 :       if (sanitize_flags_p (SANITIZE_FLOAT_CAST)
     935       452661 :           && current_function_decl != NULL_TREE)
     936              :         {
     937         4978 :           expr = save_expr (expr);
     938         4978 :           tree check = ubsan_instrument_float_cast (loc, type, expr);
     939         4978 :           expr = build1 (FIX_TRUNC_EXPR, type, expr);
     940         4978 :           if (check == NULL_TREE)
     941              :             return expr;
     942         4969 :           return maybe_fold_build2_loc (dofold, loc, COMPOUND_EXPR,
     943              :                                         TREE_TYPE (expr), check, expr);
     944              :         }
     945              :       else
     946       447683 :         return build1 (FIX_TRUNC_EXPR, type, expr);
     947              : 
     948            0 :     case FIXED_POINT_TYPE:
     949            0 :       return build1 (FIXED_CONVERT_EXPR, type, expr);
     950              : 
     951         7222 :     case COMPLEX_TYPE:
     952         7222 :       expr = maybe_fold_build1_loc (dofold, loc, REALPART_EXPR,
     953              :                                     TREE_TYPE (TREE_TYPE (expr)), expr);
     954         7222 :       return convert (type, expr);
     955              : 
     956        35966 :     case VECTOR_TYPE:
     957        35966 :       if (!tree_int_cst_equal (TYPE_SIZE (type), TYPE_SIZE (TREE_TYPE (expr))))
     958              :         {
     959            5 :           error ("cannot convert a vector of type %qT"
     960              :                  " to type %qT which has different size",
     961            5 :                  TREE_TYPE (expr), type);
     962            5 :           return error_mark_node;
     963              :         }
     964        35961 :       return build1 (VIEW_CONVERT_EXPR, type, expr);
     965              : 
     966           10 :     default:
     967           10 :       error ("aggregate value used where an integer was expected");
     968           10 :       return error_mark_node;
     969              :     }
     970              : }
     971              : 
     972              : /* Convert EXPR to some integer (or enum) type TYPE.
     973              : 
     974              :    EXPR must be pointer, integer, discrete (enum, char, or bool), float,
     975              :    fixed-point or vector; in other cases error is called.
     976              : 
     977              :    The result of this is always supposed to be a newly created tree node
     978              :    not in use in any existing structure.  */
     979              : 
     980              : tree
     981     32122691 : convert_to_integer (tree type, tree expr)
     982              : {
     983     32122691 :   return convert_to_integer_1 (type, expr, true);
     984              : }
     985              : 
     986              : /* A wrapper around convert_to_complex_1 that only folds the
     987              :    expression if DOFOLD, or if it is CONSTANT_CLASS_OR_WRAPPER_P.  */
     988              : 
     989              : tree
     990    233754556 : convert_to_integer_maybe_fold (tree type, tree expr, bool dofold)
     991              : {
     992    233754556 :   tree result
     993    233754556 :     = convert_to_integer_1 (type, expr,
     994    233754556 :                             dofold || CONSTANT_CLASS_OR_WRAPPER_P (expr));
     995    233754556 :   return preserve_any_location_wrapper (result, expr);
     996              : }
     997              : 
     998              : /* Convert EXPR to the complex type TYPE in the usual ways.  If FOLD_P is
     999              :    true, try to fold the expression.  */
    1000              : 
    1001              : static tree
    1002       467243 : convert_to_complex_1 (tree type, tree expr, bool fold_p)
    1003              : {
    1004       467243 :   location_t loc = EXPR_LOCATION (expr);
    1005       467243 :   tree subtype = TREE_TYPE (type);
    1006              : 
    1007       467243 :   switch (TREE_CODE (TREE_TYPE (expr)))
    1008              :     {
    1009       149131 :     case REAL_TYPE:
    1010       149131 :     case FIXED_POINT_TYPE:
    1011       149131 :     case INTEGER_TYPE:
    1012       149131 :     case ENUMERAL_TYPE:
    1013       149131 :     case BOOLEAN_TYPE:
    1014       149131 :     case BITINT_TYPE:
    1015       149131 :       {
    1016       149131 :         tree real = convert (subtype, expr);
    1017       149131 :         tree imag = convert (subtype, integer_zero_node);
    1018       149131 :         if (error_operand_p (real) || error_operand_p (imag))
    1019            1 :           return error_mark_node;
    1020       149130 :         return build2 (COMPLEX_EXPR, type, real, imag);
    1021              :       }
    1022              : 
    1023       318103 :     case COMPLEX_TYPE:
    1024       318103 :       {
    1025       318103 :         tree elt_type = TREE_TYPE (TREE_TYPE (expr));
    1026              : 
    1027       318103 :         if (TYPE_MAIN_VARIANT (elt_type) == TYPE_MAIN_VARIANT (subtype))
    1028              :           return expr;
    1029       280614 :         else if (TREE_CODE (expr) == COMPOUND_EXPR)
    1030              :           {
    1031           40 :             tree t = convert_to_complex_1 (type, TREE_OPERAND (expr, 1),
    1032              :                                            fold_p);
    1033           40 :             if (t == TREE_OPERAND (expr, 1))
    1034              :               return expr;
    1035           40 :             return build2_loc (EXPR_LOCATION (expr), COMPOUND_EXPR,
    1036           80 :                                TREE_TYPE (t), TREE_OPERAND (expr, 0), t);
    1037              :           }
    1038       280574 :         else if (TREE_CODE (expr) == COMPLEX_EXPR)
    1039         2371 :           return maybe_fold_build2_loc (fold_p, loc, COMPLEX_EXPR, type,
    1040              :                                         convert (subtype,
    1041              :                                                  TREE_OPERAND (expr, 0)),
    1042              :                                         convert (subtype,
    1043              :                                                  TREE_OPERAND (expr, 1)));
    1044              :         else
    1045              :           {
    1046       278203 :             expr = save_expr (expr);
    1047       278203 :             tree realp = maybe_fold_build1_loc (fold_p, loc, REALPART_EXPR,
    1048              :                                                 TREE_TYPE (TREE_TYPE (expr)),
    1049              :                                                 expr);
    1050       278203 :             tree imagp = maybe_fold_build1_loc (fold_p, loc, IMAGPART_EXPR,
    1051              :                                                 TREE_TYPE (TREE_TYPE (expr)),
    1052              :                                                 expr);
    1053       278203 :             return maybe_fold_build2_loc (fold_p, loc, COMPLEX_EXPR, type,
    1054              :                                           convert (subtype, realp),
    1055              :                                           convert (subtype, imagp));
    1056              :           }
    1057              :       }
    1058              : 
    1059            3 :     case POINTER_TYPE:
    1060            3 :     case REFERENCE_TYPE:
    1061            3 :       error ("pointer value used where a complex was expected");
    1062            3 :       return error_mark_node;
    1063              : 
    1064            6 :     default:
    1065            6 :       error ("aggregate value used where a complex was expected");
    1066            6 :       return error_mark_node;
    1067              :     }
    1068              : }
    1069              : 
    1070              : /* A wrapper around convert_to_complex_1 that always folds the
    1071              :    expression.  */
    1072              : 
    1073              : tree
    1074       136527 : convert_to_complex (tree type, tree expr)
    1075              : {
    1076       136527 :   return convert_to_complex_1 (type, expr, true);
    1077              : }
    1078              : 
    1079              : /* A wrapper around convert_to_complex_1 that only folds the
    1080              :    expression if DOFOLD, or if it is CONSTANT_CLASS_OR_WRAPPER_P.  */
    1081              : 
    1082              : tree
    1083       330676 : convert_to_complex_maybe_fold (tree type, tree expr, bool dofold)
    1084              : {
    1085       330676 :   tree result
    1086       330676 :     = convert_to_complex_1 (type, expr,
    1087       330676 :                             dofold || CONSTANT_CLASS_OR_WRAPPER_P (expr));
    1088       330676 :   return preserve_any_location_wrapper (result, expr);
    1089              : }
    1090              : 
    1091              : /* Convert EXPR to the vector type TYPE in the usual ways.  */
    1092              : 
    1093              : tree
    1094    102937047 : convert_to_vector (tree type, tree expr)
    1095              : {
    1096    102937047 :   switch (TREE_CODE (TREE_TYPE (expr)))
    1097              :     {
    1098    102937039 :     case INTEGER_TYPE:
    1099    102937039 :     case VECTOR_TYPE:
    1100    102937039 :       if (!tree_int_cst_equal (TYPE_SIZE (type), TYPE_SIZE (TREE_TYPE (expr))))
    1101              :         {
    1102            4 :           error ("cannot convert a value of type %qT"
    1103              :                  " to vector type %qT which has different size",
    1104            4 :                  TREE_TYPE (expr), type);
    1105            4 :           return error_mark_node;
    1106              :         }
    1107    102937035 :       return build1 (VIEW_CONVERT_EXPR, type, expr);
    1108              : 
    1109            8 :     default:
    1110            8 :       error ("cannot convert value to a vector");
    1111            8 :       return error_mark_node;
    1112              :     }
    1113              : }
    1114              : 
    1115              : /* Convert EXPR to some fixed-point type TYPE.
    1116              : 
    1117              :    EXPR must be fixed-point, float, integer, or enumeral;
    1118              :    in other cases error is called.  */
    1119              : 
    1120              : tree
    1121            0 : convert_to_fixed (tree type, tree expr)
    1122              : {
    1123            0 :   if (integer_zerop (expr))
    1124              :     {
    1125            0 :       tree fixed_zero_node = build_fixed (type, FCONST0 (TYPE_MODE (type)));
    1126            0 :       return fixed_zero_node;
    1127              :     }
    1128            0 :   else if (integer_onep (expr) && ALL_SCALAR_ACCUM_MODE_P (TYPE_MODE (type)))
    1129              :     {
    1130            0 :       tree fixed_one_node = build_fixed (type, FCONST1 (TYPE_MODE (type)));
    1131            0 :       return fixed_one_node;
    1132              :     }
    1133              : 
    1134            0 :   switch (TREE_CODE (TREE_TYPE (expr)))
    1135              :     {
    1136            0 :     case FIXED_POINT_TYPE:
    1137            0 :     case INTEGER_TYPE:
    1138            0 :     case ENUMERAL_TYPE:
    1139            0 :     case BOOLEAN_TYPE:
    1140            0 :     case REAL_TYPE:
    1141            0 :       return build1 (FIXED_CONVERT_EXPR, type, expr);
    1142              : 
    1143            0 :     case COMPLEX_TYPE:
    1144            0 :       return convert (type,
    1145            0 :                       fold_build1 (REALPART_EXPR,
    1146            0 :                                    TREE_TYPE (TREE_TYPE (expr)), expr));
    1147              : 
    1148            0 :     default:
    1149            0 :       error ("aggregate value used where a fixed-point was expected");
    1150            0 :       return error_mark_node;
    1151              :     }
    1152              : }
    1153              : 
    1154              : #if CHECKING_P
    1155              : 
    1156              : namespace selftest {
    1157              : 
    1158              : /* Selftests for conversions.  */
    1159              : 
    1160              : static void
    1161           16 : test_convert_to_integer_maybe_fold (tree orig_type, tree new_type)
    1162              : {
    1163              :   /* Calling convert_to_integer_maybe_fold on an INTEGER_CST.  */
    1164              : 
    1165           16 :   tree orig_cst = build_int_cst (orig_type, 42);
    1166              : 
    1167              :   /* Verify that convert_to_integer_maybe_fold on a constant returns a new
    1168              :      constant of the new type, unless the types are the same, in which
    1169              :      case verify it's a no-op.  */
    1170           16 :   {
    1171           16 :     tree result = convert_to_integer_maybe_fold (new_type,
    1172              :                                                  orig_cst, false);
    1173           16 :     if (orig_type != new_type)
    1174              :       {
    1175            8 :         ASSERT_EQ (TREE_TYPE (result), new_type);
    1176            8 :         ASSERT_EQ (TREE_CODE (result), INTEGER_CST);
    1177              :       }
    1178              :     else
    1179            8 :       ASSERT_EQ (result, orig_cst);
    1180              :   }
    1181              : 
    1182              :   /* Calling convert_to_integer_maybe_fold on a location wrapper around
    1183              :      an INTEGER_CST.
    1184              : 
    1185              :      Verify that convert_to_integer_maybe_fold on a location wrapper
    1186              :      around a constant returns a new location wrapper around an equivalent
    1187              :      constant, both of the new type, unless the types are the same,
    1188              :      in which case the original wrapper should be returned.   */
    1189           16 :   {
    1190           16 :     const location_t loc = BUILTINS_LOCATION;
    1191           16 :     tree wrapped_orig_cst = maybe_wrap_with_location (orig_cst, loc);
    1192           16 :     tree result
    1193           16 :       = convert_to_integer_maybe_fold (new_type, wrapped_orig_cst, false);
    1194           16 :     ASSERT_EQ (TREE_TYPE (result), new_type);
    1195           16 :     ASSERT_EQ (EXPR_LOCATION (result), loc);
    1196           16 :     ASSERT_TRUE (location_wrapper_p (result));
    1197           16 :     ASSERT_EQ (TREE_TYPE (TREE_OPERAND (result, 0)), new_type);
    1198           16 :     ASSERT_EQ (TREE_CODE (TREE_OPERAND (result, 0)), INTEGER_CST);
    1199              : 
    1200           16 :     if (orig_type == new_type)
    1201            8 :       ASSERT_EQ (result, wrapped_orig_cst);
    1202              :   }
    1203           16 : }
    1204              : 
    1205              : /* Verify that convert_to_integer_maybe_fold preserves locations.  */
    1206              : 
    1207              : static void
    1208            4 : test_convert_to_integer_maybe_fold ()
    1209              : {
    1210              :   /* char -> long.  */
    1211            4 :   test_convert_to_integer_maybe_fold (char_type_node, long_integer_type_node);
    1212              : 
    1213              :   /* char -> char.  */
    1214            4 :   test_convert_to_integer_maybe_fold (char_type_node, char_type_node);
    1215              : 
    1216              :   /* long -> char.  */
    1217            4 :   test_convert_to_integer_maybe_fold (char_type_node, long_integer_type_node);
    1218              : 
    1219              :   /* long -> long.  */
    1220            4 :   test_convert_to_integer_maybe_fold (long_integer_type_node,
    1221              :                                       long_integer_type_node);
    1222            4 : }
    1223              : 
    1224              : /* Run all of the selftests within this file.  */
    1225              : 
    1226              : void
    1227            4 : convert_cc_tests ()
    1228              : {
    1229            4 :   test_convert_to_integer_maybe_fold ();
    1230            4 : }
    1231              : 
    1232              : } // namespace selftest
    1233              : 
    1234              : #endif /* CHECKING_P */
        

Generated by: LCOV version 2.4-beta

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto,rust,m2 --enable-host-shared. GCC test suite is run with the built compiler.