LCOV - code coverage report
Current view: top level - gcc - convert.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 92.1 % 558 514
Test Date: 2026-05-30 15:37:04 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      7197809 : convert_to_pointer_1 (tree type, tree expr, bool fold_p)
      55              : {
      56      7197809 :   location_t loc = EXPR_LOCATION (expr);
      57      7197809 :   if (TREE_TYPE (expr) == type)
      58              :     return expr;
      59              : 
      60      7197809 :   switch (TREE_CODE (TREE_TYPE (expr)))
      61              :     {
      62      6623390 :     case POINTER_TYPE:
      63      6623390 :     case REFERENCE_TYPE:
      64      6623390 :       {
      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      6623390 :         addr_space_t to_as = TYPE_ADDR_SPACE (TREE_TYPE (type));
      68      6623390 :         addr_space_t from_as = TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (expr)));
      69              : 
      70      6623390 :         if (to_as == from_as)
      71      6623390 :           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       574401 :     case INTEGER_TYPE:
      78       574401 :     case ENUMERAL_TYPE:
      79       574401 :     case BOOLEAN_TYPE:
      80       574401 :     case BITINT_TYPE:
      81       574401 :       {
      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       574401 :         unsigned int pprec = TYPE_PRECISION (type);
      87       574401 :         unsigned int eprec = TYPE_PRECISION (TREE_TYPE (expr));
      88              : 
      89       574401 :         if (eprec != pprec)
      90       512442 :           expr
      91       512442 :             = maybe_fold_build1_loc (fold_p, loc, NOP_EXPR,
      92              :                                      lang_hooks.types.type_for_size (pprec, 0),
      93              :                                      expr);
      94              :       }
      95       574401 :       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    425453153 : preserve_any_location_wrapper (tree result, tree orig_expr)
     110              : {
     111    425453153 :   if (CONSTANT_CLASS_P (result) && location_wrapper_p (orig_expr))
     112              :     {
     113     53054216 :       if (result == TREE_OPERAND (orig_expr, 0))
     114              :         return orig_expr;
     115              :       else
     116     26527987 :         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      7197809 : convert_to_pointer (tree type, tree expr)
     127              : {
     128      7197809 :   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     20162945 : convert_to_real_1 (tree type, tree expr, bool fold_p)
     151              : {
     152     20162945 :   enum built_in_function fcode = builtin_mathfn_code (expr);
     153     20162945 :   tree itype = TREE_TYPE (expr);
     154     20162945 :   location_t loc = EXPR_LOCATION (expr);
     155              : 
     156     20162945 :   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     20162494 :   if (optimize
     169     20162494 :       && (TYPE_MODE (type) == TYPE_MODE (double_type_node)
     170     18125813 :           || TYPE_MODE (type) == TYPE_MODE (float_type_node)))
     171              :     {
     172     11119557 :       switch (fcode)
     173              :         {
     174              : #define CASE_MATHFN(FN) case BUILT_IN_##FN: case BUILT_IN_##FN##L:
     175         9777 :           CASE_MATHFN (COSH)
     176         9777 :           CASE_MATHFN (EXP)
     177         9777 :           CASE_MATHFN (EXP10)
     178         9777 :           CASE_MATHFN (EXP2)
     179         9777 :           CASE_MATHFN (EXPM1)
     180         9777 :           CASE_MATHFN (GAMMA)
     181         9777 :           CASE_MATHFN (J0)
     182         9777 :           CASE_MATHFN (J1)
     183         9777 :           CASE_MATHFN (LGAMMA)
     184         9777 :           CASE_MATHFN (POW10)
     185         9777 :           CASE_MATHFN (SINH)
     186         9777 :           CASE_MATHFN (TGAMMA)
     187         9777 :           CASE_MATHFN (Y0)
     188         9777 :           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         9777 :             if (flag_errno_math)
     193              :               break;
     194        24278 :             gcc_fallthrough ();
     195        24278 :           CASE_MATHFN (ACOS)
     196        24278 :           CASE_MATHFN (ACOSH)
     197        24278 :           CASE_MATHFN (ASIN)
     198        24278 :           CASE_MATHFN (ASINH)
     199        24278 :           CASE_MATHFN (ATAN)
     200        24278 :           CASE_MATHFN (ATANH)
     201        24278 :           CASE_MATHFN (CBRT)
     202        24278 :           CASE_MATHFN (COS)
     203        24278 :           CASE_MATHFN (ERF)
     204        24278 :           CASE_MATHFN (ERFC)
     205        24278 :           CASE_MATHFN (LOG)
     206        24278 :           CASE_MATHFN (LOG10)
     207        24278 :           CASE_MATHFN (LOG2)
     208        24278 :           CASE_MATHFN (LOG1P)
     209        24278 :           CASE_MATHFN (SIN)
     210        24278 :           CASE_MATHFN (TAN)
     211        24278 :           CASE_MATHFN (TANH)
     212              :             /* The above functions are not safe to do this conversion.  */
     213        24278 :             if (!flag_unsafe_math_optimizations)
     214              :               break;
     215         5929 :             gcc_fallthrough ();
     216         5929 :           CASE_MATHFN (SQRT)
     217         5929 :           CASE_MATHFN (FABS)
     218         5929 :           CASE_MATHFN (LOGB)
     219              : #undef CASE_MATHFN
     220         5929 :             if (call_expr_nargs (expr) != 1
     221        11858 :                 || !SCALAR_FLOAT_TYPE_P (TREE_TYPE (CALL_EXPR_ARG (expr, 0))))
     222              :               break;
     223         5829 :             {
     224         5829 :               tree arg0 = strip_float_extensions (CALL_EXPR_ARG (expr, 0));
     225         5829 :               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         5829 :               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         5829 :               if ((fcode == BUILT_IN_SQRT || fcode == BUILT_IN_SQRTL)
     247         1427 :                   && !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         1365 :                   if (TYPE_MODE (type) != TYPE_MODE (newtype))
     255              :                     break;
     256              : 
     257         1364 :                   int p1 = REAL_MODE_FORMAT (TYPE_MODE (itype))->p;
     258         1364 :                   int p2 = REAL_MODE_FORMAT (TYPE_MODE (newtype))->p;
     259         1364 :                   if (p1 < p2 * 2 + 2)
     260              :                     break;
     261              :                 }
     262              : 
     263              :               /* Be careful about integer to fp conversions.
     264              :                  These may overflow still.  */
     265         4475 :               if (FLOAT_TYPE_P (TREE_TYPE (arg0))
     266         4475 :                   && TYPE_PRECISION (newtype) < TYPE_PRECISION (itype)
     267         5868 :                   && (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     20161101 :   if (itype != type && FLOAT_TYPE_P (type))
     287     20136109 :     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        69047 :         case ABS_EXPR:
     292        69047 :         case NEGATE_EXPR:
     293        69047 :           if (!flag_rounding_math
     294        69046 :               && FLOAT_TYPE_P (itype)
     295        99976 :               && element_precision (type) < element_precision (itype))
     296              :             {
     297         4149 :               tree arg = convert_to_real_1 (type, TREE_OPERAND (expr, 0),
     298              :                                             fold_p);
     299         4149 :               return build1 (TREE_CODE (expr), type, arg);
     300              :             }
     301              :           break;
     302              :         default:
     303              :           break;
     304              :       }
     305              : 
     306     20156952 :   switch (TREE_CODE (TREE_TYPE (expr)))
     307              :     {
     308      3312192 :     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      3312192 :       return build1_loc (loc,
     312      3312192 :                          (flag_float_store
     313      3312083 :                           || DECIMAL_FLOAT_TYPE_P (type)
     314      3294704 :                           || DECIMAL_FLOAT_TYPE_P (itype))
     315      3312192 :                          ? CONVERT_EXPR : NOP_EXPR, type, expr);
     316              : 
     317     16842669 :     case INTEGER_TYPE:
     318     16842669 :     case ENUMERAL_TYPE:
     319     16842669 :     case BOOLEAN_TYPE:
     320     16842669 :     case BITINT_TYPE:
     321     16842669 :       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      1075635 : convert_to_real (tree type, tree expr)
     352              : {
     353      1075635 :   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     19081317 : convert_to_real_maybe_fold (tree type, tree expr, bool dofold)
     361              : {
     362     19081317 :   tree result
     363     19081317 :     = convert_to_real_1 (type, expr,
     364     19081317 :                          dofold || CONSTANT_CLASS_OR_WRAPPER_P (expr));
     365     19081317 :   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       560333 : 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       560333 :   tree typex = type;
     379              : 
     380              :   /* Can't do arithmetic in enumeral types
     381              :      so use an integer type that will hold the values.  */
     382       560333 :   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       560333 :   if ((ex_form == PLUS_EXPR || ex_form == MINUS_EXPR)
     389       363121 :       && !TYPE_UNSIGNED (typex)
     390       812734 :       && 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       560199 :   if (ex_form == MULT_EXPR
     397         3933 :       && !TYPE_OVERFLOW_WRAPS (TREE_TYPE (expr))
     398       562676 :       && 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       560146 :   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       560146 :       if (TYPE_UNSIGNED (TREE_TYPE (expr))
     418       177159 :           || (TYPE_UNSIGNED (TREE_TYPE (arg0))
     419        88467 :               && (TYPE_UNSIGNED (TREE_TYPE (arg1))
     420              :                   || ex_form == LSHIFT_EXPR
     421        73368 :                   || ex_form == RSHIFT_EXPR
     422              :                   || ex_form == LROTATE_EXPR
     423        72557 :                   || ex_form == RROTATE_EXPR))
     424       161249 :           || 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       721024 :           || ((!(INTEGRAL_TYPE_P (TREE_TYPE (arg0))
     432       160878 :                  && TYPE_OVERFLOW_WRAPS (TREE_TYPE (arg0)))
     433        73512 :                || !(INTEGRAL_TYPE_P (TREE_TYPE (arg1))
     434        73512 :                     && TYPE_OVERFLOW_WRAPS (TREE_TYPE (arg1))))
     435       159904 :               && ((TYPE_PRECISION (TREE_TYPE (arg0)) * 2u
     436              :                    > outprec)
     437         1577 :                   || (TYPE_PRECISION (TREE_TYPE (arg1)) * 2u
     438              :                       > outprec))
     439       159806 :               && (ex_form == PLUS_EXPR
     440              :                   || ex_form == MINUS_EXPR
     441              :                   || ex_form == MULT_EXPR)))
     442              :         {
     443       519016 :           if (!TYPE_UNSIGNED (typex))
     444       262821 :             typex = unsigned_type_for (typex);
     445              :         }
     446              :       else
     447              :         {
     448        41130 :           if (TYPE_UNSIGNED (typex))
     449        29784 :             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       560146 :       expr = maybe_fold_build2_loc (dofold, loc, ex_form, typex,
     454              :                                     convert (typex, arg0),
     455              :                                     convert (typex, arg1));
     456       560146 :       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    227145629 : convert_to_integer_1 (tree type, tree expr, bool dofold)
     474              : {
     475    227145629 :   enum tree_code ex_form = TREE_CODE (expr);
     476    227145629 :   tree intype = TREE_TYPE (expr);
     477    227145629 :   unsigned int inprec = element_precision (intype);
     478    227145629 :   unsigned int outprec = element_precision (type);
     479    227145629 :   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    227145629 :   if (!COMPLETE_TYPE_P (type))
     484              :     {
     485            4 :       error ("conversion to incomplete type");
     486            4 :       return error_mark_node;
     487              :     }
     488              : 
     489    227145625 :   if (ex_form == COMPOUND_EXPR)
     490              :     {
     491        48210 :       tree t = convert_to_integer_1 (type, TREE_OPERAND (expr, 1), dofold);
     492        48210 :       if (t == TREE_OPERAND (expr, 1))
     493              :         return expr;
     494        45337 :       return build2_loc (EXPR_LOCATION (expr), COMPOUND_EXPR, TREE_TYPE (t),
     495        90674 :                          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    227097415 :   if (optimize
     504    227097415 :       && (flag_unsafe_math_optimizations
     505    212943930 :           || (long_integer_type_node
     506    212943930 :               && outprec >= TYPE_PRECISION (long_integer_type_node))))
     507              :     {
     508     83153004 :       tree s_expr = strip_float_extensions (expr);
     509     83153004 :       tree s_intype = TREE_TYPE (s_expr);
     510     83153004 :       const enum built_in_function fcode = builtin_mathfn_code (s_expr);
     511     83153004 :       tree fn = 0;
     512              : 
     513     83153004 :       switch (fcode)
     514              :         {
     515        38095 :         CASE_FLT_FN (BUILT_IN_CEIL):
     516        38095 :         CASE_FLT_FN_FLOATN_NX (BUILT_IN_CEIL):
     517              :           /* Only convert in ISO C99 mode.  */
     518        38095 :           if (!targetm.libc_has_function (function_c99_misc, intype))
     519              :             break;
     520        38095 :           if (outprec < TYPE_PRECISION (integer_type_node)
     521        38095 :               || (outprec == TYPE_PRECISION (integer_type_node)
     522           73 :                   && !TYPE_UNSIGNED (type)))
     523           20 :             fn = mathfn_built_in (s_intype, BUILT_IN_ICEIL);
     524        38075 :           else if (outprec == TYPE_PRECISION (long_integer_type_node)
     525        38075 :                    && !TYPE_UNSIGNED (type))
     526           81 :             fn = mathfn_built_in (s_intype, BUILT_IN_LCEIL);
     527        37994 :           else if (outprec == TYPE_PRECISION (long_long_integer_type_node)
     528        37994 :                    && !TYPE_UNSIGNED (type))
     529            0 :             fn = mathfn_built_in (s_intype, BUILT_IN_LLCEIL);
     530              :           break;
     531              : 
     532        37700 :         CASE_FLT_FN (BUILT_IN_FLOOR):
     533        37700 :         CASE_FLT_FN_FLOATN_NX (BUILT_IN_FLOOR):
     534              :           /* Only convert in ISO C99 mode.  */
     535        37700 :           if (!targetm.libc_has_function (function_c99_misc, intype))
     536              :             break;
     537        37700 :           if (outprec < TYPE_PRECISION (integer_type_node)
     538        37700 :               || (outprec == TYPE_PRECISION (integer_type_node)
     539           67 :                   && !TYPE_UNSIGNED (type)))
     540           21 :             fn = mathfn_built_in (s_intype, BUILT_IN_IFLOOR);
     541        37679 :           else if (outprec == TYPE_PRECISION (long_integer_type_node)
     542        37679 :                    && !TYPE_UNSIGNED (type))
     543           82 :             fn = mathfn_built_in (s_intype, BUILT_IN_LFLOOR);
     544        37597 :           else if (outprec == TYPE_PRECISION (long_long_integer_type_node)
     545        37597 :                    && !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          478 :       if (fn
     605          478 :           && call_expr_nargs (s_expr) == 1
     606          956 :           && SCALAR_FLOAT_TYPE_P (TREE_TYPE (CALL_EXPR_ARG (s_expr, 0))))
     607              :         {
     608          468 :           tree newexpr = build_call_expr (fn, 1, CALL_EXPR_ARG (s_expr, 0));
     609          468 :           return convert_to_integer_1 (type, newexpr, dofold);
     610              :         }
     611              :     }
     612              : 
     613              :   /* Convert (int)logb(d) -> ilogb(d).  */
     614    227096941 :   if (optimize
     615    213673546 :       && flag_unsafe_math_optimizations
     616       729619 :       && !flag_trapping_math && !flag_errno_math && flag_finite_math_only
     617       729465 :       && integer_type_node
     618    227826406 :       && (outprec > TYPE_PRECISION (integer_type_node)
     619       418240 :           || (outprec == TYPE_PRECISION (integer_type_node)
     620       214759 :               && !TYPE_UNSIGNED (type))))
     621              :     {
     622       379920 :       tree s_expr = strip_float_extensions (expr);
     623       379920 :       tree s_intype = TREE_TYPE (s_expr);
     624       379920 :       const enum built_in_function fcode = builtin_mathfn_code (s_expr);
     625       379920 :       tree fn = 0;
     626              : 
     627       379920 :       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    227096938 :   switch (TREE_CODE (intype))
     647              :     {
     648       845817 :     case POINTER_TYPE:
     649       845817 :     case REFERENCE_TYPE:
     650       845817 :       if (integer_zerop (expr)
     651       845817 :           && !TREE_OVERFLOW (tree_strip_any_location_wrapper (expr)))
     652        20384 :         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       825433 :       if (!dofold)
     659       162230 :         return build1 (CONVERT_EXPR, type, expr);
     660       663203 :       expr = fold_build1 (CONVERT_EXPR,
     661              :                           lang_hooks.types.type_for_size
     662              :                             (TYPE_PRECISION (intype), 0),
     663              :                           expr);
     664       663203 :       return fold_convert (type, expr);
     665              : 
     666    225749626 :     case INTEGER_TYPE:
     667    225749626 :     case ENUMERAL_TYPE:
     668    225749626 :     case BOOLEAN_TYPE:
     669    225749626 :     case OFFSET_TYPE:
     670    225749626 :     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    225749626 :       if (TREE_CODE_CLASS (ex_form) == tcc_comparison)
     675              :         {
     676      2665421 :           expr = copy_node (expr);
     677      2665421 :           TREE_TYPE (expr) = type;
     678      2665421 :           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    223084205 :       else if (outprec >= inprec)
     686              :         {
     687    195417740 :           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    195417740 :           if (TYPE_UNSIGNED (type) != TYPE_UNSIGNED (TREE_TYPE (expr))
     699    195417740 :               && !type_has_mode_precision_p (TREE_TYPE (expr)))
     700              :             code = CONVERT_EXPR;
     701              :           else
     702              :             code = NOP_EXPR;
     703              : 
     704    195417740 :           return maybe_fold_build1_loc (dofold, loc, code, type, expr);
     705              :         }
     706              : 
     707     27666465 :       else if (TREE_CODE (type) == ENUMERAL_TYPE && BITINT_TYPE_P (type))
     708              :         {
     709           14 :           expr = convert_to_integer_1 (TREE_TYPE (type), expr, dofold);
     710           14 :           return maybe_fold_build1_loc (dofold, loc, NOP_EXPR, type, expr);
     711              :         }
     712              : 
     713              :       /* If TYPE is an enumeral type or a type with a precision less
     714              :          than the number of bits in its mode, do the conversion to the
     715              :          type corresponding to its mode, then do a nop conversion
     716              :          to TYPE.  */
     717     27666451 :       else if (TREE_CODE (type) == ENUMERAL_TYPE
     718     27666451 :                || (TREE_CODE (type) != BITINT_TYPE
     719     27502527 :                    && maybe_ne (outprec,
     720     27502527 :                                 GET_MODE_PRECISION (TYPE_MODE (type)))))
     721              :         {
     722      1371444 :           expr
     723      1371444 :             = convert_to_integer_1 (lang_hooks.types.type_for_mode
     724      1371444 :                                     (TYPE_MODE (type), TYPE_UNSIGNED (type)),
     725              :                                     expr, dofold);
     726      1371444 :           return maybe_fold_build1_loc (dofold, loc, NOP_EXPR, type, expr);
     727              :         }
     728              : 
     729              :       /* Here detect when we can distribute the truncation down past some
     730              :          arithmetic.  For example, if adding two longs and converting to an
     731              :          int, we can equally well convert both to ints and then add.
     732              :          For the operations handled here, such truncation distribution
     733              :          is always safe.
     734              :          It is desirable in these cases:
     735              :          1) when truncating down to full-word from a larger size
     736              :          2) when truncating takes no work.
     737              :          3) when at least one operand of the arithmetic has been extended
     738              :          (as by C's default conversions).  In this case we need two conversions
     739              :          if we do the arithmetic as already requested, so we might as well
     740              :          truncate both and then combine.  Perhaps that way we need only one.
     741              : 
     742              :          Note that in general we cannot do the arithmetic in a type
     743              :          shorter than the desired result of conversion, even if the operands
     744              :          are both extended from a shorter type, because they might overflow
     745              :          if combined in that type.  The exceptions to this--the times when
     746              :          two narrow values can be combined in their narrow type even to
     747              :          make a wider result--are handled by "shorten" in build_binary_op.  */
     748              : 
     749     26295007 :       if (dofold)
     750     21512958 :         switch (ex_form)
     751              :           {
     752        69955 :           case RSHIFT_EXPR:
     753              :             /* We can pass truncation down through right shifting
     754              :                when the shift count is a nonpositive constant.  */
     755        69955 :             if (TREE_CODE (TREE_OPERAND (expr, 1)) == INTEGER_CST
     756        69955 :                 && tree_int_cst_sgn (TREE_OPERAND (expr, 1)) <= 0)
     757           55 :               goto trunc1;
     758              :             break;
     759              : 
     760        17312 :           case LSHIFT_EXPR:
     761              :             /* We can pass truncation down through left shifting
     762              :                when the shift count is a nonnegative constant and
     763              :                the target type is unsigned.  */
     764        17312 :             if (TREE_CODE (TREE_OPERAND (expr, 1)) == INTEGER_CST
     765         4357 :                 && tree_int_cst_sgn (TREE_OPERAND (expr, 1)) >= 0
     766         4325 :                 && TYPE_UNSIGNED (type)
     767        19069 :                 && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)
     768              :               {
     769              :                 /* If shift count is less than the width of the truncated type,
     770              :                    really shift.  */
     771         1757 :                 if (wi::to_widest (TREE_OPERAND (expr, 1))
     772         3514 :                     < TYPE_PRECISION (type))
     773              :                   /* In this case, shifting is like multiplication.  */
     774         1734 :                   goto trunc1;
     775              :                 else
     776              :                   {
     777              :                     /* If it is >= that width, result is zero.
     778              :                        Handling this with trunc1 would give the wrong result:
     779              :                        (int) ((long long) a << 32) is well defined (as 0)
     780              :                        but (int) a << 32 is undefined and would get a
     781              :                        warning.  */
     782              : 
     783           23 :                     tree t = build_int_cst (type, 0);
     784              : 
     785              :                     /* If the original expression had side-effects, we must
     786              :                        preserve it.  */
     787           23 :                     if (TREE_SIDE_EFFECTS (expr))
     788            0 :                       return build2 (COMPOUND_EXPR, type, expr, t);
     789              :                     else
     790              :                       return t;
     791              :                   }
     792              :               }
     793              :             break;
     794              : 
     795        24112 :           case TRUNC_DIV_EXPR:
     796        24112 :             {
     797        24112 :               tree arg0 = get_unwidened (TREE_OPERAND (expr, 0), NULL_TREE);
     798        24112 :               tree arg1 = get_unwidened (TREE_OPERAND (expr, 1), NULL_TREE);
     799              : 
     800              :               /* Don't distribute unless the output precision is at least as
     801              :                  big as the actual inputs and it has the same signedness.  */
     802        24112 :               if (outprec >= TYPE_PRECISION (TREE_TYPE (arg0))
     803        12973 :                   && outprec >= TYPE_PRECISION (TREE_TYPE (arg1))
     804              :                   /* If signedness of arg0 and arg1 don't match,
     805              :                      we can't necessarily find a type to compare them in.  */
     806          546 :                   && (TYPE_UNSIGNED (TREE_TYPE (arg0))
     807          546 :                       == TYPE_UNSIGNED (TREE_TYPE (arg1)))
     808              :                   /* Do not change the sign of the division.  */
     809          378 :                   && (TYPE_UNSIGNED (TREE_TYPE (expr))
     810          378 :                       == TYPE_UNSIGNED (TREE_TYPE (arg0)))
     811              :                   /* Either require unsigned division or a division by
     812              :                      a constant that is not -1.  */
     813        24449 :                   && (TYPE_UNSIGNED (TREE_TYPE (arg0))
     814          287 :                       || (TREE_CODE (arg1) == INTEGER_CST
     815          162 :                           && !integer_all_onesp (arg1))))
     816              :                 {
     817          212 :                   tree tem = do_narrow (loc, ex_form, type, arg0, arg1,
     818              :                                         expr, inprec, outprec, dofold);
     819          212 :                   if (tem)
     820              :                     return tem;
     821              :                 }
     822              :               break;
     823              :             }
     824              : 
     825        44609 :           case MAX_EXPR:
     826        44609 :           case MIN_EXPR:
     827        44609 :           case MULT_EXPR:
     828        44609 :             {
     829        44609 :               tree arg0 = get_unwidened (TREE_OPERAND (expr, 0), type);
     830        44609 :               tree arg1 = get_unwidened (TREE_OPERAND (expr, 1), type);
     831              : 
     832              :               /* Don't distribute unless the output precision is at least as
     833              :                  big as the actual inputs.  Otherwise, the comparison of the
     834              :                  truncated values will be wrong.  */
     835        44609 :               if (outprec >= TYPE_PRECISION (TREE_TYPE (arg0))
     836        24008 :                   && outprec >= TYPE_PRECISION (TREE_TYPE (arg1))
     837              :                   /* If signedness of arg0 and arg1 don't match,
     838              :                      we can't necessarily find a type to compare them in.  */
     839        49395 :                   && (TYPE_UNSIGNED (TREE_TYPE (arg0))
     840         4786 :                       == TYPE_UNSIGNED (TREE_TYPE (arg1))))
     841         4340 :                 goto trunc1;
     842              :               break;
     843              :             }
     844              : 
     845       560141 :           case PLUS_EXPR:
     846       560141 :           case MINUS_EXPR:
     847       560141 :           case BIT_AND_EXPR:
     848       560141 :           case BIT_IOR_EXPR:
     849       560141 :           case BIT_XOR_EXPR:
     850       560141 :           trunc1:
     851       560141 :             {
     852       560141 :               tree arg0 = get_unwidened (TREE_OPERAND (expr, 0), type);
     853       560141 :               tree arg1 = get_unwidened (TREE_OPERAND (expr, 1), type);
     854              : 
     855              :               /* Do not try to narrow operands of pointer subtraction;
     856              :                  that will interfere with other folding.  */
     857       560141 :               if (ex_form == MINUS_EXPR
     858        13832 :                   && CONVERT_EXPR_P (arg0)
     859          138 :                   && CONVERT_EXPR_P (arg1)
     860           55 :                   && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (arg0, 0)))
     861       560161 :                   && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (arg1, 0))))
     862              :                 break;
     863              : 
     864       560121 :               tree tem = do_narrow (loc, ex_form, type, arg0, arg1,
     865              :                                     expr, inprec, outprec, dofold);
     866       560121 :               if (tem)
     867              :                 return tem;
     868              :             }
     869              :             break;
     870              : 
     871        57458 :           case NEGATE_EXPR:
     872              :             /* Using unsigned arithmetic for signed types may hide overflow
     873              :                bugs.  */
     874        57458 :             if (!TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (expr, 0)))
     875        57458 :                 && sanitize_flags_p (SANITIZE_SI_OVERFLOW))
     876              :               break;
     877              :             /* Fall through.  */
     878       157846 :           case BIT_NOT_EXPR:
     879              :             /* This is not correct for ABS_EXPR,
     880              :                since we must test the sign before truncation.  */
     881       157846 :             {
     882              :               /* Do the arithmetic in type TYPEX,
     883              :                  then convert result to TYPE.  */
     884       157846 :               tree typex = type;
     885              : 
     886              :               /* Can't do arithmetic in enumeral types
     887              :                  so use an integer type that will hold the values.  */
     888       157846 :               if (TREE_CODE (typex) == ENUMERAL_TYPE)
     889            0 :                 typex
     890            0 :                   = lang_hooks.types.type_for_size (TYPE_PRECISION (typex),
     891            0 :                                                     TYPE_UNSIGNED (typex));
     892              : 
     893       157846 :               if (!TYPE_UNSIGNED (typex))
     894        73414 :                 typex = unsigned_type_for (typex);
     895       157846 :               return convert (type,
     896       157846 :                               fold_build1 (ex_form, typex,
     897              :                                            convert (typex,
     898       157846 :                                                     TREE_OPERAND (expr, 0))));
     899              :             }
     900              : 
     901      2203855 :           CASE_CONVERT:
     902      2203855 :             {
     903      2203855 :               tree argtype = TREE_TYPE (TREE_OPERAND (expr, 0));
     904              :               /* Don't introduce a "can't convert between vector values
     905              :                  of different size" error.  */
     906      2203855 :               if (TREE_CODE (argtype) == VECTOR_TYPE
     907      2203855 :                   && maybe_ne (GET_MODE_SIZE (TYPE_MODE (argtype)),
     908            0 :                                GET_MODE_SIZE (TYPE_MODE (type))))
     909              :                 break;
     910              :             }
     911              :             /* If truncating after truncating, might as well do all at once.
     912              :                If truncating after extending, we may get rid of wasted work.  */
     913      2203855 :             return convert (type, get_unwidened (TREE_OPERAND (expr, 0), type));
     914              : 
     915        90231 :           case COND_EXPR:
     916              :             /* It is sometimes worthwhile to push the narrowing down through
     917              :                the conditional and never loses.  A COND_EXPR may have a throw
     918              :                as one operand, which then has void type.  Just leave void
     919              :                operands as they are.  */
     920        90231 :             return
     921        90231 :               fold_build3 (COND_EXPR, type, TREE_OPERAND (expr, 0),
     922              :                            VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (expr, 1)))
     923              :                            ? TREE_OPERAND (expr, 1)
     924              :                            : convert (type, TREE_OPERAND (expr, 1)),
     925              :                            VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (expr, 2)))
     926              :                            ? TREE_OPERAND (expr, 2)
     927              :                            : convert (type, TREE_OPERAND (expr, 2)));
     928              : 
     929              :           default:
     930              :             break;
     931              :           }
     932              : 
     933              :       /* When parsing long initializers, we might end up with a lot of casts.
     934              :          Shortcut this.  */
     935     23282906 :       if (TREE_CODE (tree_strip_any_location_wrapper (expr)) == INTEGER_CST)
     936     16210443 :         return fold_convert (type, expr);
     937      7072463 :       return build1 (CONVERT_EXPR, type, expr);
     938              : 
     939       458226 :     case REAL_TYPE:
     940       458226 :       if (sanitize_flags_p (SANITIZE_FLOAT_CAST)
     941       458226 :           && current_function_decl != NULL_TREE)
     942              :         {
     943         4978 :           expr = save_expr (expr);
     944         4978 :           tree check = ubsan_instrument_float_cast (loc, type, expr);
     945         4978 :           expr = build1 (FIX_TRUNC_EXPR, type, expr);
     946         4978 :           if (check == NULL_TREE)
     947              :             return expr;
     948         4969 :           return maybe_fold_build2_loc (dofold, loc, COMPOUND_EXPR,
     949              :                                         TREE_TYPE (expr), check, expr);
     950              :         }
     951              :       else
     952       453248 :         return build1 (FIX_TRUNC_EXPR, type, expr);
     953              : 
     954            0 :     case FIXED_POINT_TYPE:
     955            0 :       return build1 (FIXED_CONVERT_EXPR, type, expr);
     956              : 
     957         7223 :     case COMPLEX_TYPE:
     958         7223 :       expr = maybe_fold_build1_loc (dofold, loc, REALPART_EXPR,
     959              :                                     TREE_TYPE (TREE_TYPE (expr)), expr);
     960         7223 :       return convert (type, expr);
     961              : 
     962        36036 :     case VECTOR_TYPE:
     963        36036 :       if (!tree_int_cst_equal (TYPE_SIZE (type), TYPE_SIZE (TREE_TYPE (expr))))
     964              :         {
     965            5 :           error ("cannot convert a vector of type %qT"
     966              :                  " to type %qT which has different size",
     967            5 :                  TREE_TYPE (expr), type);
     968            5 :           return error_mark_node;
     969              :         }
     970        36031 :       return build1 (VIEW_CONVERT_EXPR, type, expr);
     971              : 
     972           10 :     default:
     973           10 :       error ("aggregate value used where an integer was expected");
     974           10 :       return error_mark_node;
     975              :     }
     976              : }
     977              : 
     978              : /* Convert EXPR to some integer (or enum) type TYPE.
     979              : 
     980              :    EXPR must be pointer, integer, discrete (enum, char, or bool), float,
     981              :    fixed-point or vector; in other cases error is called.
     982              : 
     983              :    The result of this is always supposed to be a newly created tree node
     984              :    not in use in any existing structure.  */
     985              : 
     986              : tree
     987     32268997 : convert_to_integer (tree type, tree expr)
     988              : {
     989     32268997 :   return convert_to_integer_1 (type, expr, true);
     990              : }
     991              : 
     992              : /* A wrapper around convert_to_complex_1 that only folds the
     993              :    expression if DOFOLD, or if it is CONSTANT_CLASS_OR_WRAPPER_P.  */
     994              : 
     995              : tree
     996    193456487 : convert_to_integer_maybe_fold (tree type, tree expr, bool dofold)
     997              : {
     998    193456487 :   tree result
     999    193456487 :     = convert_to_integer_1 (type, expr,
    1000    193456487 :                             dofold || CONSTANT_CLASS_OR_WRAPPER_P (expr));
    1001    193456487 :   return preserve_any_location_wrapper (result, expr);
    1002              : }
    1003              : 
    1004              : /* Convert EXPR to the complex type TYPE in the usual ways.  If FOLD_P is
    1005              :    true, try to fold the expression.  */
    1006              : 
    1007              : static tree
    1008       480308 : convert_to_complex_1 (tree type, tree expr, bool fold_p)
    1009              : {
    1010       480308 :   location_t loc = EXPR_LOCATION (expr);
    1011       480308 :   tree subtype = TREE_TYPE (type);
    1012              : 
    1013       480308 :   switch (TREE_CODE (TREE_TYPE (expr)))
    1014              :     {
    1015       150669 :     case REAL_TYPE:
    1016       150669 :     case FIXED_POINT_TYPE:
    1017       150669 :     case INTEGER_TYPE:
    1018       150669 :     case ENUMERAL_TYPE:
    1019       150669 :     case BOOLEAN_TYPE:
    1020       150669 :     case BITINT_TYPE:
    1021       150669 :       {
    1022       150669 :         tree real = convert (subtype, expr);
    1023       150669 :         tree imag = convert (subtype, integer_zero_node);
    1024       150669 :         if (error_operand_p (real) || error_operand_p (imag))
    1025            1 :           return error_mark_node;
    1026       150668 :         return build2 (COMPLEX_EXPR, type, real, imag);
    1027              :       }
    1028              : 
    1029       329630 :     case COMPLEX_TYPE:
    1030       329630 :       {
    1031       329630 :         tree elt_type = TREE_TYPE (TREE_TYPE (expr));
    1032              : 
    1033       329630 :         if (TYPE_MAIN_VARIANT (elt_type) == TYPE_MAIN_VARIANT (subtype))
    1034              :           return expr;
    1035       292137 :         else if (TREE_CODE (expr) == COMPOUND_EXPR)
    1036              :           {
    1037           40 :             tree t = convert_to_complex_1 (type, TREE_OPERAND (expr, 1),
    1038              :                                            fold_p);
    1039           40 :             if (t == TREE_OPERAND (expr, 1))
    1040              :               return expr;
    1041           40 :             return build2_loc (EXPR_LOCATION (expr), COMPOUND_EXPR,
    1042           80 :                                TREE_TYPE (t), TREE_OPERAND (expr, 0), t);
    1043              :           }
    1044       292097 :         else if (TREE_CODE (expr) == COMPLEX_EXPR)
    1045         2371 :           return maybe_fold_build2_loc (fold_p, loc, COMPLEX_EXPR, type,
    1046              :                                         convert (subtype,
    1047              :                                                  TREE_OPERAND (expr, 0)),
    1048              :                                         convert (subtype,
    1049              :                                                  TREE_OPERAND (expr, 1)));
    1050              :         else
    1051              :           {
    1052       289726 :             expr = save_expr (expr);
    1053       289726 :             tree realp = maybe_fold_build1_loc (fold_p, loc, REALPART_EXPR,
    1054              :                                                 TREE_TYPE (TREE_TYPE (expr)),
    1055              :                                                 expr);
    1056       289726 :             tree imagp = maybe_fold_build1_loc (fold_p, loc, IMAGPART_EXPR,
    1057              :                                                 TREE_TYPE (TREE_TYPE (expr)),
    1058              :                                                 expr);
    1059       289726 :             return maybe_fold_build2_loc (fold_p, loc, COMPLEX_EXPR, type,
    1060              :                                           convert (subtype, realp),
    1061              :                                           convert (subtype, imagp));
    1062              :           }
    1063              :       }
    1064              : 
    1065            3 :     case POINTER_TYPE:
    1066            3 :     case REFERENCE_TYPE:
    1067            3 :       error ("pointer value used where a complex was expected");
    1068            3 :       return error_mark_node;
    1069              : 
    1070            6 :     default:
    1071            6 :       error ("aggregate value used where a complex was expected");
    1072            6 :       return error_mark_node;
    1073              :     }
    1074              : }
    1075              : 
    1076              : /* A wrapper around convert_to_complex_1 that always folds the
    1077              :    expression.  */
    1078              : 
    1079              : tree
    1080       137496 : convert_to_complex (tree type, tree expr)
    1081              : {
    1082       137496 :   return convert_to_complex_1 (type, expr, true);
    1083              : }
    1084              : 
    1085              : /* A wrapper around convert_to_complex_1 that only folds the
    1086              :    expression if DOFOLD, or if it is CONSTANT_CLASS_OR_WRAPPER_P.  */
    1087              : 
    1088              : tree
    1089       342772 : convert_to_complex_maybe_fold (tree type, tree expr, bool dofold)
    1090              : {
    1091       342772 :   tree result
    1092       342772 :     = convert_to_complex_1 (type, expr,
    1093       342772 :                             dofold || CONSTANT_CLASS_OR_WRAPPER_P (expr));
    1094       342772 :   return preserve_any_location_wrapper (result, expr);
    1095              : }
    1096              : 
    1097              : /* Convert EXPR to the vector type TYPE in the usual ways.  */
    1098              : 
    1099              : tree
    1100    103156180 : convert_to_vector (tree type, tree expr)
    1101              : {
    1102    103156180 :   switch (TREE_CODE (TREE_TYPE (expr)))
    1103              :     {
    1104    103156172 :     case INTEGER_TYPE:
    1105    103156172 :     case VECTOR_TYPE:
    1106    103156172 :       if (!tree_int_cst_equal (TYPE_SIZE (type), TYPE_SIZE (TREE_TYPE (expr))))
    1107              :         {
    1108            4 :           error ("cannot convert a value of type %qT"
    1109              :                  " to vector type %qT which has different size",
    1110            4 :                  TREE_TYPE (expr), type);
    1111            4 :           return error_mark_node;
    1112              :         }
    1113    103156168 :       return build1 (VIEW_CONVERT_EXPR, type, expr);
    1114              : 
    1115            8 :     default:
    1116            8 :       error ("cannot convert value to a vector");
    1117            8 :       return error_mark_node;
    1118              :     }
    1119              : }
    1120              : 
    1121              : /* Convert EXPR to some fixed-point type TYPE.
    1122              : 
    1123              :    EXPR must be fixed-point, float, integer, or enumeral;
    1124              :    in other cases error is called.  */
    1125              : 
    1126              : tree
    1127            0 : convert_to_fixed (tree type, tree expr)
    1128              : {
    1129            0 :   if (integer_zerop (expr))
    1130              :     {
    1131            0 :       tree fixed_zero_node = build_fixed (type, FCONST0 (TYPE_MODE (type)));
    1132            0 :       return fixed_zero_node;
    1133              :     }
    1134            0 :   else if (integer_onep (expr) && ALL_SCALAR_ACCUM_MODE_P (TYPE_MODE (type)))
    1135              :     {
    1136            0 :       tree fixed_one_node = build_fixed (type, FCONST1 (TYPE_MODE (type)));
    1137            0 :       return fixed_one_node;
    1138              :     }
    1139              : 
    1140            0 :   switch (TREE_CODE (TREE_TYPE (expr)))
    1141              :     {
    1142            0 :     case FIXED_POINT_TYPE:
    1143            0 :     case INTEGER_TYPE:
    1144            0 :     case ENUMERAL_TYPE:
    1145            0 :     case BOOLEAN_TYPE:
    1146            0 :     case REAL_TYPE:
    1147            0 :       return build1 (FIXED_CONVERT_EXPR, type, expr);
    1148              : 
    1149            0 :     case COMPLEX_TYPE:
    1150            0 :       return convert (type,
    1151            0 :                       fold_build1 (REALPART_EXPR,
    1152            0 :                                    TREE_TYPE (TREE_TYPE (expr)), expr));
    1153              : 
    1154            0 :     default:
    1155            0 :       error ("aggregate value used where a fixed-point was expected");
    1156            0 :       return error_mark_node;
    1157              :     }
    1158              : }
    1159              : 
    1160              : #if CHECKING_P
    1161              : 
    1162              : namespace selftest {
    1163              : 
    1164              : /* Selftests for conversions.  */
    1165              : 
    1166              : static void
    1167           16 : test_convert_to_integer_maybe_fold (tree orig_type, tree new_type)
    1168              : {
    1169              :   /* Calling convert_to_integer_maybe_fold on an INTEGER_CST.  */
    1170              : 
    1171           16 :   tree orig_cst = build_int_cst (orig_type, 42);
    1172              : 
    1173              :   /* Verify that convert_to_integer_maybe_fold on a constant returns a new
    1174              :      constant of the new type, unless the types are the same, in which
    1175              :      case verify it's a no-op.  */
    1176           16 :   {
    1177           16 :     tree result = convert_to_integer_maybe_fold (new_type,
    1178              :                                                  orig_cst, false);
    1179           16 :     if (orig_type != new_type)
    1180              :       {
    1181            8 :         ASSERT_EQ (TREE_TYPE (result), new_type);
    1182            8 :         ASSERT_EQ (TREE_CODE (result), INTEGER_CST);
    1183              :       }
    1184              :     else
    1185            8 :       ASSERT_EQ (result, orig_cst);
    1186              :   }
    1187              : 
    1188              :   /* Calling convert_to_integer_maybe_fold on a location wrapper around
    1189              :      an INTEGER_CST.
    1190              : 
    1191              :      Verify that convert_to_integer_maybe_fold on a location wrapper
    1192              :      around a constant returns a new location wrapper around an equivalent
    1193              :      constant, both of the new type, unless the types are the same,
    1194              :      in which case the original wrapper should be returned.   */
    1195           16 :   {
    1196           16 :     const location_t loc = BUILTINS_LOCATION;
    1197           16 :     tree wrapped_orig_cst = maybe_wrap_with_location (orig_cst, loc);
    1198           16 :     tree result
    1199           16 :       = convert_to_integer_maybe_fold (new_type, wrapped_orig_cst, false);
    1200           16 :     ASSERT_EQ (TREE_TYPE (result), new_type);
    1201           16 :     ASSERT_EQ (EXPR_LOCATION (result), loc);
    1202           16 :     ASSERT_TRUE (location_wrapper_p (result));
    1203           16 :     ASSERT_EQ (TREE_TYPE (TREE_OPERAND (result, 0)), new_type);
    1204           16 :     ASSERT_EQ (TREE_CODE (TREE_OPERAND (result, 0)), INTEGER_CST);
    1205              : 
    1206           16 :     if (orig_type == new_type)
    1207            8 :       ASSERT_EQ (result, wrapped_orig_cst);
    1208              :   }
    1209           16 : }
    1210              : 
    1211              : /* Verify that convert_to_integer_maybe_fold preserves locations.  */
    1212              : 
    1213              : static void
    1214            4 : test_convert_to_integer_maybe_fold ()
    1215              : {
    1216              :   /* char -> long.  */
    1217            4 :   test_convert_to_integer_maybe_fold (char_type_node, long_integer_type_node);
    1218              : 
    1219              :   /* char -> char.  */
    1220            4 :   test_convert_to_integer_maybe_fold (char_type_node, char_type_node);
    1221              : 
    1222              :   /* long -> char.  */
    1223            4 :   test_convert_to_integer_maybe_fold (char_type_node, long_integer_type_node);
    1224              : 
    1225              :   /* long -> long.  */
    1226            4 :   test_convert_to_integer_maybe_fold (long_integer_type_node,
    1227              :                                       long_integer_type_node);
    1228            4 : }
    1229              : 
    1230              : /* Run all of the selftests within this file.  */
    1231              : 
    1232              : void
    1233            4 : convert_cc_tests ()
    1234              : {
    1235            4 :   test_convert_to_integer_maybe_fold ();
    1236            4 : }
    1237              : 
    1238              : } // namespace selftest
    1239              : 
    1240              : #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.