LCOV - code coverage report
Current view: top level - gcc - convert.c (source / functions) Hit Total Coverage
Test: gcc.info Lines: 491 541 90.8 %
Date: 2020-04-04 11:58:09 Functions: 17 19 89.5 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 0 -

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

Generated by: LCOV version 1.0

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 --enable-host-shared. GCC test suite is run with the built compiler.