LCOV - code coverage report
Current view: top level - gcc/c - c-convert.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 91.4 % 105 96
Test Date: 2024-04-20 14:03:02 Functions: 100.0 % 3 3
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: - 0 0

             Branch data     Line data    Source code
       1                 :             : /* Language-level data type conversion for GNU C.
       2                 :             :    Copyright (C) 1987-2024 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                 :             : /* This file contains the functions for converting C expressions
      22                 :             :    to different data types.  The only entry point is `convert'.
      23                 :             :    Every language front end must have a `convert' function
      24                 :             :    but what kind of conversions it does will depend on the language.  */
      25                 :             : 
      26                 :             : #include "config.h"
      27                 :             : #include "system.h"
      28                 :             : #include "coretypes.h"
      29                 :             : #include "target.h"
      30                 :             : #include "c-tree.h"
      31                 :             : #include "convert.h"
      32                 :             : #include "langhooks.h"
      33                 :             : #include "ubsan.h"
      34                 :             : #include "stringpool.h"
      35                 :             : #include "attribs.h"
      36                 :             : #include "asan.h"
      37                 :             : 
      38                 :             : /* Change of width--truncation and extension of integers or reals--
      39                 :             :    is represented with NOP_EXPR.  Proper functioning of many things
      40                 :             :    assumes that no other conversions can be NOP_EXPRs.
      41                 :             : 
      42                 :             :    Conversion between integer and pointer is represented with CONVERT_EXPR.
      43                 :             :    Converting integer to real uses FLOAT_EXPR
      44                 :             :    and real to integer uses FIX_TRUNC_EXPR.
      45                 :             : 
      46                 :             :    Here is a list of all the functions that assume that widening and
      47                 :             :    narrowing is always done with a NOP_EXPR:
      48                 :             :      In convert.cc, convert_to_integer.
      49                 :             :      In c-typeck.cc, build_binary_op (boolean ops), and
      50                 :             :         c_common_truthvalue_conversion.
      51                 :             :      In expr.cc: expand_expr, for operands of a MULT_EXPR.
      52                 :             :      In fold-const.cc: fold.
      53                 :             :      In tree.cc: get_narrower and get_unwidened.  */
      54                 :             : 
      55                 :             : /* Subroutines of `convert'.  */
      56                 :             : 
      57                 :             : 
      58                 :             : 
      59                 :             : /* Create an expression whose value is that of EXPR,
      60                 :             :    converted to type TYPE.  The TREE_TYPE of the value
      61                 :             :    is always TYPE.  This function implements all reasonable
      62                 :             :    conversions; callers should filter out those that are
      63                 :             :    not permitted by the language being compiled.
      64                 :             :    INIT_CONST is true if the conversion is for arithmetic types for a static
      65                 :             :    initializer and folding must apply accordingly (discarding floating-point
      66                 :             :    exceptions and assuming the default rounding mode is in effect).  */
      67                 :             : 
      68                 :             : static tree
      69                 :   521079547 : c_convert (tree type, tree expr, bool init_const)
      70                 :             : {
      71                 :   521079547 :   tree e = expr;
      72                 :   521079547 :   enum tree_code code = TREE_CODE (type);
      73                 :   521079547 :   const char *invalid_conv_diag;
      74                 :   521079547 :   tree ret;
      75                 :   521079547 :   location_t loc = EXPR_LOCATION (expr);
      76                 :             : 
      77                 :   521079547 :   if (type == error_mark_node
      78                 :   521079547 :       || error_operand_p (expr))
      79                 :             :     return error_mark_node;
      80                 :             : 
      81                 :  1042158902 :   if ((invalid_conv_diag
      82                 :   521079451 :        = targetm.invalid_conversion (TREE_TYPE (expr), type)))
      83                 :             :     {
      84                 :           2 :       error (invalid_conv_diag);
      85                 :           2 :       return error_mark_node;
      86                 :             :     }
      87                 :             : 
      88                 :   521079449 :   if (type == TREE_TYPE (expr))
      89                 :             :     return expr;
      90                 :   183820883 :   ret = targetm.convert_to_type (type, expr);
      91                 :   183820883 :   if (ret)
      92                 :             :       return ret;
      93                 :             : 
      94                 :   183853361 :   STRIP_TYPE_NOPS (e);
      95                 :             : 
      96                 :   183820883 :   if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (expr))
      97                 :   183820883 :       && (TREE_CODE (TREE_TYPE (expr)) != COMPLEX_TYPE
      98                 :       35216 :           || TREE_CODE (e) == COMPLEX_EXPR))
      99                 :    45625708 :     return fold_convert_loc (loc, type, expr);
     100                 :   138195175 :   if (TREE_CODE (TREE_TYPE (expr)) == ERROR_MARK)
     101                 :           0 :     return error_mark_node;
     102                 :   138195175 :   if (VOID_TYPE_P (TREE_TYPE (expr)))
     103                 :             :     {
     104                 :           0 :       error ("void value not ignored as it ought to be");
     105                 :           0 :       return error_mark_node;
     106                 :             :     }
     107                 :             : 
     108                 :   138195175 :   {
     109                 :   138195175 :     tree false_value, true_value;
     110                 :   138195175 :     if (c_hardbool_type_attr (type, &false_value, &true_value))
     111                 :             :       {
     112                 :        4284 :         bool save = in_late_binary_op;
     113                 :        4284 :         in_late_binary_op = true;
     114                 :        4284 :         expr = c_objc_common_truthvalue_conversion (input_location, expr);
     115                 :        4284 :         in_late_binary_op = save;
     116                 :             : 
     117                 :        4284 :         return fold_build3_loc (loc, COND_EXPR, type,
     118                 :        4284 :                                 expr, true_value, false_value);
     119                 :             :       }
     120                 :             :   }
     121                 :             : 
     122                 :   138190891 :   switch (code)
     123                 :             :     {
     124                 :       63395 :     case VOID_TYPE:
     125                 :       63395 :       return fold_convert_loc (loc, type, e);
     126                 :             : 
     127                 :      111454 :     case ENUMERAL_TYPE:
     128                 :      111454 :       if (ENUM_UNDERLYING_TYPE (type) != NULL_TREE
     129                 :      111454 :           && TREE_CODE (ENUM_UNDERLYING_TYPE (type)) == BOOLEAN_TYPE)
     130                 :         157 :         goto convert_to_boolean;
     131                 :    43706342 :       gcc_fallthrough ();
     132                 :             : 
     133                 :    43706342 :     case INTEGER_TYPE:
     134                 :    43706342 :     case BITINT_TYPE:
     135                 :    43706342 :       if (sanitize_flags_p (SANITIZE_FLOAT_CAST)
     136                 :       87219 :           && current_function_decl != NULL_TREE
     137                 :       87219 :           && SCALAR_FLOAT_TYPE_P (TREE_TYPE (expr))
     138                 :    43718066 :           && COMPLETE_TYPE_P (type))
     139                 :             :         {
     140                 :       11724 :           expr = save_expr (expr);
     141                 :       11724 :           expr = c_fully_fold (expr, init_const, NULL);
     142                 :       11724 :           tree check = ubsan_instrument_float_cast (loc, type, expr);
     143                 :       11724 :           expr = fold_build1 (FIX_TRUNC_EXPR, type, expr);
     144                 :       11724 :           if (check == NULL_TREE)
     145                 :             :             return expr;
     146                 :        7128 :           return fold_build2 (COMPOUND_EXPR, TREE_TYPE (expr), check, expr);
     147                 :             :         }
     148                 :    43694618 :       ret = convert_to_integer (type, e);
     149                 :    43694618 :       goto maybe_fold;
     150                 :             : 
     151                 :       44184 :     case BOOLEAN_TYPE:
     152                 :       44184 :     convert_to_boolean:
     153                 :       44184 :       return c_objc_common_truthvalue_conversion (input_location, expr, type);
     154                 :             : 
     155                 :     5919561 :     case POINTER_TYPE:
     156                 :             :       /* The type nullptr_t may be converted to a pointer type.  The result is
     157                 :             :          a null pointer value.  */
     158                 :     5919561 :       if (NULLPTR_TYPE_P (TREE_TYPE (e)))
     159                 :             :         {
     160                 :             :           /* To make sure that (void *)nullptr is not a null pointer constant,
     161                 :             :              build_c_cast will create an additional NOP_EXPR around the result
     162                 :             :              of this conversion.  */
     163                 :         130 :           if (TREE_SIDE_EFFECTS (e))
     164                 :          16 :             ret = build2 (COMPOUND_EXPR, type, e, build_int_cst (type, 0));
     165                 :             :           else
     166                 :         114 :             ret = build_int_cst (type, 0);
     167                 :         130 :           goto maybe_fold;
     168                 :             :         }
     169                 :     5919431 :       gcc_fallthrough ();
     170                 :     5919431 :     case REFERENCE_TYPE:
     171                 :     5919431 :       ret = convert_to_pointer (type, e);
     172                 :     5919431 :       goto maybe_fold;
     173                 :             : 
     174                 :           9 :     case NULLPTR_TYPE:
     175                 :             :       /* A null pointer constant or value of type nullptr_t may be
     176                 :             :          converted to nullptr_t.  The latter case has already been
     177                 :             :          handled.  build_c_cast will create an additional NOP_EXPR to
     178                 :             :          ensure the result of the conversion is not itself a null
     179                 :             :          pointer constant.  */
     180                 :           9 :       if (null_pointer_constant_p (expr))
     181                 :             :         {
     182                 :           7 :           ret = build_int_cst (type, 0);
     183                 :           7 :           goto maybe_fold;
     184                 :             :         }
     185                 :             :       break;
     186                 :             : 
     187                 :      967245 :     case REAL_TYPE:
     188                 :      967245 :       ret = convert_to_real (type, e);
     189                 :      967245 :       goto maybe_fold;
     190                 :             : 
     191                 :           0 :     case FIXED_POINT_TYPE:
     192                 :           0 :       ret = convert_to_fixed (type, e);
     193                 :           0 :       goto maybe_fold;
     194                 :             : 
     195                 :      130377 :     case COMPLEX_TYPE:
     196                 :      130377 :       ret = convert_to_complex (type, e);
     197                 :      130377 :       goto maybe_fold;
     198                 :             : 
     199                 :    87359753 :     case VECTOR_TYPE:
     200                 :    87359753 :       if (gnu_vector_type_p (type)
     201                 :           0 :           || gnu_vector_type_p (TREE_TYPE (e))
     202                 :             :           /* Allow conversions between compatible non-GNU vector types
     203                 :             :              when -flax-vector-conversions is passed.  The whole purpose
     204                 :             :              of the option is to bend the normal type rules and accept
     205                 :             :              nonconforming code.  */
     206                 :    87359753 :           || (flag_lax_vector_conversions
     207                 :           0 :               && VECTOR_TYPE_P (TREE_TYPE (e))
     208                 :           0 :               && vector_types_convertible_p (type, TREE_TYPE (e), false)))
     209                 :             :         {
     210                 :    87359753 :           ret = convert_to_vector (type, e);
     211                 :    87359753 :           goto maybe_fold;
     212                 :             :         }
     213                 :             :       break;
     214                 :             : 
     215                 :          25 :     case RECORD_TYPE:
     216                 :          25 :     case UNION_TYPE:
     217                 :          25 :       if (lang_hooks.types_compatible_p (type, TREE_TYPE (expr)))
     218                 :             :         return e;
     219                 :             :       break;
     220                 :             : 
     221                 :             :     default:
     222                 :             :       break;
     223                 :             : 
     224                 :   138071561 :     maybe_fold:
     225                 :   138071561 :       if (TREE_CODE (ret) != C_MAYBE_CONST_EXPR)
     226                 :   138071547 :         ret = init_const ? fold_init (ret) : fold (ret);
     227                 :             :       return ret;
     228                 :             :     }
     229                 :             : 
     230                 :             :   /* If we are converting to nullptr_t, don't say "non-scalar type" because
     231                 :             :      the nullptr_t type is a scalar type.  Only nullptr_t or a null pointer
     232                 :             :      constant shall be converted to nullptr_t.  */
     233                 :           8 :   if (code == NULLPTR_TYPE)
     234                 :             :     {
     235                 :           2 :       error ("conversion from %qT to %qT", TREE_TYPE (e), type);
     236                 :           2 :       inform (input_location,
     237                 :             :               "only %qT or a null pointer constant can be converted to %qT",
     238                 :             :               type, type);
     239                 :             :     }
     240                 :             :   else
     241                 :           6 :     error ("conversion to non-scalar type requested");
     242                 :           8 :   return error_mark_node;
     243                 :             : }
     244                 :             : 
     245                 :             : /* Create an expression whose value is that of EXPR, converted to type TYPE.
     246                 :             :    The TREE_TYPE of the value is always TYPE.  This function implements all
     247                 :             :    reasonable conversions; callers should filter out those that are not
     248                 :             :    permitted by the language being compiled.  */
     249                 :             : 
     250                 :             : tree
     251                 :   520536928 : convert (tree type, tree expr)
     252                 :             : {
     253                 :   520536928 :   return c_convert (type, expr, false);
     254                 :             : }
     255                 :             : 
     256                 :             : /* Create an expression whose value is that of EXPR, converted to type TYPE, in
     257                 :             :    a static initializer.  The TREE_TYPE of the value is always TYPE.  This
     258                 :             :    function implements all reasonable conversions; callers should filter out
     259                 :             :    those that are not permitted by the language being compiled.  */
     260                 :             : 
     261                 :             : tree
     262                 :      542619 : convert_init (tree type, tree expr)
     263                 :             : {
     264                 :      542619 :   return c_convert (type, expr, true);
     265                 :             : }
        

Generated by: LCOV version 2.1-beta

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