LCOV - code coverage report
Current view: top level - gcc - value-range-pretty-print.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 95.3 % 107 102
Test Date: 2025-03-08 13:07:09 Functions: 100.0 % 8 8
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: - 0 0

             Branch data     Line data    Source code
       1                 :             : /* Pretty print support for value ranges.
       2                 :             :    Copyright (C) 2019-2025 Free Software Foundation, Inc.
       3                 :             :    Contributed by Aldy Hernandez <aldyh@redhat.com>.
       4                 :             : 
       5                 :             : This file is part of GCC.
       6                 :             : 
       7                 :             : GCC is free software; you can redistribute it and/or modify
       8                 :             : it under the terms of the GNU General Public License as published by
       9                 :             : the Free Software Foundation; either version 3, or (at your option)
      10                 :             : any later version.
      11                 :             : 
      12                 :             : GCC is distributed in the hope that it will be useful,
      13                 :             : but WITHOUT ANY WARRANTY; without even the implied warranty of
      14                 :             : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      15                 :             : GNU General Public License for more details.
      16                 :             : 
      17                 :             : You should have received a copy of the GNU General Public License
      18                 :             : along with GCC; see the file COPYING3.  If not see
      19                 :             : <http://www.gnu.org/licenses/>.  */
      20                 :             : 
      21                 :             : #include "config.h"
      22                 :             : #include "system.h"
      23                 :             : #include "coretypes.h"
      24                 :             : #include "backend.h"
      25                 :             : #include "tree.h"
      26                 :             : #include "gimple.h"
      27                 :             : #include "ssa.h"
      28                 :             : #include "tree-pretty-print.h"
      29                 :             : #include "fold-const.h"
      30                 :             : #include "gimple-range.h"
      31                 :             : #include "value-range-pretty-print.h"
      32                 :             : 
      33                 :             : static void
      34                 :       19830 : print_int_bound (pretty_printer *pp, const wide_int &bound, tree type)
      35                 :             : {
      36                 :       19830 :   wide_int type_min = wi::min_value (TYPE_PRECISION (type), TYPE_SIGN (type));
      37                 :       19830 :   wide_int type_max = wi::max_value (TYPE_PRECISION (type), TYPE_SIGN (type));
      38                 :             : 
      39                 :       19830 :   if (INTEGRAL_TYPE_P (type)
      40                 :       17482 :       && !TYPE_UNSIGNED (type)
      41                 :        7184 :       && bound == type_min
      42                 :       20094 :       && TYPE_PRECISION (type) != 1)
      43                 :         264 :     pp_string (pp, "-INF");
      44                 :       19566 :   else if (bound == type_max && TYPE_PRECISION (type) != 1)
      45                 :        2625 :     pp_string (pp, "+INF");
      46                 :             :   else
      47                 :       16941 :     pp_wide_int (pp, bound, TYPE_SIGN (type));
      48                 :       19830 : }
      49                 :             : 
      50                 :             : static void
      51                 :        9014 : print_irange_bitmasks (pretty_printer *pp, const irange_bitmask &bm)
      52                 :             : {
      53                 :        9014 :   if (bm.unknown_p ())
      54                 :        6541 :     return;
      55                 :             : 
      56                 :        2473 :   pp_string (pp, " MASK ");
      57                 :        2473 :   char buf[WIDE_INT_PRINT_BUFFER_SIZE], *p;
      58                 :        2473 :   unsigned len_mask, len_val;
      59                 :        4946 :   if (print_hex_buf_size (bm.mask (), &len_mask)
      60                 :        2473 :       | print_hex_buf_size (bm.value (), &len_val))
      61                 :           0 :     p = XALLOCAVEC (char, MAX (len_mask, len_val));
      62                 :             :   else
      63                 :             :     p = buf;
      64                 :        2473 :   print_hex (bm.mask (), p);
      65                 :        2473 :   pp_string (pp, p);
      66                 :        2473 :   pp_string (pp, " VALUE ");
      67                 :        2473 :   print_hex (bm.value (), p);
      68                 :        2473 :   pp_string (pp, p);
      69                 :             : }
      70                 :             : 
      71                 :             : void
      72                 :         714 : vrange_printer::visit (const unsupported_range &r) const
      73                 :             : {
      74                 :         714 :   pp_string (pp, "[unsupported_range] ");
      75                 :         714 :   if (r.undefined_p ())
      76                 :             :     {
      77                 :           0 :       pp_string (pp, "UNDEFINED");
      78                 :           0 :       return;
      79                 :             :     }
      80                 :         714 :   if (r.varying_p ())
      81                 :             :     {
      82                 :         714 :       pp_string (pp, "VARYING");
      83                 :         714 :       return;
      84                 :             :     }
      85                 :           0 :   gcc_unreachable ();
      86                 :             : }
      87                 :             : 
      88                 :             : void
      89                 :        8103 : vrange_printer::visit (const irange &r) const
      90                 :             : {
      91                 :        8103 :   pp_string (pp, "[irange] ");
      92                 :        8103 :   if (r.undefined_p ())
      93                 :             :     {
      94                 :          12 :       pp_string (pp, "UNDEFINED");
      95                 :          12 :       return;
      96                 :             :     }
      97                 :        8091 :   dump_generic_node (pp, r.type (), 0, TDF_NONE | TDF_NOUID, false);
      98                 :        8091 :   pp_character (pp, ' ');
      99                 :        8091 :   if (r.varying_p ())
     100                 :             :     {
     101                 :         251 :       pp_string (pp, "VARYING");
     102                 :         251 :       return;
     103                 :             :     }
     104                 :       16581 :   for (unsigned i = 0; i < r.num_pairs (); ++i)
     105                 :             :     {
     106                 :        8741 :       pp_character (pp, '[');
     107                 :        8741 :       print_int_bound (pp, r.lower_bound (i), r.type ());
     108                 :        8741 :       pp_string (pp, ", ");
     109                 :        8741 :       print_int_bound (pp, r.upper_bound (i), r.type ());
     110                 :        8741 :       pp_character (pp, ']');
     111                 :             :     }
     112                 :        7840 :   print_irange_bitmasks (pp, r.m_bitmask);
     113                 :             : }
     114                 :             : 
     115                 :             : void
     116                 :        1246 : vrange_printer::visit (const prange &r) const
     117                 :             : {
     118                 :        1246 :   pp_string (pp, "[prange] ");
     119                 :        1246 :   if (r.undefined_p ())
     120                 :             :     {
     121                 :           6 :       pp_string (pp, "UNDEFINED");
     122                 :           6 :       return;
     123                 :             :     }
     124                 :        1240 :   dump_generic_node (pp, r.type (), 0, TDF_NONE | TDF_NOUID, false);
     125                 :        1240 :   pp_character (pp, ' ');
     126                 :        1240 :   if (r.varying_p ())
     127                 :             :     {
     128                 :          66 :       pp_string (pp, "VARYING");
     129                 :          66 :       return;
     130                 :             :     }
     131                 :             : 
     132                 :        1174 :   pp_character (pp, '[');
     133                 :        1174 :   print_int_bound (pp, r.lower_bound (), r.type ());
     134                 :        1174 :   pp_string (pp, ", ");
     135                 :        1174 :   print_int_bound (pp, r.upper_bound (), r.type ());
     136                 :        1174 :   pp_character (pp, ']');
     137                 :        1174 :   print_irange_bitmasks (pp, r.m_bitmask);
     138                 :             : }
     139                 :             : 
     140                 :             : void
     141                 :         932 : vrange_printer::print_real_value (tree type, const REAL_VALUE_TYPE &r) const
     142                 :             : {
     143                 :         932 :   char s[100];
     144                 :         932 :   real_to_decimal_for_mode (s, &r, sizeof (s), 0, 1, TYPE_MODE (type));
     145                 :         932 :   pp_string (pp, s);
     146                 :         932 :   if (!DECIMAL_FLOAT_TYPE_P (type)
     147                 :             :       // real_to_hexadecimal prints infinities and NAN as text.  No
     148                 :             :       // need to print them twice.
     149                 :         932 :       && !real_isinf (&r)
     150                 :        1424 :       && !real_isnan (&r))
     151                 :             :     {
     152                 :         492 :       real_to_hexadecimal (s, &r, sizeof (s), 0, 1);
     153                 :         492 :       pp_printf (pp, " (%s)", s);
     154                 :             :     }
     155                 :         932 : }
     156                 :             : 
     157                 :             : // Print an frange.
     158                 :             : 
     159                 :             : void
     160                 :         546 : vrange_printer::visit (const frange &r) const
     161                 :             : {
     162                 :         546 :   pp_string (pp, "[frange] ");
     163                 :         546 :   if (r.undefined_p ())
     164                 :             :     {
     165                 :           5 :       pp_string (pp, "UNDEFINED");
     166                 :           5 :       return;
     167                 :             :     }
     168                 :         541 :   tree type = r.type ();
     169                 :         541 :   dump_generic_node (pp, type, 0, TDF_NONE, false);
     170                 :         541 :   pp_string (pp, " ");
     171                 :         541 :   if (r.varying_p ())
     172                 :             :     {
     173                 :          72 :       pp_string (pp, "VARYING");
     174                 :          72 :       print_frange_nan (r);
     175                 :          72 :       return;
     176                 :             :     }
     177                 :         469 :   pp_character (pp, '[');
     178                 :         469 :   bool has_endpoints = !r.known_isnan ();
     179                 :         469 :   if (has_endpoints)
     180                 :             :     {
     181                 :         466 :       print_real_value (type, r.lower_bound ());
     182                 :         466 :       pp_string (pp, ", ");
     183                 :         466 :       print_real_value (type, r.upper_bound ());
     184                 :             :     }
     185                 :         469 :   pp_character (pp, ']');
     186                 :         469 :   print_frange_nan (r);
     187                 :             : }
     188                 :             : 
     189                 :             : // Print the NAN info for an frange.
     190                 :             : 
     191                 :             : void
     192                 :         541 : vrange_printer::print_frange_nan (const frange &r) const
     193                 :             : {
     194                 :         642 :   if (r.maybe_isnan ())
     195                 :             :     {
     196                 :         440 :       if (r.m_pos_nan && r.m_neg_nan)
     197                 :             :         {
     198                 :         193 :           pp_string (pp, " +-NAN");
     199                 :         193 :           return;
     200                 :             :         }
     201                 :         247 :       bool nan_sign = r.m_neg_nan;
     202                 :         247 :       if (nan_sign)
     203                 :           0 :         pp_string (pp, " -NAN");
     204                 :             :       else
     205                 :         247 :         pp_string (pp, " +NAN");
     206                 :             :     }
     207                 :             : }
        

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.