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