LCOV - code coverage report
Current view: top level - gcc/analyzer - svalue.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 74.8 % 1187 888
Test Date: 2026-05-11 19:44:49 Functions: 70.8 % 137 97
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* Symbolic values.
       2              :    Copyright (C) 2019-2026 Free Software Foundation, Inc.
       3              :    Contributed by David Malcolm <dmalcolm@redhat.com>.
       4              : 
       5              : This file is part of GCC.
       6              : 
       7              : GCC is free software; you can redistribute it and/or modify it
       8              : 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, but
      13              : WITHOUT ANY WARRANTY; without even the implied warranty of
      14              : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      15              : 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 "analyzer/common.h"
      22              : 
      23              : #include "tree-pretty-print.h"
      24              : #include "gimple-pretty-print.h"
      25              : #include "fold-const.h"
      26              : #include "diagnostic.h"
      27              : #include "tree-diagnostic.h"
      28              : #include "value-relation.h"
      29              : #include "range-op.h"
      30              : 
      31              : #include "text-art/dump.h"
      32              : 
      33              : #include "analyzer/analyzer-logging.h"
      34              : #include "analyzer/call-string.h"
      35              : #include "analyzer/program-point.h"
      36              : #include "analyzer/store.h"
      37              : #include "analyzer/svalue.h"
      38              : #include "analyzer/region-model.h"
      39              : 
      40              : #if ENABLE_ANALYZER
      41              : 
      42              : namespace ana {
      43              : 
      44              : static int cmp_csts_and_types (const_tree cst1, const_tree cst2);
      45              : 
      46              : /* class svalue and its various subclasses.  */
      47              : 
      48              : /* class svalue.  */
      49              : 
      50              : /* Dump a tree-like representation of this svalue and its constituent symbols
      51              :    to stderr, using global_dc's colorization and theming options.
      52              : 
      53              :    For example:
      54              :    . (gdb) call index_sval->dump()
      55              :    . (27): ‘int’: initial_svalue
      56              :    . ╰─ m_reg: (26): ‘int’: decl_region(‘x_10(D)’)
      57              :    .    ╰─ parent: (9): frame_region(‘test_bitmask_2’, index: 0, depth: 1)
      58              :    .       ╰─ parent: (1): stack region
      59              :    .          ╰─ parent: (0): root region
      60              :   */
      61              : 
      62              : DEBUG_FUNCTION void
      63            0 : svalue::dump () const
      64              : {
      65            0 :   text_art::dump (*this);
      66            0 : }
      67              : 
      68              : /* Dump a representation of this svalue to stderr.  */
      69              : 
      70              : DEBUG_FUNCTION void
      71            0 : svalue::dump (bool simple) const
      72              : {
      73            0 :   tree_dump_pretty_printer pp (stderr);
      74            0 :   dump_to_pp (&pp, simple);
      75            0 :   pp_newline (&pp);
      76            0 : }
      77              : 
      78              : /* Generate a textual representation of this svalue for debugging purposes.  */
      79              : 
      80              : label_text
      81          697 : svalue::get_desc (bool simple) const
      82              : {
      83          697 :   pretty_printer pp;
      84          697 :   pp_format_decoder (&pp) = default_tree_printer;
      85          697 :   dump_to_pp (&pp, simple);
      86          697 :   return label_text::take (xstrdup (pp_formatted_text (&pp)));
      87          697 : }
      88              : 
      89              : /* Return a new json::string describing the svalue.  */
      90              : 
      91              : std::unique_ptr<json::value>
      92          244 : svalue::to_json () const
      93              : {
      94          244 :   label_text desc = get_desc (true);
      95          244 :   auto sval_js = std::make_unique<json::string> (desc.get ());
      96          244 :   return sval_js;
      97          244 : }
      98              : 
      99              : /* Class for optionally adding open/close paren pairs within
     100              :    svalue::maybe_print_for_user.  */
     101              : 
     102              : class auto_add_parens
     103              : {
     104              : public:
     105          141 :   auto_add_parens (pretty_printer *pp,
     106              :                    const svalue *outer_sval,
     107              :                    const svalue &inner_sval)
     108          141 :   : m_pp (pp),
     109          141 :     m_needs_parens (needs_parens_p (outer_sval, inner_sval))
     110              :   {
     111          141 :     if (m_needs_parens)
     112           20 :       pp_string (m_pp, "(");
     113          141 :   }
     114          141 :   ~auto_add_parens ()
     115              :   {
     116          141 :     if (m_needs_parens)
     117           20 :       pp_string (m_pp, ")");
     118          141 :   }
     119              : 
     120              : private:
     121          141 :   static bool needs_parens_p (const svalue *outer_sval,
     122              :                               const svalue &inner_sval)
     123              :   {
     124          141 :     if (!outer_sval)
     125              :       return false;
     126          104 :     if (inner_sval.get_kind () == SK_BINOP)
     127              :       return true;
     128              :     return false;
     129              :   }
     130              : 
     131              :   pretty_printer *m_pp;
     132              :   bool m_needs_parens;
     133              : };
     134              : 
     135              : /* Attempt to print a user-facing description of this svalue to PP,
     136              :    using MODEL for extracting representative tree values if necessary.
     137              :    Use OUTER_SVAL (which can be null) to determine if we need to wrap
     138              :    this value in parentheses.  */
     139              : 
     140              : bool
     141          141 : svalue::maybe_print_for_user (pretty_printer *pp,
     142              :                               const region_model &model,
     143              :                               const svalue *outer_sval) const
     144              : {
     145          141 :   auto_add_parens p (pp, outer_sval, *this);
     146              : 
     147          141 :   switch (get_kind ())
     148              :     {
     149              :     default:
     150              :       break;
     151           42 :     case SK_CONSTANT:
     152           42 :       {
     153           42 :         const constant_svalue *sval = (const constant_svalue *)this;
     154           42 :         pp_printf (pp, "%E", sval->get_constant ());
     155           42 :         return true;
     156              :       }
     157           34 :     case SK_INITIAL:
     158           34 :       {
     159           34 :         const initial_svalue *sval = (const initial_svalue *)this;
     160           34 :         return sval->get_region ()->maybe_print_for_user (pp, model);
     161              :       }
     162           12 :     case SK_UNARYOP:
     163           12 :       {
     164           12 :         const unaryop_svalue *sval = (const unaryop_svalue *)this;
     165           12 :         if (sval->get_op () == NOP_EXPR)
     166              :           {
     167           12 :             if (!sval->get_arg ()->maybe_print_for_user (pp, model, outer_sval))
     168              :               return false;
     169              :             return true;
     170              :           }
     171              :       }
     172              :       break;
     173           48 :     case SK_BINOP:
     174           48 :       {
     175           48 :         const binop_svalue *sval = (const binop_svalue *)this;
     176           48 :         switch (sval->get_op ())
     177              :           {
     178              :           default:
     179              :             break;
     180              : 
     181           48 :           case PLUS_EXPR:
     182           48 :           case MINUS_EXPR:
     183           48 :           case MULT_EXPR:
     184           48 :             {
     185           48 :               if (!sval->get_arg0 ()->maybe_print_for_user (pp, model, this))
     186              :                 return false;
     187           48 :               pp_printf (pp, " %s ", op_symbol_code (sval->get_op ()));
     188           48 :               if (!sval->get_arg1 ()->maybe_print_for_user (pp, model, this))
     189              :                 return false;
     190              :               return true;
     191              :             }
     192              :           }
     193              :       }
     194              :       break;
     195              :     }
     196              : 
     197            5 :   if (tree expr = model.get_representative_tree (this))
     198              :     {
     199            4 :       expr = remove_ssa_names (expr);
     200            4 :       print_expr_for_user (pp, expr);
     201            4 :       return true;
     202              :     }
     203              : 
     204              :   return false;
     205          141 : }
     206              : 
     207              : /* Use DWI to create a text_art::widget describing this svalue in
     208              :    a tree-like form, using PREFIX as a prefix (e.g. for field names).
     209              :    We do this via two vfuncs:
     210              :    (a) print_dump_widget_label, to populate the text of a tree_widget, and
     211              :    (b) add_dump_widget_children, to add children to the tree_widget.  */
     212              : 
     213              : std::unique_ptr<text_art::tree_widget>
     214            0 : svalue::make_dump_widget (const text_art::dump_widget_info &dwi,
     215              :                           const char *prefix) const
     216              : {
     217            0 :   pretty_printer pp;
     218            0 :   pp_format_decoder (&pp) = default_tree_printer;
     219            0 :   pp_show_color (&pp) = true;
     220              : 
     221            0 :   if (prefix)
     222            0 :     pp_printf (&pp, "%s: ", prefix);
     223              : 
     224            0 :   pp_printf (&pp, "(%i): ", get_id ());
     225            0 :   if (get_type ())
     226            0 :     pp_printf (&pp, "%qT: ", get_type ());
     227              : 
     228            0 :   print_dump_widget_label (&pp);
     229              : 
     230            0 :   value_range out;
     231            0 :   if (maybe_get_value_range (out))
     232              :     {
     233            0 :       pp_printf (&pp, " value range: {"),
     234            0 :         out.print (&pp);
     235            0 :       pp_string (&pp, "}");
     236              :     }
     237              : 
     238            0 :   std::unique_ptr<text_art::tree_widget> w
     239            0 :     (text_art::tree_widget::make (dwi, &pp));
     240              : 
     241            0 :   add_dump_widget_children (*w, dwi);
     242              : 
     243            0 :   return w;
     244            0 : }
     245              : 
     246              : /* If this svalue is a constant_svalue, return the underlying tree constant.
     247              :    Otherwise return NULL_TREE.  */
     248              : 
     249              : tree
     250     14021873 : svalue::maybe_get_constant () const
     251              : {
     252     14021873 :   const svalue *sval = unwrap_any_unmergeable ();
     253     14021873 :   if (const constant_svalue *cst_sval = sval->dyn_cast_constant_svalue ())
     254      4623691 :     return cst_sval->get_constant ();
     255              :   else
     256              :     return NULL_TREE;
     257              : }
     258              : 
     259              : /* If this svalue is a region_svalue, return the region it points to.
     260              :    Otherwise return nullptr.  */
     261              : 
     262              : const region *
     263       382036 : svalue::maybe_get_region () const
     264              : {
     265       382036 :   if (const region_svalue *region_sval = dyn_cast_region_svalue ())
     266        38309 :     return region_sval->get_pointee ();
     267              :   else
     268              :     return nullptr;
     269              : }
     270              : 
     271              : /* If this svalue is a cast (i.e a unaryop NOP_EXPR or VIEW_CONVERT_EXPR),
     272              :    return the underlying svalue.
     273              :    Otherwise return nullptr.  */
     274              : 
     275              : const svalue *
     276     13264637 : svalue::maybe_undo_cast () const
     277              : {
     278     13264637 :   if (const unaryop_svalue *unaryop_sval = dyn_cast_unaryop_svalue ())
     279              :     {
     280       940454 :       enum tree_code op = unaryop_sval->get_op ();
     281       940454 :       if (op == NOP_EXPR || op == VIEW_CONVERT_EXPR)
     282       907384 :         return unaryop_sval->get_arg ();
     283              :     }
     284              :   return nullptr;
     285              : }
     286              : 
     287              : /* If this svalue is an unmergeable decorator around another svalue, return
     288              :    the underlying svalue.
     289              :    Otherwise return this svalue.  */
     290              : 
     291              : const svalue *
     292     17272931 : svalue::unwrap_any_unmergeable () const
     293              : {
     294     17272931 :   if (const unmergeable_svalue *unmergeable = dyn_cast_unmergeable_svalue ())
     295         4370 :     return unmergeable->get_arg ();
     296              :   return this;
     297              : }
     298              : 
     299              : /* Attempt to merge THIS with OTHER, returning the merged svalue.
     300              :    Return nullptr if not mergeable.  */
     301              : 
     302              : const svalue *
     303       362212 : svalue::can_merge_p (const svalue *other,
     304              :                      region_model_manager *mgr,
     305              :                      model_merger *merger) const
     306              : {
     307       362212 :   if (!(get_type () && other->get_type ()))
     308              :     return nullptr;
     309              : 
     310       313722 :   if (!types_compatible_p (get_type (), other->get_type ()))
     311              :     return nullptr;
     312              : 
     313              :   /* Reject attempts to merge unmergeable svalues.  */
     314       292538 :   if ((get_kind () == SK_UNMERGEABLE)
     315       292538 :       || (other->get_kind () == SK_UNMERGEABLE))
     316         2807 :     return nullptr;
     317              : 
     318              :   /* Reject attempts to merge poisoned svalues with other svalues
     319              :      (either non-poisoned, or other kinds of poison), so that e.g.
     320              :      we identify paths in which a variable is conditionally uninitialized.  */
     321       289731 :   if (get_kind () == SK_POISONED
     322       289731 :       || other->get_kind () == SK_POISONED)
     323         1591 :     return nullptr;
     324              : 
     325              :   /* Reject attempts to merge NULL pointers with not-NULL-pointers.  */
     326       288140 :   if (POINTER_TYPE_P (get_type ()))
     327              :     {
     328        38665 :       bool null0 = false;
     329        38665 :       bool null1 = false;
     330        38665 :       if (tree cst0 = maybe_get_constant ())
     331         8021 :         if (zerop (cst0))
     332        38665 :           null0 = true;
     333        38665 :       if (tree cst1 = other->maybe_get_constant ())
     334         5285 :         if (zerop (cst1))
     335        38665 :           null1 = true;
     336        38665 :       if (null0 != null1)
     337              :         return nullptr;
     338              :     }
     339              : 
     340              :   /* Reject merging svalues that have non-purgable sm-state,
     341              :      to avoid falsely reporting memory leaks by merging them
     342              :      with something else.  */
     343       275056 :   if (!merger->mergeable_svalue_p (this))
     344              :     return nullptr;
     345       273938 :   if (!merger->mergeable_svalue_p (other))
     346              :     return nullptr;
     347              : 
     348              :   /* Reject attempts to merge pointers that point to different base regions,
     349              :      except for the case where both are string literals.  */
     350       273241 :   if (auto this_region = maybe_get_region ())
     351         4004 :     if (auto other_region = other->maybe_get_region ())
     352          545 :       if (this_region != other_region
     353          545 :           && (this_region->get_kind () != RK_STRING
     354           61 :               || other_region->get_kind () != RK_STRING))
     355          522 :         return nullptr;
     356              : 
     357              :   /* Widening.  */
     358              :   /* Merge: (new_cst, existing_cst) -> widen (existing, new).  */
     359       272719 :   if (maybe_get_constant () && other->maybe_get_constant ())
     360         3602 :     return mgr->get_or_create_widening_svalue (other->get_type (),
     361              :                                                merger->get_supernode (),
     362         3602 :                                                other, this);
     363              : 
     364              :   /* Merger of:
     365              :          this: BINOP (X, OP, CST)
     366              :         other: X, where X is non-widening
     367              :            to: WIDENING (other, this).  */
     368       269117 :   if (const binop_svalue *binop_sval = dyn_cast_binop_svalue ())
     369        12077 :     if (binop_sval->get_arg0 () == other
     370         1654 :         && binop_sval->get_arg1 ()->get_kind () == SK_CONSTANT
     371        13607 :         && other->get_kind () != SK_WIDENING)
     372          687 :       return mgr->get_or_create_widening_svalue (other->get_type (),
     373              :                                                  merger->get_supernode (),
     374          687 :                                                  other, this);
     375              : 
     376              :   /* Merge: (Widen(existing_val, V), existing_val) -> Widen (existing_val, V)
     377              :      and thus get a fixed point.  */
     378       268430 :   if (const widening_svalue *widen_sval = dyn_cast_widening_svalue ())
     379              :     {
     380         8122 :       if (other == widen_sval->get_base_svalue ())
     381              :         return this;
     382         1782 :       if (other == widen_sval->get_iter_svalue ())
     383              :         return this;
     384              :     }
     385              : 
     386       261192 :   if (const binop_svalue *binop_sval = dyn_cast_binop_svalue ())
     387        11390 :     if (const widening_svalue *widen_arg0
     388        11390 :         = binop_sval->get_arg0 ()->dyn_cast_widening_svalue ())
     389              :       {
     390         3386 :         if (other == binop_sval->get_arg1 ())
     391              :           {
     392              :             /* Merger of: (Widen(..., OTHER) BINOP X)
     393              :                and      : OTHER
     394              :                to       : (Widen(..., OTHER) BINOP X)
     395              :                e.g. merge of Widen(0, 1) + 1 with 1 to the Widen(0, 1) + 1.  */
     396              :             return this;
     397              :           }
     398              : 
     399              :         /* Merger of : (Widen() BINOP X)
     400              :            and       : Widen()
     401              :            to        : Widen()
     402              :            e.g. merge of Widen(0, 1) + 1 and Widen(0, 1) to Widen(0, 1).
     403              :            However, we want to update constraints for this case, since we're
     404              :            considering another iteration.
     405              :            Presumably we also want to ensure that it converges; we don't want
     406              :            a descending chain of constraints.  */
     407         2526 :         if (other == widen_arg0)
     408              :           {
     409          843 :             merger->on_widening_reuse (widen_arg0);
     410          843 :             return widen_arg0;
     411              :           }
     412              : 
     413              :         /* Merger of:
     414              :             this: BINOP(WIDENING(BASE, BINOP(BASE, X)), X)
     415              :            other: BINOP(BASE, X)
     416              :               to: WIDENING(BASE, BINOP(BASE, X)).  */
     417         1683 :         if (widen_arg0->get_iter_svalue () == other)
     418         1426 :           if (const binop_svalue *other_binop_sval
     419          713 :                 = other->dyn_cast_binop_svalue ())
     420          529 :             if (other_binop_sval->get_arg0 () == widen_arg0->get_base_svalue ()
     421          529 :                 && other_binop_sval->get_arg1 () == binop_sval->get_arg1 ())
     422              :               return widen_arg0;
     423              :       }
     424              : 
     425       258960 :   return mgr->get_or_create_unknown_svalue (get_type ());
     426              : }
     427              : 
     428              : /* Determine if this svalue is either within LIVE_SVALUES, or is implicitly
     429              :    live with respect to LIVE_SVALUES and MODEL.
     430              :    LIVE_SVALUES can be nullptr, in which case determine if this svalue is
     431              :    intrinsically live.  */
     432              : 
     433              : bool
     434     11065523 : svalue::live_p (const svalue_set *live_svalues,
     435              :                 const region_model *model) const
     436              : {
     437              :   /* Determine if SVAL is explicitly live.  */
     438     11065523 :   if (live_svalues)
     439     11063673 :     if (const_cast<svalue_set *> (live_svalues)->contains (this))
     440              :       return true;
     441              : 
     442              :   /* Otherwise, determine if SVAL is implicitly live due to being made of
     443              :      other live svalues.  */
     444      4772664 :   return implicitly_live_p (live_svalues, model);
     445              : }
     446              : 
     447              : /* Base implementation of svalue::implicitly_live_p.  */
     448              : 
     449              : bool
     450       191244 : svalue::implicitly_live_p (const svalue_set *, const region_model *) const
     451              : {
     452       191244 :   return false;
     453              : }
     454              : 
     455              : /* Comparator for imposing a deterministic order on constants that are
     456              :    of the same type.  */
     457              : 
     458              : static int
     459      1525016 : cmp_csts_same_type (const_tree cst1, const_tree cst2)
     460              : {
     461      1525016 :   gcc_assert (TREE_TYPE (cst1) == TREE_TYPE (cst2));
     462      1525016 :   gcc_assert (TREE_CODE (cst1) == TREE_CODE (cst2));
     463      1525016 :   switch (TREE_CODE (cst1))
     464              :     {
     465            0 :     default:
     466            0 :       gcc_unreachable ();
     467      1524736 :     case INTEGER_CST:
     468      1524736 :       return tree_int_cst_compare (cst1, cst2);
     469            0 :     case STRING_CST:
     470            0 :       if (TREE_STRING_LENGTH (cst1) < TREE_STRING_LENGTH (cst2))
     471              :         return -1;
     472            0 :       if (TREE_STRING_LENGTH (cst1) > TREE_STRING_LENGTH (cst2))
     473              :         return 1;
     474            0 :       return memcmp (TREE_STRING_POINTER (cst1),
     475            0 :                      TREE_STRING_POINTER (cst2),
     476            0 :                      TREE_STRING_LENGTH (cst1));
     477           28 :     case RAW_DATA_CST:
     478           28 :       if (RAW_DATA_LENGTH (cst1) < RAW_DATA_LENGTH (cst2))
     479              :         return -1;
     480           28 :       if (RAW_DATA_LENGTH (cst1) > RAW_DATA_LENGTH (cst2))
     481              :         return 1;
     482           28 :       return memcmp (RAW_DATA_POINTER (cst1),
     483           28 :                      RAW_DATA_POINTER (cst2),
     484           28 :                      RAW_DATA_LENGTH (cst1));
     485          188 :     case REAL_CST:
     486              :       /* Impose an arbitrary but deterministic order.  */
     487          188 :       return memcmp (TREE_REAL_CST_PTR (cst1),
     488          188 :                      TREE_REAL_CST_PTR (cst2),
     489          188 :                      sizeof (real_value));
     490           64 :     case COMPLEX_CST:
     491           64 :       if (int cmp_real = cmp_csts_and_types (TREE_REALPART (cst1),
     492           64 :                                              TREE_REALPART (cst2)))
     493              :         return cmp_real;
     494           24 :       return cmp_csts_and_types (TREE_IMAGPART (cst1), TREE_IMAGPART (cst2));
     495            0 :     case VECTOR_CST:
     496            0 :       if (int cmp_log2_npatterns
     497            0 :             = ((int)VECTOR_CST_LOG2_NPATTERNS (cst1)
     498            0 :                - (int)VECTOR_CST_LOG2_NPATTERNS (cst2)))
     499              :         return cmp_log2_npatterns;
     500            0 :       if (int cmp_nelts_per_pattern
     501            0 :             = ((int)VECTOR_CST_NELTS_PER_PATTERN (cst1)
     502            0 :                - (int)VECTOR_CST_NELTS_PER_PATTERN (cst2)))
     503              :         return cmp_nelts_per_pattern;
     504            0 :       unsigned encoded_nelts = vector_cst_encoded_nelts (cst1);
     505            0 :       for (unsigned i = 0; i < encoded_nelts; i++)
     506              :         {
     507            0 :           const_tree elt1 = VECTOR_CST_ENCODED_ELT (cst1, i);
     508            0 :           const_tree elt2 = VECTOR_CST_ENCODED_ELT (cst2, i);
     509            0 :           if (int el_cmp = cmp_csts_and_types (elt1, elt2))
     510              :             return el_cmp;
     511              :         }
     512              :       return 0;
     513              :     }
     514              : }
     515              : 
     516              : /* Comparator for imposing a deterministic order on constants that might
     517              :    not be of the same type.  */
     518              : 
     519              : static int
     520      1525038 : cmp_csts_and_types (const_tree cst1, const_tree cst2)
     521              : {
     522      1525038 :   int t1 = TYPE_UID (TREE_TYPE (cst1));
     523      1525038 :   int t2 = TYPE_UID (TREE_TYPE (cst2));
     524      1525038 :   if (int cmp_type = t1 - t2)
     525              :     return cmp_type;
     526      1525016 :   return cmp_csts_same_type (cst1, cst2);
     527              : }
     528              : 
     529              : /* Comparator for imposing a deterministic order on svalues.  */
     530              : 
     531              : int
     532     43860362 : svalue::cmp_ptr (const svalue *sval1, const svalue *sval2)
     533              : {
     534     45296168 :   if (sval1 == sval2)
     535              :     return 0;
     536     43537883 :   if (int cmp_kind = sval1->get_kind () - sval2->get_kind ())
     537              :     return cmp_kind;
     538     16462287 :   int t1 = sval1->get_type () ? TYPE_UID (sval1->get_type ()) : -1;
     539     16462287 :   int t2 = sval2->get_type () ? TYPE_UID (sval2->get_type ()) : -1;
     540     16462287 :   if (int cmp_type = t1 - t2)
     541              :     return cmp_type;
     542     10530637 :   switch (sval1->get_kind ())
     543              :     {
     544            0 :     default:
     545            0 :       gcc_unreachable ();
     546       768567 :     case SK_REGION:
     547       768567 :       {
     548       768567 :         const region_svalue *region_sval1 = (const region_svalue *)sval1;
     549       768567 :         const region_svalue *region_sval2 = (const region_svalue *)sval2;
     550       768567 :         return region::cmp_ids (region_sval1->get_pointee (),
     551      1537134 :                                 region_sval2->get_pointee ());
     552              :       }
     553      1524950 :       break;
     554      1524950 :     case SK_CONSTANT:
     555      1524950 :       {
     556      1524950 :         const constant_svalue *constant_sval1 = (const constant_svalue *)sval1;
     557      1524950 :         const constant_svalue *constant_sval2 = (const constant_svalue *)sval2;
     558      1524950 :         const_tree cst1 = constant_sval1->get_constant ();
     559      1524950 :         const_tree cst2 = constant_sval2->get_constant ();
     560              :         /* The svalues have the same type, but the underlying trees
     561              :            might not (for the case where both svalues are typeless).  */
     562      1524950 :         return cmp_csts_and_types (cst1, cst2);
     563              :       }
     564            0 :       break;
     565            0 :     case SK_UNKNOWN:
     566            0 :       {
     567            0 :         gcc_assert (sval1 == sval2);
     568              :         return 0;
     569              :       }
     570            0 :       break;
     571            0 :     case SK_POISONED:
     572            0 :       {
     573            0 :         const poisoned_svalue *poisoned_sval1 = (const poisoned_svalue *)sval1;
     574            0 :         const poisoned_svalue *poisoned_sval2 = (const poisoned_svalue *)sval2;
     575            0 :         return (static_cast<int> (poisoned_sval1->get_poison_kind ())
     576            0 :                 - static_cast<int> (poisoned_sval2->get_poison_kind ()));
     577              :       }
     578            0 :       break;
     579            0 :     case SK_SETJMP:
     580            0 :       {
     581            0 :         const setjmp_svalue *setjmp_sval1 = (const setjmp_svalue *)sval1;
     582            0 :         const setjmp_svalue *setjmp_sval2 = (const setjmp_svalue *)sval2;
     583            0 :         const setjmp_record &rec1 = setjmp_sval1->get_setjmp_record ();
     584            0 :         const setjmp_record &rec2 = setjmp_sval2->get_setjmp_record ();
     585            0 :         return setjmp_record::cmp (rec1, rec2);
     586              :       }
     587      2075024 :       break;
     588      2075024 :     case SK_INITIAL:
     589      2075024 :       {
     590      2075024 :         const initial_svalue *initial_sval1 = (const initial_svalue *)sval1;
     591      2075024 :         const initial_svalue *initial_sval2 = (const initial_svalue *)sval2;
     592      2075024 :         return region::cmp_ids (initial_sval1->get_region (),
     593      4150048 :                                 initial_sval2->get_region ());
     594              :       }
     595       743019 :       break;
     596       743019 :     case SK_UNARYOP:
     597       743019 :       {
     598       743019 :         const unaryop_svalue *unaryop_sval1 = (const unaryop_svalue *)sval1;
     599       743019 :         const unaryop_svalue *unaryop_sval2 = (const unaryop_svalue *)sval2;
     600       743019 :         if (int op_cmp = unaryop_sval1->get_op () - unaryop_sval2->get_op ())
     601              :           return op_cmp;
     602       742979 :         return svalue::cmp_ptr (unaryop_sval1->get_arg (),
     603       742979 :                                 unaryop_sval2->get_arg ());
     604              :       }
     605      1829703 :       break;
     606      1829703 :     case SK_BINOP:
     607      1829703 :       {
     608      1829703 :         const binop_svalue *binop_sval1 = (const binop_svalue *)sval1;
     609      1829703 :         const binop_svalue *binop_sval2 = (const binop_svalue *)sval2;
     610      1829703 :         if (int op_cmp = binop_sval1->get_op () - binop_sval2->get_op ())
     611              :           return op_cmp;
     612      1805929 :         if (int arg0_cmp = svalue::cmp_ptr (binop_sval1->get_arg0 (),
     613              :                                             binop_sval2->get_arg0 ()))
     614              :           return arg0_cmp;
     615       692496 :         return svalue::cmp_ptr (binop_sval1->get_arg1 (),
     616       692496 :                                 binop_sval2->get_arg1 ());
     617              :       }
     618       403654 :       break;
     619       403654 :     case SK_SUB:
     620       403654 :       {
     621       403654 :         const sub_svalue *sub_sval1 = (const sub_svalue *)sval1;
     622       403654 :         const sub_svalue *sub_sval2 = (const sub_svalue *)sval2;
     623       403654 :         if (int parent_cmp = svalue::cmp_ptr (sub_sval1->get_parent (),
     624              :                                               sub_sval2->get_parent ()))
     625              :           return parent_cmp;
     626       403650 :         return region::cmp_ids (sub_sval1->get_subregion (),
     627       807300 :                                 sub_sval2->get_subregion ());
     628              :       }
     629          307 :       break;
     630          307 :     case SK_REPEATED:
     631          307 :       {
     632          307 :         const repeated_svalue *repeated_sval1 = (const repeated_svalue *)sval1;
     633          307 :         const repeated_svalue *repeated_sval2 = (const repeated_svalue *)sval2;
     634          307 :         return svalue::cmp_ptr (repeated_sval1->get_inner_svalue (),
     635          307 :                                 repeated_sval2->get_inner_svalue ());
     636              :       }
     637          375 :       break;
     638          375 :     case SK_BITS_WITHIN:
     639          375 :       {
     640          375 :         const bits_within_svalue *bits_within_sval1
     641              :           = (const bits_within_svalue *)sval1;
     642          375 :         const bits_within_svalue *bits_within_sval2
     643              :           = (const bits_within_svalue *)sval2;
     644          375 :         if (int cmp = bit_range::cmp (bits_within_sval1->get_bits (),
     645              :                                        bits_within_sval2->get_bits ()))
     646              :           return cmp;
     647            0 :         return svalue::cmp_ptr (bits_within_sval1->get_inner_svalue (),
     648            0 :                                 bits_within_sval2->get_inner_svalue ());
     649              :       }
     650            0 :       break;
     651            0 :     case SK_UNMERGEABLE:
     652            0 :       {
     653            0 :         const unmergeable_svalue *unmergeable_sval1
     654              :           = (const unmergeable_svalue *)sval1;
     655            0 :         const unmergeable_svalue *unmergeable_sval2
     656              :           = (const unmergeable_svalue *)sval2;
     657            0 :         return svalue::cmp_ptr (unmergeable_sval1->get_arg (),
     658            0 :                                 unmergeable_sval2->get_arg ());
     659              :       }
     660            0 :       break;
     661            0 :     case SK_PLACEHOLDER:
     662            0 :       {
     663            0 :         const placeholder_svalue *placeholder_sval1
     664              :           = (const placeholder_svalue *)sval1;
     665            0 :         const placeholder_svalue *placeholder_sval2
     666              :           = (const placeholder_svalue *)sval2;
     667            0 :         return strcmp (placeholder_sval1->get_name (),
     668            0 :                        placeholder_sval2->get_name ());
     669              :       }
     670         1711 :       break;
     671         1711 :     case SK_WIDENING:
     672         1711 :       {
     673         1711 :         const widening_svalue *widening_sval1 = (const widening_svalue *)sval1;
     674         1711 :         const widening_svalue *widening_sval2 = (const widening_svalue *)sval2;
     675         1711 :         if (int index_cmp = (widening_sval1->get_snode ()->m_id
     676         1711 :                              - widening_sval2->get_snode ()->m_id))
     677              :           return index_cmp;
     678         1483 :         if (int base_cmp = svalue::cmp_ptr (widening_sval1->get_base_svalue (),
     679              :                                             widening_sval2->get_base_svalue ()))
     680              :           return base_cmp;
     681           24 :         return svalue::cmp_ptr (widening_sval1->get_iter_svalue (),
     682           24 :                                 widening_sval2->get_iter_svalue ());
     683              :       }
     684           28 :       break;
     685           28 :     case SK_COMPOUND:
     686           28 :       {
     687           28 :         const compound_svalue *compound_sval1 = (const compound_svalue *)sval1;
     688           28 :         const compound_svalue *compound_sval2 = (const compound_svalue *)sval2;
     689           28 :         return concrete_binding_map::cmp
     690           28 :           (compound_sval1->get_concrete_bindings (),
     691           28 :            compound_sval2->get_concrete_bindings ());
     692              :       }
     693      3183195 :       break;
     694      3183195 :     case SK_CONJURED:
     695      3183195 :       {
     696      3183195 :         const conjured_svalue *conjured_sval1 = (const conjured_svalue *)sval1;
     697      3183195 :         const conjured_svalue *conjured_sval2 = (const conjured_svalue *)sval2;
     698      3183195 :         if (int stmt_cmp = (conjured_sval1->get_stmt ()->uid
     699      3183195 :                             - conjured_sval2->get_stmt ()->uid))
     700              :           return stmt_cmp;
     701        37198 :         return region::cmp_ids (conjured_sval1->get_id_region (),
     702        74396 :                                 conjured_sval2->get_id_region ());
     703              :       }
     704           24 :       break;
     705           24 :     case SK_ASM_OUTPUT:
     706           24 :       {
     707           24 :         const asm_output_svalue *asm_output_sval1
     708              :           = (const asm_output_svalue *)sval1;
     709           24 :         const asm_output_svalue *asm_output_sval2
     710              :           = (const asm_output_svalue *)sval2;
     711           24 :         if (int asm_string_cmp = strcmp (asm_output_sval1->get_asm_string (),
     712              :                                          asm_output_sval2->get_asm_string ()))
     713              :           return asm_string_cmp;
     714           24 :         if (int output_idx_cmp = ((int)asm_output_sval1->get_output_idx ()
     715           24 :                                   - (int)asm_output_sval2->get_output_idx ()))
     716              :           return output_idx_cmp;
     717           24 :         if (int cmp = ((int)asm_output_sval1->get_num_inputs ()
     718           24 :                        - (int)asm_output_sval2->get_num_inputs ()))
     719              :           return cmp;
     720           24 :         for (unsigned i = 0; i < asm_output_sval1->get_num_inputs (); i++)
     721           24 :           if (int input_cmp
     722           24 :               = svalue::cmp_ptr (asm_output_sval1->get_input (i),
     723              :                                  asm_output_sval2->get_input (i)))
     724              :             return input_cmp;
     725              :         return 0;
     726              :       }
     727           80 :       break;
     728           80 :     case SK_CONST_FN_RESULT:
     729           80 :       {
     730           80 :         const const_fn_result_svalue *const_fn_result_sval1
     731              :           = (const const_fn_result_svalue *)sval1;
     732           80 :         const const_fn_result_svalue *const_fn_result_sval2
     733              :           = (const const_fn_result_svalue *)sval2;
     734           80 :         int d1 = DECL_UID (const_fn_result_sval1->get_fndecl ());
     735           80 :         int d2 = DECL_UID (const_fn_result_sval2->get_fndecl ());
     736           80 :         if (int cmp_fndecl = d1 - d2)
     737              :           return cmp_fndecl;
     738           64 :         if (int cmp = ((int)const_fn_result_sval1->get_num_inputs ()
     739           64 :                        - (int)const_fn_result_sval2->get_num_inputs ()))
     740              :           return cmp;
     741           48 :         for (unsigned i = 0; i < const_fn_result_sval1->get_num_inputs (); i++)
     742           48 :           if (int input_cmp
     743           48 :               = svalue::cmp_ptr (const_fn_result_sval1->get_input (i),
     744              :                                  const_fn_result_sval2->get_input (i)))
     745              :             return input_cmp;
     746              :         return 0;
     747              :       }
     748              :     }
     749              : }
     750              : 
     751              : /* Comparator for use by vec<const svalue *>::qsort.  */
     752              : 
     753              : int
     754      7758022 : svalue::cmp_ptr_ptr (const void *p1, const void *p2)
     755              : {
     756      7758022 :   const svalue *sval1 = *(const svalue * const *)p1;
     757      7758022 :   const svalue *sval2 = *(const svalue * const *)p2;
     758      7758022 :   return cmp_ptr (sval1, sval2);
     759              : }
     760              : 
     761              : /* Subclass of visitor for use in implementing svalue::involves_p.  */
     762              : 
     763              : class involvement_visitor : public visitor
     764              : {
     765              : public:
     766       648056 :   involvement_visitor (const svalue *needle)
     767       648056 :   : m_needle (needle), m_found (false) {}
     768              : 
     769       293587 :   void visit_initial_svalue (const initial_svalue *candidate) final override
     770              :   {
     771       293587 :     if (candidate == m_needle)
     772           60 :       m_found = true;
     773       293587 :   }
     774              : 
     775       291973 :   void visit_conjured_svalue (const conjured_svalue *candidate) final override
     776              :   {
     777       291973 :     if (candidate == m_needle)
     778         6548 :       m_found = true;
     779       291973 :   }
     780              : 
     781         5113 :   void visit_widening_svalue (const widening_svalue *candidate) final override
     782              :   {
     783         5113 :     if (candidate == m_needle)
     784          172 :       m_found = true;
     785         5113 :   }
     786              : 
     787       648056 :   bool found_p () const { return m_found; }
     788              : 
     789              : private:
     790              :   const svalue *m_needle;
     791              :   bool m_found;
     792              : };
     793              : 
     794              : /* Return true iff this svalue is defined in terms of OTHER.  */
     795              : 
     796              : bool
     797       648056 : svalue::involves_p (const svalue *other) const
     798              : {
     799              :   /* Currently only implemented for these kinds.  */
     800       648056 :   gcc_assert (other->get_kind () == SK_INITIAL
     801              :               || other->get_kind () == SK_CONJURED
     802              :               || other->get_kind () == SK_WIDENING);
     803              : 
     804       648056 :   involvement_visitor v (other);
     805       648056 :   accept (&v);
     806       648056 :   return v.found_p ();
     807              : }
     808              : 
     809              : /* Extract SUBRANGE from this value, of type TYPE.  */
     810              : 
     811              : const svalue *
     812        19540 : svalue::extract_bit_range (tree type,
     813              :                            const bit_range &subrange,
     814              :                            region_model_manager *mgr) const
     815              : {
     816        19540 :   return mgr->get_or_create_bits_within (type, subrange, this);
     817              : }
     818              : 
     819              : /* Base implementation of svalue::maybe_fold_bits_within vfunc.  */
     820              : 
     821              : const svalue *
     822         1712 : svalue::maybe_fold_bits_within (tree,
     823              :                                 const bit_range &,
     824              :                                 region_model_manager *) const
     825              : {
     826              :   /* By default, don't fold.  */
     827         1712 :   return nullptr;
     828              : }
     829              : 
     830              : /* Base implementation of svalue::all_zeroes_p.
     831              :    Return true if this value is known to be all zeroes.  */
     832              : 
     833              : bool
     834       139441 : svalue::all_zeroes_p () const
     835              : {
     836       139441 :   return false;
     837              : }
     838              : 
     839              : /* If this svalue is a pointer, attempt to determine the base region it points
     840              :    to.  Return nullptr on any problems.  */
     841              : 
     842              : const region *
     843        20399 : svalue::maybe_get_deref_base_region () const
     844              : {
     845        20399 :   const svalue *iter = this;
     846        20727 :   while (1)
     847              :     {
     848        20563 :       switch (iter->get_kind ())
     849              :         {
     850              :         default:
     851              :           return nullptr;
     852              : 
     853         8905 :         case SK_REGION:
     854         8905 :           {
     855         8905 :             const region_svalue *region_sval
     856         8905 :               = as_a <const region_svalue *> (iter);
     857         8905 :             return region_sval->get_pointee ()->get_base_region ();
     858              :           }
     859              : 
     860          330 :         case SK_BINOP:
     861          330 :           {
     862          330 :             const binop_svalue *binop_sval
     863          330 :               = as_a <const binop_svalue *> (iter);
     864          330 :             switch (binop_sval->get_op ())
     865              :               {
     866          164 :               case POINTER_PLUS_EXPR:
     867              :                 /* If we have a symbolic value expressing pointer arithmetic,
     868              :                    use the LHS.  */
     869          164 :                 iter = binop_sval->get_arg0 ();
     870          164 :                 continue;
     871              : 
     872              :               default:
     873              :                 return nullptr;
     874              :               }
     875              :             return nullptr;
     876              :           }
     877              :         }
     878          164 :     }
     879              : }
     880              : 
     881              : /* If this svalue is a pointer to the typeinfo instance for a particular
     882              :    type, return that type.  Otherwise return NULL_TREE.  */
     883              : 
     884              : tree
     885          659 : svalue::maybe_get_type_from_typeinfo () const
     886              : {
     887          659 :   if (const region *reg = maybe_get_region ())
     888          494 :     if (const decl_region *decl_reg = reg->dyn_cast_decl_region ())
     889          494 :       return TREE_TYPE (DECL_NAME (decl_reg->get_decl ()));
     890              : 
     891              :   return NULL_TREE;
     892              : }
     893              : 
     894              : /* Return true if we can get a value_range for TYPE (which could be
     895              :    NULL_TREE); false otherwise.  */
     896              : 
     897              : static bool
     898       191492 : type_can_have_value_range_p (tree type)
     899              : {
     900       191492 :   if (!type)
     901              :     return false;
     902       191416 :   if (irange::supports_p (type))
     903              :     return true;
     904        35358 :   if (frange::supports_p (type))
     905              :     return true;
     906              :   return false;
     907              : }
     908              : 
     909              : /* Base implementation of svalue::maybe_get_value_range_1 vfunc.
     910              :    If there is a suitable underlying type, write a "varying" for it to OUT
     911              :    (for "any value of that type") and return true; otherwise return false.  */
     912              : 
     913              : bool
     914        96491 : svalue::maybe_get_value_range_1 (value_range &out) const
     915              : {
     916        96491 :   tree type = get_type ();
     917        96491 :   if (!type_can_have_value_range_p (type))
     918              :     return false;
     919              : 
     920        63021 :   out.set_varying (type);
     921        63021 :   return true;
     922              : }
     923              : 
     924              : /* class region_svalue : public svalue.  */
     925              : 
     926              : /* Implementation of svalue::dump_to_pp vfunc for region_svalue.  */
     927              : 
     928              : void
     929        10045 : region_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
     930              : {
     931        10045 :   if (simple)
     932              :     {
     933         9426 :       pp_string (pp, "&");
     934         9426 :       m_reg->dump_to_pp (pp, simple);
     935              :     }
     936              :   else
     937              :     {
     938          619 :       pp_string (pp, "region_svalue(");
     939          619 :       if (get_type ())
     940              :         {
     941          619 :           print_quoted_type (pp, get_type ());
     942          619 :           pp_string (pp, ", ");
     943              :         }
     944          619 :       m_reg->dump_to_pp (pp, simple);
     945          619 :       pp_string (pp, ")");
     946              :     }
     947        10045 : }
     948              : 
     949              : /* Implementation of svalue::print_dump_widget_label vfunc for
     950              :    region_svalue.  */
     951              : 
     952              : void
     953            0 : region_svalue::print_dump_widget_label (pretty_printer *pp) const
     954              : {
     955            0 :   pp_printf (pp, "region_svalue: %qs", "&");
     956            0 : }
     957              : 
     958              : /* Implementation of svalue::add_dump_widget_children vfunc for
     959              :    region_svalue.  */
     960              : 
     961              : void
     962            0 : region_svalue::
     963              : add_dump_widget_children (text_art::tree_widget &w,
     964              :                           const text_art::dump_widget_info &dwi) const
     965              : {
     966            0 :   w.add_child (m_reg->make_dump_widget (dwi));
     967            0 : }
     968              : 
     969              : /* Implementation of svalue::accept vfunc for region_svalue.  */
     970              : 
     971              : void
     972       752881 : region_svalue::accept (visitor *v) const
     973              : {
     974       752881 :   m_reg->accept (v);
     975       752881 :   v->visit_region_svalue (this);
     976       752881 : }
     977              : 
     978              : /* Implementation of svalue::implicitly_live_p vfunc for region_svalue.  */
     979              : 
     980              : bool
     981       262669 : region_svalue::implicitly_live_p (const svalue_set *,
     982              :                                   const region_model *model) const
     983              : {
     984              :   /* Pointers into clusters that have escaped should be treated as live.  */
     985       262669 :   const region *base_reg = get_pointee ()->get_base_region ();
     986       262669 :   const store *store = model->get_store ();
     987       262669 :   if (const binding_cluster *c = store->get_cluster (base_reg))
     988       242549 :     if (c->escaped_p ())
     989              :         return true;
     990              : 
     991              :   return false;
     992              : }
     993              : 
     994              : /* Evaluate the condition LHS OP RHS.
     995              :    Subroutine of region_model::eval_condition for when we have a pair of
     996              :    pointers.  */
     997              : 
     998              : tristate
     999          344 : region_svalue::eval_condition (const region_svalue *lhs,
    1000              :                                enum tree_code op,
    1001              :                                const region_svalue *rhs)
    1002              : {
    1003              :   /* See if they point to the same region.  */
    1004          344 :   const region *lhs_reg = lhs->get_pointee ();
    1005          344 :   const region *rhs_reg = rhs->get_pointee ();
    1006          344 :   bool ptr_equality = lhs_reg == rhs_reg;
    1007          344 :   switch (op)
    1008              :     {
    1009            0 :     default:
    1010            0 :       gcc_unreachable ();
    1011              : 
    1012           73 :     case EQ_EXPR:
    1013           73 :       if (ptr_equality)
    1014            0 :         return tristate::TS_TRUE;
    1015              :       else
    1016           73 :         return tristate::TS_FALSE;
    1017          263 :       break;
    1018              : 
    1019          263 :     case NE_EXPR:
    1020          263 :       if (ptr_equality)
    1021            0 :         return tristate::TS_FALSE;
    1022              :       else
    1023          263 :         return tristate::TS_TRUE;
    1024            4 :       break;
    1025              : 
    1026            4 :     case GE_EXPR:
    1027            4 :     case LE_EXPR:
    1028            4 :       if (ptr_equality)
    1029            0 :         return tristate::TS_TRUE;
    1030              :       break;
    1031              : 
    1032            4 :     case GT_EXPR:
    1033            4 :     case LT_EXPR:
    1034            4 :       if (ptr_equality)
    1035            0 :         return tristate::TS_FALSE;
    1036              :       break;
    1037              :     }
    1038              : 
    1039            8 :   return tristate::TS_UNKNOWN;
    1040              : }
    1041              : 
    1042              : /* class constant_svalue : public svalue.  */
    1043              : 
    1044              : /* Implementation of svalue::dump_to_pp vfunc for constant_svalue.  */
    1045              : 
    1046              : void
    1047        16442 : constant_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
    1048              : {
    1049        16442 :   if (simple)
    1050              :     {
    1051        15793 :       pp_string (pp, "(");
    1052        15793 :       dump_tree (pp, get_type ());
    1053        15793 :       pp_string (pp, ")");
    1054        15793 :       dump_tree (pp, m_cst_expr);
    1055              :     }
    1056              :   else
    1057              :     {
    1058          649 :       pp_string (pp, "constant_svalue(");
    1059          649 :       if (get_type ())
    1060              :         {
    1061          649 :           print_quoted_type (pp, get_type ());
    1062          649 :           pp_string (pp, ", ");
    1063              :         }
    1064          649 :       dump_tree (pp, m_cst_expr);
    1065          649 :       pp_string (pp, ")");
    1066              :     }
    1067        16442 : }
    1068              : 
    1069              : /* Implementation of svalue::print_dump_widget_label vfunc for
    1070              :    constant_svalue.  */
    1071              : 
    1072              : void
    1073            0 : constant_svalue::print_dump_widget_label (pretty_printer *pp) const
    1074              : {
    1075            0 :   pp_printf (pp, "constant_svalue (%qE)", m_cst_expr);
    1076            0 : }
    1077              : 
    1078              : /* Implementation of svalue::add_dump_widget_children vfunc for
    1079              :    constant_svalue.  */
    1080              : 
    1081              : void
    1082            0 : constant_svalue::
    1083              : add_dump_widget_children (text_art::tree_widget &,
    1084              :                           const text_art::dump_widget_info &) const
    1085              : {
    1086              :   /* No children.  */
    1087            0 : }
    1088              : 
    1089              : /* Implementation of svalue::accept vfunc for constant_svalue.  */
    1090              : 
    1091              : void
    1092      9319468 : constant_svalue::accept (visitor *v) const
    1093              : {
    1094      9319468 :   v->visit_constant_svalue (this);
    1095      9319468 : }
    1096              : 
    1097              : /* Implementation of svalue::implicitly_live_p vfunc for constant_svalue.
    1098              :    Constants are implicitly live.  */
    1099              : 
    1100              : bool
    1101       678048 : constant_svalue::implicitly_live_p (const svalue_set *,
    1102              :                                     const region_model *) const
    1103              : {
    1104       678048 :   return true;
    1105              : }
    1106              : 
    1107              : /* Given EXPR, a non-NULL expression of boolean type, convert to
    1108              :    a tristate based on whether this is known to be true, false,
    1109              :    or is not known.  */
    1110              : 
    1111              : static tristate
    1112        14635 : tristate_from_boolean_tree_node (tree expr)
    1113              : {
    1114        14635 :   gcc_assert (TREE_TYPE (expr) == boolean_type_node);
    1115              : 
    1116        14635 :   if (expr == boolean_true_node)
    1117        10661 :     return tristate (tristate::TS_TRUE);
    1118         3974 :   else if (expr == boolean_false_node)
    1119         3974 :     return tristate (tristate::TS_FALSE);
    1120              :   else
    1121            0 :     return tristate (tristate::TS_UNKNOWN);
    1122              : }
    1123              : 
    1124              : /* Evaluate the condition LHS OP RHS.
    1125              :    Subroutine of region_model::eval_condition for when we have a pair of
    1126              :    constants.  */
    1127              : 
    1128              : tristate
    1129        15190 : constant_svalue::eval_condition (const constant_svalue *lhs,
    1130              :                                  enum tree_code op,
    1131              :                                  const constant_svalue *rhs)
    1132              : {
    1133        15190 :   tree lhs_const = lhs->get_constant ();
    1134        15190 :   tree rhs_const = rhs->get_constant ();
    1135              : 
    1136        15190 :   gcc_assert (CONSTANT_CLASS_P (lhs_const));
    1137        15190 :   gcc_assert (CONSTANT_CLASS_P (rhs_const));
    1138              : 
    1139        15190 :   if ((lhs->get_type () == NULL_TREE || rhs->get_type () == NULL_TREE)
    1140          366 :       && TREE_CODE (lhs_const) == INTEGER_CST
    1141        15556 :       && TREE_CODE (rhs_const) == INTEGER_CST
    1142              :       )
    1143              :     {
    1144          366 :      if (tree tree_cmp = const_binop (op, boolean_type_node,
    1145              :                                       lhs_const, rhs_const))
    1146              :        {
    1147          366 :          tristate ts = tristate_from_boolean_tree_node (tree_cmp);
    1148          366 :          if (ts.is_known ())
    1149          366 :            return ts;
    1150              :        }
    1151              :     }
    1152              : 
    1153              :   /* Check for comparable types.  */
    1154        14824 :   if (types_compatible_p (TREE_TYPE (lhs_const), TREE_TYPE (rhs_const)))
    1155              :     {
    1156        14269 :       tree tree_cmp
    1157        14269 :         = fold_binary (op, boolean_type_node, lhs_const, rhs_const);
    1158        14269 :       tristate ts = tristate_from_boolean_tree_node (tree_cmp);
    1159        14269 :       if (ts.is_known ())
    1160        14269 :         return ts;
    1161              :     }
    1162          555 :   return tristate::TS_UNKNOWN;
    1163              : }
    1164              : 
    1165              : /* Implementation of svalue::maybe_fold_bits_within vfunc
    1166              :    for constant_svalue.  */
    1167              : 
    1168              : const svalue *
    1169          442 : constant_svalue::maybe_fold_bits_within (tree type,
    1170              :                                          const bit_range &bits,
    1171              :                                          region_model_manager *mgr) const
    1172              : {
    1173              :   /* Bits within an all-zero value are also all zero.  */
    1174          442 :   if (zerop (m_cst_expr))
    1175              :     {
    1176           93 :       if (type)
    1177           92 :         return mgr->get_or_create_cast (type, this);
    1178              :       else
    1179            1 :         return this;
    1180              :     }
    1181              : 
    1182              :   /* Handle the case of extracting a single bit. */
    1183          498 :   if (bits.m_size_in_bits == 1
    1184          204 :       && TREE_CODE (m_cst_expr) == INTEGER_CST
    1185          204 :       && type
    1186          204 :       && INTEGRAL_TYPE_P (type)
    1187          553 :       && tree_fits_uhwi_p (m_cst_expr))
    1188              :     {
    1189          200 :       unsigned HOST_WIDE_INT bit = bits.m_start_bit_offset.to_uhwi ();
    1190          200 :       unsigned HOST_WIDE_INT mask = (1 << bit);
    1191          200 :       unsigned HOST_WIDE_INT val_as_hwi = tree_to_uhwi (m_cst_expr);
    1192          200 :       unsigned HOST_WIDE_INT masked_val = val_as_hwi & mask;
    1193          200 :       int result = masked_val ? 1 : 0;
    1194          200 :       return mgr->get_or_create_int_cst (type, result);
    1195              :     }
    1196              : 
    1197              :   /* Otherwise, don't fold.  */
    1198              :   return nullptr;
    1199              : }
    1200              : 
    1201              : /* Implementation of svalue::all_zeroes_p for constant_svalue.  */
    1202              : 
    1203              : bool
    1204       115780 : constant_svalue::all_zeroes_p () const
    1205              : {
    1206       115780 :   return zerop (m_cst_expr);
    1207              : }
    1208              : 
    1209              : 
    1210              : /* Implementation of svalue::maybe_get_value_range_1 for constant_svalue.
    1211              :    If there is a suitable underlying type, write the value_range for the
    1212              :    single value of m_cst_expr to OUT and return true; otherwise return
    1213              :    false.  */
    1214              : 
    1215              : bool
    1216        52668 : constant_svalue::maybe_get_value_range_1 (value_range &out) const
    1217              : {
    1218        52668 :   if (!type_can_have_value_range_p (get_type ()))
    1219              :     return false;
    1220              : 
    1221        52573 :   out = value_range (m_cst_expr, m_cst_expr);
    1222        52573 :   return true;
    1223              : }
    1224              : 
    1225              : /* class unknown_svalue : public svalue.  */
    1226              : 
    1227              : /* Implementation of svalue::dump_to_pp vfunc for unknown_svalue.  */
    1228              : 
    1229              : void
    1230         3670 : unknown_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
    1231              : {
    1232         3670 :   if (simple)
    1233              :     {
    1234         2943 :       pp_string (pp, "UNKNOWN(");
    1235         2943 :       if (get_type ())
    1236         2940 :         dump_tree (pp, get_type ());
    1237         2943 :       pp_character (pp, ')');
    1238              :     }
    1239              :   else
    1240              :     {
    1241          727 :       pp_string (pp, "unknown_svalue(");
    1242          727 :       if (get_type ())
    1243          727 :         dump_tree (pp, get_type ());
    1244          727 :       pp_character (pp, ')');
    1245              :     }
    1246         3670 : }
    1247              : 
    1248              : /* Implementation of svalue::print_dump_widget_label vfunc for
    1249              :    unknown_svalue.  */
    1250              : 
    1251              : void
    1252            0 : unknown_svalue::print_dump_widget_label (pretty_printer *pp) const
    1253              : {
    1254            0 :   pp_printf (pp, "unknown_svalue");
    1255            0 : }
    1256              : 
    1257              : /* Implementation of svalue::add_dump_widget_children vfunc for
    1258              :    unknown_svalue.  */
    1259              : 
    1260              : void
    1261            0 : unknown_svalue::
    1262              : add_dump_widget_children (text_art::tree_widget &,
    1263              :                           const text_art::dump_widget_info &) const
    1264              : {
    1265              :   /* No children.  */
    1266            0 : }
    1267              : 
    1268              : /* Implementation of svalue::accept vfunc for unknown_svalue.  */
    1269              : 
    1270              : void
    1271      1900379 : unknown_svalue::accept (visitor *v) const
    1272              : {
    1273      1900379 :   v->visit_unknown_svalue (this);
    1274      1900379 : }
    1275              : 
    1276              : /* Implementation of svalue::maybe_fold_bits_within vfunc
    1277              :    for unknown_svalue.  */
    1278              : 
    1279              : const svalue *
    1280         7142 : unknown_svalue::maybe_fold_bits_within (tree type,
    1281              :                                         const bit_range &,
    1282              :                                         region_model_manager *mgr) const
    1283              : {
    1284              :   /* Bits within an unknown_svalue are themselves unknown.  */
    1285         7142 :   return mgr->get_or_create_unknown_svalue (type);
    1286              : }
    1287              : 
    1288              : bool
    1289        16994 : unknown_svalue::maybe_get_value_range_1 (value_range &) const
    1290              : {
    1291              :   /* Don't attempt to participate in range ops.  */
    1292        16994 :   return false;
    1293              : }
    1294              : 
    1295              : 
    1296              : /* Get a string for KIND for use in debug dumps.  */
    1297              : 
    1298              : const char *
    1299           12 : poison_kind_to_str (enum poison_kind kind)
    1300              : {
    1301           12 :   switch (kind)
    1302              :     {
    1303            0 :     default:
    1304            0 :       gcc_unreachable ();
    1305              :     case poison_kind::uninit:
    1306              :       return "uninit";
    1307            0 :     case poison_kind::freed:
    1308            0 :       return "freed";
    1309            0 :     case poison_kind::deleted:
    1310            0 :       return "deleted";
    1311            0 :     case poison_kind::popped_stack:
    1312            0 :       return "popped stack";
    1313              :     }
    1314              : }
    1315              : 
    1316              : /* class poisoned_svalue : public svalue.  */
    1317              : 
    1318              : /* Implementation of svalue::dump_to_pp vfunc for poisoned_svalue.  */
    1319              : 
    1320              : void
    1321            4 : poisoned_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
    1322              : {
    1323            4 :   if (simple)
    1324              :     {
    1325            4 :       pp_string (pp, "POISONED(");
    1326            4 :       print_quoted_type (pp, get_type ());
    1327            4 :       pp_printf (pp, ", %s)", poison_kind_to_str (m_kind));
    1328              :     }
    1329              :   else
    1330              :     {
    1331            0 :       pp_string (pp, "poisoned_svalue(");
    1332            0 :       print_quoted_type (pp, get_type ());
    1333            0 :       pp_printf (pp, ", %s)", poison_kind_to_str (m_kind));
    1334              :     }
    1335            4 : }
    1336              : 
    1337              : /* Implementation of svalue::print_dump_widget_label vfunc for
    1338              :    poisoned_svalue.  */
    1339              : 
    1340              : void
    1341            0 : poisoned_svalue::print_dump_widget_label (pretty_printer *pp) const
    1342              : {
    1343            0 :   pp_printf (pp, "poisoned_svalue(%s)", poison_kind_to_str (m_kind));
    1344            0 : }
    1345              : 
    1346              : /* Implementation of svalue::add_dump_widget_children vfunc for
    1347              :    poisoned_svalue.  */
    1348              : 
    1349              : void
    1350            0 : poisoned_svalue::
    1351              : add_dump_widget_children (text_art::tree_widget &,
    1352              :                           const text_art::dump_widget_info &) const
    1353              : {
    1354              :   /* No children.  */
    1355            0 : }
    1356              : 
    1357              : /* Implementation of svalue::accept vfunc for poisoned_svalue.  */
    1358              : 
    1359              : void
    1360        12768 : poisoned_svalue::accept (visitor *v) const
    1361              : {
    1362        12768 :   v->visit_poisoned_svalue (this);
    1363        12768 : }
    1364              : 
    1365              : /* Implementation of svalue::maybe_fold_bits_within vfunc
    1366              :    for poisoned_svalue.  */
    1367              : 
    1368              : const svalue *
    1369         5701 : poisoned_svalue::maybe_fold_bits_within (tree type,
    1370              :                                          const bit_range &,
    1371              :                                          region_model_manager *mgr) const
    1372              : {
    1373              :   /* Bits within a poisoned value are also poisoned.  */
    1374         5701 :   return mgr->get_or_create_poisoned_svalue (m_kind, type);
    1375              : }
    1376              : 
    1377              : /* class setjmp_svalue's implementation is in setjmp-longjmp.cc.  */
    1378              : 
    1379              : /* class initial_svalue : public svalue.  */
    1380              : 
    1381              : /* Implementation of svalue::dump_to_pp vfunc for initial_svalue.  */
    1382              : 
    1383              : void
    1384        11953 : initial_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
    1385              : {
    1386        11953 :   if (simple)
    1387              :     {
    1388        11817 :       pp_string (pp, "INIT_VAL(");
    1389        11817 :       m_reg->dump_to_pp (pp, simple);
    1390        11817 :       pp_string (pp, ")");
    1391              :     }
    1392              :   else
    1393              :     {
    1394          136 :       pp_string (pp, "initial_svalue(");
    1395          136 :       if (get_type ())
    1396              :         {
    1397          136 :           print_quoted_type (pp, get_type ());
    1398          136 :           pp_string (pp, ", ");
    1399              :         }
    1400          136 :       m_reg->dump_to_pp (pp, simple);
    1401          136 :       pp_string (pp, ")");
    1402              :     }
    1403        11953 : }
    1404              : 
    1405              : /* Implementation of svalue::print_dump_widget_label vfunc for
    1406              :    initial_svalue.  */
    1407              : 
    1408              : void
    1409            0 : initial_svalue::print_dump_widget_label (pretty_printer *pp) const
    1410              : {
    1411            0 :   pp_printf (pp, "initial_svalue");
    1412            0 : }
    1413              : 
    1414              : /* Implementation of svalue::add_dump_widget_children vfunc for
    1415              :    initial_svalue.  */
    1416              : 
    1417              : void
    1418            0 : initial_svalue::
    1419              : add_dump_widget_children (text_art::tree_widget &w,
    1420              :                           const text_art::dump_widget_info &dwi) const
    1421              : {
    1422            0 :   w.add_child (m_reg->make_dump_widget (dwi, "m_reg"));
    1423            0 : }
    1424              : 
    1425              : /* Implementation of svalue::accept vfunc for initial_svalue.  */
    1426              : 
    1427              : void
    1428      1569048 : initial_svalue::accept (visitor *v) const
    1429              : {
    1430      1569048 :   m_reg->accept (v);
    1431      1569048 :   v->visit_initial_svalue (this);
    1432      1569048 : }
    1433              : 
    1434              : /* Implementation of svalue::implicitly_live_p vfunc for initial_svalue.  */
    1435              : 
    1436              : bool
    1437      2647090 : initial_svalue::implicitly_live_p (const svalue_set *,
    1438              :                                    const region_model *model) const
    1439              : {
    1440              :   /* This svalue may be implicitly live if the region still implicitly
    1441              :      has its initial value and is reachable.  */
    1442              : 
    1443              :   /* It must be a region that exists; we don't want to consider
    1444              :      INIT_VAL(R) as still being implicitly reachable if R is in
    1445              :      a popped stack frame.  */
    1446      2647090 :   if (model->region_exists_p (m_reg))
    1447              :     {
    1448      2630757 :       const svalue *reg_sval = model->get_store_value (m_reg, nullptr);
    1449      2630757 :       if (reg_sval == this)
    1450              :         return true;
    1451              :     }
    1452              : 
    1453              :   /* Assume that the initial values of params for the top level frame
    1454              :      are still live, because (presumably) they're still
    1455              :      live in the external caller.  */
    1456       150008 :   if (initial_value_of_param_p ())
    1457        15431 :     if (const frame_region *frame_reg = m_reg->maybe_get_frame_region ())
    1458        15431 :       if (frame_reg->get_calling_frame () == nullptr)
    1459              :         return true;
    1460              : 
    1461              :   return false;
    1462              : }
    1463              : 
    1464              : /* Return true if this is the initial value of a function parameter.  */
    1465              : 
    1466              : bool
    1467       154174 : initial_svalue::initial_value_of_param_p () const
    1468              : {
    1469       154174 :   if (tree reg_decl = m_reg->maybe_get_decl ())
    1470        88403 :     if (TREE_CODE (reg_decl) == SSA_NAME)
    1471              :       {
    1472        15478 :         tree ssa_name = reg_decl;
    1473        15478 :         if (SSA_NAME_IS_DEFAULT_DEF (ssa_name)
    1474        15478 :             && SSA_NAME_VAR (ssa_name)
    1475        30956 :             && TREE_CODE (SSA_NAME_VAR (ssa_name)) == PARM_DECL)
    1476        15463 :           return true;
    1477              :       }
    1478              :   return false;
    1479              : }
    1480              : 
    1481              : /* class unaryop_svalue : public svalue.  */
    1482              : 
    1483              : /* Implementation of svalue::dump_to_pp vfunc for unaryop_svalue.  */
    1484              : 
    1485              : void
    1486         4548 : unaryop_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
    1487              : {
    1488         4548 :   if (simple)
    1489              :     {
    1490         4382 :       if (m_op == VIEW_CONVERT_EXPR || m_op == NOP_EXPR)
    1491              :         {
    1492         4201 :           pp_string (pp, "CAST(");
    1493         4201 :           dump_tree (pp, get_type ());
    1494         4201 :           pp_string (pp, ", ");
    1495         4201 :           m_arg->dump_to_pp (pp, simple);
    1496         4201 :           pp_character (pp, ')');
    1497              :         }
    1498              :       else
    1499              :         {
    1500          181 :           pp_character (pp, '(');
    1501          181 :           pp_string (pp, get_tree_code_name (m_op));
    1502              :           //pp_string (pp, op_symbol_code (m_op));
    1503          181 :           m_arg->dump_to_pp (pp, simple);
    1504          181 :           pp_character (pp, ')');
    1505              :         }
    1506              :     }
    1507              :   else
    1508              :     {
    1509          166 :       pp_string (pp, "unaryop_svalue (");
    1510          166 :       pp_string (pp, get_tree_code_name (m_op));
    1511          166 :       pp_string (pp, ", ");
    1512          166 :       m_arg->dump_to_pp (pp, simple);
    1513          166 :       pp_character (pp, ')');
    1514              :     }
    1515         4548 : }
    1516              : 
    1517              : /* Implementation of svalue::print_dump_widget_label vfunc for
    1518              :    unaryop_svalue.  */
    1519              : 
    1520              : void
    1521            0 : unaryop_svalue::print_dump_widget_label (pretty_printer *pp) const
    1522              : {
    1523            0 :   pp_printf (pp,
    1524              :              "unaryop_svalue(%s)",
    1525            0 :              get_tree_code_name (m_op));
    1526            0 : }
    1527              : 
    1528              : /* Implementation of svalue::add_dump_widget_children vfunc for
    1529              :    unaryop_svalue.  */
    1530              : 
    1531              : void
    1532            0 : unaryop_svalue::
    1533              : add_dump_widget_children (text_art::tree_widget &w,
    1534              :                           const text_art::dump_widget_info &dwi) const
    1535              : {
    1536            0 :   w.add_child (m_arg->make_dump_widget (dwi));
    1537            0 : }
    1538              : 
    1539              : /* Implementation of svalue::accept vfunc for unaryop_svalue.  */
    1540              : 
    1541              : void
    1542      7054495 : unaryop_svalue::accept (visitor *v) const
    1543              : {
    1544      7054495 :   m_arg->accept (v);
    1545      7054495 :   v->visit_unaryop_svalue (this);
    1546      7054495 : }
    1547              : 
    1548              : /* Implementation of svalue::implicitly_live_p vfunc for unaryop_svalue.  */
    1549              : 
    1550              : bool
    1551      1046277 : unaryop_svalue::implicitly_live_p (const svalue_set *live_svalues,
    1552              :                                    const region_model *model) const
    1553              : {
    1554      1046277 :   return get_arg ()->live_p (live_svalues, model);
    1555              : }
    1556              : 
    1557              : /* Implementation of svalue::maybe_fold_bits_within vfunc
    1558              :    for unaryop_svalue.  */
    1559              : 
    1560              : const svalue *
    1561         3402 : unaryop_svalue::maybe_fold_bits_within (tree type,
    1562              :                                         const bit_range &,
    1563              :                                         region_model_manager *mgr) const
    1564              : {
    1565         3402 :   switch (m_op)
    1566              :     {
    1567              :     default:
    1568              :       break;
    1569         3402 :     case NOP_EXPR:
    1570              :       /* A cast of zero is zero.  */
    1571         3402 :       if (tree cst = m_arg->maybe_get_constant ())
    1572         3402 :         if (zerop (cst))
    1573              :           {
    1574         3402 :             if (type)
    1575          140 :               return mgr->get_or_create_cast (type, this);
    1576              :             else
    1577         3262 :               return this;
    1578              :           }
    1579              :       break;
    1580              :     }
    1581              :   /* Otherwise, don't fold.  */
    1582              :   return nullptr;
    1583              : }
    1584              : 
    1585              : /* Implementation of svalue::maybe_get_value_range_1 for unaryop_svalue.  */
    1586              : 
    1587              : bool
    1588        16061 : unaryop_svalue::maybe_get_value_range_1 (value_range &out) const
    1589              : {
    1590        16061 :   tree type = get_type ();
    1591        16061 :   if (!type_can_have_value_range_p (type))
    1592              :     return false;
    1593              : 
    1594        16027 :   value_range arg_vr;
    1595        16027 :   if (m_arg->maybe_get_value_range (arg_vr))
    1596              :     {
    1597        15136 :       range_op_handler handler (m_op);
    1598        15136 :       if (handler
    1599        30272 :           && handler.operand_check_p (type, arg_vr.type (), type))
    1600              :         {
    1601              :           /* For unary ops, range_op_hander::fold_range expects
    1602              :              a VARYING of the unknown value as the 2nd operand.  */
    1603        15134 :           value_range varying (type);
    1604        15134 :           varying.set_varying (type);
    1605        15134 :           out.set_range_class (type);
    1606        15134 :           if (handler.fold_range (out, type, arg_vr, varying))
    1607        15134 :             return true;
    1608        15134 :         }
    1609              :     }
    1610              :   return false;
    1611        16027 : }
    1612              : 
    1613              : /* class binop_svalue : public svalue.  */
    1614              : 
    1615              : /* Return whether OP be printed as an infix operator.  */
    1616              : 
    1617              : static bool
    1618        10065 : infix_p (enum tree_code op)
    1619              : {
    1620            0 :   switch (op)
    1621              :     {
    1622              :     default:
    1623              :       return true;
    1624            0 :     case MAX_EXPR:
    1625            0 :     case MIN_EXPR:
    1626            0 :       return false;
    1627              :     }
    1628              : }
    1629              : 
    1630              : /* Implementation of svalue::dump_to_pp vfunc for binop_svalue.  */
    1631              : 
    1632              : void
    1633        10504 : binop_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
    1634              : {
    1635        10504 :   if (simple)
    1636              :     {
    1637        10065 :       if (infix_p (m_op))
    1638              :         {
    1639              :           /* Print "(A OP B)".  */
    1640        10065 :           pp_character (pp, '(');
    1641        10065 :           m_arg0->dump_to_pp (pp, simple);
    1642        10065 :           pp_string (pp, op_symbol_code (m_op));
    1643        10065 :           m_arg1->dump_to_pp (pp, simple);
    1644        10065 :           pp_character (pp, ')');
    1645              :         }
    1646              :       else
    1647              :         {
    1648              :           /* Print "OP(A, B)".  */
    1649            0 :           pp_string (pp, op_symbol_code (m_op));
    1650            0 :           pp_character (pp, '(');
    1651            0 :           m_arg0->dump_to_pp (pp, simple);
    1652            0 :           pp_string (pp, ", ");
    1653            0 :           m_arg1->dump_to_pp (pp, simple);
    1654            0 :           pp_character (pp, ')');
    1655              :         }
    1656              :     }
    1657              :   else
    1658              :     {
    1659          439 :       pp_string (pp, "binop_svalue (");
    1660          439 :       pp_string (pp, get_tree_code_name (m_op));
    1661          439 :       pp_string (pp, ", ");
    1662          439 :       m_arg0->dump_to_pp (pp, simple);
    1663          439 :       pp_string (pp, ", ");
    1664          439 :       m_arg1->dump_to_pp (pp, simple);
    1665          439 :       pp_character (pp, ')');
    1666              :     }
    1667        10504 : }
    1668              : 
    1669              : /* Implementation of svalue::print_dump_widget_label vfunc for
    1670              :    binop_svalue.  */
    1671              : 
    1672              : void
    1673            0 : binop_svalue::print_dump_widget_label (pretty_printer *pp) const
    1674              : {
    1675            0 :   pp_printf (pp,
    1676              :              "binop_svalue(%s: %qs)",
    1677            0 :              get_tree_code_name (m_op),
    1678            0 :              op_symbol_code (m_op));
    1679            0 : }
    1680              : 
    1681              : /* Implementation of svalue::add_dump_widget_children vfunc for
    1682              :    binop_svalue.  */
    1683              : 
    1684              : void
    1685            0 : binop_svalue::
    1686              : add_dump_widget_children (text_art::tree_widget &w,
    1687              :                           const text_art::dump_widget_info &dwi) const
    1688              : {
    1689            0 :   w.add_child (m_arg0->make_dump_widget (dwi));
    1690            0 :   w.add_child (m_arg1->make_dump_widget (dwi));
    1691            0 : }
    1692              : 
    1693              : /* Implementation of svalue::accept vfunc for binop_svalue.  */
    1694              : 
    1695              : void
    1696      6260618 : binop_svalue::accept (visitor *v) const
    1697              : {
    1698      6260618 :   m_arg0->accept (v);
    1699      6260618 :   m_arg1->accept (v);
    1700      6260618 :   v->visit_binop_svalue (this);
    1701      6260618 : }
    1702              : 
    1703              : /* Implementation of svalue::implicitly_live_p vfunc for binop_svalue.  */
    1704              : 
    1705              : bool
    1706      1122414 : binop_svalue::implicitly_live_p (const svalue_set *live_svalues,
    1707              :                                  const region_model *model) const
    1708              : {
    1709      1122414 :   return (get_arg0 ()->live_p (live_svalues, model)
    1710      1122414 :           && get_arg1 ()->live_p (live_svalues, model));
    1711              : }
    1712              : 
    1713              : /* class sub_svalue : public svalue.  */
    1714              : 
    1715              : /* sub_svalue'c ctor.  */
    1716              : 
    1717         2331 : sub_svalue::sub_svalue (symbol::id_t id,
    1718              :                         tree type, const svalue *parent_svalue,
    1719         2331 :                         const region *subregion)
    1720              : : svalue (complexity::from_pair (parent_svalue->get_complexity (),
    1721              :                                  subregion->get_complexity ()),
    1722              :           id,
    1723              :           type),
    1724         2331 :   m_parent_svalue (parent_svalue), m_subregion (subregion)
    1725              : {
    1726         2331 :   gcc_assert (parent_svalue->can_have_associated_state_p ());
    1727         2331 : }
    1728              : 
    1729              : /* Implementation of svalue::maybe_get_value_range_1 for binop_svalue.  */
    1730              : 
    1731              : bool
    1732        26272 : binop_svalue::maybe_get_value_range_1 (value_range &out) const
    1733              : {
    1734        26272 :   tree type = get_type ();
    1735        26272 :   if (!type_can_have_value_range_p (type))
    1736              :     return false;
    1737              : 
    1738              :   /* Avoid cases where we have been sloppy about types.  */
    1739        24589 :   if (!m_arg0->get_type ())
    1740              :     return false;
    1741        24589 :   if (!m_arg1->get_type ())
    1742              :     return false;
    1743        24589 :   if (!range_compatible_p (m_arg0->get_type (), m_arg1->get_type ()))
    1744              :     return false;
    1745              : 
    1746        24411 :   value_range lhs, rhs;
    1747        24411 :   if (m_arg0->maybe_get_value_range (lhs))
    1748        22293 :     if (m_arg1->maybe_get_value_range (rhs))
    1749              :       {
    1750        22139 :         range_op_handler handler (m_op);
    1751        22139 :         if (handler)
    1752              :           {
    1753        22139 :             out.set_range_class (type);
    1754        22139 :             if (handler.fold_range (out, get_type (), lhs, rhs))
    1755        22139 :               return true;
    1756              :           }
    1757              :       }
    1758              :   return false;
    1759        24411 : }
    1760              : 
    1761              : /* Implementation of svalue::dump_to_pp vfunc for sub_svalue.  */
    1762              : 
    1763              : void
    1764         1273 : sub_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
    1765              : {
    1766         1273 :   if (simple)
    1767              :     {
    1768         1222 :       pp_string (pp, "SUB(");
    1769         1222 :       m_parent_svalue->dump_to_pp (pp, simple);
    1770         1222 :       pp_string (pp, ", ");
    1771         1222 :       m_subregion->dump_to_pp (pp, simple);
    1772         1222 :       pp_character (pp, ')');
    1773              :     }
    1774              :   else
    1775              :     {
    1776           51 :       pp_string (pp, "sub_svalue (");
    1777           51 :       pp_string (pp, ", ");
    1778           51 :       m_parent_svalue->dump_to_pp (pp, simple);
    1779           51 :       pp_string (pp, ", ");
    1780           51 :       m_subregion->dump_to_pp (pp, simple);
    1781           51 :       pp_character (pp, ')');
    1782              :     }
    1783         1273 : }
    1784              : 
    1785              : /* Implementation of svalue::print_dump_widget_label vfunc for
    1786              :    sub_svalue.  */
    1787              : 
    1788              : void
    1789            0 : sub_svalue::print_dump_widget_label (pretty_printer *pp) const
    1790              : {
    1791            0 :   pp_printf (pp, "sub_svalue");
    1792            0 : }
    1793              : 
    1794              : /* Implementation of svalue::add_dump_widget_children vfunc for
    1795              :    sub_svalue.  */
    1796              : 
    1797              : void
    1798            0 : sub_svalue::
    1799              : add_dump_widget_children (text_art::tree_widget &w,
    1800              :                           const text_art::dump_widget_info &dwi) const
    1801              : {
    1802            0 :   w.add_child (m_parent_svalue->make_dump_widget (dwi, "m_parent_svalue"));
    1803            0 :   w.add_child (m_subregion->make_dump_widget (dwi, "m_subregion"));
    1804            0 : }
    1805              : 
    1806              : /* Implementation of svalue::accept vfunc for sub_svalue.  */
    1807              : 
    1808              : void
    1809      3944631 : sub_svalue::accept (visitor *v) const
    1810              : {
    1811      3944631 :   m_parent_svalue->accept (v);
    1812      3944631 :   m_subregion->accept (v);
    1813      3944631 :   v->visit_sub_svalue (this);
    1814      3944631 : }
    1815              : 
    1816              : /* Implementation of svalue::implicitly_live_p vfunc for sub_svalue.  */
    1817              : 
    1818              : bool
    1819       594129 : sub_svalue::implicitly_live_p (const svalue_set *live_svalues,
    1820              :                                const region_model *model) const
    1821              : {
    1822       594129 :   return get_parent ()->live_p (live_svalues, model);
    1823              : }
    1824              : 
    1825              : /* class repeated_svalue : public svalue.  */
    1826              : 
    1827              : /* repeated_svalue'c ctor.  */
    1828              : 
    1829          512 : repeated_svalue::repeated_svalue (symbol::id_t id,
    1830              :                                   tree type,
    1831              :                                   const svalue *outer_size,
    1832          512 :                                   const svalue *inner_svalue)
    1833          512 : : svalue (complexity::from_pair (outer_size, inner_svalue), id, type),
    1834          512 :   m_outer_size (outer_size),
    1835         1024 :   m_inner_svalue (inner_svalue)
    1836              : {
    1837          512 :   gcc_assert (outer_size->can_have_associated_state_p ());
    1838          512 :   gcc_assert (inner_svalue->can_have_associated_state_p ());
    1839          512 : }
    1840              : 
    1841              : /* Implementation of svalue::dump_to_pp vfunc for repeated_svalue.  */
    1842              : 
    1843              : void
    1844            0 : repeated_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
    1845              : {
    1846            0 :   if (simple)
    1847              :     {
    1848            0 :       pp_string (pp, "REPEATED(");
    1849            0 :       if (get_type ())
    1850              :         {
    1851            0 :           print_quoted_type (pp, get_type ());
    1852            0 :           pp_string (pp, ", ");
    1853              :         }
    1854            0 :       pp_string (pp, "outer_size: ");
    1855            0 :       m_outer_size->dump_to_pp (pp, simple);
    1856            0 :       pp_string (pp, ", inner_val: ");
    1857            0 :       m_inner_svalue->dump_to_pp (pp, simple);
    1858            0 :       pp_character (pp, ')');
    1859              :     }
    1860              :   else
    1861              :     {
    1862            0 :       pp_string (pp, "repeated_svalue (");
    1863            0 :       if (get_type ())
    1864              :         {
    1865            0 :           print_quoted_type (pp, get_type ());
    1866            0 :           pp_string (pp, ", ");
    1867              :         }
    1868            0 :       pp_string (pp, "outer_size: ");
    1869            0 :       m_outer_size->dump_to_pp (pp, simple);
    1870            0 :       pp_string (pp, ", inner_val: ");
    1871            0 :       m_inner_svalue->dump_to_pp (pp, simple);
    1872            0 :       pp_character (pp, ')');
    1873              :     }
    1874            0 : }
    1875              : 
    1876              : /* Implementation of svalue::print_dump_widget_label vfunc for
    1877              :    repeated_svalue.  */
    1878              : 
    1879              : void
    1880            0 : repeated_svalue::print_dump_widget_label (pretty_printer *pp) const
    1881              : {
    1882            0 :   pp_printf (pp, "repeated_svalue");
    1883            0 : }
    1884              : 
    1885              : /* Implementation of svalue::add_dump_widget_children vfunc for
    1886              :    repeated_svalue.  */
    1887              : 
    1888              : void
    1889            0 : repeated_svalue::
    1890              : add_dump_widget_children (text_art::tree_widget &w,
    1891              :                           const text_art::dump_widget_info &dwi) const
    1892              : {
    1893            0 :   w.add_child (m_outer_size->make_dump_widget (dwi, "m_outer_size"));
    1894            0 :   w.add_child (m_inner_svalue->make_dump_widget (dwi, "m_inner_svalue"));
    1895            0 : }
    1896              : 
    1897              : /* Implementation of svalue::accept vfunc for repeated_svalue.  */
    1898              : 
    1899              : void
    1900        45188 : repeated_svalue::accept (visitor *v) const
    1901              : {
    1902        45188 :   m_inner_svalue->accept (v);
    1903        45188 :   v->visit_repeated_svalue (this);
    1904        45188 : }
    1905              : 
    1906              : /* Implementation of svalue::all_zeroes_p for repeated_svalue.  */
    1907              : 
    1908              : bool
    1909         1925 : repeated_svalue::all_zeroes_p () const
    1910              : {
    1911         1925 :   return m_inner_svalue->all_zeroes_p ();
    1912              : }
    1913              : 
    1914              : /* Implementation of svalue::maybe_fold_bits_within vfunc
    1915              :    for repeated_svalue.  */
    1916              : 
    1917              : const svalue *
    1918         1625 : repeated_svalue::maybe_fold_bits_within (tree type,
    1919              :                                          const bit_range &bits,
    1920              :                                          region_model_manager *mgr) const
    1921              : {
    1922         1625 :   const svalue *innermost_sval = m_inner_svalue;
    1923              :   /* Fold
    1924              :        BITS_WITHIN (range, REPEATED_SVALUE (ZERO))
    1925              :      to:
    1926              :        REPEATED_SVALUE (ZERO).  */
    1927         1625 :   if (all_zeroes_p ())
    1928              :     {
    1929         1313 :       byte_range bytes (0,0);
    1930         1313 :       if (bits.as_byte_range (&bytes))
    1931              :         {
    1932         1313 :           const svalue *byte_size
    1933         1313 :             = mgr->get_or_create_int_cst (size_type_node,
    1934         1313 :                                           bytes.m_size_in_bytes.to_uhwi ());
    1935         1313 :           return mgr->get_or_create_repeated_svalue (type, byte_size,
    1936         1313 :                                                      innermost_sval);
    1937              :         }
    1938              :     }
    1939              : 
    1940              :   /* Fold:
    1941              :        BITS_WITHIN (range, REPEATED_SVALUE (INNERMOST_SVALUE))
    1942              :      to:
    1943              :        BITS_WITHIN (range - offset, INNERMOST_SVALUE)
    1944              :      if range is fully within one instance of INNERMOST_SVALUE.  */
    1945          312 :   if (tree innermost_type = innermost_sval->get_type ())
    1946              :     {
    1947          312 :       bit_size_t element_bit_size;
    1948          312 :       if (int_size_in_bits (innermost_type, &element_bit_size)
    1949          312 :           && element_bit_size > 0)
    1950              :         {
    1951          312 :           HOST_WIDE_INT start_idx
    1952          312 :             = (bits.get_start_bit_offset ()
    1953          312 :                / element_bit_size).to_shwi ();
    1954          312 :           HOST_WIDE_INT last_idx
    1955          312 :             = (bits.get_last_bit_offset ()
    1956          312 :                / element_bit_size).to_shwi ();
    1957          312 :           if (start_idx == last_idx)
    1958              :             {
    1959          288 :               bit_offset_t start_of_element
    1960          288 :                 = start_idx * element_bit_size;
    1961          288 :               bit_range range_within_element
    1962          288 :                 (bits.m_start_bit_offset - start_of_element,
    1963          288 :                  bits.m_size_in_bits);
    1964          288 :               return mgr->get_or_create_bits_within (type,
    1965              :                                                      range_within_element,
    1966              :                                                      innermost_sval);
    1967              :             }
    1968              :         }
    1969              :     }
    1970              : 
    1971              :   return nullptr;
    1972              : }
    1973              : 
    1974              : /* class bits_within_svalue : public svalue.  */
    1975              : 
    1976              : /* bits_within_svalue'c ctor.  */
    1977              : 
    1978          763 : bits_within_svalue::bits_within_svalue (symbol::id_t id,
    1979              :                                         tree type,
    1980              :                                         const bit_range &bits,
    1981          763 :                                         const svalue *inner_svalue)
    1982          763 : : svalue (complexity (inner_svalue), id, type),
    1983          763 :   m_bits (bits),
    1984          763 :   m_inner_svalue (inner_svalue)
    1985              : {
    1986          763 :   gcc_assert (inner_svalue->can_have_associated_state_p ());
    1987          763 : }
    1988              : 
    1989              : /* Implementation of svalue::dump_to_pp vfunc for bits_within_svalue.  */
    1990              : 
    1991              : void
    1992          610 : bits_within_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
    1993              : {
    1994          610 :   if (simple)
    1995              :     {
    1996          504 :       pp_string (pp, "BITS_WITHIN(");
    1997          504 :       if (get_type ())
    1998              :         {
    1999            0 :           print_quoted_type (pp, get_type ());
    2000            0 :           pp_string (pp, ", ");
    2001              :         }
    2002          504 :       m_bits.dump_to_pp (pp);
    2003          504 :       pp_string (pp, ", inner_val: ");
    2004          504 :       m_inner_svalue->dump_to_pp (pp, simple);
    2005          504 :       pp_character (pp, ')');
    2006              :     }
    2007              :   else
    2008              :     {
    2009          106 :       pp_string (pp, "bits_within_svalue (");
    2010          106 :       if (get_type ())
    2011              :         {
    2012            0 :           print_quoted_type (pp, get_type ());
    2013            0 :           pp_string (pp, ", ");
    2014              :         }
    2015          106 :       m_bits.dump_to_pp (pp);
    2016          106 :       pp_string (pp, ", inner_val: ");
    2017          106 :       m_inner_svalue->dump_to_pp (pp, simple);
    2018          106 :       pp_character (pp, ')');
    2019              :     }
    2020          610 : }
    2021              : 
    2022              : /* Implementation of svalue::print_dump_widget_label vfunc for
    2023              :    bits_within_svalue.  */
    2024              : 
    2025              : void
    2026            0 : bits_within_svalue::print_dump_widget_label (pretty_printer *pp) const
    2027              : {
    2028            0 :   pp_printf (pp, "bits_within_svalue: ");
    2029            0 :   m_bits.dump_to_pp (pp);
    2030            0 : }
    2031              : 
    2032              : /* Implementation of svalue::add_dump_widget_children vfunc for
    2033              :    bits_within_svalue.  */
    2034              : 
    2035              : void
    2036            0 : bits_within_svalue::
    2037              : add_dump_widget_children (text_art::tree_widget &w,
    2038              :                           const text_art::dump_widget_info &dwi) const
    2039              : {
    2040            0 :   w.add_child (m_inner_svalue->make_dump_widget (dwi, "m_inner_svalue"));
    2041            0 : }
    2042              : 
    2043              : /* Implementation of svalue::maybe_fold_bits_within vfunc
    2044              :    for bits_within_svalue.  */
    2045              : 
    2046              : const svalue *
    2047          777 : bits_within_svalue::maybe_fold_bits_within (tree type,
    2048              :                                             const bit_range &bits,
    2049              :                                             region_model_manager *mgr) const
    2050              : {
    2051              :   /* Fold:
    2052              :        BITS_WITHIN (range1, BITS_WITHIN (range2, VAL))
    2053              :      to:
    2054              :        BITS_WITHIN (range1 in range 2, VAL).  */
    2055         1554 :   bit_range offset_bits (m_bits.get_start_bit_offset ()
    2056          777 :                          + bits.m_start_bit_offset,
    2057          777 :                          bits.m_size_in_bits);
    2058          777 :   return mgr->get_or_create_bits_within (type, offset_bits, m_inner_svalue);
    2059              : }
    2060              : 
    2061              : /* Implementation of svalue::accept vfunc for bits_within_svalue.  */
    2062              : 
    2063              : void
    2064        49232 : bits_within_svalue::accept (visitor *v) const
    2065              : {
    2066        49232 :   m_inner_svalue->accept (v);
    2067        49232 :   v->visit_bits_within_svalue (this);
    2068        49232 : }
    2069              : 
    2070              : /* Implementation of svalue::implicitly_live_p vfunc for bits_within_svalue.  */
    2071              : 
    2072              : bool
    2073          695 : bits_within_svalue::implicitly_live_p (const svalue_set *live_svalues,
    2074              :                                        const region_model *model) const
    2075              : {
    2076          695 :   return m_inner_svalue->live_p (live_svalues, model);
    2077              : }
    2078              : 
    2079              : /* class widening_svalue : public svalue.  */
    2080              : 
    2081              : /* Implementation of svalue::dump_to_pp vfunc for widening_svalue.  */
    2082              : 
    2083              : void
    2084         3901 : widening_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
    2085              : {
    2086         3901 :   if (simple)
    2087              :     {
    2088         3677 :       pp_string (pp, "WIDENING(");
    2089         3677 :       pp_character (pp, '{');
    2090         3677 :       m_snode->print (pp);
    2091         3677 :       pp_string (pp, "}, ");
    2092         3677 :       m_base_sval->dump_to_pp (pp, simple);
    2093         3677 :       pp_string (pp, ", ");
    2094         3677 :       m_iter_sval->dump_to_pp (pp, simple);
    2095         3677 :       pp_character (pp, ')');
    2096              :     }
    2097              :   else
    2098              :     {
    2099          224 :       pp_string (pp, "widening_svalue (");
    2100          224 :       pp_string (pp, ", ");
    2101          224 :       pp_character (pp, '{');
    2102          224 :       m_snode->print (pp);
    2103          224 :       pp_string (pp, "}, ");
    2104          224 :       m_base_sval->dump_to_pp (pp, simple);
    2105          224 :       pp_string (pp, ", ");
    2106          224 :       m_iter_sval->dump_to_pp (pp, simple);
    2107          224 :       pp_character (pp, ')');
    2108              :     }
    2109         3901 : }
    2110              : 
    2111              : /* Implementation of svalue::print_dump_widget_label vfunc for
    2112              :    widening_svalue.  */
    2113              : 
    2114              : void
    2115            0 : widening_svalue::print_dump_widget_label (pretty_printer *pp) const
    2116              : {
    2117            0 :   pp_printf (pp, "widening_svalue at ");
    2118            0 :   m_snode->print (pp);
    2119            0 : }
    2120              : 
    2121              : /* Implementation of svalue::add_dump_widget_children vfunc for
    2122              :    widening_svalue.  */
    2123              : 
    2124              : void
    2125            0 : widening_svalue::
    2126              : add_dump_widget_children (text_art::tree_widget &w,
    2127              :                           const text_art::dump_widget_info &dwi) const
    2128              : {
    2129            0 :   w.add_child (m_base_sval->make_dump_widget (dwi, "m_base_sval"));
    2130            0 :   w.add_child (m_iter_sval->make_dump_widget (dwi, "m_iter_sval"));
    2131            0 : }
    2132              : 
    2133              : /* Implementation of svalue::accept vfunc for widening_svalue.  */
    2134              : 
    2135              : void
    2136       116984 : widening_svalue::accept (visitor *v) const
    2137              : {
    2138       116984 :   m_base_sval->accept (v);
    2139       116984 :   m_iter_sval->accept (v);
    2140       116984 :   v->visit_widening_svalue (this);
    2141       116984 : }
    2142              : 
    2143              : /* Attempt to determine in which direction this value is changing
    2144              :    w.r.t. the initial value.  */
    2145              : 
    2146              : enum widening_svalue::direction_t
    2147         1922 : widening_svalue::get_direction () const
    2148              : {
    2149         1922 :   tree base_cst = m_base_sval->maybe_get_constant ();
    2150         1922 :   if (base_cst == NULL_TREE)
    2151              :     return DIR_UNKNOWN;
    2152         1922 :   tree iter_cst = m_iter_sval->maybe_get_constant ();
    2153         1922 :   if (iter_cst == NULL_TREE)
    2154              :     return DIR_UNKNOWN;
    2155              : 
    2156         1922 :   tree iter_gt_base = fold_binary (GT_EXPR, boolean_type_node,
    2157              :                                    iter_cst, base_cst);
    2158         1922 :   if (iter_gt_base == boolean_true_node)
    2159              :     return DIR_ASCENDING;
    2160              : 
    2161          489 :   tree iter_lt_base = fold_binary (LT_EXPR, boolean_type_node,
    2162              :                                    iter_cst, base_cst);
    2163          489 :   if (iter_lt_base == boolean_true_node)
    2164              :     return DIR_DESCENDING;
    2165              : 
    2166              :   return DIR_UNKNOWN;
    2167              : }
    2168              : 
    2169              : /* Compare this value against constant RHS_CST.  */
    2170              : 
    2171              : tristate
    2172         2934 : widening_svalue::eval_condition_without_cm (enum tree_code op,
    2173              :                                             tree rhs_cst) const
    2174              : {
    2175         2934 :   tree base_cst = m_base_sval->maybe_get_constant ();
    2176         2934 :   if (base_cst == NULL_TREE)
    2177         1020 :     return tristate::TS_UNKNOWN;
    2178         1914 :   tree iter_cst = m_iter_sval->maybe_get_constant ();
    2179         1914 :   if (iter_cst == NULL_TREE)
    2180            0 :     return tristate::TS_UNKNOWN;
    2181              : 
    2182         1914 :   switch (get_direction ())
    2183              :     {
    2184            0 :     default:
    2185            0 :       gcc_unreachable ();
    2186         1425 :     case DIR_ASCENDING:
    2187              :       /* LHS is in [base_cst, +ve infinity), assuming no overflow.  */
    2188         1425 :       switch (op)
    2189              :         {
    2190          281 :         case LE_EXPR:
    2191          281 :         case LT_EXPR:
    2192          281 :           {
    2193              :             /* [BASE, +INF) OP RHS:
    2194              :                This is either true or false at +ve ininity,
    2195              :                It can be true for points X where X OP RHS, so we have either
    2196              :                "false", or "unknown".  */
    2197          281 :             tree base_op_rhs = fold_binary (op, boolean_type_node,
    2198              :                                             base_cst, rhs_cst);
    2199          281 :             if (base_op_rhs == boolean_true_node)
    2200          265 :               return tristate::TS_UNKNOWN;
    2201              :             else
    2202           16 :               return tristate::TS_FALSE;
    2203              :           }
    2204              : 
    2205          804 :         case GE_EXPR:
    2206          804 :         case GT_EXPR:
    2207          804 :           {
    2208              :             /* [BASE, +INF) OP RHS:
    2209              :                This is true at +ve infinity.  It will be true everywhere
    2210              :                in the range if BASE >= RHS.  */
    2211          804 :             tree base_op_rhs = fold_binary (op, boolean_type_node,
    2212              :                                             base_cst, rhs_cst);
    2213          804 :             if (base_op_rhs == boolean_true_node)
    2214           61 :               return tristate::TS_TRUE;
    2215              :             else
    2216          743 :               return tristate::TS_UNKNOWN;
    2217              :           }
    2218              : 
    2219          168 :         case EQ_EXPR:
    2220          168 :           {
    2221              :             /* [BASE, +INF) == RHS:
    2222              :                Could this be true at any point in the range?  If so we
    2223              :                have "unknown", otherwise we have "false".  */
    2224          168 :             tree base_le_rhs = fold_binary (LE_EXPR, boolean_type_node,
    2225              :                                             base_cst, rhs_cst);
    2226          168 :             if (base_le_rhs == boolean_true_node)
    2227          158 :               return tristate::TS_UNKNOWN;
    2228              :             else
    2229           10 :               return tristate::TS_FALSE;
    2230              :           }
    2231              : 
    2232          172 :         case NE_EXPR:
    2233          172 :           {
    2234              :             /* [BASE, +INF) != RHS:
    2235              :                Could we have equality at any point in the range?  If so we
    2236              :                have "unknown", otherwise we have "true".  */
    2237          172 :             tree base_le_rhs = fold_binary (LE_EXPR, boolean_type_node,
    2238              :                                             base_cst, rhs_cst);
    2239          172 :             if (base_le_rhs == boolean_true_node)
    2240          162 :               return tristate::TS_UNKNOWN;
    2241              :             else
    2242           10 :               return tristate::TS_TRUE;
    2243              :           }
    2244              : 
    2245            0 :         default:
    2246            0 :           return tristate::TS_UNKNOWN;
    2247              :         }
    2248              : 
    2249          447 :     case DIR_DESCENDING:
    2250              :       /* LHS is in (-ve infinity, base_cst], assuming no overflow.  */
    2251          447 :       return tristate::TS_UNKNOWN;
    2252              : 
    2253           42 :     case DIR_UNKNOWN:
    2254           42 :       return tristate::TS_UNKNOWN;
    2255              :     }
    2256              : }
    2257              : 
    2258              : /* class placeholder_svalue : public svalue.  */
    2259              : 
    2260              : /* Implementation of svalue::dump_to_pp vfunc for placeholder_svalue.  */
    2261              : 
    2262              : void
    2263            0 : placeholder_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
    2264              : {
    2265            0 :   if (simple)
    2266            0 :     pp_printf (pp, "PLACEHOLDER(%qs)", m_name);
    2267              :   else
    2268            0 :     pp_printf (pp, "placeholder_svalue (%qs)", m_name);
    2269            0 : }
    2270              : 
    2271              : /* Implementation of svalue::print_dump_widget_label vfunc for
    2272              :    placeholder_svalue.  */
    2273              : 
    2274              : void
    2275            0 : placeholder_svalue::print_dump_widget_label (pretty_printer *pp) const
    2276              : {
    2277            0 :   pp_printf (pp, "placeholder_svalue: %qs", m_name);
    2278            0 : }
    2279              : 
    2280              : /* Implementation of svalue::add_dump_widget_children vfunc for
    2281              :    placeholder_svalue.  */
    2282              : 
    2283              : void
    2284            0 : placeholder_svalue::
    2285              : add_dump_widget_children (text_art::tree_widget &,
    2286              :                           const text_art::dump_widget_info &) const
    2287              : {
    2288              :   /* No children.  */
    2289            0 : }
    2290              : 
    2291              : /* Implementation of svalue::accept vfunc for placeholder_svalue.  */
    2292              : 
    2293              : void
    2294        38169 : placeholder_svalue::accept (visitor *v) const
    2295              : {
    2296        38169 :   v->visit_placeholder_svalue (this);
    2297        38169 : }
    2298              : 
    2299              : /* class unmergeable_svalue : public svalue.  */
    2300              : 
    2301              : /* Implementation of svalue::dump_to_pp vfunc for unmergeable_svalue.  */
    2302              : 
    2303              : void
    2304           20 : unmergeable_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
    2305              : {
    2306           20 :   if (simple)
    2307              :     {
    2308           20 :       pp_string (pp, "UNMERGEABLE(");
    2309           20 :       m_arg->dump_to_pp (pp, simple);
    2310           20 :       pp_character (pp, ')');
    2311              :     }
    2312              :   else
    2313              :     {
    2314            0 :       pp_string (pp, "unmergeable_svalue (");
    2315            0 :       m_arg->dump_to_pp (pp, simple);
    2316            0 :       pp_character (pp, ')');
    2317              :     }
    2318           20 : }
    2319              : 
    2320              : /* Implementation of svalue::print_dump_widget_label vfunc for
    2321              :    unmergeable_svalue.  */
    2322              : 
    2323              : void
    2324            0 : unmergeable_svalue::print_dump_widget_label (pretty_printer *pp) const
    2325              : {
    2326            0 :   pp_printf (pp, "unmergeable_svalue");
    2327            0 : }
    2328              : 
    2329              : /* Implementation of svalue::add_dump_widget_children vfunc for
    2330              :    unmergeable_svalue.  */
    2331              : 
    2332              : void
    2333            0 : unmergeable_svalue::
    2334              : add_dump_widget_children (text_art::tree_widget &w,
    2335              :                           const text_art::dump_widget_info &dwi) const
    2336              : {
    2337            0 :   w.add_child (m_arg->make_dump_widget (dwi));
    2338            0 : }
    2339              : 
    2340              : /* Implementation of svalue::accept vfunc for unmergeable_svalue.  */
    2341              : 
    2342              : void
    2343         6752 : unmergeable_svalue::accept (visitor *v) const
    2344              : {
    2345         6752 :   m_arg->accept (v);
    2346         6752 :   v->visit_unmergeable_svalue (this);
    2347         6752 : }
    2348              : 
    2349              : /* Implementation of svalue::implicitly_live_p vfunc for unmergeable_svalue.  */
    2350              : 
    2351              : bool
    2352          894 : unmergeable_svalue::implicitly_live_p (const svalue_set *live_svalues,
    2353              :                                        const region_model *model) const
    2354              : {
    2355          894 :   return get_arg ()->live_p (live_svalues, model);
    2356              : }
    2357              : 
    2358              : /* class compound_svalue : public svalue.  */
    2359              : 
    2360          562 : compound_svalue::compound_svalue (symbol::id_t id,
    2361              :                                   tree type,
    2362          562 :                                   concrete_binding_map &&map)
    2363          562 : : svalue (map.calc_complexity (), id, type), m_map (std::move (map))
    2364              : {
    2365              : #if CHECKING_P
    2366         2374 :   for (auto iter : *this)
    2367              :     {
    2368              :       /* We don't nest compound svalues.  */
    2369         1812 :       const svalue *sval = iter.second;
    2370         1812 :       gcc_assert (sval->get_kind () != SK_COMPOUND);
    2371              :     }
    2372              : #endif
    2373          562 : }
    2374              : 
    2375           50 : compound_svalue::compound_svalue (symbol::id_t id,
    2376              :                                   tree type,
    2377           50 :                                   const concrete_binding_map &map)
    2378           50 : : svalue (map.calc_complexity (), id, type), m_map (map)
    2379              : {
    2380              : #if CHECKING_P
    2381          122 :   for (auto iter : *this)
    2382              :     {
    2383              :       /* We don't nest compound svalues.  */
    2384           72 :       const svalue *sval = iter.second;
    2385           72 :       gcc_assert (sval->get_kind () != SK_COMPOUND);
    2386              :     }
    2387              : #endif
    2388           50 : }
    2389              : 
    2390              : /* Implementation of svalue::dump_to_pp vfunc for compound_svalue.  */
    2391              : 
    2392              : void
    2393            2 : compound_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
    2394              : {
    2395            2 :   if (simple)
    2396              :     {
    2397            2 :       pp_string (pp, "COMPOUND(");
    2398            2 :       if (get_type ())
    2399              :         {
    2400            0 :           print_quoted_type (pp, get_type ());
    2401            0 :           pp_string (pp, ", ");
    2402              :         }
    2403            2 :       pp_character (pp, '{');
    2404            2 :       m_map.dump_to_pp (pp, simple, false);
    2405            2 :       pp_string (pp, "})");
    2406              :     }
    2407              :   else
    2408              :     {
    2409            0 :       pp_string (pp, "compound_svalue (");
    2410            0 :       if (get_type ())
    2411              :         {
    2412            0 :           print_quoted_type (pp, get_type ());
    2413            0 :           pp_string (pp, ", ");
    2414              :         }
    2415            0 :       pp_character (pp, '{');
    2416            0 :       m_map.dump_to_pp (pp, simple, false);
    2417            0 :       pp_string (pp, "})");
    2418              :     }
    2419            2 : }
    2420              : 
    2421              : /* Implementation of svalue::print_dump_widget_label vfunc for
    2422              :    compound_svalue.  */
    2423              : 
    2424              : void
    2425            0 : compound_svalue::print_dump_widget_label (pretty_printer *pp) const
    2426              : {
    2427            0 :   pp_printf (pp, "compound_svalue");
    2428            0 : }
    2429              : 
    2430              : /* Implementation of svalue::add_dump_widget_children vfunc for
    2431              :    compound_svalue.  */
    2432              : 
    2433              : void
    2434            0 : compound_svalue::
    2435              : add_dump_widget_children (text_art::tree_widget &w,
    2436              :                           const text_art::dump_widget_info &dwi) const
    2437              : {
    2438            0 :   m_map.add_to_tree_widget (w, dwi);
    2439            0 : }
    2440              : 
    2441              : /* Implementation of svalue::accept vfunc for compound_svalue.  */
    2442              : 
    2443              : void
    2444           38 : compound_svalue::accept (visitor *v) const
    2445              : {
    2446          114 :   for (auto iter : m_map)
    2447           76 :     iter.second->accept (v);
    2448           38 :   v->visit_compound_svalue (this);
    2449           38 : }
    2450              : 
    2451              : /* Implementation of svalue::maybe_fold_bits_within vfunc
    2452              :    for compound_svalue.  */
    2453              : 
    2454              : const svalue *
    2455           56 : compound_svalue::maybe_fold_bits_within (tree type,
    2456              :                                          const bit_range &bits,
    2457              :                                          region_model_manager *mgr) const
    2458              : {
    2459           56 :   concrete_binding_map result_map;
    2460          256 :   for (auto iter : m_map)
    2461              :     {
    2462          200 :       const bit_range &iter_bits = iter.first;
    2463              : 
    2464              :       /* Ignore concrete bindings outside BITS.  */
    2465          200 :       if (!iter_bits.intersects_p (bits))
    2466           28 :         continue;
    2467              : 
    2468          172 :       const svalue *sval = iter.second;
    2469              :       /* Get the position of iter_bits relative to BITS.  */
    2470          172 :       bit_range result_location (iter_bits.get_start_bit_offset ()
    2471          172 :                                  - bits.get_start_bit_offset (),
    2472          172 :                                  iter_bits.m_size_in_bits);
    2473              :       /* If iter_bits starts after BITS, trim off leading bits
    2474              :          from the svalue and adjust binding location.  */
    2475          172 :       if (result_location.m_start_bit_offset < 0)
    2476              :         {
    2477            0 :           bit_size_t leading_bits_to_drop
    2478            0 :             = -result_location.m_start_bit_offset;
    2479            0 :           result_location = bit_range
    2480            0 :             (0, result_location.m_size_in_bits - leading_bits_to_drop);
    2481            0 :           bit_range bits_within_sval (leading_bits_to_drop,
    2482            0 :                                       result_location.m_size_in_bits);
    2483              :           /* Trim off leading bits from iter_sval.  */
    2484            0 :           sval = mgr->get_or_create_bits_within (NULL_TREE,
    2485              :                                                  bits_within_sval,
    2486              :                                                  sval);
    2487              :         }
    2488              :       /* If iter_bits finishes after BITS, trim off trailing bits
    2489              :          from the svalue and adjust binding location.  */
    2490          344 :       if (iter_bits.get_next_bit_offset ()
    2491          344 :           > bits.get_next_bit_offset ())
    2492              :         {
    2493           44 :           bit_size_t trailing_bits_to_drop
    2494           44 :             = (iter_bits.get_next_bit_offset ()
    2495           44 :                - bits.get_next_bit_offset ());
    2496           44 :           result_location = bit_range
    2497              :             (result_location.m_start_bit_offset,
    2498           44 :              result_location.m_size_in_bits - trailing_bits_to_drop);
    2499           44 :           bit_range bits_within_sval (0,
    2500           44 :                                       result_location.m_size_in_bits);
    2501              :           /* Trim off leading bits from iter_sval.  */
    2502           44 :           sval = mgr->get_or_create_bits_within (NULL_TREE,
    2503              :                                                  bits_within_sval,
    2504              :                                                  sval);
    2505              :         }
    2506          172 :       result_map.insert (result_location, sval);
    2507              :     }
    2508           56 :   return mgr->get_or_create_compound_svalue (type, std::move (result_map));
    2509           56 : }
    2510              : 
    2511              : /* class conjured_svalue : public svalue.  */
    2512              : 
    2513              : /* Implementation of svalue::dump_to_pp vfunc for conjured_svalue.  */
    2514              : 
    2515              : void
    2516         3194 : conjured_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
    2517              : {
    2518         3194 :   if (simple)
    2519              :     {
    2520         2804 :       pp_string (pp, "CONJURED(");
    2521         2804 :       pp_gimple_stmt_1 (pp, m_stmt, 0, (dump_flags_t)0);
    2522         2804 :       pp_string (pp, ", ");
    2523         2804 :       m_id_reg->dump_to_pp (pp, simple);
    2524         2804 :       pp_character (pp, ')');
    2525              :     }
    2526              :   else
    2527              :     {
    2528          390 :       pp_string (pp, "conjured_svalue (");
    2529          390 :       if (get_type ())
    2530              :         {
    2531          390 :           print_quoted_type (pp, get_type ());
    2532          390 :           pp_string (pp, ", ");
    2533              :         }
    2534          390 :       pp_gimple_stmt_1 (pp, m_stmt, 0, (dump_flags_t)0);
    2535          390 :       pp_string (pp, ", ");
    2536          390 :       m_id_reg->dump_to_pp (pp, simple);
    2537          390 :       pp_character (pp, ')');
    2538              :     }
    2539         3194 : }
    2540              : 
    2541              : /* Implementation of svalue::print_dump_widget_label vfunc for
    2542              :    conjured_svalue.  */
    2543              : 
    2544              : void
    2545            0 : conjured_svalue::print_dump_widget_label (pretty_printer *pp) const
    2546              : {
    2547            0 :   pp_printf (pp, "conjured_svalue (");
    2548            0 :   pp_gimple_stmt_1 (pp, m_stmt, 0, (dump_flags_t)0);
    2549            0 :   if (m_idx != 0)
    2550            0 :     pp_printf (pp, ", %i", m_idx);
    2551            0 :   pp_character (pp, ')');
    2552            0 : }
    2553              : 
    2554              : /* Implementation of svalue::add_dump_widget_children vfunc for
    2555              :    conjured_svalue.  */
    2556              : 
    2557              : void
    2558            0 : conjured_svalue::
    2559              : add_dump_widget_children (text_art::tree_widget &w,
    2560              :                           const text_art::dump_widget_info &dwi) const
    2561              : {
    2562            0 :   w.add_child (m_id_reg->make_dump_widget (dwi));
    2563            0 : }
    2564              : 
    2565              : /* Implementation of svalue::accept vfunc for conjured_svalue.  */
    2566              : 
    2567              : void
    2568      5303000 : conjured_svalue::accept (visitor *v) const
    2569              : {
    2570      5303000 :   m_id_reg->accept (v);
    2571      5303000 :   v->visit_conjured_svalue (this);
    2572      5303000 : }
    2573              : 
    2574              : /* Return true iff this conjured_svalue is for the LHS of the
    2575              :    stmt that conjured it.  */
    2576              : 
    2577              : bool
    2578            0 : conjured_svalue::lhs_value_p () const
    2579              : {
    2580            0 :   if (tree decl = m_id_reg->maybe_get_decl ())
    2581            0 :     return decl == gimple_get_lhs (m_stmt);
    2582              :   return false;
    2583              : }
    2584              : 
    2585              : /* class asm_output_svalue : public svalue.  */
    2586              : 
    2587              : /* Implementation of svalue::dump_to_pp vfunc for asm_output_svalue.  */
    2588              : 
    2589              : void
    2590           52 : asm_output_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
    2591              : {
    2592           52 :   if (simple)
    2593              :     {
    2594           52 :       pp_printf (pp, "ASM_OUTPUT(%qs, %%%i, {",
    2595              :                  get_asm_string (),
    2596              :                  get_output_idx ());
    2597          144 :       for (unsigned i = 0; i < m_num_inputs; i++)
    2598              :         {
    2599           92 :           if (i > 0)
    2600           40 :             pp_string (pp, ", ");
    2601           92 :           dump_input (pp, 0, m_input_arr[i], simple);
    2602              :         }
    2603           52 :       pp_string (pp, "})");
    2604              :     }
    2605              :   else
    2606              :     {
    2607            0 :       pp_printf (pp, "asm_output_svalue (%qs, %%%i, {",
    2608              :                  get_asm_string (),
    2609              :                  get_output_idx ());
    2610            0 :       for (unsigned i = 0; i < m_num_inputs; i++)
    2611              :         {
    2612            0 :           if (i > 0)
    2613            0 :             pp_string (pp, ", ");
    2614            0 :           dump_input (pp, 0, m_input_arr[i], simple);
    2615              :         }
    2616            0 :       pp_string (pp, "})");
    2617              :     }
    2618           52 : }
    2619              : 
    2620              : /* Implementation of svalue::print_dump_widget_label vfunc for
    2621              :    asm_output_svalue.  */
    2622              : 
    2623              : void
    2624            0 : asm_output_svalue::print_dump_widget_label (pretty_printer *pp) const
    2625              : {
    2626            0 :   pp_printf (pp, "asm_output_svalue(%qs, %%%i)",
    2627              :              get_asm_string (),
    2628              :              get_output_idx ());
    2629            0 : }
    2630              : 
    2631              : /* Implementation of svalue::add_dump_widget_children vfunc for
    2632              :    asm_output_svalue.  */
    2633              : 
    2634              : void
    2635            0 : asm_output_svalue::
    2636              : add_dump_widget_children (text_art::tree_widget &w,
    2637              :                           const text_art::dump_widget_info &dwi) const
    2638              : {
    2639            0 :   for (unsigned i = 0; i < m_num_inputs; i++)
    2640              :     {
    2641            0 :       pretty_printer pp;
    2642            0 :       pp_printf (&pp, "arg %i", i);
    2643            0 :       w.add_child (m_input_arr[i]->make_dump_widget (dwi,
    2644              :                                                      pp_formatted_text (&pp)));
    2645            0 :     }
    2646            0 : }
    2647              : 
    2648              : /* Subroutine of asm_output_svalue::dump_to_pp.  */
    2649              : 
    2650              : void
    2651           92 : asm_output_svalue::dump_input (pretty_printer *pp,
    2652              :                                unsigned input_idx,
    2653              :                                const svalue *sval,
    2654              :                                bool simple) const
    2655              : {
    2656           92 :   pp_printf (pp, "%%%i: ", input_idx_to_asm_idx (input_idx));
    2657           92 :   sval->dump_to_pp (pp, simple);
    2658           92 : }
    2659              : 
    2660              : /* Convert INPUT_IDX from an index into the array of inputs
    2661              :    into the index of all operands for the asm stmt.  */
    2662              : 
    2663              : unsigned
    2664           92 : asm_output_svalue::input_idx_to_asm_idx (unsigned input_idx) const
    2665              : {
    2666           92 :   return input_idx + m_num_outputs;
    2667              : }
    2668              : 
    2669              : /* Implementation of svalue::accept vfunc for asm_output_svalue.  */
    2670              : 
    2671              : void
    2672         6099 : asm_output_svalue::accept (visitor *v) const
    2673              : {
    2674        16803 :   for (unsigned i = 0; i < m_num_inputs; i++)
    2675        10704 :     m_input_arr[i]->accept (v);
    2676         6099 :   v->visit_asm_output_svalue (this);
    2677         6099 : }
    2678              : 
    2679              : /* class const_fn_result_svalue : public svalue.  */
    2680              : 
    2681              : /* Implementation of svalue::dump_to_pp vfunc for const_fn_result_svalue.  */
    2682              : 
    2683              : void
    2684         4391 : const_fn_result_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
    2685              : {
    2686         4391 :   if (simple)
    2687              :     {
    2688         3945 :       pp_printf (pp, "CONST_FN_RESULT(%qD, {", m_fndecl);
    2689         3993 :       for (unsigned i = 0; i < m_num_inputs; i++)
    2690              :         {
    2691           48 :           if (i > 0)
    2692            0 :             pp_string (pp, ", ");
    2693           48 :           dump_input (pp, i, m_input_arr[i], simple);
    2694              :         }
    2695         3945 :       pp_string (pp, "})");
    2696              :     }
    2697              :   else
    2698              :     {
    2699          446 :       pp_printf (pp, "CONST_FN_RESULT(%qD, {", m_fndecl);
    2700          446 :       for (unsigned i = 0; i < m_num_inputs; i++)
    2701              :         {
    2702            0 :           if (i > 0)
    2703            0 :             pp_string (pp, ", ");
    2704            0 :           dump_input (pp, i, m_input_arr[i], simple);
    2705              :         }
    2706          446 :       pp_string (pp, "})");
    2707              :     }
    2708         4391 : }
    2709              : 
    2710              : /* Implementation of svalue::print_dump_widget_label vfunc for
    2711              :    const_fn_result_svalue.  */
    2712              : 
    2713              : void
    2714            0 : const_fn_result_svalue::print_dump_widget_label (pretty_printer *pp) const
    2715              : {
    2716            0 :   pp_printf (pp, "const_fn_result_svalue: %qD", m_fndecl);
    2717            0 : }
    2718              : 
    2719              : /* Implementation of svalue::add_dump_widget_children vfunc for
    2720              :    const_fn_result_svalue.  */
    2721              : 
    2722              : void
    2723            0 : const_fn_result_svalue::
    2724              : add_dump_widget_children (text_art::tree_widget &w,
    2725              :                           const text_art::dump_widget_info &dwi) const
    2726              : {
    2727            0 :   for (unsigned i = 0; i < m_num_inputs; i++)
    2728              :     {
    2729            0 :       pretty_printer pp;
    2730            0 :       pp_printf (&pp, "arg %i", i);
    2731            0 :       w.add_child (m_input_arr[i]->make_dump_widget (dwi,
    2732              :                                                      pp_formatted_text (&pp)));
    2733            0 :     }
    2734            0 : }
    2735              : 
    2736              : /* Subroutine of const_fn_result_svalue::dump_to_pp.  */
    2737              : 
    2738              : void
    2739           48 : const_fn_result_svalue::dump_input (pretty_printer *pp,
    2740              :                                     unsigned input_idx,
    2741              :                                     const svalue *sval,
    2742              :                                     bool simple) const
    2743              : {
    2744           48 :   pp_printf (pp, "arg%i: ", input_idx);
    2745           48 :   sval->dump_to_pp (pp, simple);
    2746           48 : }
    2747              : 
    2748              : /* Implementation of svalue::accept vfunc for const_fn_result_svalue.  */
    2749              : 
    2750              : void
    2751         8497 : const_fn_result_svalue::accept (visitor *v) const
    2752              : {
    2753        14306 :   for (unsigned i = 0; i < m_num_inputs; i++)
    2754         5809 :     m_input_arr[i]->accept (v);
    2755         8497 :   v->visit_const_fn_result_svalue (this);
    2756         8497 : }
    2757              : 
    2758              : } // namespace ana
    2759              : 
    2760              : #endif /* #if ENABLE_ANALYZER */
        

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.