LCOV - code coverage report
Current view: top level - gcc/analyzer - svalue.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 74.9 % 1169 876
Test Date: 2026-05-30 15:37:04 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     13996643 : svalue::maybe_get_constant () const
     251              : {
     252     13996643 :   const svalue *sval = unwrap_any_unmergeable ();
     253     13996643 :   if (const constant_svalue *cst_sval = sval->dyn_cast_constant_svalue ())
     254      4748509 :     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       393638 : svalue::maybe_get_region () const
     264              : {
     265       393638 :   if (const region_svalue *region_sval = dyn_cast_region_svalue ())
     266        38953 :     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     13246363 : svalue::maybe_undo_cast () const
     277              : {
     278     13246363 :   if (const unaryop_svalue *unaryop_sval = dyn_cast_unaryop_svalue ())
     279              :     {
     280       889440 :       enum tree_code op = unaryop_sval->get_op ();
     281       889440 :       if (op == NOP_EXPR || op == VIEW_CONVERT_EXPR)
     282       856174 :         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     17298515 : svalue::unwrap_any_unmergeable () const
     293              : {
     294     17298515 :   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       372862 : svalue::can_merge_p (const svalue *other,
     304              :                      region_model_manager *mgr,
     305              :                      model_merger *merger) const
     306              : {
     307       372862 :   if (!(get_type () && other->get_type ()))
     308              :     return nullptr;
     309              : 
     310       323588 :   if (!types_compatible_p (get_type (), other->get_type ()))
     311              :     return nullptr;
     312              : 
     313              :   /* Reject attempts to merge unmergeable svalues.  */
     314       302134 :   if ((get_kind () == SK_UNMERGEABLE)
     315       302134 :       || (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       299327 :   if (get_kind () == SK_POISONED
     322       299327 :       || other->get_kind () == SK_POISONED)
     323         1591 :     return nullptr;
     324              : 
     325              :   /* Reject attempts to merge NULL pointers with not-NULL-pointers.  */
     326       297736 :   if (POINTER_TYPE_P (get_type ()))
     327              :     {
     328        38411 :       bool null0 = false;
     329        38411 :       bool null1 = false;
     330        38411 :       if (tree cst0 = maybe_get_constant ())
     331         7910 :         if (zerop (cst0))
     332        38411 :           null0 = true;
     333        38411 :       if (tree cst1 = other->maybe_get_constant ())
     334         5321 :         if (zerop (cst1))
     335        38411 :           null1 = true;
     336        38411 :       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       284727 :   if (!merger->mergeable_svalue_p (this))
     344              :     return nullptr;
     345       283618 :   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       282920 :   if (auto this_region = maybe_get_region ())
     351         3851 :     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       282398 :   if (maybe_get_constant () && other->maybe_get_constant ())
     360         3614 :     return mgr->get_or_create_widening_svalue (other->get_type (),
     361              :                                                merger->get_supernode (),
     362         3614 :                                                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       278784 :   if (const binop_svalue *binop_sval = dyn_cast_binop_svalue ())
     369        11272 :     if (binop_sval->get_arg0 () == other
     370         1672 :         && binop_sval->get_arg1 ()->get_kind () == SK_CONSTANT
     371        12801 :         && other->get_kind () != SK_WIDENING)
     372          686 :       return mgr->get_or_create_widening_svalue (other->get_type (),
     373              :                                                  merger->get_supernode (),
     374          686 :                                                  other, this);
     375              : 
     376              :   /* Merge: (Widen(existing_val, V), existing_val) -> Widen (existing_val, V)
     377              :      and thus get a fixed point.  */
     378       278098 :   if (const widening_svalue *widen_sval = dyn_cast_widening_svalue ())
     379              :     {
     380         8037 :       if (other == widen_sval->get_base_svalue ())
     381              :         return this;
     382         1707 :       if (other == widen_sval->get_iter_svalue ())
     383              :         return this;
     384              :     }
     385              : 
     386       270857 :   if (const binop_svalue *binop_sval = dyn_cast_binop_svalue ())
     387        10586 :     if (const widening_svalue *widen_arg0
     388        10586 :         = binop_sval->get_arg0 ()->dyn_cast_widening_svalue ())
     389              :       {
     390         3305 :         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         2445 :         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         1602 :         if (widen_arg0->get_iter_svalue () == other)
     418         1424 :           if (const binop_svalue *other_binop_sval
     419          712 :                 = other->dyn_cast_binop_svalue ())
     420          528 :             if (other_binop_sval->get_arg0 () == widen_arg0->get_base_svalue ()
     421          528 :                 && other_binop_sval->get_arg1 () == binop_sval->get_arg1 ())
     422              :               return widen_arg0;
     423              :       }
     424              : 
     425       268626 :   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     11201908 : svalue::live_p (const svalue_set *live_svalues,
     435              :                 const region_model *model) const
     436              : {
     437              :   /* Determine if SVAL is explicitly live.  */
     438     11201908 :   if (live_svalues)
     439     11200058 :     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      4798975 :   return implicitly_live_p (live_svalues, model);
     445              : }
     446              : 
     447              : /* Base implementation of svalue::implicitly_live_p.  */
     448              : 
     449              : bool
     450       191918 : svalue::implicitly_live_p (const svalue_set *, const region_model *) const
     451              : {
     452       191918 :   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      1540526 : cmp_csts_same_type (const_tree cst1, const_tree cst2)
     460              : {
     461      1540526 :   gcc_assert (TREE_TYPE (cst1) == TREE_TYPE (cst2));
     462      1540526 :   gcc_assert (TREE_CODE (cst1) == TREE_CODE (cst2));
     463      1540526 :   switch (TREE_CODE (cst1))
     464              :     {
     465            0 :     default:
     466            0 :       gcc_unreachable ();
     467      1540246 :     case INTEGER_CST:
     468      1540246 :       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      1540546 : cmp_csts_and_types (const_tree cst1, const_tree cst2)
     521              : {
     522      1540546 :   int t1 = TYPE_UID (TREE_TYPE (cst1));
     523      1540546 :   int t2 = TYPE_UID (TREE_TYPE (cst2));
     524      1540546 :   if (int cmp_type = t1 - t2)
     525              :     return cmp_type;
     526      1540526 :   return cmp_csts_same_type (cst1, cst2);
     527              : }
     528              : 
     529              : /* Comparator for imposing a deterministic order on svalues.  */
     530              : 
     531              : int
     532     44701166 : svalue::cmp_ptr (const svalue *sval1, const svalue *sval2)
     533              : {
     534     46132995 :   if (sval1 == sval2)
     535              :     return 0;
     536     44378824 :   if (int cmp_kind = sval1->get_kind () - sval2->get_kind ())
     537              :     return cmp_kind;
     538     16716835 :   int t1 = sval1->get_type () ? TYPE_UID (sval1->get_type ()) : -1;
     539     16716835 :   int t2 = sval2->get_type () ? TYPE_UID (sval2->get_type ()) : -1;
     540     16716835 :   if (int cmp_type = t1 - t2)
     541              :     return cmp_type;
     542     10554278 :   switch (sval1->get_kind ())
     543              :     {
     544            0 :     default:
     545            0 :       gcc_unreachable ();
     546       773084 :     case SK_REGION:
     547       773084 :       {
     548       773084 :         const region_svalue *region_sval1 = (const region_svalue *)sval1;
     549       773084 :         const region_svalue *region_sval2 = (const region_svalue *)sval2;
     550       773084 :         return region::cmp_ids (region_sval1->get_pointee (),
     551      1546168 :                                 region_sval2->get_pointee ());
     552              :       }
     553      1540458 :       break;
     554      1540458 :     case SK_CONSTANT:
     555      1540458 :       {
     556      1540458 :         const constant_svalue *constant_sval1 = (const constant_svalue *)sval1;
     557      1540458 :         const constant_svalue *constant_sval2 = (const constant_svalue *)sval2;
     558      1540458 :         const_tree cst1 = constant_sval1->get_constant ();
     559      1540458 :         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      1540458 :         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      2082684 :       break;
     588      2082684 :     case SK_INITIAL:
     589      2082684 :       {
     590      2082684 :         const initial_svalue *initial_sval1 = (const initial_svalue *)sval1;
     591      2082684 :         const initial_svalue *initial_sval2 = (const initial_svalue *)sval2;
     592      2082684 :         return region::cmp_ids (initial_sval1->get_region (),
     593      4165368 :                                 initial_sval2->get_region ());
     594              :       }
     595       743022 :       break;
     596       743022 :     case SK_UNARYOP:
     597       743022 :       {
     598       743022 :         const unaryop_svalue *unaryop_sval1 = (const unaryop_svalue *)sval1;
     599       743022 :         const unaryop_svalue *unaryop_sval2 = (const unaryop_svalue *)sval2;
     600       743022 :         if (int op_cmp = unaryop_sval1->get_op () - unaryop_sval2->get_op ())
     601              :           return op_cmp;
     602       742982 :         return svalue::cmp_ptr (unaryop_sval1->get_arg (),
     603       742982 :                                 unaryop_sval2->get_arg ());
     604              :       }
     605      1825702 :       break;
     606      1825702 :     case SK_BINOP:
     607      1825702 :       {
     608      1825702 :         const binop_svalue *binop_sval1 = (const binop_svalue *)sval1;
     609      1825702 :         const binop_svalue *binop_sval2 = (const binop_svalue *)sval2;
     610      1825702 :         if (int op_cmp = binop_sval1->get_op () - binop_sval2->get_op ())
     611              :           return op_cmp;
     612      1801927 :         if (int arg0_cmp = svalue::cmp_ptr (binop_sval1->get_arg0 (),
     613              :                                             binop_sval2->get_arg0 ()))
     614              :           return arg0_cmp;
     615       688524 :         return svalue::cmp_ptr (binop_sval1->get_arg1 (),
     616       688524 :                                 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          299 :       break;
     630          299 :     case SK_REPEATED:
     631          299 :       {
     632          299 :         const repeated_svalue *repeated_sval1 = (const repeated_svalue *)sval1;
     633          299 :         const repeated_svalue *repeated_sval2 = (const repeated_svalue *)sval2;
     634          299 :         return svalue::cmp_ptr (repeated_sval1->get_inner_svalue (),
     635          299 :                                 repeated_sval2->get_inner_svalue ());
     636              :       }
     637          373 :       break;
     638          373 :     case SK_BITS_WITHIN:
     639          373 :       {
     640          373 :         const bits_within_svalue *bits_within_sval1
     641              :           = (const bits_within_svalue *)sval1;
     642          373 :         const bits_within_svalue *bits_within_sval2
     643              :           = (const bits_within_svalue *)sval2;
     644          373 :         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         1713 :       break;
     671         1713 :     case SK_WIDENING:
     672         1713 :       {
     673         1713 :         const widening_svalue *widening_sval1 = (const widening_svalue *)sval1;
     674         1713 :         const widening_svalue *widening_sval2 = (const widening_svalue *)sval2;
     675         1713 :         if (int index_cmp = (widening_sval1->get_snode ()->m_id
     676         1713 :                              - widening_sval2->get_snode ()->m_id))
     677              :           return index_cmp;
     678         1487 :         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      3183157 :       break;
     694      3183157 :     case SK_CONJURED:
     695      3183157 :       {
     696      3183157 :         const conjured_svalue *conjured_sval1 = (const conjured_svalue *)sval1;
     697      3183157 :         const conjured_svalue *conjured_sval2 = (const conjured_svalue *)sval2;
     698      3183157 :         if (int stmt_cmp = (conjured_sval1->get_stmt ()->uid
     699      3183157 :                             - conjured_sval2->get_stmt ()->uid))
     700              :           return stmt_cmp;
     701        37158 :         return region::cmp_ids (conjured_sval1->get_id_region (),
     702        74316 :                                 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      7766728 : svalue::cmp_ptr_ptr (const void *p1, const void *p2)
     755              : {
     756      7766728 :   const svalue *sval1 = *(const svalue * const *)p1;
     757      7766728 :   const svalue *sval2 = *(const svalue * const *)p2;
     758      7766728 :   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       650105 :   involvement_visitor (const svalue *needle)
     767       650105 :   : m_needle (needle), m_found (false) {}
     768              : 
     769       295943 :   void visit_initial_svalue (const initial_svalue *candidate) final override
     770              :   {
     771       295943 :     if (candidate == m_needle)
     772           60 :       m_found = true;
     773       295943 :   }
     774              : 
     775       292303 :   void visit_conjured_svalue (const conjured_svalue *candidate) final override
     776              :   {
     777       292303 :     if (candidate == m_needle)
     778         6516 :       m_found = true;
     779       292303 :   }
     780              : 
     781         5107 :   void visit_widening_svalue (const widening_svalue *candidate) final override
     782              :   {
     783         5107 :     if (candidate == m_needle)
     784          172 :       m_found = true;
     785         5107 :   }
     786              : 
     787       650105 :   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       650105 : svalue::involves_p (const svalue *other) const
     798              : {
     799              :   /* Currently only implemented for these kinds.  */
     800       650105 :   gcc_assert (other->get_kind () == SK_INITIAL
     801              :               || other->get_kind () == SK_CONJURED
     802              :               || other->get_kind () == SK_WIDENING);
     803              : 
     804       650105 :   involvement_visitor v (other);
     805       650105 :   accept (&v);
     806       650105 :   return v.found_p ();
     807              : }
     808              : 
     809              : /* Extract SUBRANGE from this value, of type TYPE.  */
     810              : 
     811              : const svalue *
     812        19763 : svalue::extract_bit_range (tree type,
     813              :                            const bit_range &subrange,
     814              :                            region_model_manager *mgr) const
     815              : {
     816        19763 :   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         1713 : svalue::maybe_fold_bits_within (tree,
     823              :                                 const bit_range &,
     824              :                                 region_model_manager *) const
     825              : {
     826              :   /* By default, don't fold.  */
     827         1713 :   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       142930 : svalue::all_zeroes_p () const
     835              : {
     836       142930 :   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        20686 : svalue::maybe_get_deref_base_region () const
     844              : {
     845        20686 :   const svalue *iter = this;
     846        21238 :   while (1)
     847              :     {
     848        20962 :       switch (iter->get_kind ())
     849              :         {
     850              :         default:
     851              :           return nullptr;
     852              : 
     853         9053 :         case SK_REGION:
     854         9053 :           {
     855         9053 :             const region_svalue *region_sval
     856         9053 :               = as_a <const region_svalue *> (iter);
     857         9053 :             return region_sval->get_pointee ()->get_base_region ();
     858              :           }
     859              : 
     860          442 :         case SK_BINOP:
     861          442 :           {
     862          442 :             const binop_svalue *binop_sval
     863          442 :               = as_a <const binop_svalue *> (iter);
     864          442 :             switch (binop_sval->get_op ())
     865              :               {
     866          276 :               case POINTER_PLUS_EXPR:
     867              :                 /* If we have a symbolic value expressing pointer arithmetic,
     868              :                    use the LHS.  */
     869          276 :                 iter = binop_sval->get_arg0 ();
     870          276 :                 continue;
     871              : 
     872              :               default:
     873              :                 return nullptr;
     874              :               }
     875              :             return nullptr;
     876              :           }
     877              :         }
     878          276 :     }
     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       197160 : type_can_have_value_range_p (tree type)
     899              : {
     900       197160 :   if (!type)
     901              :     return false;
     902       196868 :   if (irange::supports_p (type))
     903              :     return true;
     904        37297 :   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        99183 : svalue::maybe_get_value_range_1 (value_range &out) const
     915              : {
     916        99183 :   tree type = get_type ();
     917        99183 :   if (!type_can_have_value_range_p (type))
     918              :     return false;
     919              : 
     920        63799 :   out.set_varying (type);
     921        63799 :   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        10017 : region_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
     930              : {
     931        10017 :   if (simple)
     932              :     {
     933         9398 :       pp_string (pp, "&");
     934         9398 :       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        10017 : }
     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       823305 : region_svalue::accept (visitor *v) const
     973              : {
     974       823305 :   m_reg->accept (v);
     975       823305 :   v->visit_region_svalue (this);
     976       823305 : }
     977              : 
     978              : /* Implementation of svalue::implicitly_live_p vfunc for region_svalue.  */
     979              : 
     980              : bool
     981       268242 : 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       268242 :   const region *base_reg = get_pointee ()->get_base_region ();
     986       268242 :   const store *store = model->get_store ();
     987       268242 :   if (const binding_cluster *c = store->get_cluster (base_reg))
     988       247421 :     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          910 : region_svalue::eval_condition (const region_svalue *lhs,
    1000              :                                enum tree_code op,
    1001              :                                const region_svalue *rhs,
    1002              :                                const region_model &model)
    1003              : {
    1004              :   /* Convert to region_offset representation, and work with that.  */
    1005          910 :   const region *lhs_reg = lhs->get_pointee ();
    1006          910 :   const region *rhs_reg = rhs->get_pointee ();
    1007              : 
    1008          910 :   region_model_manager *mgr = model.get_manager ();
    1009          910 :   region_offset lhs_offset = lhs_reg->get_offset (mgr);
    1010          910 :   region_offset rhs_offset = rhs_reg->get_offset (mgr);
    1011              : 
    1012          910 :   return eval_region_offset_comparison (lhs_offset, op, rhs_offset, model);
    1013              : }
    1014              : 
    1015              : /* class constant_svalue : public svalue.  */
    1016              : 
    1017              : /* Implementation of svalue::dump_to_pp vfunc for constant_svalue.  */
    1018              : 
    1019              : void
    1020        16558 : constant_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
    1021              : {
    1022        16558 :   if (simple)
    1023              :     {
    1024        15909 :       pp_string (pp, "(");
    1025        15909 :       dump_tree (pp, get_type ());
    1026        15909 :       pp_string (pp, ")");
    1027        15909 :       dump_tree (pp, m_cst_expr);
    1028              :     }
    1029              :   else
    1030              :     {
    1031          649 :       pp_string (pp, "constant_svalue(");
    1032          649 :       if (get_type ())
    1033              :         {
    1034          649 :           print_quoted_type (pp, get_type ());
    1035          649 :           pp_string (pp, ", ");
    1036              :         }
    1037          649 :       dump_tree (pp, m_cst_expr);
    1038          649 :       pp_string (pp, ")");
    1039              :     }
    1040        16558 : }
    1041              : 
    1042              : /* Implementation of svalue::print_dump_widget_label vfunc for
    1043              :    constant_svalue.  */
    1044              : 
    1045              : void
    1046            0 : constant_svalue::print_dump_widget_label (pretty_printer *pp) const
    1047              : {
    1048            0 :   pp_printf (pp, "constant_svalue (%qE)", m_cst_expr);
    1049            0 : }
    1050              : 
    1051              : /* Implementation of svalue::add_dump_widget_children vfunc for
    1052              :    constant_svalue.  */
    1053              : 
    1054              : void
    1055            0 : constant_svalue::
    1056              : add_dump_widget_children (text_art::tree_widget &,
    1057              :                           const text_art::dump_widget_info &) const
    1058              : {
    1059              :   /* No children.  */
    1060            0 : }
    1061              : 
    1062              : /* Implementation of svalue::accept vfunc for constant_svalue.  */
    1063              : 
    1064              : void
    1065      9357889 : constant_svalue::accept (visitor *v) const
    1066              : {
    1067      9357889 :   v->visit_constant_svalue (this);
    1068      9357889 : }
    1069              : 
    1070              : /* Implementation of svalue::implicitly_live_p vfunc for constant_svalue.
    1071              :    Constants are implicitly live.  */
    1072              : 
    1073              : bool
    1074       679022 : constant_svalue::implicitly_live_p (const svalue_set *,
    1075              :                                     const region_model *) const
    1076              : {
    1077       679022 :   return true;
    1078              : }
    1079              : 
    1080              : /* Given EXPR, a non-NULL expression of boolean type, convert to
    1081              :    a tristate based on whether this is known to be true, false,
    1082              :    or is not known.  */
    1083              : 
    1084              : static tristate
    1085        15540 : tristate_from_boolean_tree_node (tree expr)
    1086              : {
    1087        15540 :   gcc_assert (TREE_TYPE (expr) == boolean_type_node);
    1088              : 
    1089        15540 :   if (expr == boolean_true_node)
    1090        11383 :     return tristate (tristate::TS_TRUE);
    1091         4157 :   else if (expr == boolean_false_node)
    1092         4157 :     return tristate (tristate::TS_FALSE);
    1093              :   else
    1094            0 :     return tristate (tristate::TS_UNKNOWN);
    1095              : }
    1096              : 
    1097              : /* Evaluate the condition LHS OP RHS.
    1098              :    Subroutine of region_model::eval_condition for when we have a pair of
    1099              :    constants.  */
    1100              : 
    1101              : tristate
    1102        16095 : constant_svalue::eval_condition (const constant_svalue *lhs,
    1103              :                                  enum tree_code op,
    1104              :                                  const constant_svalue *rhs)
    1105              : {
    1106        16095 :   tree lhs_const = lhs->get_constant ();
    1107        16095 :   tree rhs_const = rhs->get_constant ();
    1108              : 
    1109        16095 :   gcc_assert (CONSTANT_CLASS_P (lhs_const));
    1110        16095 :   gcc_assert (CONSTANT_CLASS_P (rhs_const));
    1111              : 
    1112        16095 :   if ((lhs->get_type () == NULL_TREE || rhs->get_type () == NULL_TREE)
    1113          366 :       && TREE_CODE (lhs_const) == INTEGER_CST
    1114        16461 :       && TREE_CODE (rhs_const) == INTEGER_CST
    1115              :       )
    1116              :     {
    1117          366 :      if (tree tree_cmp = const_binop (op, boolean_type_node,
    1118              :                                       lhs_const, rhs_const))
    1119              :        {
    1120          366 :          tristate ts = tristate_from_boolean_tree_node (tree_cmp);
    1121          366 :          if (ts.is_known ())
    1122          366 :            return ts;
    1123              :        }
    1124              :     }
    1125              : 
    1126              :   /* Check for comparable types.  */
    1127        15729 :   if (types_compatible_p (TREE_TYPE (lhs_const), TREE_TYPE (rhs_const)))
    1128              :     {
    1129        15174 :       tree tree_cmp
    1130        15174 :         = fold_binary (op, boolean_type_node, lhs_const, rhs_const);
    1131        15174 :       tristate ts = tristate_from_boolean_tree_node (tree_cmp);
    1132        15174 :       if (ts.is_known ())
    1133        15174 :         return ts;
    1134              :     }
    1135          555 :   return tristate::TS_UNKNOWN;
    1136              : }
    1137              : 
    1138              : /* Implementation of svalue::maybe_fold_bits_within vfunc
    1139              :    for constant_svalue.  */
    1140              : 
    1141              : const svalue *
    1142          442 : constant_svalue::maybe_fold_bits_within (tree type,
    1143              :                                          const bit_range &bits,
    1144              :                                          region_model_manager *mgr) const
    1145              : {
    1146              :   /* Bits within an all-zero value are also all zero.  */
    1147          442 :   if (zerop (m_cst_expr))
    1148              :     {
    1149           93 :       if (type)
    1150           92 :         return mgr->get_or_create_cast (type, this);
    1151              :       else
    1152            1 :         return this;
    1153              :     }
    1154              : 
    1155              :   /* Handle the case of extracting a single bit. */
    1156          498 :   if (bits.m_size_in_bits == 1
    1157          204 :       && TREE_CODE (m_cst_expr) == INTEGER_CST
    1158          204 :       && type
    1159          204 :       && INTEGRAL_TYPE_P (type)
    1160          553 :       && tree_fits_uhwi_p (m_cst_expr))
    1161              :     {
    1162          200 :       unsigned HOST_WIDE_INT bit = bits.m_start_bit_offset.to_uhwi ();
    1163          200 :       unsigned HOST_WIDE_INT mask = (1 << bit);
    1164          200 :       unsigned HOST_WIDE_INT val_as_hwi = tree_to_uhwi (m_cst_expr);
    1165          200 :       unsigned HOST_WIDE_INT masked_val = val_as_hwi & mask;
    1166          200 :       int result = masked_val ? 1 : 0;
    1167          200 :       return mgr->get_or_create_int_cst (type, result);
    1168              :     }
    1169              : 
    1170              :   /* Otherwise, don't fold.  */
    1171              :   return nullptr;
    1172              : }
    1173              : 
    1174              : /* Implementation of svalue::all_zeroes_p for constant_svalue.  */
    1175              : 
    1176              : bool
    1177       118890 : constant_svalue::all_zeroes_p () const
    1178              : {
    1179       118890 :   return zerop (m_cst_expr);
    1180              : }
    1181              : 
    1182              : 
    1183              : /* Implementation of svalue::maybe_get_value_range_1 for constant_svalue.
    1184              :    If there is a suitable underlying type, write the value_range for the
    1185              :    single value of m_cst_expr to OUT and return true; otherwise return
    1186              :    false.  */
    1187              : 
    1188              : bool
    1189        53488 : constant_svalue::maybe_get_value_range_1 (value_range &out) const
    1190              : {
    1191        53488 :   if (!type_can_have_value_range_p (get_type ()))
    1192              :     return false;
    1193              : 
    1194        53393 :   out = value_range (m_cst_expr, m_cst_expr);
    1195        53393 :   return true;
    1196              : }
    1197              : 
    1198              : /* class unknown_svalue : public svalue.  */
    1199              : 
    1200              : /* Implementation of svalue::dump_to_pp vfunc for unknown_svalue.  */
    1201              : 
    1202              : void
    1203         3670 : unknown_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
    1204              : {
    1205         3670 :   if (simple)
    1206              :     {
    1207         2943 :       pp_string (pp, "UNKNOWN(");
    1208         2943 :       if (get_type ())
    1209         2940 :         dump_tree (pp, get_type ());
    1210         2943 :       pp_character (pp, ')');
    1211              :     }
    1212              :   else
    1213              :     {
    1214          727 :       pp_string (pp, "unknown_svalue(");
    1215          727 :       if (get_type ())
    1216          727 :         dump_tree (pp, get_type ());
    1217          727 :       pp_character (pp, ')');
    1218              :     }
    1219         3670 : }
    1220              : 
    1221              : /* Implementation of svalue::print_dump_widget_label vfunc for
    1222              :    unknown_svalue.  */
    1223              : 
    1224              : void
    1225            0 : unknown_svalue::print_dump_widget_label (pretty_printer *pp) const
    1226              : {
    1227            0 :   pp_printf (pp, "unknown_svalue");
    1228            0 : }
    1229              : 
    1230              : /* Implementation of svalue::add_dump_widget_children vfunc for
    1231              :    unknown_svalue.  */
    1232              : 
    1233              : void
    1234            0 : unknown_svalue::
    1235              : add_dump_widget_children (text_art::tree_widget &,
    1236              :                           const text_art::dump_widget_info &) const
    1237              : {
    1238              :   /* No children.  */
    1239            0 : }
    1240              : 
    1241              : /* Implementation of svalue::accept vfunc for unknown_svalue.  */
    1242              : 
    1243              : void
    1244      1932302 : unknown_svalue::accept (visitor *v) const
    1245              : {
    1246      1932302 :   v->visit_unknown_svalue (this);
    1247      1932302 : }
    1248              : 
    1249              : /* Implementation of svalue::maybe_fold_bits_within vfunc
    1250              :    for unknown_svalue.  */
    1251              : 
    1252              : const svalue *
    1253         7172 : unknown_svalue::maybe_fold_bits_within (tree type,
    1254              :                                         const bit_range &,
    1255              :                                         region_model_manager *mgr) const
    1256              : {
    1257              :   /* Bits within an unknown_svalue are themselves unknown.  */
    1258         7172 :   return mgr->get_or_create_unknown_svalue (type);
    1259              : }
    1260              : 
    1261              : bool
    1262        17272 : unknown_svalue::maybe_get_value_range_1 (value_range &) const
    1263              : {
    1264              :   /* Don't attempt to participate in range ops.  */
    1265        17272 :   return false;
    1266              : }
    1267              : 
    1268              : 
    1269              : /* Get a string for KIND for use in debug dumps.  */
    1270              : 
    1271              : const char *
    1272           12 : poison_kind_to_str (enum poison_kind kind)
    1273              : {
    1274           12 :   switch (kind)
    1275              :     {
    1276            0 :     default:
    1277            0 :       gcc_unreachable ();
    1278              :     case poison_kind::uninit:
    1279              :       return "uninit";
    1280            0 :     case poison_kind::freed:
    1281            0 :       return "freed";
    1282            0 :     case poison_kind::deleted:
    1283            0 :       return "deleted";
    1284            0 :     case poison_kind::popped_stack:
    1285            0 :       return "popped stack";
    1286              :     }
    1287              : }
    1288              : 
    1289              : /* class poisoned_svalue : public svalue.  */
    1290              : 
    1291              : /* Implementation of svalue::dump_to_pp vfunc for poisoned_svalue.  */
    1292              : 
    1293              : void
    1294            4 : poisoned_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
    1295              : {
    1296            4 :   if (simple)
    1297              :     {
    1298            4 :       pp_string (pp, "POISONED(");
    1299            4 :       print_quoted_type (pp, get_type ());
    1300            4 :       pp_printf (pp, ", %s)", poison_kind_to_str (m_kind));
    1301              :     }
    1302              :   else
    1303              :     {
    1304            0 :       pp_string (pp, "poisoned_svalue(");
    1305            0 :       print_quoted_type (pp, get_type ());
    1306            0 :       pp_printf (pp, ", %s)", poison_kind_to_str (m_kind));
    1307              :     }
    1308            4 : }
    1309              : 
    1310              : /* Implementation of svalue::print_dump_widget_label vfunc for
    1311              :    poisoned_svalue.  */
    1312              : 
    1313              : void
    1314            0 : poisoned_svalue::print_dump_widget_label (pretty_printer *pp) const
    1315              : {
    1316            0 :   pp_printf (pp, "poisoned_svalue(%s)", poison_kind_to_str (m_kind));
    1317            0 : }
    1318              : 
    1319              : /* Implementation of svalue::add_dump_widget_children vfunc for
    1320              :    poisoned_svalue.  */
    1321              : 
    1322              : void
    1323            0 : poisoned_svalue::
    1324              : add_dump_widget_children (text_art::tree_widget &,
    1325              :                           const text_art::dump_widget_info &) const
    1326              : {
    1327              :   /* No children.  */
    1328            0 : }
    1329              : 
    1330              : /* Implementation of svalue::accept vfunc for poisoned_svalue.  */
    1331              : 
    1332              : void
    1333        22893 : poisoned_svalue::accept (visitor *v) const
    1334              : {
    1335        22893 :   v->visit_poisoned_svalue (this);
    1336        22893 : }
    1337              : 
    1338              : /* Implementation of svalue::maybe_fold_bits_within vfunc
    1339              :    for poisoned_svalue.  */
    1340              : 
    1341              : const svalue *
    1342         5893 : poisoned_svalue::maybe_fold_bits_within (tree type,
    1343              :                                          const bit_range &,
    1344              :                                          region_model_manager *mgr) const
    1345              : {
    1346              :   /* Bits within a poisoned value are also poisoned.  */
    1347         5893 :   return mgr->get_or_create_poisoned_svalue (m_kind, type);
    1348              : }
    1349              : 
    1350              : /* class setjmp_svalue's implementation is in setjmp-longjmp.cc.  */
    1351              : 
    1352              : /* class initial_svalue : public svalue.  */
    1353              : 
    1354              : /* Implementation of svalue::dump_to_pp vfunc for initial_svalue.  */
    1355              : 
    1356              : void
    1357        12143 : initial_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
    1358              : {
    1359        12143 :   if (simple)
    1360              :     {
    1361        12007 :       pp_string (pp, "INIT_VAL(");
    1362        12007 :       m_reg->dump_to_pp (pp, simple);
    1363        12007 :       pp_string (pp, ")");
    1364              :     }
    1365              :   else
    1366              :     {
    1367          136 :       pp_string (pp, "initial_svalue(");
    1368          136 :       if (get_type ())
    1369              :         {
    1370          136 :           print_quoted_type (pp, get_type ());
    1371          136 :           pp_string (pp, ", ");
    1372              :         }
    1373          136 :       m_reg->dump_to_pp (pp, simple);
    1374          136 :       pp_string (pp, ")");
    1375              :     }
    1376        12143 : }
    1377              : 
    1378              : /* Implementation of svalue::print_dump_widget_label vfunc for
    1379              :    initial_svalue.  */
    1380              : 
    1381              : void
    1382            0 : initial_svalue::print_dump_widget_label (pretty_printer *pp) const
    1383              : {
    1384            0 :   pp_printf (pp, "initial_svalue");
    1385            0 : }
    1386              : 
    1387              : /* Implementation of svalue::add_dump_widget_children vfunc for
    1388              :    initial_svalue.  */
    1389              : 
    1390              : void
    1391            0 : initial_svalue::
    1392              : add_dump_widget_children (text_art::tree_widget &w,
    1393              :                           const text_art::dump_widget_info &dwi) const
    1394              : {
    1395            0 :   w.add_child (m_reg->make_dump_widget (dwi, "m_reg"));
    1396            0 : }
    1397              : 
    1398              : /* Implementation of svalue::accept vfunc for initial_svalue.  */
    1399              : 
    1400              : void
    1401      1671362 : initial_svalue::accept (visitor *v) const
    1402              : {
    1403      1671362 :   m_reg->accept (v);
    1404      1671362 :   v->visit_initial_svalue (this);
    1405      1671362 : }
    1406              : 
    1407              : /* Implementation of svalue::implicitly_live_p vfunc for initial_svalue.  */
    1408              : 
    1409              : bool
    1410      2716386 : initial_svalue::implicitly_live_p (const svalue_set *,
    1411              :                                    const region_model *model) const
    1412              : {
    1413              :   /* This svalue may be implicitly live if the region still implicitly
    1414              :      has its initial value and is reachable.  */
    1415              : 
    1416              :   /* It must be a region that exists; we don't want to consider
    1417              :      INIT_VAL(R) as still being implicitly reachable if R is in
    1418              :      a popped stack frame.  */
    1419      2716386 :   if (model->region_exists_p (m_reg))
    1420              :     {
    1421      2698529 :       const svalue *reg_sval = model->get_store_value (m_reg, nullptr);
    1422      2698529 :       if (reg_sval == this)
    1423              :         return true;
    1424              :     }
    1425              : 
    1426              :   /* Assume that the initial values of params for the top level frame
    1427              :      are still live, because (presumably) they're still
    1428              :      live in the external caller.  */
    1429       152784 :   if (initial_value_of_param_p ())
    1430        16901 :     if (const frame_region *frame_reg = m_reg->maybe_get_frame_region ())
    1431        16901 :       if (frame_reg->get_calling_frame () == nullptr)
    1432              :         return true;
    1433              : 
    1434              :   return false;
    1435              : }
    1436              : 
    1437              : /* Return true if this is the initial value of a function parameter.  */
    1438              : 
    1439              : bool
    1440       156990 : initial_svalue::initial_value_of_param_p () const
    1441              : {
    1442       156990 :   if (tree reg_decl = m_reg->maybe_get_decl ())
    1443        89942 :     if (TREE_CODE (reg_decl) == SSA_NAME)
    1444              :       {
    1445        16990 :         tree ssa_name = reg_decl;
    1446        16990 :         if (SSA_NAME_IS_DEFAULT_DEF (ssa_name)
    1447        16990 :             && SSA_NAME_VAR (ssa_name)
    1448        33980 :             && TREE_CODE (SSA_NAME_VAR (ssa_name)) == PARM_DECL)
    1449        16973 :           return true;
    1450              :       }
    1451              :   return false;
    1452              : }
    1453              : 
    1454              : /* class unaryop_svalue : public svalue.  */
    1455              : 
    1456              : /* Implementation of svalue::dump_to_pp vfunc for unaryop_svalue.  */
    1457              : 
    1458              : void
    1459         4534 : unaryop_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
    1460              : {
    1461         4534 :   if (simple)
    1462              :     {
    1463         4368 :       if (m_op == VIEW_CONVERT_EXPR || m_op == NOP_EXPR)
    1464              :         {
    1465         4187 :           pp_string (pp, "CAST(");
    1466         4187 :           dump_tree (pp, get_type ());
    1467         4187 :           pp_string (pp, ", ");
    1468         4187 :           m_arg->dump_to_pp (pp, simple);
    1469         4187 :           pp_character (pp, ')');
    1470              :         }
    1471              :       else
    1472              :         {
    1473          181 :           pp_character (pp, '(');
    1474          181 :           pp_string (pp, get_tree_code_name (m_op));
    1475              :           //pp_string (pp, op_symbol_code (m_op));
    1476          181 :           m_arg->dump_to_pp (pp, simple);
    1477          181 :           pp_character (pp, ')');
    1478              :         }
    1479              :     }
    1480              :   else
    1481              :     {
    1482          166 :       pp_string (pp, "unaryop_svalue (");
    1483          166 :       pp_string (pp, get_tree_code_name (m_op));
    1484          166 :       pp_string (pp, ", ");
    1485          166 :       m_arg->dump_to_pp (pp, simple);
    1486          166 :       pp_character (pp, ')');
    1487              :     }
    1488         4534 : }
    1489              : 
    1490              : /* Implementation of svalue::print_dump_widget_label vfunc for
    1491              :    unaryop_svalue.  */
    1492              : 
    1493              : void
    1494            0 : unaryop_svalue::print_dump_widget_label (pretty_printer *pp) const
    1495              : {
    1496            0 :   pp_printf (pp,
    1497              :              "unaryop_svalue(%s)",
    1498            0 :              get_tree_code_name (m_op));
    1499            0 : }
    1500              : 
    1501              : /* Implementation of svalue::add_dump_widget_children vfunc for
    1502              :    unaryop_svalue.  */
    1503              : 
    1504              : void
    1505            0 : unaryop_svalue::
    1506              : add_dump_widget_children (text_art::tree_widget &w,
    1507              :                           const text_art::dump_widget_info &dwi) const
    1508              : {
    1509            0 :   w.add_child (m_arg->make_dump_widget (dwi));
    1510            0 : }
    1511              : 
    1512              : /* Implementation of svalue::accept vfunc for unaryop_svalue.  */
    1513              : 
    1514              : void
    1515      7057489 : unaryop_svalue::accept (visitor *v) const
    1516              : {
    1517      7057489 :   m_arg->accept (v);
    1518      7057489 :   v->visit_unaryop_svalue (this);
    1519      7057489 : }
    1520              : 
    1521              : /* Implementation of svalue::implicitly_live_p vfunc for unaryop_svalue.  */
    1522              : 
    1523              : bool
    1524      1050134 : unaryop_svalue::implicitly_live_p (const svalue_set *live_svalues,
    1525              :                                    const region_model *model) const
    1526              : {
    1527      1050134 :   return get_arg ()->live_p (live_svalues, model);
    1528              : }
    1529              : 
    1530              : /* Implementation of svalue::maybe_fold_bits_within vfunc
    1531              :    for unaryop_svalue.  */
    1532              : 
    1533              : const svalue *
    1534         3402 : unaryop_svalue::maybe_fold_bits_within (tree type,
    1535              :                                         const bit_range &,
    1536              :                                         region_model_manager *mgr) const
    1537              : {
    1538         3402 :   switch (m_op)
    1539              :     {
    1540              :     default:
    1541              :       break;
    1542         3402 :     case NOP_EXPR:
    1543              :       /* A cast of zero is zero.  */
    1544         3402 :       if (tree cst = m_arg->maybe_get_constant ())
    1545         3402 :         if (zerop (cst))
    1546              :           {
    1547         3402 :             if (type)
    1548          140 :               return mgr->get_or_create_cast (type, this);
    1549              :             else
    1550         3262 :               return this;
    1551              :           }
    1552              :       break;
    1553              :     }
    1554              :   /* Otherwise, don't fold.  */
    1555              :   return nullptr;
    1556              : }
    1557              : 
    1558              : /* Implementation of svalue::maybe_get_value_range_1 for unaryop_svalue.  */
    1559              : 
    1560              : bool
    1561        17363 : unaryop_svalue::maybe_get_value_range_1 (value_range &out) const
    1562              : {
    1563        17363 :   tree type = get_type ();
    1564        17363 :   if (!type_can_have_value_range_p (type))
    1565              :     return false;
    1566              : 
    1567        17094 :   value_range arg_vr;
    1568        17094 :   if (m_arg->maybe_get_value_range (arg_vr))
    1569              :     {
    1570        15432 :       range_op_handler handler (m_op);
    1571        15432 :       if (handler
    1572        30864 :           && handler.operand_check_p (type, arg_vr.type (), type))
    1573              :         {
    1574              :           /* For unary ops, range_op_hander::fold_range expects
    1575              :              a VARYING of the unknown value as the 2nd operand.  */
    1576        15430 :           value_range varying (type);
    1577        15430 :           varying.set_varying (type);
    1578        15430 :           out.set_range_class (type);
    1579        15430 :           if (handler.fold_range (out, type, arg_vr, varying))
    1580        15430 :             return true;
    1581        15430 :         }
    1582              :     }
    1583              :   return false;
    1584        17094 : }
    1585              : 
    1586              : /* class binop_svalue : public svalue.  */
    1587              : 
    1588              : /* Return whether OP be printed as an infix operator.  */
    1589              : 
    1590              : static bool
    1591        10205 : infix_p (enum tree_code op)
    1592              : {
    1593            0 :   switch (op)
    1594              :     {
    1595              :     default:
    1596              :       return true;
    1597            0 :     case MAX_EXPR:
    1598            0 :     case MIN_EXPR:
    1599            0 :       return false;
    1600              :     }
    1601              : }
    1602              : 
    1603              : /* Implementation of svalue::dump_to_pp vfunc for binop_svalue.  */
    1604              : 
    1605              : void
    1606        10644 : binop_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
    1607              : {
    1608        10644 :   if (simple)
    1609              :     {
    1610        10205 :       if (infix_p (m_op))
    1611              :         {
    1612              :           /* Print "(A OP B)".  */
    1613        10205 :           pp_character (pp, '(');
    1614        10205 :           m_arg0->dump_to_pp (pp, simple);
    1615        10205 :           pp_string (pp, op_symbol_code (m_op));
    1616        10205 :           m_arg1->dump_to_pp (pp, simple);
    1617        10205 :           pp_character (pp, ')');
    1618              :         }
    1619              :       else
    1620              :         {
    1621              :           /* Print "OP(A, B)".  */
    1622            0 :           pp_string (pp, op_symbol_code (m_op));
    1623            0 :           pp_character (pp, '(');
    1624            0 :           m_arg0->dump_to_pp (pp, simple);
    1625            0 :           pp_string (pp, ", ");
    1626            0 :           m_arg1->dump_to_pp (pp, simple);
    1627            0 :           pp_character (pp, ')');
    1628              :         }
    1629              :     }
    1630              :   else
    1631              :     {
    1632          439 :       pp_string (pp, "binop_svalue (");
    1633          439 :       pp_string (pp, get_tree_code_name (m_op));
    1634          439 :       pp_string (pp, ", ");
    1635          439 :       m_arg0->dump_to_pp (pp, simple);
    1636          439 :       pp_string (pp, ", ");
    1637          439 :       m_arg1->dump_to_pp (pp, simple);
    1638          439 :       pp_character (pp, ')');
    1639              :     }
    1640        10644 : }
    1641              : 
    1642              : /* Implementation of svalue::print_dump_widget_label vfunc for
    1643              :    binop_svalue.  */
    1644              : 
    1645              : void
    1646            0 : binop_svalue::print_dump_widget_label (pretty_printer *pp) const
    1647              : {
    1648            0 :   pp_printf (pp,
    1649              :              "binop_svalue(%s: %qs)",
    1650            0 :              get_tree_code_name (m_op),
    1651            0 :              op_symbol_code (m_op));
    1652            0 : }
    1653              : 
    1654              : /* Implementation of svalue::add_dump_widget_children vfunc for
    1655              :    binop_svalue.  */
    1656              : 
    1657              : void
    1658            0 : binop_svalue::
    1659              : add_dump_widget_children (text_art::tree_widget &w,
    1660              :                           const text_art::dump_widget_info &dwi) const
    1661              : {
    1662            0 :   w.add_child (m_arg0->make_dump_widget (dwi));
    1663            0 :   w.add_child (m_arg1->make_dump_widget (dwi));
    1664            0 : }
    1665              : 
    1666              : /* Implementation of svalue::accept vfunc for binop_svalue.  */
    1667              : 
    1668              : void
    1669      6291369 : binop_svalue::accept (visitor *v) const
    1670              : {
    1671      6291369 :   m_arg0->accept (v);
    1672      6291369 :   m_arg1->accept (v);
    1673      6291369 :   v->visit_binop_svalue (this);
    1674      6291369 : }
    1675              : 
    1676              : /* Implementation of svalue::implicitly_live_p vfunc for binop_svalue.  */
    1677              : 
    1678              : bool
    1679      1123957 : binop_svalue::implicitly_live_p (const svalue_set *live_svalues,
    1680              :                                  const region_model *model) const
    1681              : {
    1682      1123957 :   return (get_arg0 ()->live_p (live_svalues, model)
    1683      1123957 :           && get_arg1 ()->live_p (live_svalues, model));
    1684              : }
    1685              : 
    1686              : /* class sub_svalue : public svalue.  */
    1687              : 
    1688              : /* sub_svalue'c ctor.  */
    1689              : 
    1690         2368 : sub_svalue::sub_svalue (symbol::id_t id,
    1691              :                         tree type, const svalue *parent_svalue,
    1692         2368 :                         const region *subregion)
    1693              : : svalue (complexity::from_pair (parent_svalue->get_complexity (),
    1694              :                                  subregion->get_complexity ()),
    1695              :           id,
    1696              :           type),
    1697         2368 :   m_parent_svalue (parent_svalue), m_subregion (subregion)
    1698              : {
    1699         2368 :   gcc_assert (parent_svalue->can_have_associated_state_p ());
    1700         2368 : }
    1701              : 
    1702              : /* Implementation of svalue::maybe_get_value_range_1 for binop_svalue.  */
    1703              : 
    1704              : bool
    1705        27126 : binop_svalue::maybe_get_value_range_1 (value_range &out) const
    1706              : {
    1707        27126 :   tree type = get_type ();
    1708        27126 :   if (!type_can_have_value_range_p (type))
    1709              :     return false;
    1710              : 
    1711              :   /* Avoid cases where we have been sloppy about types.  */
    1712        25437 :   if (!m_arg0->get_type ())
    1713              :     return false;
    1714        25437 :   if (!m_arg1->get_type ())
    1715              :     return false;
    1716        25437 :   if (!range_compatible_p (m_arg0->get_type (), m_arg1->get_type ()))
    1717              :     return false;
    1718              : 
    1719        25259 :   value_range lhs, rhs;
    1720        25259 :   if (m_arg0->maybe_get_value_range (lhs))
    1721        22553 :     if (m_arg1->maybe_get_value_range (rhs))
    1722              :       {
    1723        22399 :         range_op_handler handler (m_op);
    1724        22399 :         if (handler
    1725        44798 :             && handler.operand_check_p (type, lhs.type (), rhs.type ()))
    1726              :           {
    1727        22399 :             out.set_range_class (type);
    1728        22399 :             if (handler.fold_range (out, get_type (), lhs, rhs))
    1729        22399 :               return true;
    1730              :           }
    1731              :       }
    1732              :   return false;
    1733        25259 : }
    1734              : 
    1735              : /* Implementation of svalue::dump_to_pp vfunc for sub_svalue.  */
    1736              : 
    1737              : void
    1738         1273 : sub_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
    1739              : {
    1740         1273 :   if (simple)
    1741              :     {
    1742         1222 :       pp_string (pp, "SUB(");
    1743         1222 :       m_parent_svalue->dump_to_pp (pp, simple);
    1744         1222 :       pp_string (pp, ", ");
    1745         1222 :       m_subregion->dump_to_pp (pp, simple);
    1746         1222 :       pp_character (pp, ')');
    1747              :     }
    1748              :   else
    1749              :     {
    1750           51 :       pp_string (pp, "sub_svalue (");
    1751           51 :       pp_string (pp, ", ");
    1752           51 :       m_parent_svalue->dump_to_pp (pp, simple);
    1753           51 :       pp_string (pp, ", ");
    1754           51 :       m_subregion->dump_to_pp (pp, simple);
    1755           51 :       pp_character (pp, ')');
    1756              :     }
    1757         1273 : }
    1758              : 
    1759              : /* Implementation of svalue::print_dump_widget_label vfunc for
    1760              :    sub_svalue.  */
    1761              : 
    1762              : void
    1763            0 : sub_svalue::print_dump_widget_label (pretty_printer *pp) const
    1764              : {
    1765            0 :   pp_printf (pp, "sub_svalue");
    1766            0 : }
    1767              : 
    1768              : /* Implementation of svalue::add_dump_widget_children vfunc for
    1769              :    sub_svalue.  */
    1770              : 
    1771              : void
    1772            0 : sub_svalue::
    1773              : add_dump_widget_children (text_art::tree_widget &w,
    1774              :                           const text_art::dump_widget_info &dwi) const
    1775              : {
    1776            0 :   w.add_child (m_parent_svalue->make_dump_widget (dwi, "m_parent_svalue"));
    1777            0 :   w.add_child (m_subregion->make_dump_widget (dwi, "m_subregion"));
    1778            0 : }
    1779              : 
    1780              : /* Implementation of svalue::accept vfunc for sub_svalue.  */
    1781              : 
    1782              : void
    1783      3944317 : sub_svalue::accept (visitor *v) const
    1784              : {
    1785      3944317 :   m_parent_svalue->accept (v);
    1786      3944317 :   m_subregion->accept (v);
    1787      3944317 :   v->visit_sub_svalue (this);
    1788      3944317 : }
    1789              : 
    1790              : /* Implementation of svalue::implicitly_live_p vfunc for sub_svalue.  */
    1791              : 
    1792              : bool
    1793       594129 : sub_svalue::implicitly_live_p (const svalue_set *live_svalues,
    1794              :                                const region_model *model) const
    1795              : {
    1796       594129 :   return get_parent ()->live_p (live_svalues, model);
    1797              : }
    1798              : 
    1799              : /* class repeated_svalue : public svalue.  */
    1800              : 
    1801              : /* repeated_svalue'c ctor.  */
    1802              : 
    1803          512 : repeated_svalue::repeated_svalue (symbol::id_t id,
    1804              :                                   tree type,
    1805              :                                   const svalue *outer_size,
    1806          512 :                                   const svalue *inner_svalue)
    1807          512 : : svalue (complexity::from_pair (outer_size, inner_svalue), id, type),
    1808          512 :   m_outer_size (outer_size),
    1809         1024 :   m_inner_svalue (inner_svalue)
    1810              : {
    1811          512 :   gcc_assert (outer_size->can_have_associated_state_p ());
    1812          512 :   gcc_assert (inner_svalue->can_have_associated_state_p ());
    1813          512 : }
    1814              : 
    1815              : /* Implementation of svalue::dump_to_pp vfunc for repeated_svalue.  */
    1816              : 
    1817              : void
    1818            0 : repeated_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
    1819              : {
    1820            0 :   if (simple)
    1821              :     {
    1822            0 :       pp_string (pp, "REPEATED(");
    1823            0 :       if (get_type ())
    1824              :         {
    1825            0 :           print_quoted_type (pp, get_type ());
    1826            0 :           pp_string (pp, ", ");
    1827              :         }
    1828            0 :       pp_string (pp, "outer_size: ");
    1829            0 :       m_outer_size->dump_to_pp (pp, simple);
    1830            0 :       pp_string (pp, ", inner_val: ");
    1831            0 :       m_inner_svalue->dump_to_pp (pp, simple);
    1832            0 :       pp_character (pp, ')');
    1833              :     }
    1834              :   else
    1835              :     {
    1836            0 :       pp_string (pp, "repeated_svalue (");
    1837            0 :       if (get_type ())
    1838              :         {
    1839            0 :           print_quoted_type (pp, get_type ());
    1840            0 :           pp_string (pp, ", ");
    1841              :         }
    1842            0 :       pp_string (pp, "outer_size: ");
    1843            0 :       m_outer_size->dump_to_pp (pp, simple);
    1844            0 :       pp_string (pp, ", inner_val: ");
    1845            0 :       m_inner_svalue->dump_to_pp (pp, simple);
    1846            0 :       pp_character (pp, ')');
    1847              :     }
    1848            0 : }
    1849              : 
    1850              : /* Implementation of svalue::print_dump_widget_label vfunc for
    1851              :    repeated_svalue.  */
    1852              : 
    1853              : void
    1854            0 : repeated_svalue::print_dump_widget_label (pretty_printer *pp) const
    1855              : {
    1856            0 :   pp_printf (pp, "repeated_svalue");
    1857            0 : }
    1858              : 
    1859              : /* Implementation of svalue::add_dump_widget_children vfunc for
    1860              :    repeated_svalue.  */
    1861              : 
    1862              : void
    1863            0 : repeated_svalue::
    1864              : add_dump_widget_children (text_art::tree_widget &w,
    1865              :                           const text_art::dump_widget_info &dwi) const
    1866              : {
    1867            0 :   w.add_child (m_outer_size->make_dump_widget (dwi, "m_outer_size"));
    1868            0 :   w.add_child (m_inner_svalue->make_dump_widget (dwi, "m_inner_svalue"));
    1869            0 : }
    1870              : 
    1871              : /* Implementation of svalue::accept vfunc for repeated_svalue.  */
    1872              : 
    1873              : void
    1874        45091 : repeated_svalue::accept (visitor *v) const
    1875              : {
    1876        45091 :   m_inner_svalue->accept (v);
    1877        45091 :   v->visit_repeated_svalue (this);
    1878        45091 : }
    1879              : 
    1880              : /* Implementation of svalue::all_zeroes_p for repeated_svalue.  */
    1881              : 
    1882              : bool
    1883         1925 : repeated_svalue::all_zeroes_p () const
    1884              : {
    1885         1925 :   return m_inner_svalue->all_zeroes_p ();
    1886              : }
    1887              : 
    1888              : /* Implementation of svalue::maybe_fold_bits_within vfunc
    1889              :    for repeated_svalue.  */
    1890              : 
    1891              : const svalue *
    1892         1625 : repeated_svalue::maybe_fold_bits_within (tree type,
    1893              :                                          const bit_range &bits,
    1894              :                                          region_model_manager *mgr) const
    1895              : {
    1896         1625 :   const svalue *innermost_sval = m_inner_svalue;
    1897              :   /* Fold
    1898              :        BITS_WITHIN (range, REPEATED_SVALUE (ZERO))
    1899              :      to:
    1900              :        REPEATED_SVALUE (ZERO).  */
    1901         1625 :   if (all_zeroes_p ())
    1902              :     {
    1903         1313 :       byte_range bytes (0,0);
    1904         1313 :       if (bits.as_byte_range (&bytes))
    1905              :         {
    1906         1313 :           const svalue *byte_size
    1907         1313 :             = mgr->get_or_create_int_cst (size_type_node,
    1908         1313 :                                           bytes.m_size_in_bytes.to_uhwi ());
    1909         1313 :           return mgr->get_or_create_repeated_svalue (type, byte_size,
    1910         1313 :                                                      innermost_sval);
    1911              :         }
    1912              :     }
    1913              : 
    1914              :   /* Fold:
    1915              :        BITS_WITHIN (range, REPEATED_SVALUE (INNERMOST_SVALUE))
    1916              :      to:
    1917              :        BITS_WITHIN (range - offset, INNERMOST_SVALUE)
    1918              :      if range is fully within one instance of INNERMOST_SVALUE.  */
    1919          312 :   if (tree innermost_type = innermost_sval->get_type ())
    1920              :     {
    1921          312 :       bit_size_t element_bit_size;
    1922          312 :       if (int_size_in_bits (innermost_type, &element_bit_size)
    1923          312 :           && element_bit_size > 0)
    1924              :         {
    1925          312 :           HOST_WIDE_INT start_idx
    1926          312 :             = (bits.get_start_bit_offset ()
    1927          312 :                / element_bit_size).to_shwi ();
    1928          312 :           HOST_WIDE_INT last_idx
    1929          312 :             = (bits.get_last_bit_offset ()
    1930          312 :                / element_bit_size).to_shwi ();
    1931          312 :           if (start_idx == last_idx)
    1932              :             {
    1933          288 :               bit_offset_t start_of_element
    1934          288 :                 = start_idx * element_bit_size;
    1935          288 :               bit_range range_within_element
    1936          288 :                 (bits.m_start_bit_offset - start_of_element,
    1937          288 :                  bits.m_size_in_bits);
    1938          288 :               return mgr->get_or_create_bits_within (type,
    1939              :                                                      range_within_element,
    1940              :                                                      innermost_sval);
    1941              :             }
    1942              :         }
    1943              :     }
    1944              : 
    1945              :   return nullptr;
    1946              : }
    1947              : 
    1948              : /* class bits_within_svalue : public svalue.  */
    1949              : 
    1950              : /* bits_within_svalue'c ctor.  */
    1951              : 
    1952          771 : bits_within_svalue::bits_within_svalue (symbol::id_t id,
    1953              :                                         tree type,
    1954              :                                         const bit_range &bits,
    1955          771 :                                         const svalue *inner_svalue)
    1956          771 : : svalue (complexity (inner_svalue), id, type),
    1957          771 :   m_bits (bits),
    1958          771 :   m_inner_svalue (inner_svalue)
    1959              : {
    1960          771 :   gcc_assert (inner_svalue->can_have_associated_state_p ());
    1961          771 : }
    1962              : 
    1963              : /* Implementation of svalue::dump_to_pp vfunc for bits_within_svalue.  */
    1964              : 
    1965              : void
    1966          610 : bits_within_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
    1967              : {
    1968          610 :   if (simple)
    1969              :     {
    1970          504 :       pp_string (pp, "BITS_WITHIN(");
    1971          504 :       if (get_type ())
    1972              :         {
    1973            0 :           print_quoted_type (pp, get_type ());
    1974            0 :           pp_string (pp, ", ");
    1975              :         }
    1976          504 :       m_bits.dump_to_pp (pp);
    1977          504 :       pp_string (pp, ", inner_val: ");
    1978          504 :       m_inner_svalue->dump_to_pp (pp, simple);
    1979          504 :       pp_character (pp, ')');
    1980              :     }
    1981              :   else
    1982              :     {
    1983          106 :       pp_string (pp, "bits_within_svalue (");
    1984          106 :       if (get_type ())
    1985              :         {
    1986            0 :           print_quoted_type (pp, get_type ());
    1987            0 :           pp_string (pp, ", ");
    1988              :         }
    1989          106 :       m_bits.dump_to_pp (pp);
    1990          106 :       pp_string (pp, ", inner_val: ");
    1991          106 :       m_inner_svalue->dump_to_pp (pp, simple);
    1992          106 :       pp_character (pp, ')');
    1993              :     }
    1994          610 : }
    1995              : 
    1996              : /* Implementation of svalue::print_dump_widget_label vfunc for
    1997              :    bits_within_svalue.  */
    1998              : 
    1999              : void
    2000            0 : bits_within_svalue::print_dump_widget_label (pretty_printer *pp) const
    2001              : {
    2002            0 :   pp_printf (pp, "bits_within_svalue: ");
    2003            0 :   m_bits.dump_to_pp (pp);
    2004            0 : }
    2005              : 
    2006              : /* Implementation of svalue::add_dump_widget_children vfunc for
    2007              :    bits_within_svalue.  */
    2008              : 
    2009              : void
    2010            0 : bits_within_svalue::
    2011              : add_dump_widget_children (text_art::tree_widget &w,
    2012              :                           const text_art::dump_widget_info &dwi) const
    2013              : {
    2014            0 :   w.add_child (m_inner_svalue->make_dump_widget (dwi, "m_inner_svalue"));
    2015            0 : }
    2016              : 
    2017              : /* Implementation of svalue::maybe_fold_bits_within vfunc
    2018              :    for bits_within_svalue.  */
    2019              : 
    2020              : const svalue *
    2021          793 : bits_within_svalue::maybe_fold_bits_within (tree type,
    2022              :                                             const bit_range &bits,
    2023              :                                             region_model_manager *mgr) const
    2024              : {
    2025              :   /* Fold:
    2026              :        BITS_WITHIN (range1, BITS_WITHIN (range2, VAL))
    2027              :      to:
    2028              :        BITS_WITHIN (range1 in range 2, VAL).  */
    2029         1586 :   bit_range offset_bits (m_bits.get_start_bit_offset ()
    2030          793 :                          + bits.m_start_bit_offset,
    2031          793 :                          bits.m_size_in_bits);
    2032          793 :   return mgr->get_or_create_bits_within (type, offset_bits, m_inner_svalue);
    2033              : }
    2034              : 
    2035              : /* Implementation of svalue::accept vfunc for bits_within_svalue.  */
    2036              : 
    2037              : void
    2038        48834 : bits_within_svalue::accept (visitor *v) const
    2039              : {
    2040        48834 :   m_inner_svalue->accept (v);
    2041        48834 :   v->visit_bits_within_svalue (this);
    2042        48834 : }
    2043              : 
    2044              : /* Implementation of svalue::implicitly_live_p vfunc for bits_within_svalue.  */
    2045              : 
    2046              : bool
    2047          701 : bits_within_svalue::implicitly_live_p (const svalue_set *live_svalues,
    2048              :                                        const region_model *model) const
    2049              : {
    2050          701 :   return m_inner_svalue->live_p (live_svalues, model);
    2051              : }
    2052              : 
    2053              : /* class widening_svalue : public svalue.  */
    2054              : 
    2055              : /* Implementation of svalue::dump_to_pp vfunc for widening_svalue.  */
    2056              : 
    2057              : void
    2058         3901 : widening_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
    2059              : {
    2060         3901 :   if (simple)
    2061              :     {
    2062         3677 :       pp_string (pp, "WIDENING(");
    2063         3677 :       pp_character (pp, '{');
    2064         3677 :       m_snode->print (pp);
    2065         3677 :       pp_string (pp, "}, ");
    2066         3677 :       m_base_sval->dump_to_pp (pp, simple);
    2067         3677 :       pp_string (pp, ", ");
    2068         3677 :       m_iter_sval->dump_to_pp (pp, simple);
    2069         3677 :       pp_character (pp, ')');
    2070              :     }
    2071              :   else
    2072              :     {
    2073          224 :       pp_string (pp, "widening_svalue (");
    2074          224 :       pp_string (pp, ", ");
    2075          224 :       pp_character (pp, '{');
    2076          224 :       m_snode->print (pp);
    2077          224 :       pp_string (pp, "}, ");
    2078          224 :       m_base_sval->dump_to_pp (pp, simple);
    2079          224 :       pp_string (pp, ", ");
    2080          224 :       m_iter_sval->dump_to_pp (pp, simple);
    2081          224 :       pp_character (pp, ')');
    2082              :     }
    2083         3901 : }
    2084              : 
    2085              : /* Implementation of svalue::print_dump_widget_label vfunc for
    2086              :    widening_svalue.  */
    2087              : 
    2088              : void
    2089            0 : widening_svalue::print_dump_widget_label (pretty_printer *pp) const
    2090              : {
    2091            0 :   pp_printf (pp, "widening_svalue at ");
    2092            0 :   m_snode->print (pp);
    2093            0 : }
    2094              : 
    2095              : /* Implementation of svalue::add_dump_widget_children vfunc for
    2096              :    widening_svalue.  */
    2097              : 
    2098              : void
    2099            0 : widening_svalue::
    2100              : add_dump_widget_children (text_art::tree_widget &w,
    2101              :                           const text_art::dump_widget_info &dwi) const
    2102              : {
    2103            0 :   w.add_child (m_base_sval->make_dump_widget (dwi, "m_base_sval"));
    2104            0 :   w.add_child (m_iter_sval->make_dump_widget (dwi, "m_iter_sval"));
    2105            0 : }
    2106              : 
    2107              : /* Implementation of svalue::accept vfunc for widening_svalue.  */
    2108              : 
    2109              : void
    2110       116686 : widening_svalue::accept (visitor *v) const
    2111              : {
    2112       116686 :   m_base_sval->accept (v);
    2113       116686 :   m_iter_sval->accept (v);
    2114       116686 :   v->visit_widening_svalue (this);
    2115       116686 : }
    2116              : 
    2117              : /* Attempt to determine in which direction this value is changing
    2118              :    w.r.t. the initial value.  */
    2119              : 
    2120              : enum widening_svalue::direction_t
    2121         1912 : widening_svalue::get_direction () const
    2122              : {
    2123         1912 :   tree base_cst = m_base_sval->maybe_get_constant ();
    2124         1912 :   if (base_cst == NULL_TREE)
    2125              :     return DIR_UNKNOWN;
    2126         1912 :   tree iter_cst = m_iter_sval->maybe_get_constant ();
    2127         1912 :   if (iter_cst == NULL_TREE)
    2128              :     return DIR_UNKNOWN;
    2129              : 
    2130         1912 :   tree iter_gt_base = fold_binary (GT_EXPR, boolean_type_node,
    2131              :                                    iter_cst, base_cst);
    2132         1912 :   if (iter_gt_base == boolean_true_node)
    2133              :     return DIR_ASCENDING;
    2134              : 
    2135          475 :   tree iter_lt_base = fold_binary (LT_EXPR, boolean_type_node,
    2136              :                                    iter_cst, base_cst);
    2137          475 :   if (iter_lt_base == boolean_true_node)
    2138              :     return DIR_DESCENDING;
    2139              : 
    2140              :   return DIR_UNKNOWN;
    2141              : }
    2142              : 
    2143              : /* Compare this value against constant RHS_CST.  */
    2144              : 
    2145              : tristate
    2146         2910 : widening_svalue::eval_condition_without_cm (enum tree_code op,
    2147              :                                             tree rhs_cst) const
    2148              : {
    2149         2910 :   tree base_cst = m_base_sval->maybe_get_constant ();
    2150         2910 :   if (base_cst == NULL_TREE)
    2151         1006 :     return tristate::TS_UNKNOWN;
    2152         1904 :   tree iter_cst = m_iter_sval->maybe_get_constant ();
    2153         1904 :   if (iter_cst == NULL_TREE)
    2154            0 :     return tristate::TS_UNKNOWN;
    2155              : 
    2156         1904 :   switch (get_direction ())
    2157              :     {
    2158            0 :     default:
    2159            0 :       gcc_unreachable ();
    2160         1429 :     case DIR_ASCENDING:
    2161              :       /* LHS is in [base_cst, +ve infinity), assuming no overflow.  */
    2162         1429 :       switch (op)
    2163              :         {
    2164          281 :         case LE_EXPR:
    2165          281 :         case LT_EXPR:
    2166          281 :           {
    2167              :             /* [BASE, +INF) OP RHS:
    2168              :                This is either true or false at +ve ininity,
    2169              :                It can be true for points X where X OP RHS, so we have either
    2170              :                "false", or "unknown".  */
    2171          281 :             tree base_op_rhs = fold_binary (op, boolean_type_node,
    2172              :                                             base_cst, rhs_cst);
    2173          281 :             if (base_op_rhs == boolean_true_node)
    2174          265 :               return tristate::TS_UNKNOWN;
    2175              :             else
    2176           16 :               return tristate::TS_FALSE;
    2177              :           }
    2178              : 
    2179          808 :         case GE_EXPR:
    2180          808 :         case GT_EXPR:
    2181          808 :           {
    2182              :             /* [BASE, +INF) OP RHS:
    2183              :                This is true at +ve infinity.  It will be true everywhere
    2184              :                in the range if BASE >= RHS.  */
    2185          808 :             tree base_op_rhs = fold_binary (op, boolean_type_node,
    2186              :                                             base_cst, rhs_cst);
    2187          808 :             if (base_op_rhs == boolean_true_node)
    2188           65 :               return tristate::TS_TRUE;
    2189              :             else
    2190          743 :               return tristate::TS_UNKNOWN;
    2191              :           }
    2192              : 
    2193          168 :         case EQ_EXPR:
    2194          168 :           {
    2195              :             /* [BASE, +INF) == RHS:
    2196              :                Could this be true at any point in the range?  If so we
    2197              :                have "unknown", otherwise we have "false".  */
    2198          168 :             tree base_le_rhs = fold_binary (LE_EXPR, boolean_type_node,
    2199              :                                             base_cst, rhs_cst);
    2200          168 :             if (base_le_rhs == boolean_true_node)
    2201          158 :               return tristate::TS_UNKNOWN;
    2202              :             else
    2203           10 :               return tristate::TS_FALSE;
    2204              :           }
    2205              : 
    2206          172 :         case NE_EXPR:
    2207          172 :           {
    2208              :             /* [BASE, +INF) != RHS:
    2209              :                Could we have equality at any point in the range?  If so we
    2210              :                have "unknown", otherwise we have "true".  */
    2211          172 :             tree base_le_rhs = fold_binary (LE_EXPR, boolean_type_node,
    2212              :                                             base_cst, rhs_cst);
    2213          172 :             if (base_le_rhs == boolean_true_node)
    2214          162 :               return tristate::TS_UNKNOWN;
    2215              :             else
    2216           10 :               return tristate::TS_TRUE;
    2217              :           }
    2218              : 
    2219            0 :         default:
    2220            0 :           return tristate::TS_UNKNOWN;
    2221              :         }
    2222              : 
    2223          447 :     case DIR_DESCENDING:
    2224              :       /* LHS is in (-ve infinity, base_cst], assuming no overflow.  */
    2225          447 :       return tristate::TS_UNKNOWN;
    2226              : 
    2227           28 :     case DIR_UNKNOWN:
    2228           28 :       return tristate::TS_UNKNOWN;
    2229              :     }
    2230              : }
    2231              : 
    2232              : /* class placeholder_svalue : public svalue.  */
    2233              : 
    2234              : /* Implementation of svalue::dump_to_pp vfunc for placeholder_svalue.  */
    2235              : 
    2236              : void
    2237            0 : placeholder_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
    2238              : {
    2239            0 :   if (simple)
    2240            0 :     pp_printf (pp, "PLACEHOLDER(%qs)", m_name);
    2241              :   else
    2242            0 :     pp_printf (pp, "placeholder_svalue (%qs)", m_name);
    2243            0 : }
    2244              : 
    2245              : /* Implementation of svalue::print_dump_widget_label vfunc for
    2246              :    placeholder_svalue.  */
    2247              : 
    2248              : void
    2249            0 : placeholder_svalue::print_dump_widget_label (pretty_printer *pp) const
    2250              : {
    2251            0 :   pp_printf (pp, "placeholder_svalue: %qs", m_name);
    2252            0 : }
    2253              : 
    2254              : /* Implementation of svalue::add_dump_widget_children vfunc for
    2255              :    placeholder_svalue.  */
    2256              : 
    2257              : void
    2258            0 : placeholder_svalue::
    2259              : add_dump_widget_children (text_art::tree_widget &,
    2260              :                           const text_art::dump_widget_info &) const
    2261              : {
    2262              :   /* No children.  */
    2263            0 : }
    2264              : 
    2265              : /* Implementation of svalue::accept vfunc for placeholder_svalue.  */
    2266              : 
    2267              : void
    2268        38158 : placeholder_svalue::accept (visitor *v) const
    2269              : {
    2270        38158 :   v->visit_placeholder_svalue (this);
    2271        38158 : }
    2272              : 
    2273              : /* class unmergeable_svalue : public svalue.  */
    2274              : 
    2275              : /* Implementation of svalue::dump_to_pp vfunc for unmergeable_svalue.  */
    2276              : 
    2277              : void
    2278           20 : unmergeable_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
    2279              : {
    2280           20 :   if (simple)
    2281              :     {
    2282           20 :       pp_string (pp, "UNMERGEABLE(");
    2283           20 :       m_arg->dump_to_pp (pp, simple);
    2284           20 :       pp_character (pp, ')');
    2285              :     }
    2286              :   else
    2287              :     {
    2288            0 :       pp_string (pp, "unmergeable_svalue (");
    2289            0 :       m_arg->dump_to_pp (pp, simple);
    2290            0 :       pp_character (pp, ')');
    2291              :     }
    2292           20 : }
    2293              : 
    2294              : /* Implementation of svalue::print_dump_widget_label vfunc for
    2295              :    unmergeable_svalue.  */
    2296              : 
    2297              : void
    2298            0 : unmergeable_svalue::print_dump_widget_label (pretty_printer *pp) const
    2299              : {
    2300            0 :   pp_printf (pp, "unmergeable_svalue");
    2301            0 : }
    2302              : 
    2303              : /* Implementation of svalue::add_dump_widget_children vfunc for
    2304              :    unmergeable_svalue.  */
    2305              : 
    2306              : void
    2307            0 : unmergeable_svalue::
    2308              : add_dump_widget_children (text_art::tree_widget &w,
    2309              :                           const text_art::dump_widget_info &dwi) const
    2310              : {
    2311            0 :   w.add_child (m_arg->make_dump_widget (dwi));
    2312            0 : }
    2313              : 
    2314              : /* Implementation of svalue::accept vfunc for unmergeable_svalue.  */
    2315              : 
    2316              : void
    2317         6752 : unmergeable_svalue::accept (visitor *v) const
    2318              : {
    2319         6752 :   m_arg->accept (v);
    2320         6752 :   v->visit_unmergeable_svalue (this);
    2321         6752 : }
    2322              : 
    2323              : /* Implementation of svalue::implicitly_live_p vfunc for unmergeable_svalue.  */
    2324              : 
    2325              : bool
    2326          894 : unmergeable_svalue::implicitly_live_p (const svalue_set *live_svalues,
    2327              :                                        const region_model *model) const
    2328              : {
    2329          894 :   return get_arg ()->live_p (live_svalues, model);
    2330              : }
    2331              : 
    2332              : /* class compound_svalue : public svalue.  */
    2333              : 
    2334          611 : compound_svalue::compound_svalue (symbol::id_t id,
    2335              :                                   tree type,
    2336          611 :                                   concrete_binding_map &&map)
    2337          611 : : svalue (map.calc_complexity (), id, type), m_map (std::move (map))
    2338              : {
    2339              : #if CHECKING_P
    2340         2518 :   for (auto iter : *this)
    2341              :     {
    2342              :       /* We don't nest compound svalues.  */
    2343         1907 :       const svalue *sval = iter.second;
    2344         1907 :       gcc_assert (sval->get_kind () != SK_COMPOUND);
    2345              :     }
    2346              : #endif
    2347          611 : }
    2348              : 
    2349           50 : compound_svalue::compound_svalue (symbol::id_t id,
    2350              :                                   tree type,
    2351           50 :                                   const concrete_binding_map &map)
    2352           50 : : svalue (map.calc_complexity (), id, type), m_map (map)
    2353              : {
    2354              : #if CHECKING_P
    2355          122 :   for (auto iter : *this)
    2356              :     {
    2357              :       /* We don't nest compound svalues.  */
    2358           72 :       const svalue *sval = iter.second;
    2359           72 :       gcc_assert (sval->get_kind () != SK_COMPOUND);
    2360              :     }
    2361              : #endif
    2362           50 : }
    2363              : 
    2364              : /* Implementation of svalue::dump_to_pp vfunc for compound_svalue.  */
    2365              : 
    2366              : void
    2367            2 : compound_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
    2368              : {
    2369            2 :   if (simple)
    2370              :     {
    2371            2 :       pp_string (pp, "COMPOUND(");
    2372            2 :       if (get_type ())
    2373              :         {
    2374            0 :           print_quoted_type (pp, get_type ());
    2375            0 :           pp_string (pp, ", ");
    2376              :         }
    2377            2 :       pp_character (pp, '{');
    2378            2 :       m_map.dump_to_pp (pp, simple, false);
    2379            2 :       pp_string (pp, "})");
    2380              :     }
    2381              :   else
    2382              :     {
    2383            0 :       pp_string (pp, "compound_svalue (");
    2384            0 :       if (get_type ())
    2385              :         {
    2386            0 :           print_quoted_type (pp, get_type ());
    2387            0 :           pp_string (pp, ", ");
    2388              :         }
    2389            0 :       pp_character (pp, '{');
    2390            0 :       m_map.dump_to_pp (pp, simple, false);
    2391            0 :       pp_string (pp, "})");
    2392              :     }
    2393            2 : }
    2394              : 
    2395              : /* Implementation of svalue::print_dump_widget_label vfunc for
    2396              :    compound_svalue.  */
    2397              : 
    2398              : void
    2399            0 : compound_svalue::print_dump_widget_label (pretty_printer *pp) const
    2400              : {
    2401            0 :   pp_printf (pp, "compound_svalue");
    2402            0 : }
    2403              : 
    2404              : /* Implementation of svalue::add_dump_widget_children vfunc for
    2405              :    compound_svalue.  */
    2406              : 
    2407              : void
    2408            0 : compound_svalue::
    2409              : add_dump_widget_children (text_art::tree_widget &w,
    2410              :                           const text_art::dump_widget_info &dwi) const
    2411              : {
    2412            0 :   m_map.add_to_tree_widget (w, dwi);
    2413            0 : }
    2414              : 
    2415              : /* Implementation of svalue::accept vfunc for compound_svalue.  */
    2416              : 
    2417              : void
    2418           38 : compound_svalue::accept (visitor *v) const
    2419              : {
    2420          114 :   for (auto iter : m_map)
    2421           76 :     iter.second->accept (v);
    2422           38 :   v->visit_compound_svalue (this);
    2423           38 : }
    2424              : 
    2425              : /* Implementation of svalue::maybe_fold_bits_within vfunc
    2426              :    for compound_svalue.  */
    2427              : 
    2428              : const svalue *
    2429           56 : compound_svalue::maybe_fold_bits_within (tree type,
    2430              :                                          const bit_range &bits,
    2431              :                                          region_model_manager *mgr) const
    2432              : {
    2433           56 :   concrete_binding_map result_map;
    2434          256 :   for (auto iter : m_map)
    2435              :     {
    2436          200 :       const bit_range &iter_bits = iter.first;
    2437              : 
    2438              :       /* Ignore concrete bindings outside BITS.  */
    2439          200 :       if (!iter_bits.intersects_p (bits))
    2440           28 :         continue;
    2441              : 
    2442          172 :       const svalue *sval = iter.second;
    2443              :       /* Get the position of iter_bits relative to BITS.  */
    2444          172 :       bit_range result_location (iter_bits.get_start_bit_offset ()
    2445          172 :                                  - bits.get_start_bit_offset (),
    2446          172 :                                  iter_bits.m_size_in_bits);
    2447              :       /* If iter_bits starts after BITS, trim off leading bits
    2448              :          from the svalue and adjust binding location.  */
    2449          172 :       if (result_location.m_start_bit_offset < 0)
    2450              :         {
    2451            0 :           bit_size_t leading_bits_to_drop
    2452            0 :             = -result_location.m_start_bit_offset;
    2453            0 :           result_location = bit_range
    2454            0 :             (0, result_location.m_size_in_bits - leading_bits_to_drop);
    2455            0 :           bit_range bits_within_sval (leading_bits_to_drop,
    2456            0 :                                       result_location.m_size_in_bits);
    2457              :           /* Trim off leading bits from iter_sval.  */
    2458            0 :           sval = mgr->get_or_create_bits_within (NULL_TREE,
    2459              :                                                  bits_within_sval,
    2460              :                                                  sval);
    2461              :         }
    2462              :       /* If iter_bits finishes after BITS, trim off trailing bits
    2463              :          from the svalue and adjust binding location.  */
    2464          344 :       if (iter_bits.get_next_bit_offset ()
    2465          344 :           > bits.get_next_bit_offset ())
    2466              :         {
    2467           44 :           bit_size_t trailing_bits_to_drop
    2468           44 :             = (iter_bits.get_next_bit_offset ()
    2469           44 :                - bits.get_next_bit_offset ());
    2470           44 :           result_location = bit_range
    2471              :             (result_location.m_start_bit_offset,
    2472           44 :              result_location.m_size_in_bits - trailing_bits_to_drop);
    2473           44 :           bit_range bits_within_sval (0,
    2474           44 :                                       result_location.m_size_in_bits);
    2475              :           /* Trim off leading bits from iter_sval.  */
    2476           44 :           sval = mgr->get_or_create_bits_within (NULL_TREE,
    2477              :                                                  bits_within_sval,
    2478              :                                                  sval);
    2479              :         }
    2480          172 :       result_map.insert (result_location, sval);
    2481              :     }
    2482           56 :   return mgr->get_or_create_compound_svalue (type, std::move (result_map));
    2483           56 : }
    2484              : 
    2485              : /* class conjured_svalue : public svalue.  */
    2486              : 
    2487              : /* Implementation of svalue::dump_to_pp vfunc for conjured_svalue.  */
    2488              : 
    2489              : void
    2490         3194 : conjured_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
    2491              : {
    2492         3194 :   if (simple)
    2493              :     {
    2494         2804 :       pp_string (pp, "CONJURED(");
    2495         2804 :       pp_gimple_stmt_1 (pp, m_stmt, 0, (dump_flags_t)0);
    2496         2804 :       pp_string (pp, ", ");
    2497         2804 :       m_id_reg->dump_to_pp (pp, simple);
    2498         2804 :       pp_character (pp, ')');
    2499              :     }
    2500              :   else
    2501              :     {
    2502          390 :       pp_string (pp, "conjured_svalue (");
    2503          390 :       if (get_type ())
    2504              :         {
    2505          390 :           print_quoted_type (pp, get_type ());
    2506          390 :           pp_string (pp, ", ");
    2507              :         }
    2508          390 :       pp_gimple_stmt_1 (pp, m_stmt, 0, (dump_flags_t)0);
    2509          390 :       pp_string (pp, ", ");
    2510          390 :       m_id_reg->dump_to_pp (pp, simple);
    2511          390 :       pp_character (pp, ')');
    2512              :     }
    2513         3194 : }
    2514              : 
    2515              : /* Implementation of svalue::print_dump_widget_label vfunc for
    2516              :    conjured_svalue.  */
    2517              : 
    2518              : void
    2519            0 : conjured_svalue::print_dump_widget_label (pretty_printer *pp) const
    2520              : {
    2521            0 :   pp_printf (pp, "conjured_svalue (");
    2522            0 :   pp_gimple_stmt_1 (pp, m_stmt, 0, (dump_flags_t)0);
    2523            0 :   if (m_idx != 0)
    2524            0 :     pp_printf (pp, ", %i", m_idx);
    2525            0 :   pp_character (pp, ')');
    2526            0 : }
    2527              : 
    2528              : /* Implementation of svalue::add_dump_widget_children vfunc for
    2529              :    conjured_svalue.  */
    2530              : 
    2531              : void
    2532            0 : conjured_svalue::
    2533              : add_dump_widget_children (text_art::tree_widget &w,
    2534              :                           const text_art::dump_widget_info &dwi) const
    2535              : {
    2536            0 :   w.add_child (m_id_reg->make_dump_widget (dwi));
    2537            0 : }
    2538              : 
    2539              : /* Implementation of svalue::accept vfunc for conjured_svalue.  */
    2540              : 
    2541              : void
    2542      5321969 : conjured_svalue::accept (visitor *v) const
    2543              : {
    2544      5321969 :   m_id_reg->accept (v);
    2545      5321969 :   v->visit_conjured_svalue (this);
    2546      5321969 : }
    2547              : 
    2548              : /* Return true iff this conjured_svalue is for the LHS of the
    2549              :    stmt that conjured it.  */
    2550              : 
    2551              : bool
    2552            0 : conjured_svalue::lhs_value_p () const
    2553              : {
    2554            0 :   if (tree decl = m_id_reg->maybe_get_decl ())
    2555            0 :     return decl == gimple_get_lhs (m_stmt);
    2556              :   return false;
    2557              : }
    2558              : 
    2559              : /* class asm_output_svalue : public svalue.  */
    2560              : 
    2561              : /* Implementation of svalue::dump_to_pp vfunc for asm_output_svalue.  */
    2562              : 
    2563              : void
    2564           52 : asm_output_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
    2565              : {
    2566           52 :   if (simple)
    2567              :     {
    2568           52 :       pp_printf (pp, "ASM_OUTPUT(%qs, %%%i, {",
    2569              :                  get_asm_string (),
    2570              :                  get_output_idx ());
    2571          144 :       for (unsigned i = 0; i < m_num_inputs; i++)
    2572              :         {
    2573           92 :           if (i > 0)
    2574           40 :             pp_string (pp, ", ");
    2575           92 :           dump_input (pp, 0, m_input_arr[i], simple);
    2576              :         }
    2577           52 :       pp_string (pp, "})");
    2578              :     }
    2579              :   else
    2580              :     {
    2581            0 :       pp_printf (pp, "asm_output_svalue (%qs, %%%i, {",
    2582              :                  get_asm_string (),
    2583              :                  get_output_idx ());
    2584            0 :       for (unsigned i = 0; i < m_num_inputs; i++)
    2585              :         {
    2586            0 :           if (i > 0)
    2587            0 :             pp_string (pp, ", ");
    2588            0 :           dump_input (pp, 0, m_input_arr[i], simple);
    2589              :         }
    2590            0 :       pp_string (pp, "})");
    2591              :     }
    2592           52 : }
    2593              : 
    2594              : /* Implementation of svalue::print_dump_widget_label vfunc for
    2595              :    asm_output_svalue.  */
    2596              : 
    2597              : void
    2598            0 : asm_output_svalue::print_dump_widget_label (pretty_printer *pp) const
    2599              : {
    2600            0 :   pp_printf (pp, "asm_output_svalue(%qs, %%%i)",
    2601              :              get_asm_string (),
    2602              :              get_output_idx ());
    2603            0 : }
    2604              : 
    2605              : /* Implementation of svalue::add_dump_widget_children vfunc for
    2606              :    asm_output_svalue.  */
    2607              : 
    2608              : void
    2609            0 : asm_output_svalue::
    2610              : add_dump_widget_children (text_art::tree_widget &w,
    2611              :                           const text_art::dump_widget_info &dwi) const
    2612              : {
    2613            0 :   for (unsigned i = 0; i < m_num_inputs; i++)
    2614              :     {
    2615            0 :       pretty_printer pp;
    2616            0 :       pp_printf (&pp, "arg %i", i);
    2617            0 :       w.add_child (m_input_arr[i]->make_dump_widget (dwi,
    2618              :                                                      pp_formatted_text (&pp)));
    2619            0 :     }
    2620            0 : }
    2621              : 
    2622              : /* Subroutine of asm_output_svalue::dump_to_pp.  */
    2623              : 
    2624              : void
    2625           92 : asm_output_svalue::dump_input (pretty_printer *pp,
    2626              :                                unsigned input_idx,
    2627              :                                const svalue *sval,
    2628              :                                bool simple) const
    2629              : {
    2630           92 :   pp_printf (pp, "%%%i: ", input_idx_to_asm_idx (input_idx));
    2631           92 :   sval->dump_to_pp (pp, simple);
    2632           92 : }
    2633              : 
    2634              : /* Convert INPUT_IDX from an index into the array of inputs
    2635              :    into the index of all operands for the asm stmt.  */
    2636              : 
    2637              : unsigned
    2638           92 : asm_output_svalue::input_idx_to_asm_idx (unsigned input_idx) const
    2639              : {
    2640           92 :   return input_idx + m_num_outputs;
    2641              : }
    2642              : 
    2643              : /* Implementation of svalue::accept vfunc for asm_output_svalue.  */
    2644              : 
    2645              : void
    2646         6099 : asm_output_svalue::accept (visitor *v) const
    2647              : {
    2648        16803 :   for (unsigned i = 0; i < m_num_inputs; i++)
    2649        10704 :     m_input_arr[i]->accept (v);
    2650         6099 :   v->visit_asm_output_svalue (this);
    2651         6099 : }
    2652              : 
    2653              : /* class const_fn_result_svalue : public svalue.  */
    2654              : 
    2655              : /* Implementation of svalue::dump_to_pp vfunc for const_fn_result_svalue.  */
    2656              : 
    2657              : void
    2658         4391 : const_fn_result_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
    2659              : {
    2660         4391 :   if (simple)
    2661              :     {
    2662         3945 :       pp_printf (pp, "CONST_FN_RESULT(%qD, {", m_fndecl);
    2663         3993 :       for (unsigned i = 0; i < m_num_inputs; i++)
    2664              :         {
    2665           48 :           if (i > 0)
    2666            0 :             pp_string (pp, ", ");
    2667           48 :           dump_input (pp, i, m_input_arr[i], simple);
    2668              :         }
    2669         3945 :       pp_string (pp, "})");
    2670              :     }
    2671              :   else
    2672              :     {
    2673          446 :       pp_printf (pp, "CONST_FN_RESULT(%qD, {", m_fndecl);
    2674          446 :       for (unsigned i = 0; i < m_num_inputs; i++)
    2675              :         {
    2676            0 :           if (i > 0)
    2677            0 :             pp_string (pp, ", ");
    2678            0 :           dump_input (pp, i, m_input_arr[i], simple);
    2679              :         }
    2680          446 :       pp_string (pp, "})");
    2681              :     }
    2682         4391 : }
    2683              : 
    2684              : /* Implementation of svalue::print_dump_widget_label vfunc for
    2685              :    const_fn_result_svalue.  */
    2686              : 
    2687              : void
    2688            0 : const_fn_result_svalue::print_dump_widget_label (pretty_printer *pp) const
    2689              : {
    2690            0 :   pp_printf (pp, "const_fn_result_svalue: %qD", m_fndecl);
    2691            0 : }
    2692              : 
    2693              : /* Implementation of svalue::add_dump_widget_children vfunc for
    2694              :    const_fn_result_svalue.  */
    2695              : 
    2696              : void
    2697            0 : const_fn_result_svalue::
    2698              : add_dump_widget_children (text_art::tree_widget &w,
    2699              :                           const text_art::dump_widget_info &dwi) const
    2700              : {
    2701            0 :   for (unsigned i = 0; i < m_num_inputs; i++)
    2702              :     {
    2703            0 :       pretty_printer pp;
    2704            0 :       pp_printf (&pp, "arg %i", i);
    2705            0 :       w.add_child (m_input_arr[i]->make_dump_widget (dwi,
    2706              :                                                      pp_formatted_text (&pp)));
    2707            0 :     }
    2708            0 : }
    2709              : 
    2710              : /* Subroutine of const_fn_result_svalue::dump_to_pp.  */
    2711              : 
    2712              : void
    2713           48 : const_fn_result_svalue::dump_input (pretty_printer *pp,
    2714              :                                     unsigned input_idx,
    2715              :                                     const svalue *sval,
    2716              :                                     bool simple) const
    2717              : {
    2718           48 :   pp_printf (pp, "arg%i: ", input_idx);
    2719           48 :   sval->dump_to_pp (pp, simple);
    2720           48 : }
    2721              : 
    2722              : /* Implementation of svalue::accept vfunc for const_fn_result_svalue.  */
    2723              : 
    2724              : void
    2725         8497 : const_fn_result_svalue::accept (visitor *v) const
    2726              : {
    2727        14306 :   for (unsigned i = 0; i < m_num_inputs; i++)
    2728         5809 :     m_input_arr[i]->accept (v);
    2729         8497 :   v->visit_const_fn_result_svalue (this);
    2730         8497 : }
    2731              : 
    2732              : } // namespace ana
    2733              : 
    2734              : #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.