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: 2026-02-28 14:20:25 Functions: 100.0 % 8 8
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* Pretty print support for value ranges.
       2              :    Copyright (C) 2019-2026 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        82462 : print_int_bound (pretty_printer *pp, const wide_int &bound, tree type)
      35              : {
      36        82462 :   wide_int type_min = wi::min_value (TYPE_PRECISION (type), TYPE_SIGN (type));
      37        82462 :   wide_int type_max = wi::max_value (TYPE_PRECISION (type), TYPE_SIGN (type));
      38              : 
      39        82462 :   if (INTEGRAL_TYPE_P (type)
      40        79780 :       && !TYPE_UNSIGNED (type)
      41        23702 :       && bound == type_min
      42        82847 :       && TYPE_PRECISION (type) != 1)
      43          385 :     pp_string (pp, "-INF");
      44        82077 :   else if (bound == type_max && TYPE_PRECISION (type) != 1)
      45        12436 :     pp_string (pp, "+INF");
      46              :   else
      47        69641 :     pp_wide_int (pp, bound, TYPE_SIGN (type));
      48        82462 : }
      49              : 
      50              : static void
      51        38414 : print_irange_bitmasks (pretty_printer *pp, const irange_bitmask &bm)
      52              : {
      53        38414 :   if (bm.unknown_p ())
      54        30754 :     return;
      55              : 
      56         7660 :   pp_string (pp, " MASK ");
      57         7660 :   char buf[WIDE_INT_PRINT_BUFFER_SIZE], *p;
      58         7660 :   unsigned len_mask, len_val;
      59        15320 :   if (print_hex_buf_size (bm.mask (), &len_mask)
      60         7660 :       | print_hex_buf_size (bm.value (), &len_val))
      61            0 :     p = XALLOCAVEC (char, MAX (len_mask, len_val));
      62              :   else
      63              :     p = buf;
      64         7660 :   print_hex (bm.mask (), p);
      65         7660 :   pp_string (pp, p);
      66         7660 :   pp_string (pp, " VALUE ");
      67         7660 :   print_hex (bm.value (), p);
      68         7660 :   pp_string (pp, p);
      69              : }
      70              : 
      71              : void
      72          575 : vrange_printer::visit (const unsupported_range &r) const
      73              : {
      74          575 :   pp_string (pp, "[unsupported_range] ");
      75          575 :   if (r.undefined_p ())
      76              :     {
      77            0 :       pp_string (pp, "UNDEFINED");
      78            0 :       return;
      79              :     }
      80          575 :   if (r.varying_p ())
      81              :     {
      82          575 :       pp_string (pp, "VARYING");
      83          575 :       return;
      84              :     }
      85            0 :   gcc_unreachable ();
      86              : }
      87              : 
      88              : void
      89        38066 : vrange_printer::visit (const irange &r) const
      90              : {
      91        38066 :   pp_string (pp, "[irange] ");
      92        38066 :   if (r.undefined_p ())
      93              :     {
      94           16 :       pp_string (pp, "UNDEFINED");
      95           16 :       return;
      96              :     }
      97        38050 :   dump_generic_node (pp, r.type (), 0, TDF_NONE | TDF_NOUID, false);
      98        38050 :   pp_character (pp, ' ');
      99        38050 :   if (r.varying_p ())
     100              :     {
     101          977 :       pp_string (pp, "VARYING");
     102          977 :       return;
     103              :     }
     104        76963 :   for (unsigned i = 0; i < r.num_pairs (); ++i)
     105              :     {
     106        39890 :       pp_character (pp, '[');
     107        39890 :       print_int_bound (pp, r.lower_bound (i), r.type ());
     108        39890 :       pp_string (pp, ", ");
     109        39890 :       print_int_bound (pp, r.upper_bound (i), r.type ());
     110        39890 :       pp_character (pp, ']');
     111              :     }
     112        37073 :   print_irange_bitmasks (pp, r.m_bitmask);
     113              : }
     114              : 
     115              : void
     116         1449 : vrange_printer::visit (const prange &r) const
     117              : {
     118         1449 :   pp_string (pp, "[prange] ");
     119         1449 :   if (r.undefined_p ())
     120              :     {
     121            6 :       pp_string (pp, "UNDEFINED");
     122            6 :       return;
     123              :     }
     124         1443 :   dump_generic_node (pp, r.type (), 0, TDF_NONE | TDF_NOUID, false);
     125         1443 :   pp_character (pp, ' ');
     126         1443 :   if (r.varying_p ())
     127              :     {
     128          102 :       pp_string (pp, "VARYING");
     129          102 :       return;
     130              :     }
     131              : 
     132         1341 :   pp_character (pp, '[');
     133         1341 :   print_int_bound (pp, r.lower_bound (), r.type ());
     134         1341 :   pp_string (pp, ", ");
     135         1341 :   print_int_bound (pp, r.upper_bound (), r.type ());
     136         1341 :   pp_character (pp, ']');
     137         1341 :   print_irange_bitmasks (pp, r.m_bitmask);
     138              : }
     139              : 
     140              : void
     141          746 : vrange_printer::print_real_value (tree type, const REAL_VALUE_TYPE &r) const
     142              : {
     143          746 :   char s[100];
     144          746 :   real_to_decimal_for_mode (s, &r, sizeof (s), 0, 1, TYPE_MODE (type));
     145          746 :   pp_string (pp, s);
     146          746 :   if (!DECIMAL_FLOAT_TYPE_P (type)
     147              :       // real_to_hexadecimal prints infinities and NAN as text.  No
     148              :       // need to print them twice.
     149          746 :       && !real_isinf (&r)
     150         1179 :       && !real_isnan (&r))
     151              :     {
     152          433 :       real_to_hexadecimal (s, &r, sizeof (s), 0, 1);
     153          433 :       pp_printf (pp, " (%s)", s);
     154              :     }
     155          746 : }
     156              : 
     157              : // Print an frange.
     158              : 
     159              : void
     160          448 : vrange_printer::visit (const frange &r) const
     161              : {
     162          448 :   pp_string (pp, "[frange] ");
     163          448 :   if (r.undefined_p ())
     164              :     {
     165            5 :       pp_string (pp, "UNDEFINED");
     166            5 :       return;
     167              :     }
     168          443 :   tree type = r.type ();
     169          443 :   dump_generic_node (pp, type, 0, TDF_NONE, false);
     170          443 :   pp_string (pp, " ");
     171          443 :   if (r.varying_p ())
     172              :     {
     173           67 :       pp_string (pp, "VARYING");
     174           67 :       print_frange_nan (r);
     175           67 :       return;
     176              :     }
     177          376 :   pp_character (pp, '[');
     178          376 :   bool has_endpoints = !r.known_isnan ();
     179          376 :   if (has_endpoints)
     180              :     {
     181          373 :       print_real_value (type, r.lower_bound ());
     182          373 :       pp_string (pp, ", ");
     183          373 :       print_real_value (type, r.upper_bound ());
     184              :     }
     185          376 :   pp_character (pp, ']');
     186          376 :   print_frange_nan (r);
     187              : }
     188              : 
     189              : // Print the NAN info for an frange.
     190              : 
     191              : void
     192          443 : vrange_printer::print_frange_nan (const frange &r) const
     193              : {
     194          570 :   if (r.maybe_isnan ())
     195              :     {
     196          316 :       if (r.m_pos_nan && r.m_neg_nan)
     197              :         {
     198          150 :           pp_string (pp, " +-NAN");
     199          150 :           return;
     200              :         }
     201          166 :       bool nan_sign = r.m_neg_nan;
     202          166 :       if (nan_sign)
     203            0 :         pp_string (pp, " -NAN");
     204              :       else
     205          166 :         pp_string (pp, " +NAN");
     206              :     }
     207              : }
        

Generated by: LCOV version 2.4-beta

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