LCOV - code coverage report
Current view: top level - gcc/analyzer - region.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 73.8 % 1076 794
Test Date: 2026-05-30 15:37:04 Functions: 66.2 % 148 98
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* Regions of memory.
       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 "ordered-hash-map.h"
      24              : #include "options.h"
      25              : #include "cgraph.h"
      26              : #include "cfg.h"
      27              : #include "digraph.h"
      28              : #include "sbitmap.h"
      29              : #include "fold-const.h"
      30              : #include "tree-ssa.h"
      31              : 
      32              : #include "analyzer/analyzer-logging.h"
      33              : #include "analyzer/supergraph.h"
      34              : #include "analyzer/call-string.h"
      35              : #include "analyzer/program-point.h"
      36              : #include "analyzer/store.h"
      37              : #include "analyzer/region.h"
      38              : #include "analyzer/region-model.h"
      39              : #include "analyzer/sm.h"
      40              : #include "analyzer/program-state.h"
      41              : #include "text-art/dump.h"
      42              : 
      43              : #if ENABLE_ANALYZER
      44              : 
      45              : namespace ana {
      46              : 
      47              : bool
      48          854 : compare_bit_offsets_p (bit_offset_t a,
      49              :                        enum tree_code op,
      50              :                        bit_offset_t b)
      51              : {
      52          854 :   switch (op)
      53              :     {
      54            0 :     default:
      55            0 :       gcc_unreachable ();
      56          790 :     case EQ_EXPR: return a == b;
      57            0 :     case NE_EXPR: return a != b;
      58           16 :     case GE_EXPR: return a >= b;
      59           16 :     case LE_EXPR: return a <= b;
      60           16 :     case GT_EXPR: return a > b;
      61           16 :     case LT_EXPR: return a < b;
      62              :     }
      63              : }
      64              : 
      65              : region_offset
      66         1314 : region_offset::make_byte_offset (const region *base_region,
      67              :                                  const svalue *num_bytes_sval)
      68              : {
      69         1314 :   if (tree num_bytes_cst = num_bytes_sval->maybe_get_constant ())
      70              :     {
      71          982 :       gcc_assert (TREE_CODE (num_bytes_cst) == INTEGER_CST);
      72          982 :       bit_offset_t num_bits = wi::to_offset (num_bytes_cst) * BITS_PER_UNIT;
      73          982 :       return make_concrete (base_region, num_bits);
      74              :     }
      75              :   else
      76              :     {
      77          332 :       return make_symbolic (base_region, num_bytes_sval);
      78              :     }
      79              : }
      80              : 
      81              : const svalue &
      82          580 : region_offset::calc_symbolic_bit_offset (region_model_manager *mgr) const
      83              : {
      84          580 :   if (symbolic_p ())
      85              :     {
      86          127 :       const svalue *bits_per_byte
      87          127 :         = mgr->get_or_create_int_cst (NULL_TREE, BITS_PER_UNIT);
      88          127 :       return *mgr->get_or_create_binop (NULL_TREE, MULT_EXPR,
      89          127 :                                         m_sym_offset, bits_per_byte);
      90              :     }
      91              :   else
      92          453 :     return *mgr->get_or_create_int_cst (NULL_TREE, m_offset);
      93              : }
      94              : 
      95              : const svalue *
      96          206 : region_offset::calc_symbolic_byte_offset (region_model_manager *mgr) const
      97              : {
      98          206 :   if (symbolic_p ())
      99              :     return m_sym_offset;
     100              :   else
     101              :     {
     102           18 :       byte_offset_t concrete_byte_offset;
     103           18 :       if (get_concrete_byte_offset (&concrete_byte_offset))
     104           18 :         return mgr->get_or_create_int_cst (size_type_node,
     105           18 :                                            concrete_byte_offset);
     106              :       else
     107              :         /* Can't handle bitfields; return UNKNOWN.  */
     108            0 :         return mgr->get_or_create_unknown_svalue (size_type_node);
     109              :     }
     110              : }
     111              : 
     112              : void
     113            0 : region_offset::dump_to_pp (pretty_printer *pp, bool simple) const
     114              : {
     115            0 :   pp_string (pp, "{");
     116            0 :   m_base_region->dump_to_pp (pp, simple);
     117            0 :   if (symbolic_p ())
     118              :     {
     119            0 :       pp_string (pp, " byte ");
     120            0 :       m_sym_offset->dump_to_pp (pp, simple);
     121              :     }
     122              :   else
     123              :     {
     124            0 :       if (m_offset % BITS_PER_UNIT == 0)
     125              :         {
     126            0 :           pp_string (pp, " byte ");
     127            0 :           pp_wide_int (pp, m_offset / BITS_PER_UNIT, SIGNED);
     128              :         }
     129              :       else
     130              :         {
     131            0 :           pp_string (pp, " bit ");
     132            0 :           pp_wide_int (pp, m_offset, SIGNED);
     133              :         }
     134              :     }
     135            0 :   pp_string (pp, "}");
     136            0 : }
     137              : 
     138              : DEBUG_FUNCTION void
     139            0 : region_offset::dump (bool simple) const
     140              : {
     141            0 :   tree_dump_pretty_printer pp (stderr);
     142            0 :   dump_to_pp (&pp, simple);
     143            0 :   pp_newline (&pp);
     144            0 : }
     145              : 
     146              : /* An svalue that matches the pattern (BASE * FACTOR) + OFFSET
     147              :    where FACTOR or OFFSET could be the identity (represented as nullptr).  */
     148              : 
     149              : struct linear_op
     150              : {
     151         5470 :   linear_op (const svalue *base,
     152              :              const svalue *factor,
     153              :              const svalue *offset)
     154         1868 :   : m_base (base), m_factor (factor), m_offset (offset)
     155              :   {
     156              :   }
     157              : 
     158         3452 :   bool maybe_get_cst_factor (bit_offset_t *out) const
     159              :   {
     160         3452 :     if (m_factor == nullptr)
     161              :       {
     162          732 :         *out = 1;
     163          732 :         return true;
     164              :       }
     165         2720 :     if (tree cst_factor = m_factor->maybe_get_constant ())
     166              :       {
     167         2720 :         *out = wi::to_offset (cst_factor);
     168         2720 :         return true;
     169              :       }
     170              :     return false;
     171              :   }
     172              : 
     173         3126 :   bool maybe_get_cst_offset (bit_offset_t *out) const
     174              :   {
     175         3126 :     if (m_offset == nullptr)
     176              :       {
     177          842 :         *out = 0;
     178          842 :         return true;
     179              :       }
     180         2284 :     if (tree cst_offset = m_offset->maybe_get_constant ())
     181              :       {
     182         2222 :         *out = wi::to_offset (cst_offset);
     183         2222 :         return true;
     184              :       }
     185              :     return false;
     186              :   }
     187              : 
     188              :   static tristate
     189         1675 :   less (const linear_op &a, const linear_op &b)
     190              :   {
     191              :     /* Same base.  */
     192         1675 :     if (a.m_base == b.m_base)
     193              :       {
     194         1611 :         bit_offset_t a_wi_factor;
     195         1611 :         bit_offset_t b_wi_factor;
     196         1611 :         if (a.maybe_get_cst_factor (&a_wi_factor)
     197         1611 :             && b.maybe_get_cst_factor (&b_wi_factor))
     198              :           {
     199         1611 :             if (a_wi_factor != b_wi_factor)
     200          172 :               return tristate (a_wi_factor < b_wi_factor);
     201              :             else
     202              :               {
     203         1495 :                 bit_offset_t a_wi_offset;
     204         1495 :                 bit_offset_t b_wi_offset;
     205         1495 :                 if (a.maybe_get_cst_offset (&a_wi_offset)
     206         1495 :                     && b.maybe_get_cst_offset (&b_wi_offset))
     207         2498 :                   return tristate (a_wi_offset < b_wi_offset);
     208              :               }
     209              :           }
     210              :       }
     211          124 :     return tristate::unknown ();
     212              :   }
     213              : 
     214              :   static tristate
     215          115 :   le (const linear_op &a, const linear_op &b)
     216              :   {
     217              :     /* Same base.  */
     218          115 :     if (a.m_base == b.m_base)
     219              :       {
     220          115 :         bit_offset_t a_wi_factor;
     221          115 :         bit_offset_t b_wi_factor;
     222          115 :         if (a.maybe_get_cst_factor (&a_wi_factor)
     223          115 :             && b.maybe_get_cst_factor (&b_wi_factor))
     224              :           {
     225          115 :             if (a_wi_factor != b_wi_factor)
     226           32 :               return tristate (a_wi_factor <= b_wi_factor);
     227              :             else
     228              :               {
     229           99 :                 bit_offset_t a_wi_offset;
     230           99 :                 bit_offset_t b_wi_offset;
     231           99 :                 if (a.maybe_get_cst_offset (&a_wi_offset)
     232           99 :                     && b.maybe_get_cst_offset (&b_wi_offset))
     233          140 :                   return tristate (a_wi_offset <= b_wi_offset);
     234              :               }
     235              :           }
     236              :       }
     237            2 :     return tristate::unknown ();
     238              :   }
     239              : 
     240              :   static bool
     241         3680 :   from_svalue (const svalue &sval, linear_op *out)
     242              :   {
     243         3680 :     switch (sval.get_kind ())
     244              :       {
     245              :       default:
     246              :         break;
     247         3602 :       case SK_BINOP:
     248         3602 :         {
     249         3602 :           const binop_svalue &binop_sval ((const binop_svalue &)sval);
     250         3602 :           if (binop_sval.get_op () == MULT_EXPR)
     251              :             {
     252         1078 :               *out = linear_op (binop_sval.get_arg0 (),
     253              :                                 binop_sval.get_arg1 (),
     254         1078 :                                 nullptr);
     255         1078 :               return true;
     256              :             }
     257         2524 :           else if (binop_sval.get_op () == PLUS_EXPR)
     258              :             {
     259         2524 :               if (binop_sval.get_arg0 ()->get_kind () == SK_BINOP)
     260              :                 {
     261         1786 :                   const binop_svalue &inner_binop_sval
     262         1786 :                     ((const binop_svalue &)*binop_sval.get_arg0 ());
     263         1786 :                   if (inner_binop_sval.get_op () == MULT_EXPR)
     264              :                     {
     265         1642 :                       *out = linear_op (inner_binop_sval.get_arg0 (),
     266              :                                         inner_binop_sval.get_arg1 (),
     267         1642 :                                         binop_sval.get_arg1 ());
     268         1642 :                       return true;
     269              :                     }
     270              :                 }
     271              : 
     272          882 :               *out = linear_op (binop_sval.get_arg0 (),
     273              :                                 nullptr,
     274          882 :                                 binop_sval.get_arg1 ());
     275          882 :               return true;
     276              :             }
     277              :         }
     278              :         break;
     279              :       }
     280              :     return false;
     281              :   }
     282              : 
     283              :   const svalue *m_base;
     284              :   const svalue *m_factor;
     285              :   const svalue *m_offset;
     286              : };
     287              : 
     288              : bool
     289        24035 : operator< (const region_offset &a, const region_offset &b)
     290              : {
     291        24035 :   if (a.symbolic_p ())
     292              :     {
     293         2152 :       if (b.symbolic_p ())
     294              :         {
     295              :           /* Symbolic vs symbolic.  */
     296         1743 :           const svalue &a_sval = *a.get_symbolic_byte_offset ();
     297         1743 :           const svalue &b_sval = *b.get_symbolic_byte_offset ();
     298              : 
     299         1743 :           linear_op op_a (nullptr, nullptr, nullptr);
     300         1743 :           linear_op op_b (nullptr, nullptr, nullptr);
     301         1743 :           if (linear_op::from_svalue (a_sval, &op_a)
     302         1743 :               && linear_op::from_svalue (b_sval, &op_b))
     303              :             {
     304         1675 :               tristate ts = linear_op::less (op_a, op_b);
     305         1675 :               if (ts.is_true ())
     306         1743 :                 return true;
     307         1243 :               else if (ts.is_false ())
     308              :                 return false;
     309              :             }
     310              :           /* Use svalue's deterministic order, for now.  */
     311          192 :           return (svalue::cmp_ptr (a.get_symbolic_byte_offset (),
     312              :                                    b.get_symbolic_byte_offset ())
     313          192 :                   < 0);
     314              :         }
     315              :       else
     316              :         /* Symbolic vs concrete: put all symbolic after all concrete.  */
     317              :         return false;
     318              :     }
     319              :   else
     320              :     {
     321        21883 :       if (b.symbolic_p ())
     322              :         /* Concrete vs symbolic: put all concrete before all symbolic.  */
     323              :         return true;
     324              :       else
     325              :         /* Concrete vs concrete.  */
     326        21526 :         return a.get_bit_offset () < b.get_bit_offset ();
     327              :     }
     328              : }
     329              : 
     330              : bool
     331         1567 : operator<= (const region_offset &a, const region_offset &b)
     332              : {
     333         1567 :   if (a.symbolic_p ())
     334              :     {
     335          168 :       if (b.symbolic_p ())
     336              :         {
     337              :           /* Symbolic vs symbolic.  */
     338          125 :           const svalue &a_sval = *a.get_symbolic_byte_offset ();
     339          125 :           const svalue &b_sval = *b.get_symbolic_byte_offset ();
     340              : 
     341          125 :           linear_op op_a (nullptr, nullptr, nullptr);
     342          125 :           linear_op op_b (nullptr, nullptr, nullptr);
     343          125 :           if (linear_op::from_svalue (a_sval, &op_a)
     344          125 :               && linear_op::from_svalue (b_sval, &op_b))
     345              :             {
     346          115 :               tristate ts = linear_op::le (op_a, op_b);
     347          115 :               if (ts.is_true ())
     348          125 :                 return true;
     349           61 :               else if (ts.is_false ())
     350              :                 return false;
     351              :             }
     352              :           /* Use svalue's deterministic order, for now.  */
     353           12 :           return (svalue::cmp_ptr (a.get_symbolic_byte_offset (),
     354              :                                    b.get_symbolic_byte_offset ())
     355           12 :                   <= 0);
     356              :         }
     357              :       else
     358              :         /* Symbolic vs concrete: put all symbolic after all concrete.  */
     359              :         return false;
     360              :     }
     361              :   else
     362              :     {
     363         1399 :       if (b.symbolic_p ())
     364              :         /* Concrete vs symbolic: put all concrete before all symbolic.  */
     365              :         return true;
     366              :       else
     367              :         /* Concrete vs concrete.  */
     368         1324 :         return a.get_bit_offset () <= b.get_bit_offset ();
     369              :     }
     370              : }
     371              : 
     372              : bool
     373           30 : operator> (const region_offset &a, const region_offset &b)
     374              : {
     375           30 :   return b < a;
     376              : }
     377              : 
     378              : bool
     379          136 : operator>= (const region_offset &a, const region_offset &b)
     380              : {
     381          136 :   return b <= a;
     382              : }
     383              : 
     384              : region_offset
     385         5176 : strip_types (const region_offset &offset, region_model_manager &mgr)
     386              : {
     387         5176 :   if (offset.symbolic_p ())
     388          877 :     return region_offset::make_symbolic
     389          877 :       (offset.get_base_region (),
     390              :        strip_types (offset.get_symbolic_byte_offset (),
     391          877 :                     mgr));
     392              :   else
     393         4299 :     return offset;
     394              : }
     395              : 
     396              : /* Ignoring base regions, compare the byte offset of OFFSET_A and OFFSET_B
     397              :    within their respective base regions.  */
     398              : 
     399              : static tristate
     400         1070 : eval_byte_offset_comparison (region_offset offset_a,
     401              :                              enum tree_code op,
     402              :                              region_offset offset_b,
     403              :                              const region_model &model)
     404              : {
     405         1070 :   if (offset_a.concrete_p ())
     406              :     {
     407          854 :       if (offset_b.concrete_p ())
     408              :         {
     409              :           // Concrete vs concrete: we know the result:
     410          854 :           return compare_bit_offsets_p (offset_a.get_bit_offset (),
     411              :                                         op,
     412          854 :                                         offset_b.get_bit_offset ());
     413              :         }
     414              :       else
     415              :         {
     416              :           // Concrete vs symbolic
     417              :           // TODO: There may be room for improved precision here
     418            0 :           return tristate::unknown ();
     419              :         }
     420              :     }
     421              :   else
     422              :     {
     423          216 :       if (offset_b.concrete_p ())
     424              :         {
     425              :           // Symbolic vs concrete
     426              :           // TODO: There may be room for improved precision here
     427            0 :           return tristate::unknown ();
     428              :         }
     429              :       else
     430              :         {
     431              :           // Symbolic vs symbolic
     432          216 :           const svalue *offset_sval_a = offset_a.get_symbolic_byte_offset ();
     433          216 :           const svalue *offset_sval_b = offset_b.get_symbolic_byte_offset ();
     434          216 :           return model.eval_condition (offset_sval_a, op, offset_sval_b);
     435              :         }
     436              :     }
     437              : }
     438              : 
     439              : /* Evaluate the condition LHS_OFFSET OP RHS_OFFSET for comparing
     440              :    pointers.
     441              : 
     442              :    See if they point to the same base region, and if we know about
     443              :    the offsets within their regions.
     444              : 
     445              :    Use MODEL for aliasing information and any knowledge from
     446              :    constraint_manager about ordering of pointers.  */
     447              : 
     448              : tristate
     449          910 : eval_region_offset_comparison (region_offset lhs_offset,
     450              :                                enum tree_code op,
     451              :                                region_offset rhs_offset,
     452              :                                const region_model &model)
     453              : {
     454              :   /* Try to determine if they're the same base region.  */
     455          910 :   const tristate same_base_region
     456          910 :     = model.get_store ()->eval_alias (lhs_offset.get_base_region (),
     457              :                                       rhs_offset.get_base_region (),
     458              :                                       model);
     459              : 
     460              :   /* Try to determine if they're the same offset relative to their
     461              :      base region.  */
     462          910 :   const tristate same_byte_offset
     463          910 :     = eval_byte_offset_comparison (lhs_offset, EQ_EXPR, rhs_offset, model);
     464              : 
     465              :   /* With that, we might know if they're equal/non-equal.  */
     466          910 :   const tristate equality = same_base_region.and_(same_byte_offset);
     467              : 
     468          910 :   switch (op)
     469              :     {
     470            0 :     default:
     471            0 :       gcc_unreachable ();
     472              : 
     473          324 :     case EQ_EXPR:
     474          324 :       return equality;
     475              : 
     476          290 :     case NE_EXPR:
     477          290 :       return equality.not_ ();
     478              : 
     479          148 :     case GE_EXPR:
     480          148 :     case LE_EXPR:
     481          148 :       if (equality.is_true ())
     482           16 :         return tristate (true);
     483          132 :       else if (same_base_region.is_true ())
     484           80 :         return eval_byte_offset_comparison (lhs_offset, op, rhs_offset, model);
     485              :       else
     486           52 :         return tristate::unknown ();
     487              : 
     488          148 :     case GT_EXPR:
     489          148 :     case LT_EXPR:
     490          148 :       if (equality.is_true ())
     491           16 :         return tristate (false);
     492          132 :       else if (same_base_region.is_true ())
     493           80 :         return eval_byte_offset_comparison (lhs_offset, op, rhs_offset, model);
     494              :       else
     495           52 :         return tristate::unknown ();
     496              :     }
     497              : }
     498              : 
     499              : /* class region and its various subclasses.  */
     500              : 
     501              : /* class region.  */
     502              : 
     503       219108 : region::~region ()
     504              : {
     505       219108 :   delete m_cached_offset;
     506       219108 : }
     507              : 
     508              : /* Determine the base region for this region: when considering bindings
     509              :    for this region, the base region is the ancestor which identifies
     510              :    which cluster they should be partitioned into.
     511              :    Regions within the same struct/union/array are in the same cluster.
     512              :    Different decls are in different clusters.  */
     513              : 
     514              : const region *
     515     51569241 : region::get_base_region () const
     516              : {
     517     51569241 :   const region *iter = this;
     518     53459902 :   while (iter)
     519              :     {
     520     53459902 :       switch (iter->get_kind ())
     521              :         {
     522      1890661 :         case RK_FIELD:
     523      1890661 :         case RK_ELEMENT:
     524      1890661 :         case RK_OFFSET:
     525      1890661 :         case RK_SIZED:
     526      1890661 :         case RK_BIT_RANGE:
     527      1890661 :         case RK_CAST:
     528      1890661 :           iter = iter->get_parent_region ();
     529      1890661 :           continue;
     530              :         default:
     531              :           return iter;
     532              :         }
     533              :     }
     534              :   return iter;
     535              : }
     536              : 
     537              : /* Return true if get_base_region() == this for this region.  */
     538              : 
     539              : bool
     540       253347 : region::base_region_p () const
     541              : {
     542       253347 :   switch (get_kind ())
     543              :     {
     544              :     /* Region kinds representing a descendent of a base region.  */
     545              :     case RK_FIELD:
     546              :     case RK_ELEMENT:
     547              :     case RK_OFFSET:
     548              :     case RK_SIZED:
     549              :     case RK_CAST:
     550              :     case RK_BIT_RANGE:
     551              :       return false;
     552              : 
     553       191738 :     default:
     554       191738 :       return true;
     555              :     }
     556              : }
     557              : 
     558              : /* Return true if this region is ELDER or one of its descendents.  */
     559              : 
     560              : bool
     561       259382 : region::descendent_of_p (const region *elder) const
     562              : {
     563       259382 :   const region *iter = this;
     564       999722 :   while (iter)
     565              :     {
     566       800119 :       if (iter == elder)
     567              :         return true;
     568       740340 :       iter = iter->get_parent_region ();
     569              :     }
     570              :   return false;
     571              : }
     572              : 
     573              : /* If this region is a frame_region, or a descendent of one, return it.
     574              :    Otherwise return nullptr.  */
     575              : 
     576              : const frame_region *
     577      2739089 : region::maybe_get_frame_region () const
     578              : {
     579      2739089 :   const region *iter = this;
     580      6690907 :   while (iter)
     581              :     {
     582      6094641 :       if (const frame_region *frame_reg = iter->dyn_cast_frame_region ())
     583              :         return frame_reg;
     584      3951818 :       iter = iter->get_parent_region ();
     585              :     }
     586              :   return nullptr;
     587              : }
     588              : 
     589              : /* Get the memory space of this region.  */
     590              : 
     591              : enum memory_space
     592      3929420 : region::get_memory_space () const
     593              : {
     594      3929420 :   const region *iter = this;
     595      8251636 :   while (iter)
     596              :     {
     597      7513791 :       switch (iter->get_kind ())
     598              :         {
     599      4322216 :         default:
     600      4322216 :           break;
     601              :         case RK_GLOBALS:
     602              :           return MEMSPACE_GLOBALS;
     603              :         case RK_CODE:
     604              :         case RK_FUNCTION:
     605              :         case RK_LABEL:
     606              :           return MEMSPACE_CODE;
     607              :         case RK_FRAME:
     608              :         case RK_STACK:
     609              :         case RK_ALLOCA:
     610              :           return MEMSPACE_STACK;
     611              :         case RK_HEAP:
     612              :         case RK_HEAP_ALLOCATED:
     613              :           return MEMSPACE_HEAP;
     614              :         case RK_STRING:
     615              :           return MEMSPACE_READONLY_DATA;
     616              :         case RK_PRIVATE:
     617              :           return MEMSPACE_PRIVATE;
     618              :         }
     619      4322216 :       iter = iter->get_parent_region ();
     620              :     }
     621              :   return MEMSPACE_UNKNOWN;
     622              : }
     623              : 
     624              : /* Subroutine for use by region_model_manager::get_or_create_initial_value.
     625              :    Return true if this region has an initial_svalue.
     626              :    Return false if attempting to use INIT_VAL(this_region) should give
     627              :    the "UNINITIALIZED" poison value.  */
     628              : 
     629              : bool
     630      3185943 : region::can_have_initial_svalue_p () const
     631              : {
     632      3185943 :   const region *base_reg = get_base_region ();
     633              : 
     634              :   /* Check for memory spaces that are uninitialized by default.  */
     635      3185943 :   enum memory_space mem_space = base_reg->get_memory_space ();
     636      3185943 :   switch (mem_space)
     637              :     {
     638            0 :     default:
     639            0 :       gcc_unreachable ();
     640              :     case MEMSPACE_UNKNOWN:
     641              :     case MEMSPACE_CODE:
     642              :     case MEMSPACE_GLOBALS:
     643              :     case MEMSPACE_READONLY_DATA:
     644              :     case MEMSPACE_PRIVATE:
     645              :       /* Such regions have initial_svalues.  */
     646              :       return true;
     647              : 
     648              :     case MEMSPACE_HEAP:
     649              :       /* Heap allocations are uninitialized by default.  */
     650              :       return false;
     651              : 
     652      2281213 :     case MEMSPACE_STACK:
     653      2281213 :       if (tree decl = base_reg->maybe_get_decl ())
     654              :         {
     655              :           /* See the assertion in frame_region::get_region_for_local for the
     656              :              tree codes we need to handle here.  */
     657      2275295 :           switch (TREE_CODE (decl))
     658              :             {
     659            0 :             default:
     660            0 :               gcc_unreachable ();
     661              : 
     662              :             case PARM_DECL:
     663              :               /* Parameters have initial values.  */
     664              :               return true;
     665              : 
     666              :             case VAR_DECL:
     667              :             case RESULT_DECL:
     668              :               /* Function locals don't have initial values.  */
     669              :               return false;
     670              : 
     671      2188067 :             case SSA_NAME:
     672      2188067 :               {
     673              :                 /* Some SSA names have an implicit default defined value.  */
     674      2188067 :                 tree ssa_name = decl;
     675      2188067 :                 if (SSA_NAME_IS_DEFAULT_DEF (ssa_name))
     676      2127624 :                   return ssa_defined_default_def_p (ssa_name);
     677              :                 /* Others don't.  */
     678              :                 return false;
     679              :               }
     680              :             }
     681              :         }
     682              : 
     683              :       /* If we have an on-stack region that isn't associated with a decl
     684              :          or SSA name, then we have VLA/alloca, which is uninitialized.  */
     685              :       return false;
     686              :     }
     687              : }
     688              : 
     689              : /* For regions within a global decl, get the svalue for the initial
     690              :    value of this region when the program starts, caching the result.  */
     691              : 
     692              : const svalue *
     693        14707 : region::get_initial_value_at_main (region_model_manager *mgr) const
     694              : {
     695        14707 :   if (!m_cached_init_sval_at_main)
     696          421 :     m_cached_init_sval_at_main = calc_initial_value_at_main (mgr);
     697        14707 :   return m_cached_init_sval_at_main;
     698              : }
     699              : 
     700              : /* Implementation of region::get_initial_value_at_main.  */
     701              : 
     702              : const svalue *
     703          421 : region::calc_initial_value_at_main (region_model_manager *mgr) const
     704              : {
     705          421 :   const decl_region *base_reg = get_base_region ()->dyn_cast_decl_region ();
     706          421 :   gcc_assert (base_reg);
     707              : 
     708              :   /* Attempt to get the initializer value for base_reg.  */
     709          842 :   if (const svalue *base_reg_init
     710          421 :       = base_reg->get_svalue_for_initializer (mgr))
     711              :     {
     712          304 :       if (this == base_reg)
     713              :         return base_reg_init;
     714              :       else
     715              :         {
     716              :           /* Get the value for REG within base_reg_init.  */
     717          168 :           binding_cluster c (*mgr->get_store_manager (), base_reg);
     718          168 :           c.bind (mgr->get_store_manager (), base_reg, base_reg_init);
     719          168 :           const svalue *sval
     720          168 :             = c.get_any_binding (mgr->get_store_manager (), this);
     721          168 :           if (sval)
     722              :             {
     723          167 :               if (get_type ())
     724          147 :                 sval = mgr->get_or_create_cast (get_type (), sval);
     725          167 :               return sval;
     726              :             }
     727          168 :         }
     728              :     }
     729              : 
     730              :   /* Otherwise, return INIT_VAL(REG).  */
     731          118 :   return mgr->get_or_create_initial_value (this);
     732              : }
     733              : 
     734              : /* If this region is a decl_region, return the decl.
     735              :    Otherwise return NULL_TREE.  */
     736              : 
     737              : tree
     738      3489931 : region::maybe_get_decl () const
     739              : {
     740      3489931 :   if (const decl_region *decl_reg = dyn_cast_decl_region ())
     741      3119909 :     return decl_reg->get_decl ();
     742              :   return NULL_TREE;
     743              : }
     744              : 
     745              : /* Get the region_offset for this region (calculating it on the
     746              :    first call and caching it internally).  */
     747              : 
     748              : region_offset
     749      4867405 : region::get_offset (region_model_manager *mgr) const
     750              : {
     751      4867405 :   if(!m_cached_offset)
     752       150169 :     m_cached_offset = new region_offset (calc_offset (mgr));
     753      4867405 :   return *m_cached_offset;
     754              : }
     755              : 
     756              : /* Get the region_offset for immediately beyond this region.  */
     757              : 
     758              : region_offset
     759         1031 : region::get_next_offset (region_model_manager *mgr) const
     760              : {
     761         1031 :   region_offset start = get_offset (mgr);
     762              : 
     763         1031 :   bit_size_t bit_size;
     764         1031 :   if (get_bit_size (&bit_size))
     765              :     {
     766         1013 :       if (start.concrete_p ())
     767              :         {
     768          825 :           bit_offset_t next_bit_offset = start.get_bit_offset () + bit_size;
     769          825 :           return region_offset::make_concrete (start.get_base_region (),
     770              :                                                next_bit_offset);
     771              :         }
     772              :     }
     773              : 
     774          206 :   const svalue *start_byte_offset_sval = start.calc_symbolic_byte_offset (mgr);
     775          206 :   const svalue *byte_size_sval = get_byte_size_sval (mgr);
     776          206 :   const svalue *sum_sval
     777          206 :     = mgr->get_or_create_binop (size_type_node,
     778              :                                 PLUS_EXPR,
     779              :                                 start_byte_offset_sval,
     780              :                                 byte_size_sval);
     781          206 :   return region_offset::make_symbolic (start.get_base_region (),
     782          206 :                                        sum_sval);
     783              : }
     784              : 
     785              : /* Base class implementation of region::get_byte_size vfunc.
     786              :    If the size of this region (in bytes) is known statically, write it to *OUT
     787              :    and return true.
     788              :    Otherwise return false.  */
     789              : 
     790              : bool
     791         6274 : region::get_byte_size (byte_size_t *out) const
     792              : {
     793         6274 :   tree type = get_type ();
     794              : 
     795              :   /* Bail out e.g. for heap-allocated regions.  */
     796         6274 :   if (!type)
     797              :     return false;
     798              : 
     799         6118 :   HOST_WIDE_INT bytes = int_size_in_bytes (type);
     800         6118 :   if (bytes == -1)
     801              :     return false;
     802         6118 :   *out = bytes;
     803         6118 :   return true;
     804              : }
     805              : 
     806              : /* Base implementation of region::get_byte_size_sval vfunc.  */
     807              : 
     808              : const svalue *
     809        57600 : region::get_byte_size_sval (region_model_manager *mgr) const
     810              : {
     811        57600 :   tree type = get_type ();
     812              : 
     813              :   /* Bail out e.g. for heap-allocated regions.  */
     814        57600 :   if (!type)
     815        15130 :     return mgr->get_or_create_unknown_svalue (size_type_node);
     816              : 
     817        42470 :   HOST_WIDE_INT bytes = int_size_in_bytes (type);
     818        42470 :   if (bytes == -1)
     819          525 :     return mgr->get_or_create_unknown_svalue (size_type_node);
     820              : 
     821        41945 :   tree byte_size = size_in_bytes (type);
     822        41945 :   if (TREE_TYPE (byte_size) != size_type_node)
     823        41945 :     byte_size = fold_build1 (NOP_EXPR, size_type_node, byte_size);
     824        41945 :   return mgr->get_or_create_constant_svalue (byte_size);
     825              : }
     826              : 
     827              : /* Attempt to get the size of TYPE in bits.
     828              :    If successful, return true and write the size to *OUT.
     829              :    Otherwise return false.  */
     830              : 
     831              : bool
     832     10096521 : int_size_in_bits (const_tree type, bit_size_t *out)
     833              : {
     834     10096521 :   if (INTEGRAL_TYPE_P (type))
     835              :     {
     836      4221135 :       *out = TYPE_PRECISION (type);
     837      4221135 :       return true;
     838              :     }
     839              : 
     840      5875386 :   tree sz = TYPE_SIZE (type);
     841      5875386 :   if (sz
     842      5858524 :       && tree_fits_uhwi_p (sz)
     843              :       /* If the size is zero, then we may have a zero-sized
     844              :          array; handle such cases by returning false.  */
     845     11733708 :       && !integer_zerop (sz))
     846              :     {
     847      5856033 :       *out = TREE_INT_CST_LOW (sz);
     848      5856033 :       return true;
     849              :     }
     850              :   else
     851        19353 :     return false;
     852              : }
     853              : 
     854              : /* Base implementation of region::get_bit_size_sval vfunc.  */
     855              : 
     856              : const svalue *
     857       863765 : region::get_bit_size_sval (region_model_manager *mgr) const
     858              : {
     859       863765 :   tree type = get_type ();
     860              : 
     861              :   /* Bail out e.g. for heap-allocated regions.  */
     862       863765 :   if (!type)
     863         8324 :     return mgr->get_or_create_unknown_svalue (size_type_node);
     864              : 
     865       855441 :   bit_size_t bits;
     866       855441 :   if (!int_size_in_bits (type, &bits))
     867           71 :     return mgr->get_or_create_unknown_svalue (size_type_node);
     868              : 
     869       855370 :   return mgr->get_or_create_int_cst (size_type_node, bits);
     870              : }
     871              : 
     872              : /* If the size of this region (in bits) is known statically, write it to *OUT
     873              :    and return true.
     874              :    Otherwise return false.  */
     875              : 
     876              : bool
     877     10882034 : region::get_bit_size (bit_size_t *out) const
     878              : {
     879     10882034 :   tree type = get_type ();
     880              : 
     881              :   /* Bail out e.g. for heap-allocated regions.  */
     882     10882034 :   if (!type)
     883              :     return false;
     884              : 
     885      9237994 :   return int_size_in_bits (type, out);
     886              : }
     887              : 
     888              : /* Get the field within RECORD_TYPE at BIT_OFFSET.  */
     889              : 
     890              : tree
     891         2030 : get_field_at_bit_offset (tree record_type, bit_offset_t bit_offset)
     892              : {
     893         2030 :   gcc_assert (TREE_CODE (record_type) == RECORD_TYPE);
     894         2030 :   if (bit_offset < 0)
     895              :     return nullptr;
     896              : 
     897              :   /* Find the first field that has an offset > BIT_OFFSET,
     898              :      then return the one preceding it.
     899              :      Skip other trees within the chain, such as FUNCTION_DECLs.  */
     900         2030 :   tree last_field = NULL_TREE;
     901        48545 :   for (tree iter = TYPE_FIELDS (record_type); iter != NULL_TREE;
     902        46515 :        iter = DECL_CHAIN (iter))
     903              :     {
     904        47326 :       if (TREE_CODE (iter) == FIELD_DECL)
     905              :         {
     906         4702 :           int iter_field_offset = int_bit_position (iter);
     907         4702 :           if (bit_offset < iter_field_offset)
     908          811 :             return last_field;
     909         3891 :           last_field = iter;
     910              :         }
     911              :     }
     912              :   return last_field;
     913              : }
     914              : 
     915              : /* Populate *OUT with descendent regions of type TYPE that match
     916              :    RELATIVE_BIT_OFFSET and SIZE_IN_BITS within this region.  */
     917              : 
     918              : void
     919         8980 : region::get_subregions_for_binding (region_model_manager *mgr,
     920              :                                     bit_offset_t relative_bit_offset,
     921              :                                     bit_size_t size_in_bits,
     922              :                                     tree type,
     923              :                                     auto_vec <const region *> *out) const
     924              : {
     925         8980 :   if (get_type () == NULL_TREE || type == NULL_TREE)
     926              :     return;
     927         8710 :   if (relative_bit_offset == 0
     928         8710 :       && types_compatible_p (get_type (), type))
     929              :     {
     930         7430 :       out->safe_push (this);
     931         7430 :       return;
     932              :     }
     933         1280 :   switch (TREE_CODE (get_type ()))
     934              :     {
     935           79 :     case ARRAY_TYPE:
     936           79 :       {
     937           79 :         tree element_type = TREE_TYPE (get_type ());
     938           79 :         HOST_WIDE_INT hwi_byte_size = int_size_in_bytes (element_type);
     939           79 :         if (hwi_byte_size > 0)
     940              :           {
     941           79 :             HOST_WIDE_INT bits_per_element
     942              :               = hwi_byte_size << LOG2_BITS_PER_UNIT;
     943           79 :             HOST_WIDE_INT element_index
     944           79 :               = (relative_bit_offset.to_shwi () / bits_per_element);
     945           79 :             tree element_index_cst
     946           79 :               = build_int_cst (integer_type_node, element_index);
     947           79 :             HOST_WIDE_INT inner_bit_offset
     948           79 :               = relative_bit_offset.to_shwi () % bits_per_element;
     949           79 :             const region *subregion = mgr->get_element_region
     950           79 :               (this, element_type,
     951              :                mgr->get_or_create_constant_svalue (element_index_cst));
     952           79 :             subregion->get_subregions_for_binding (mgr, inner_bit_offset,
     953              :                                                    size_in_bits, type, out);
     954              :           }
     955              :       }
     956              :       break;
     957         1076 :     case RECORD_TYPE:
     958         1076 :       {
     959              :         /* The bit offset might be *within* one of the fields (such as
     960              :            with nested structs).
     961              :            So we want to find the enclosing field, adjust the offset,
     962              :            and repeat.  */
     963         1076 :         if (tree field = get_field_at_bit_offset (get_type (),
     964              :                                                   relative_bit_offset))
     965              :           {
     966         1076 :             int field_bit_offset = int_bit_position (field);
     967         1076 :             const region *subregion = mgr->get_field_region (this, field);
     968         1076 :             subregion->get_subregions_for_binding
     969         1076 :               (mgr, relative_bit_offset - field_bit_offset,
     970              :                size_in_bits, type, out);
     971              :           }
     972              :       }
     973              :       break;
     974            4 :     case UNION_TYPE:
     975            4 :       {
     976           12 :         for (tree field = TYPE_FIELDS (get_type ()); field != NULL_TREE;
     977            8 :              field = DECL_CHAIN (field))
     978              :           {
     979            8 :             if (TREE_CODE (field) != FIELD_DECL)
     980            0 :               continue;
     981            8 :             const region *subregion = mgr->get_field_region (this, field);
     982            8 :             subregion->get_subregions_for_binding (mgr,
     983              :                                                    relative_bit_offset,
     984              :                                                    size_in_bits,
     985              :                                                    type,
     986              :                                                    out);
     987              :           }
     988              :       }
     989              :       break;
     990              :     default:
     991              :       /* Do nothing.  */
     992              :       break;
     993              :     }
     994              : }
     995              : 
     996              : /* Walk from this region up to the base region within its cluster, calculating
     997              :    the offset relative to the base region, either as an offset in bits,
     998              :    or a symbolic offset.  */
     999              : 
    1000              : region_offset
    1001       150169 : region::calc_offset (region_model_manager *mgr) const
    1002              : {
    1003       150169 :   const region *iter_region = this;
    1004       150169 :   bit_offset_t accum_bit_offset = 0;
    1005       150169 :   const svalue *accum_byte_sval = nullptr;
    1006              : 
    1007       182241 :   while (iter_region)
    1008              :     {
    1009       182241 :       switch (iter_region->get_kind ())
    1010              :         {
    1011        22571 :         case RK_FIELD:
    1012        22571 :         case RK_ELEMENT:
    1013        22571 :         case RK_OFFSET:
    1014        22571 :         case RK_BIT_RANGE:
    1015        22571 :           if (accum_byte_sval)
    1016              :             {
    1017         3093 :               const svalue *sval
    1018         3093 :                 = iter_region->get_relative_symbolic_offset (mgr);
    1019         3093 :               accum_byte_sval
    1020         3093 :                 = mgr->get_or_create_binop (ptrdiff_type_node, PLUS_EXPR,
    1021              :                                             accum_byte_sval, sval);
    1022         3093 :               iter_region = iter_region->get_parent_region ();
    1023              :             }
    1024              :           else
    1025              :             {
    1026        19478 :               bit_offset_t rel_bit_offset;
    1027        19478 :               if (iter_region->get_relative_concrete_offset (&rel_bit_offset))
    1028              :                 {
    1029        16858 :                   accum_bit_offset += rel_bit_offset;
    1030        16858 :                   iter_region = iter_region->get_parent_region ();
    1031              :                 }
    1032              :               else
    1033              :                 {
    1034              :                   /* If the iter_region is not concrete anymore, convert the
    1035              :                      accumulated bits to a svalue in bytes and revisit the
    1036              :                      iter_region collecting the symbolic value.  */
    1037         2620 :                   byte_offset_t byte_offset = accum_bit_offset / BITS_PER_UNIT;
    1038         2620 :                   tree offset_tree = wide_int_to_tree (ptrdiff_type_node,
    1039         2620 :                                                        byte_offset);
    1040         2620 :                   accum_byte_sval
    1041         2620 :                     = mgr->get_or_create_constant_svalue (offset_tree);
    1042              :                 }
    1043              :             }
    1044        22571 :           continue;
    1045         9501 :         case RK_SIZED:
    1046         9501 :         case RK_CAST:
    1047         9501 :           iter_region = iter_region->get_parent_region ();
    1048         9501 :           continue;
    1049              : 
    1050       150169 :         default:
    1051       150169 :           return accum_byte_sval
    1052       150169 :                   ? region_offset::make_symbolic (iter_region,
    1053              :                                                   accum_byte_sval)
    1054       147549 :                   : region_offset::make_concrete (iter_region,
    1055              :                                                   accum_bit_offset);
    1056        32072 :         }
    1057              :     }
    1058              : 
    1059            0 :   return accum_byte_sval ? region_offset::make_symbolic (iter_region,
    1060              :                                                          accum_byte_sval)
    1061            0 :                          : region_offset::make_concrete (iter_region,
    1062              :                                                          accum_bit_offset);
    1063              : }
    1064              : 
    1065              : /* Base implementation of region::get_relative_concrete_offset vfunc.  */
    1066              : 
    1067              : bool
    1068           32 : region::get_relative_concrete_offset (bit_offset_t *) const
    1069              : {
    1070           32 :   return false;
    1071              : }
    1072              : 
    1073              : /* Base implementation of region::get_relative_symbolic_offset vfunc.  */
    1074              : 
    1075              : const svalue *
    1076            0 : region::get_relative_symbolic_offset (region_model_manager *mgr) const
    1077              : {
    1078            0 :   return mgr->get_or_create_unknown_svalue (ptrdiff_type_node);
    1079              : }
    1080              : 
    1081              : /* Attempt to get the position and size of this region expressed as a
    1082              :    concrete range of bytes relative to its parent.
    1083              :    If successful, return true and write to *OUT.
    1084              :    Otherwise return false.  */
    1085              : 
    1086              : bool
    1087         6376 : region::get_relative_concrete_byte_range (byte_range *out) const
    1088              : {
    1089              :   /* We must have a concrete offset relative to the parent.  */
    1090         6376 :   bit_offset_t rel_bit_offset;
    1091         6376 :   if (!get_relative_concrete_offset (&rel_bit_offset))
    1092              :     return false;
    1093              :   /* ...which must be a whole number of bytes.  */
    1094         6274 :   if (rel_bit_offset % BITS_PER_UNIT != 0)
    1095              :     return false;
    1096         6274 :   byte_offset_t start_byte_offset = rel_bit_offset / BITS_PER_UNIT;
    1097              : 
    1098              :   /* We must have a concrete size, which must be a whole number
    1099              :      of bytes.  */
    1100         6274 :   byte_size_t num_bytes;
    1101         6274 :   if (!get_byte_size (&num_bytes))
    1102              :     return false;
    1103              : 
    1104              :   /* Success.  */
    1105         6118 :   *out = byte_range (start_byte_offset, num_bytes);
    1106         6118 :   return true;
    1107              : }
    1108              : 
    1109              : /* Dump a description of this region to stderr.  */
    1110              : 
    1111              : DEBUG_FUNCTION void
    1112            0 : region::dump (bool simple) const
    1113              : {
    1114            0 :   tree_dump_pretty_printer pp (stderr);
    1115            0 :   dump_to_pp (&pp, simple);
    1116            0 :   pp_newline (&pp);
    1117            0 : }
    1118              : 
    1119              : /* Dump a tree-like representation of this region and its constituent symbols
    1120              :    to stderr, using global_dc's colorization and theming options.
    1121              : 
    1122              :    For example:
    1123              :    . (gdb) call reg->dump()
    1124              :    . (26): ‘int’: decl_region(‘x_10(D)’)
    1125              :    . ╰─ parent: (9): frame_region(‘test_bitmask_2’, index: 0, depth: 1)
    1126              :    .    ╰─ parent: (1): stack region
    1127              :    .       ╰─ parent: (0): root region
    1128              :   */
    1129              : 
    1130              : DEBUG_FUNCTION void
    1131            0 : region::dump () const
    1132              : {
    1133            0 :   text_art::dump (*this);
    1134            0 : }
    1135              : 
    1136              : /* Return a new json::string describing the region.  */
    1137              : 
    1138              : std::unique_ptr<json::value>
    1139           16 : region::to_json () const
    1140              : {
    1141           16 :   label_text desc = get_desc (true);
    1142           16 :   auto reg_js = std::make_unique<json::string> (desc.get ());
    1143           16 :   return reg_js;
    1144           16 : }
    1145              : 
    1146              : bool
    1147           34 : region::maybe_print_for_user (pretty_printer *pp,
    1148              :                               const region_model &) const
    1149              : {
    1150           34 :   switch (get_kind ())
    1151              :     {
    1152              :     default:
    1153              :       break;
    1154           34 :     case RK_DECL:
    1155           34 :       {
    1156           34 :         const decl_region *reg = (const decl_region *)this;
    1157           34 :         tree decl = reg->get_decl ();
    1158           34 :         if (TREE_CODE (decl) == SSA_NAME)
    1159           34 :           decl = SSA_NAME_VAR (decl);
    1160           34 :         print_expr_for_user (pp, decl);
    1161           34 :         return true;
    1162              :       }
    1163              :     }
    1164              : 
    1165              :   return false;
    1166              : }
    1167              : 
    1168              : /* Use DWI to create a text_art::widget describing this region in
    1169              :    a tree-like form, using PREFIX as a prefix (e.g. for field names).  */
    1170              : 
    1171              : std::unique_ptr<text_art::tree_widget>
    1172            0 : region::make_dump_widget (const text_art::dump_widget_info &dwi,
    1173              :                           const char *prefix) const
    1174              : {
    1175            0 :   pretty_printer pp;
    1176            0 :   pp_format_decoder (&pp) = default_tree_printer;
    1177            0 :   pp_show_color (&pp) = true;
    1178              : 
    1179            0 :   if (prefix)
    1180            0 :     pp_printf (&pp, "%s: ", prefix);
    1181              : 
    1182            0 :   pp_printf (&pp, "(%i): ", get_id ());
    1183            0 :   if (get_type ())
    1184            0 :     pp_printf (&pp, "%qT: ", get_type ());
    1185              : 
    1186            0 :   print_dump_widget_label (&pp);
    1187              : 
    1188            0 :   std::unique_ptr<text_art::tree_widget> w
    1189            0 :     (text_art::tree_widget::make (dwi, &pp));
    1190              : 
    1191            0 :   add_dump_widget_children (*w, dwi);
    1192              : 
    1193            0 :   if (m_parent)
    1194            0 :     w->add_child (m_parent->make_dump_widget (dwi, "parent"));
    1195              : 
    1196            0 :   return w;
    1197            0 : }
    1198              : 
    1199              : void
    1200            0 : region::add_dump_widget_children (text_art::tree_widget &,
    1201              :                                   const text_art::dump_widget_info &) const
    1202              : {
    1203              :   /* By default, add nothing (parent is added in make_dump_widget).  */
    1204            0 : }
    1205              : 
    1206              : /* Generate a description of this region.  */
    1207              : 
    1208              : DEBUG_FUNCTION label_text
    1209           16 : region::get_desc (bool simple) const
    1210              : {
    1211           16 :   pretty_printer pp;
    1212           16 :   pp_format_decoder (&pp) = default_tree_printer;
    1213           16 :   dump_to_pp (&pp, simple);
    1214           16 :   return label_text::take (xstrdup (pp_formatted_text (&pp)));
    1215           16 : }
    1216              : 
    1217              : /* Base implementation of region::accept vfunc.
    1218              :    Subclass implementations should chain up to this.  */
    1219              : 
    1220              : void
    1221     51012488 : region::accept (visitor *v) const
    1222              : {
    1223     51012488 :   v->visit_region (this);
    1224     51012488 :   if (m_parent)
    1225     38696354 :     m_parent->accept (v);
    1226     51012488 : }
    1227              : 
    1228              : /* Return true if this is a symbolic region for deferencing an
    1229              :    unknown ptr.
    1230              :    We shouldn't attempt to bind values for this region (but
    1231              :    can unbind values for other regions).  */
    1232              : 
    1233              : bool
    1234      5327713 : region::symbolic_for_unknown_ptr_p () const
    1235              : {
    1236      5327713 :   if (const symbolic_region *sym_reg = dyn_cast_symbolic_region ())
    1237       628779 :     if (sym_reg->get_pointer ()->get_kind () == SK_UNKNOWN)
    1238              :       return true;
    1239              :   return false;
    1240              : }
    1241              : 
    1242              : /* Return true if this is a symbolic region.  */
    1243              : 
    1244              : bool
    1245       869644 : region::symbolic_p () const
    1246              : {
    1247       869644 :   return get_kind () == RK_SYMBOLIC;
    1248              : }
    1249              : 
    1250              : /* Return true if this region is known to be zero bits in size.  */
    1251              : 
    1252              : bool
    1253      7179892 : region::empty_p () const
    1254              : {
    1255      7179892 :   bit_size_t num_bits;
    1256      7179892 :   if (get_bit_size (&num_bits))
    1257      6852117 :     if (num_bits == 0)
    1258              :       return true;
    1259              :   return false;
    1260              : }
    1261              : 
    1262              : /* Return true if this is a region for a decl with name DECL_NAME.
    1263              :    Intended for use when debugging (for assertions and conditional
    1264              :    breakpoints).  */
    1265              : 
    1266              : DEBUG_FUNCTION bool
    1267            0 : region::is_named_decl_p (const char *decl_name) const
    1268              : {
    1269            0 :   if (tree decl = maybe_get_decl ())
    1270            0 :     if (DECL_NAME (decl)
    1271            0 :         && !strcmp (IDENTIFIER_POINTER (DECL_NAME (decl)), decl_name))
    1272            0 :       return true;
    1273              :   return false;
    1274              : }
    1275              : 
    1276              : /* region's ctor.  */
    1277              : 
    1278       219192 : region::region (complexity c, symbol::id_t id, const region *parent, tree type)
    1279              : : symbol (c, id),
    1280       219192 :   m_parent (parent), m_type (type),
    1281       219192 :   m_cached_offset (nullptr), m_cached_init_sval_at_main (nullptr)
    1282              : {
    1283       219192 :   gcc_assert (type == NULL_TREE || TYPE_P (type));
    1284       219192 : }
    1285              : 
    1286              : /* Comparator for use by vec<const region *>::qsort,
    1287              :    using their IDs to order them.  */
    1288              : 
    1289              : int
    1290     63081421 : region::cmp_ptr_ptr (const void *p1, const void *p2)
    1291              : {
    1292     63081421 :   const region * const *reg1 = (const region * const *)p1;
    1293     63081421 :   const region * const *reg2 = (const region * const *)p2;
    1294              : 
    1295     63081421 :   return cmp_ids (*reg1, *reg2);
    1296              : }
    1297              : 
    1298              : /* Determine if a pointer to this region must be non-NULL.
    1299              : 
    1300              :    Generally, pointers to regions must be non-NULL, but pointers
    1301              :    to symbolic_regions might, in fact, be NULL.
    1302              : 
    1303              :    This allows us to simulate functions like malloc and calloc with:
    1304              :    - only one "outcome" from each statement,
    1305              :    - the idea that the pointer is on the heap if non-NULL
    1306              :    - the possibility that the pointer could be NULL
    1307              :    - the idea that successive values returned from malloc are non-equal
    1308              :    - to be able to zero-fill for calloc.  */
    1309              : 
    1310              : bool
    1311        21257 : region::non_null_p () const
    1312              : {
    1313        21257 :   switch (get_kind ())
    1314              :     {
    1315              :     default:
    1316              :       return true;
    1317              :     case RK_SYMBOLIC:
    1318              :       /* Are we within a symbolic_region?  If so, it could be NULL, and we
    1319              :          have to fall back on the constraints.  */
    1320              :       return false;
    1321              :     case RK_HEAP_ALLOCATED:
    1322              :       return false;
    1323              :     }
    1324              : }
    1325              : 
    1326              : /* Return true iff this region is defined in terms of SVAL.  */
    1327              : 
    1328              : bool
    1329       461855 : region::involves_p (const svalue *sval) const
    1330              : {
    1331       461855 :   if (const symbolic_region *symbolic_reg = dyn_cast_symbolic_region ())
    1332              :     {
    1333        58474 :       if (symbolic_reg->get_pointer ()->involves_p (sval))
    1334              :         return true;
    1335              :     }
    1336              : 
    1337              :   return false;
    1338              : }
    1339              : 
    1340              : /* Comparator for trees to impose a deterministic ordering on
    1341              :    T1 and T2.  */
    1342              : 
    1343              : static int
    1344        73560 : tree_cmp (const_tree t1, const_tree t2)
    1345              : {
    1346        73560 :   gcc_assert (t1);
    1347        73560 :   gcc_assert (t2);
    1348              : 
    1349              :   /* Test tree codes first.  */
    1350        73560 :   if (TREE_CODE (t1) != TREE_CODE (t2))
    1351        31744 :     return TREE_CODE (t1) - TREE_CODE (t2);
    1352              : 
    1353              :   /* From this point on, we know T1 and T2 have the same tree code.  */
    1354              : 
    1355        41816 :   if (DECL_P (t1))
    1356              :     {
    1357            0 :       if (DECL_NAME (t1) && DECL_NAME (t2))
    1358            0 :         return strcmp (IDENTIFIER_POINTER (DECL_NAME (t1)),
    1359            0 :                        IDENTIFIER_POINTER (DECL_NAME (t2)));
    1360              :       else
    1361              :         {
    1362            0 :           if (DECL_NAME (t1))
    1363              :             return -1;
    1364            0 :           else if (DECL_NAME (t2))
    1365              :             return 1;
    1366              :           else
    1367            0 :             return DECL_UID (t1) - DECL_UID (t2);
    1368              :         }
    1369              :     }
    1370              : 
    1371        41816 :   switch (TREE_CODE (t1))
    1372              :     {
    1373            0 :     case SSA_NAME:
    1374            0 :       {
    1375            0 :         if (SSA_NAME_VAR (t1) && SSA_NAME_VAR (t2))
    1376              :           {
    1377            0 :             int var_cmp = tree_cmp (SSA_NAME_VAR (t1), SSA_NAME_VAR (t2));
    1378            0 :             if (var_cmp)
    1379              :               return var_cmp;
    1380            0 :             return SSA_NAME_VERSION (t1) - SSA_NAME_VERSION (t2);
    1381              :           }
    1382              :         else
    1383              :           {
    1384            0 :             if (SSA_NAME_VAR (t1))
    1385              :               return -1;
    1386            0 :             else if (SSA_NAME_VAR (t2))
    1387              :               return 1;
    1388              :             else
    1389            0 :               return SSA_NAME_VERSION (t1) - SSA_NAME_VERSION (t2);
    1390              :           }
    1391              :       }
    1392         8384 :       break;
    1393              : 
    1394         8384 :     case INTEGER_CST:
    1395         8384 :       return tree_int_cst_compare (t1, t2);
    1396              : 
    1397        33432 :     case REAL_CST:
    1398        33432 :       {
    1399        33432 :         const real_value *rv1 = TREE_REAL_CST_PTR (t1);
    1400        33432 :         const real_value *rv2 = TREE_REAL_CST_PTR (t2);
    1401        33432 :         if (real_compare (UNORDERED_EXPR, rv1, rv2))
    1402              :           {
    1403              :             /* Impose an arbitrary order on NaNs relative to other NaNs
    1404              :                and to non-NaNs.  */
    1405        25040 :             if (int cmp_isnan = real_isnan (rv1) - real_isnan (rv2))
    1406              :               return cmp_isnan;
    1407        16800 :             if (int cmp_issignaling_nan
    1408         8400 :                   = real_issignaling_nan (rv1) - real_issignaling_nan (rv2))
    1409              :               return cmp_issignaling_nan;
    1410         4016 :             return real_isneg (rv1) - real_isneg (rv2);
    1411              :           }
    1412         8392 :         if (real_compare (LT_EXPR, rv1, rv2))
    1413              :           return -1;
    1414         5008 :         if (real_compare (GT_EXPR, rv1, rv2))
    1415              :           return 1;
    1416              :         return 0;
    1417              :       }
    1418              : 
    1419            0 :     case STRING_CST:
    1420            0 :       return strcmp (TREE_STRING_POINTER (t1),
    1421            0 :                      TREE_STRING_POINTER (t2));
    1422              : 
    1423            0 :     default:
    1424            0 :       gcc_unreachable ();
    1425              :       break;
    1426              :     }
    1427              : 
    1428              :   gcc_unreachable ();
    1429              : 
    1430              :   return 0;
    1431              : }
    1432              : 
    1433              : /* qsort comparator for trees to impose a deterministic ordering on
    1434              :    P1 and P2.  */
    1435              : 
    1436              : int
    1437        73560 : tree_cmp (const void *p1, const void *p2)
    1438              : {
    1439        73560 :   const_tree t1 = *(const_tree const *)p1;
    1440        73560 :   const_tree t2 = *(const_tree const *)p2;
    1441              : 
    1442        73560 :   return tree_cmp (t1, t2);
    1443              : }
    1444              : 
    1445              : /* class frame_region : public space_region.  */
    1446              : 
    1447        33012 : frame_region::~frame_region ()
    1448              : {
    1449       126794 :   for (map_t::iterator iter = m_locals.begin ();
    1450       126794 :        iter != m_locals.end ();
    1451       110288 :        ++iter)
    1452       110288 :     delete (*iter).second;
    1453        33012 : }
    1454              : 
    1455              : void
    1456     10057041 : frame_region::accept (visitor *v) const
    1457              : {
    1458     10612222 :   region::accept (v);
    1459     10612222 :   if (m_calling_frame)
    1460              :     m_calling_frame->accept (v);
    1461     10057041 : }
    1462              : 
    1463              : /* Implementation of region::dump_to_pp vfunc for frame_region.  */
    1464              : 
    1465              : void
    1466         4290 : frame_region::dump_to_pp (pretty_printer *pp, bool simple) const
    1467              : {
    1468         4290 :   if (simple)
    1469         4264 :     pp_printf (pp, "frame: %qs@%i", function_name (&m_fun), get_stack_depth ());
    1470              :   else
    1471           26 :     pp_printf (pp, "frame_region(%qs, index: %i, depth: %i)",
    1472           26 :                function_name (&m_fun), m_index, get_stack_depth ());
    1473         4290 : }
    1474              : 
    1475              : void
    1476            0 : frame_region::print_dump_widget_label (pretty_printer *pp) const
    1477              : {
    1478            0 :   pp_printf (pp, "frame_region(%qs, index: %i, depth: %i)",
    1479            0 :              function_name (&m_fun), m_index, get_stack_depth ());
    1480            0 : }
    1481              : 
    1482              : const decl_region *
    1483      1505286 : frame_region::get_region_for_local (region_model_manager *mgr,
    1484              :                                     tree expr,
    1485              :                                     const region_model_context *ctxt) const
    1486              : {
    1487      1505286 :   if (CHECKING_P)
    1488              :     {
    1489              :       /* Verify that EXPR is a local or SSA name, and that it's for the
    1490              :          correct function for this stack frame.  */
    1491      1505286 :       gcc_assert (TREE_CODE (expr) == PARM_DECL
    1492              :                   || TREE_CODE (expr) == VAR_DECL
    1493              :                   || TREE_CODE (expr) == SSA_NAME
    1494              :                   || TREE_CODE (expr) == RESULT_DECL);
    1495      1505286 :       switch (TREE_CODE (expr))
    1496              :         {
    1497            0 :         default:
    1498            0 :           gcc_unreachable ();
    1499       111646 :         case VAR_DECL:
    1500       111646 :           gcc_assert (!is_global_var (expr));
    1501              :           /* Fall through.  */
    1502       145769 :         case PARM_DECL:
    1503       145769 :         case RESULT_DECL:
    1504       145769 :           gcc_assert (DECL_CONTEXT (expr) == m_fun.decl);
    1505              :           break;
    1506      1359517 :         case SSA_NAME:
    1507      1359517 :           {
    1508      1359517 :             if (tree var = SSA_NAME_VAR (expr))
    1509              :               {
    1510       650020 :                 if (DECL_P (var))
    1511       650020 :                   gcc_assert (DECL_CONTEXT (var) == m_fun.decl);
    1512              :               }
    1513       709497 :             else if (ctxt)
    1514       434269 :               if (const extrinsic_state *ext_state = ctxt->get_ext_state ())
    1515       370217 :                 if (const supergraph *sg
    1516       370217 :                     = ext_state->get_engine ()->get_supergraph ())
    1517              :                   {
    1518       370217 :                     const gimple *def_stmt = SSA_NAME_DEF_STMT (expr);
    1519       370217 :                     if (gimple_code (def_stmt) != GIMPLE_PHI)
    1520              :                       {
    1521       363734 :                         const supernode *snode
    1522       363734 :                           = sg->get_supernode_for_stmt (def_stmt);
    1523       363734 :                         gcc_assert (snode->get_function () == &m_fun);
    1524              :                       }
    1525              :                   }
    1526              :           }
    1527              :           break;
    1528              :         }
    1529              :     }
    1530              : 
    1531              :   /* Ideally we'd use mutable here.  */
    1532      1505286 :   map_t &mutable_locals = const_cast <map_t &> (m_locals);
    1533              : 
    1534      1505286 :   if (decl_region **slot = mutable_locals.get (expr))
    1535      1394998 :     return *slot;
    1536       110288 :   decl_region *reg
    1537       110288 :     = new decl_region (mgr->alloc_symbol_id (), this, expr);
    1538       110288 :   mutable_locals.put (expr, reg);
    1539       110288 :   return reg;
    1540              : }
    1541              : 
    1542              : /* class globals_region : public space_region.  */
    1543              : 
    1544              : /* Implementation of region::dump_to_pp vfunc for globals_region.  */
    1545              : 
    1546              : void
    1547         2347 : globals_region::dump_to_pp (pretty_printer *pp, bool simple) const
    1548              : {
    1549         2347 :   if (simple)
    1550         1278 :     pp_string (pp, "::");
    1551              :   else
    1552         1069 :     pp_string (pp, "globals");
    1553         2347 : }
    1554              : 
    1555              : void
    1556            0 : globals_region::print_dump_widget_label (pretty_printer *pp) const
    1557              : {
    1558            0 :   pp_string (pp, "globals");
    1559            0 : }
    1560              : 
    1561              : /* class code_region : public map_region.  */
    1562              : 
    1563              : /* Implementation of region::dump_to_pp vfunc for code_region.  */
    1564              : 
    1565              : void
    1566            0 : code_region::dump_to_pp (pretty_printer *pp, bool simple) const
    1567              : {
    1568            0 :   if (simple)
    1569            0 :     pp_string (pp, "code region");
    1570              :   else
    1571            0 :     pp_string (pp, "code_region()");
    1572            0 : }
    1573              : 
    1574              : void
    1575            0 : code_region::print_dump_widget_label (pretty_printer *pp) const
    1576              : {
    1577            0 :   pp_string (pp, "code region");
    1578            0 : }
    1579              : 
    1580              : /* class function_region : public region.  */
    1581              : 
    1582              : /* Implementation of region::dump_to_pp vfunc for function_region.  */
    1583              : 
    1584              : void
    1585          413 : function_region::dump_to_pp (pretty_printer *pp, bool simple) const
    1586              : {
    1587          413 :   if (simple)
    1588              :     {
    1589          413 :       dump_quoted_tree (pp, m_fndecl);
    1590              :     }
    1591              :   else
    1592              :     {
    1593            0 :       pp_string (pp, "function_region(");
    1594            0 :       dump_quoted_tree (pp, m_fndecl);
    1595            0 :       pp_string (pp, ")");
    1596              :     }
    1597          413 : }
    1598              : 
    1599              : void
    1600            0 : function_region::print_dump_widget_label (pretty_printer *pp) const
    1601              : {
    1602            0 :   pp_string (pp, "function_region(");
    1603            0 :   dump_quoted_tree (pp, m_fndecl);
    1604            0 :   pp_string (pp, ")");
    1605            0 : }
    1606              : 
    1607              : /* class label_region : public region.  */
    1608              : 
    1609              : /* Implementation of region::dump_to_pp vfunc for label_region.  */
    1610              : 
    1611              : void
    1612            0 : label_region::dump_to_pp (pretty_printer *pp, bool simple) const
    1613              : {
    1614            0 :   if (simple)
    1615              :     {
    1616            0 :       dump_quoted_tree (pp, m_label);
    1617              :     }
    1618              :   else
    1619              :     {
    1620            0 :       pp_string (pp, "label_region(");
    1621            0 :       dump_quoted_tree (pp, m_label);
    1622            0 :       pp_string (pp, ")");
    1623              :     }
    1624            0 : }
    1625              : 
    1626              : void
    1627            0 : label_region::print_dump_widget_label (pretty_printer *pp) const
    1628              : {
    1629            0 :   pp_string (pp, "label_region(");
    1630            0 :   dump_quoted_tree (pp, m_label);
    1631            0 :   pp_string (pp, ")");
    1632            0 : }
    1633              : 
    1634              : /* class stack_region : public region.  */
    1635              : 
    1636              : /* Implementation of region::dump_to_pp vfunc for stack_region.  */
    1637              : 
    1638              : void
    1639            0 : stack_region::dump_to_pp (pretty_printer *pp, bool simple) const
    1640              : {
    1641            0 :   if (simple)
    1642            0 :     pp_string (pp, "stack region");
    1643              :   else
    1644            0 :     pp_string (pp, "stack_region()");
    1645            0 : }
    1646              : 
    1647              : void
    1648            0 : stack_region::print_dump_widget_label (pretty_printer *pp) const
    1649              : {
    1650            0 :   pp_string (pp, "stack region");
    1651            0 : }
    1652              : 
    1653              : /* class heap_region : public region.  */
    1654              : 
    1655              : /* Implementation of region::dump_to_pp vfunc for heap_region.  */
    1656              : 
    1657              : void
    1658          190 : heap_region::dump_to_pp (pretty_printer *pp, bool simple) const
    1659              : {
    1660          190 :   if (simple)
    1661          190 :     pp_string (pp, "heap region");
    1662              :   else
    1663            0 :     pp_string (pp, "heap_region()");
    1664          190 : }
    1665              : 
    1666              : void
    1667            0 : heap_region::print_dump_widget_label (pretty_printer *pp) const
    1668              : {
    1669            0 :   pp_string (pp, "heap_region");
    1670            0 : }
    1671              : 
    1672              : /* class root_region : public region.  */
    1673              : 
    1674              : /* root_region's ctor.  */
    1675              : 
    1676         4034 : root_region::root_region (symbol::id_t id)
    1677         4034 : : region (complexity (1, 1), id, nullptr, NULL_TREE)
    1678              : {
    1679         4034 : }
    1680              : 
    1681              : /* Implementation of region::dump_to_pp vfunc for root_region.  */
    1682              : 
    1683              : void
    1684         1478 : root_region::dump_to_pp (pretty_printer *pp, bool simple) const
    1685              : {
    1686         1478 :   if (simple)
    1687         1370 :     pp_string (pp, "root region");
    1688              :   else
    1689          108 :     pp_string (pp, "root_region()");
    1690         1478 : }
    1691              : 
    1692              : void
    1693            0 : root_region::print_dump_widget_label (pretty_printer *pp) const
    1694              : {
    1695            0 :   pp_string (pp, "root region");
    1696            0 : }
    1697              : 
    1698              : /* class thread_local_region : public space_region.  */
    1699              : 
    1700              : void
    1701            0 : thread_local_region::dump_to_pp (pretty_printer *pp, bool simple) const
    1702              : {
    1703            0 :   if (simple)
    1704            0 :     pp_string (pp, "thread_local_region");
    1705              :   else
    1706            0 :     pp_string (pp, "thread_local_region()");
    1707            0 : }
    1708              : 
    1709              : void
    1710            0 : thread_local_region::print_dump_widget_label (pretty_printer *pp) const
    1711              : {
    1712            0 :   pp_string (pp, "thread_local_region");
    1713            0 : }
    1714              : 
    1715              : /* class symbolic_region : public map_region.  */
    1716              : 
    1717              : /* symbolic_region's ctor.  */
    1718              : 
    1719         8908 : symbolic_region::symbolic_region (symbol::id_t id, region *parent,
    1720         8908 :                                   const svalue *sval_ptr)
    1721         8908 : : region (complexity::from_pair (parent, sval_ptr), id, parent,
    1722         8908 :           (sval_ptr->get_type ()
    1723         8825 :            ? TREE_TYPE (sval_ptr->get_type ())
    1724              :            : NULL_TREE)),
    1725        26641 :   m_sval_ptr (sval_ptr)
    1726              : {
    1727         8908 : }
    1728              : 
    1729              : /* Implementation of region::accept vfunc for symbolic_region.  */
    1730              : 
    1731              : void
    1732       549642 : symbolic_region::accept (visitor *v) const
    1733              : {
    1734       549642 :   region::accept (v);
    1735       549642 :   m_sval_ptr->accept (v);
    1736       549642 : }
    1737              : 
    1738              : /* Implementation of region::dump_to_pp vfunc for symbolic_region.  */
    1739              : 
    1740              : void
    1741         7089 : symbolic_region::dump_to_pp (pretty_printer *pp, bool simple) const
    1742              : {
    1743         7089 :   if (simple)
    1744              :     {
    1745         6981 :       pp_string (pp, "(*");
    1746         6981 :       m_sval_ptr->dump_to_pp (pp, simple);
    1747         6981 :       pp_string (pp, ")");
    1748              :     }
    1749              :   else
    1750              :     {
    1751          108 :       pp_string (pp, "symbolic_region(");
    1752          108 :       get_parent_region ()->dump_to_pp (pp, simple);
    1753          108 :       if (get_type ())
    1754              :         {
    1755          108 :           pp_string (pp, ", ");
    1756          108 :           print_quoted_type (pp, get_type ());
    1757              :         }
    1758          108 :       pp_string (pp, ", ");
    1759          108 :       m_sval_ptr->dump_to_pp (pp, simple);
    1760          108 :       pp_string (pp, ")");
    1761              :     }
    1762         7089 : }
    1763              : 
    1764              : void
    1765            0 : symbolic_region::print_dump_widget_label (pretty_printer *pp) const
    1766              : {
    1767            0 :   pp_string (pp, "symbolic_region: %<*%>");
    1768            0 : }
    1769              : 
    1770              : void
    1771            0 : symbolic_region::
    1772              : add_dump_widget_children (text_art::tree_widget &w,
    1773              :                           const text_art::dump_widget_info &dwi) const
    1774              : {
    1775            0 :   w.add_child (m_sval_ptr->make_dump_widget (dwi, "m_sval_ptr"));
    1776            0 : }
    1777              : 
    1778              : /* class decl_region : public region.  */
    1779              : 
    1780              : /* Implementation of region::dump_to_pp vfunc for decl_region.  */
    1781              : 
    1782              : void
    1783        26249 : decl_region::dump_to_pp (pretty_printer *pp, bool simple) const
    1784              : {
    1785        26249 :   if (simple)
    1786        25154 :     pp_printf (pp, "%E", m_decl);
    1787              :   else
    1788              :     {
    1789         1095 :       pp_string (pp, "decl_region(");
    1790         1095 :       get_parent_region ()->dump_to_pp (pp, simple);
    1791         1095 :       pp_string (pp, ", ");
    1792         1095 :       print_quoted_type (pp, get_type ());
    1793         1095 :       pp_printf (pp, ", %qE)", m_decl);
    1794              :     }
    1795        26249 : }
    1796              : 
    1797              : void
    1798            0 : decl_region::print_dump_widget_label (pretty_printer *pp) const
    1799              : {
    1800            0 :   pp_printf (pp, "decl_region(%qE)", m_decl);
    1801            0 : }
    1802              : 
    1803              : /* Get the stack depth for the frame containing this decl, or 0
    1804              :    for a global.  */
    1805              : 
    1806              : int
    1807        10195 : decl_region::get_stack_depth () const
    1808              : {
    1809        10195 :   if (get_parent_region () == nullptr)
    1810              :     return 0;
    1811        20390 :   if (const frame_region *frame_reg
    1812        10195 :         = get_parent_region ()->dyn_cast_frame_region ())
    1813         9705 :     return frame_reg->get_stack_depth ();
    1814              :   return 0;
    1815              : }
    1816              : 
    1817              : /* If the underlying decl is in the global constant pool,
    1818              :    return an svalue representing the constant value.
    1819              :    Otherwise return nullptr.  */
    1820              : 
    1821              : const svalue *
    1822      3568554 : decl_region::maybe_get_constant_value (region_model_manager *mgr) const
    1823              : {
    1824      3568554 :   if (VAR_P (m_decl)
    1825       319423 :       && DECL_IN_CONSTANT_POOL (m_decl)
    1826           16 :       && DECL_INITIAL (m_decl)
    1827      3568570 :       && TREE_CODE (DECL_INITIAL (m_decl)) == CONSTRUCTOR)
    1828           16 :     return get_svalue_for_constructor (DECL_INITIAL (m_decl), mgr);
    1829              :   return nullptr;
    1830              : }
    1831              : 
    1832              : /* Implementation of decl_region::get_svalue_for_constructor
    1833              :    for when the cached value hasn't yet been calculated.  */
    1834              : 
    1835              : const svalue *
    1836          122 : decl_region::calc_svalue_for_constructor (tree ctor,
    1837              :                                           region_model_manager *mgr) const
    1838              : {
    1839              :   /* Create a concrete_binding_map, applying ctor to it, using this
    1840              :      decl_region as the base region when building child regions
    1841              :      for offset calculations.  */
    1842          122 :   concrete_binding_map map;
    1843          122 :   if (!map.apply_ctor_to_region (this, ctor, mgr))
    1844            1 :     return mgr->get_or_create_unknown_svalue (get_type ());
    1845              : 
    1846              :   /* Return a compound svalue for the map we built.  */
    1847          121 :   return mgr->get_or_create_compound_svalue (get_type (), std::move (map));
    1848          122 : }
    1849              : 
    1850              : /* Get an svalue for CTOR, a CONSTRUCTOR for this region's decl.  */
    1851              : 
    1852              : const svalue *
    1853          218 : decl_region::get_svalue_for_constructor (tree ctor,
    1854              :                                          region_model_manager *mgr) const
    1855              : {
    1856          218 :   gcc_assert (!TREE_CLOBBER_P (ctor));
    1857          218 :   gcc_assert (ctor == DECL_INITIAL (m_decl));
    1858              : 
    1859          218 :   if (!m_ctor_svalue)
    1860          122 :     m_ctor_svalue = calc_svalue_for_constructor (ctor, mgr);
    1861              : 
    1862          218 :   return m_ctor_svalue;
    1863              : }
    1864              : 
    1865              : /* For use on decl_regions for global variables.
    1866              : 
    1867              :    Get an svalue for the initial value of this region at entry to
    1868              :    "main" (either based on DECL_INITIAL, or implicit initialization to
    1869              :    zero.
    1870              : 
    1871              :    Return nullptr if there is a problem.  */
    1872              : 
    1873              : const svalue *
    1874          421 : decl_region::get_svalue_for_initializer (region_model_manager *mgr) const
    1875              : {
    1876          421 :   tree init = DECL_INITIAL (m_decl);
    1877          421 :   if (!init)
    1878              :     {
    1879              :       /* If we have an "extern" decl then there may be an initializer in
    1880              :          another TU.  */
    1881          146 :       if (DECL_EXTERNAL (m_decl))
    1882              :         return nullptr;
    1883              : 
    1884           33 :       if (empty_p ())
    1885              :         return nullptr;
    1886              : 
    1887              :       /* Implicit initialization to zero; use a compound_svalue for it.
    1888              :          Doing so requires that we have a concrete binding for this region,
    1889              :          which can fail if we have a region with unknown size
    1890              :          (e.g. "extern const char arr[];").  */
    1891           33 :       const binding_key *binding
    1892           33 :         = binding_key::make (mgr->get_store_manager (), this);
    1893           33 :       if (binding->symbolic_p ())
    1894              :         return nullptr;
    1895              : 
    1896              :       /* If we don't care about tracking the content of this region, then
    1897              :          it's unused, and the value doesn't matter.  */
    1898           33 :       if (!tracked_p ())
    1899              :         return nullptr;
    1900              : 
    1901           33 :       binding_cluster c (*mgr->get_store_manager (), this);
    1902           33 :       c.zero_fill_region (mgr->get_store_manager (), this);
    1903           33 :       return mgr->get_or_create_compound_svalue (TREE_TYPE (m_decl),
    1904           33 :                                                  c.get_map ().get_concrete_bindings ());
    1905           33 :     }
    1906              : 
    1907              :   /* LTO can write out error_mark_node as the DECL_INITIAL for simple scalar
    1908              :      values (to avoid writing out an extra section).  */
    1909          275 :   if (init == error_mark_node)
    1910              :     return nullptr;
    1911              : 
    1912          271 :   if (TREE_CODE (init) == CONSTRUCTOR)
    1913          202 :     return get_svalue_for_constructor (init, mgr);
    1914              : 
    1915              :   /* Reuse the get_rvalue logic from region_model.  */
    1916           69 :   region_model m (mgr);
    1917           69 :   return m.get_rvalue (path_var (init, 0), nullptr);
    1918           69 : }
    1919              : 
    1920              : /* Subroutine of symnode_requires_tracking_p; return true if REF
    1921              :    might imply that we should be tracking the value of its decl.  */
    1922              : 
    1923              : static bool
    1924         4172 : ipa_ref_requires_tracking (ipa_ref *ref)
    1925              : {
    1926              :   /* If we have a load/store/alias of the symbol, then we'll track
    1927              :      the decl's value.  */
    1928         4172 :   if (ref->use != IPA_REF_ADDR)
    1929              :     return true;
    1930              : 
    1931         4141 :   if (ref->stmt == nullptr)
    1932              :     return true;
    1933              : 
    1934         4141 :   switch (ref->stmt->code)
    1935              :     {
    1936              :     default:
    1937              :       return true;
    1938         4109 :     case GIMPLE_CALL:
    1939         4109 :       {
    1940         4157 :         cgraph_node *caller_cnode = dyn_cast <cgraph_node *> (ref->referring);
    1941         4109 :         if (caller_cnode == nullptr)
    1942              :           return true;
    1943         4109 :         cgraph_edge *edge = caller_cnode->get_edge (ref->stmt);
    1944         4109 :         if (!edge)
    1945              :           return true;
    1946         4109 :         if (edge->callee == nullptr)
    1947              :           return true; /* e.g. call through function ptr.  */
    1948         4108 :         if (edge->callee->definition)
    1949              :           return true;
    1950              :         /* If we get here, then this ref is a pointer passed to
    1951              :            a function we don't have the definition for.  */
    1952              :         return false;
    1953              :       }
    1954           17 :       break;
    1955           17 :     case GIMPLE_ASM:
    1956           17 :       {
    1957           17 :         const gasm *asm_stmt = as_a <const gasm *> (ref->stmt);
    1958           17 :         if (gimple_asm_noutputs (asm_stmt) > 0)
    1959              :           return true;
    1960           17 :         if (gimple_asm_nclobbers (asm_stmt) > 0)
    1961              :           return true;
    1962              :         /* If we get here, then this ref is the decl being passed
    1963              :            by pointer to asm with no outputs.  */
    1964              :         return false;
    1965              :       }
    1966              :       break;
    1967              :     }
    1968              : }
    1969              : 
    1970              : /* Determine if the decl for SYMNODE should have binding_clusters
    1971              :    in our state objects; return false to optimize away tracking
    1972              :    certain decls in our state objects, as an optimization.  */
    1973              : 
    1974              : static bool
    1975         5506 : symnode_requires_tracking_p (symtab_node *symnode)
    1976              : {
    1977         5506 :   gcc_assert (symnode);
    1978         5506 :   if (symnode->externally_visible)
    1979              :     return true;
    1980         4729 :   tree context_fndecl = DECL_CONTEXT (symnode->decl);
    1981         4729 :   if (context_fndecl == nullptr)
    1982              :     return true;
    1983         4715 :   if (TREE_CODE (context_fndecl) != FUNCTION_DECL)
    1984              :     return true;
    1985        16511 :   for (auto ref : symnode->ref_list.referring)
    1986         4172 :     if (ipa_ref_requires_tracking (ref))
    1987              :       return true;
    1988              : 
    1989              :   /* If we get here, then we don't have uses of this decl that require
    1990              :      tracking; we never read from it or write to it explicitly.  */
    1991              :   return false;
    1992              : }
    1993              : 
    1994              : /* Subroutine of decl_region ctor: determine whether this decl_region
    1995              :    can have binding_clusters; return false to optimize away tracking
    1996              :    of certain decls in our state objects, as an optimization.  */
    1997              : 
    1998              : bool
    1999       116686 : decl_region::calc_tracked_p (tree decl)
    2000              : {
    2001              :   /* Precondition of symtab_node::get.  */
    2002       116686 :   if (TREE_CODE (decl) == VAR_DECL
    2003       116686 :       && (TREE_STATIC (decl) || DECL_EXTERNAL (decl) || in_lto_p))
    2004         6400 :     if (symtab_node *symnode = symtab_node::get (decl))
    2005         5506 :       return symnode_requires_tracking_p (symnode);
    2006              :   return true;
    2007              : }
    2008              : 
    2009              : /* class field_region : public region.  */
    2010              : 
    2011              : /* Implementation of region::dump_to_pp vfunc for field_region.  */
    2012              : 
    2013              : void
    2014         1941 : field_region::dump_to_pp (pretty_printer *pp, bool simple) const
    2015              : {
    2016         1941 :   if (simple)
    2017              :     {
    2018         1941 :       get_parent_region ()->dump_to_pp (pp, simple);
    2019         1941 :       pp_string (pp, ".");
    2020         1941 :       pp_printf (pp, "%E", m_field);
    2021              :     }
    2022              :   else
    2023              :     {
    2024            0 :       pp_string (pp, "field_region(");
    2025            0 :       get_parent_region ()->dump_to_pp (pp, simple);
    2026            0 :       pp_string (pp, ", ");
    2027            0 :       print_quoted_type (pp, get_type ());
    2028            0 :       pp_printf (pp, ", %qE)", m_field);
    2029              :     }
    2030         1941 : }
    2031              : 
    2032              : void
    2033            0 : field_region::print_dump_widget_label (pretty_printer *pp) const
    2034              : {
    2035            0 :   pp_printf (pp, "field_region(%qE)", m_field);
    2036            0 : }
    2037              : 
    2038              : /* Implementation of region::get_relative_concrete_offset vfunc
    2039              :    for field_region.  */
    2040              : 
    2041              : bool
    2042        11407 : field_region::get_relative_concrete_offset (bit_offset_t *out) const
    2043              : {
    2044              :   /* Compare with e.g. gimple-fold.cc's
    2045              :      fold_nonarray_ctor_reference.  */
    2046        11407 :   tree byte_offset = DECL_FIELD_OFFSET (m_field);
    2047        11407 :   if (TREE_CODE (byte_offset) != INTEGER_CST)
    2048              :     return false;
    2049        11405 :   tree field_offset = DECL_FIELD_BIT_OFFSET (m_field);
    2050              :   /* Compute bit offset of the field.  */
    2051        11405 :   offset_int bitoffset
    2052        11405 :     = (wi::to_offset (field_offset)
    2053        11405 :        + (wi::to_offset (byte_offset) << LOG2_BITS_PER_UNIT));
    2054        11405 :   *out = bitoffset;
    2055        11405 :   return true;
    2056              : }
    2057              : 
    2058              : 
    2059              : /* Implementation of region::get_relative_symbolic_offset vfunc
    2060              :    for field_region.
    2061              :    If known, the returned svalue is equal to the offset converted to bytes and
    2062              :    rounded off.  */
    2063              : 
    2064              : const svalue *
    2065          372 : field_region::get_relative_symbolic_offset (region_model_manager *mgr) const
    2066              : {
    2067          372 :   bit_offset_t out;
    2068          372 :   if (get_relative_concrete_offset (&out))
    2069              :     {
    2070          371 :       tree cst_tree
    2071          371 :         = wide_int_to_tree (ptrdiff_type_node, out / BITS_PER_UNIT);
    2072          371 :       return mgr->get_or_create_constant_svalue (cst_tree);
    2073              :     }
    2074            1 :   return mgr->get_or_create_unknown_svalue (ptrdiff_type_node);
    2075              : }
    2076              : 
    2077              : /* class element_region : public region.  */
    2078              : 
    2079              : /* Implementation of region::accept vfunc for element_region.  */
    2080              : 
    2081              : void
    2082      3939245 : element_region::accept (visitor *v) const
    2083              : {
    2084      3939245 :   region::accept (v);
    2085      3939245 :   m_index->accept (v);
    2086      3939245 : }
    2087              : 
    2088              : /* Implementation of region::dump_to_pp vfunc for element_region.  */
    2089              : 
    2090              : void
    2091          276 : element_region::dump_to_pp (pretty_printer *pp, bool simple) const
    2092              : {
    2093          276 :   if (simple)
    2094              :     {
    2095              :       //pp_string (pp, "(");
    2096          276 :       get_parent_region ()->dump_to_pp (pp, simple);
    2097          276 :       pp_string (pp, "[");
    2098          276 :       m_index->dump_to_pp (pp, simple);
    2099          276 :       pp_string (pp, "]");
    2100              :       //pp_string (pp, ")");
    2101              :     }
    2102              :   else
    2103              :     {
    2104            0 :       pp_string (pp, "element_region(");
    2105            0 :       get_parent_region ()->dump_to_pp (pp, simple);
    2106            0 :       pp_string (pp, ", ");
    2107            0 :       print_quoted_type (pp, get_type ());
    2108            0 :       pp_string (pp, ", ");
    2109            0 :       m_index->dump_to_pp (pp, simple);
    2110            0 :       pp_printf (pp, ")");
    2111              :     }
    2112          276 : }
    2113              : 
    2114              : void
    2115            0 : element_region::print_dump_widget_label (pretty_printer *pp) const
    2116              : {
    2117            0 :   pp_printf (pp, "element_region: %<[]%>");
    2118            0 : }
    2119              : 
    2120              : void
    2121            0 : element_region::
    2122              : add_dump_widget_children (text_art::tree_widget &w,
    2123              :                           const text_art::dump_widget_info &dwi) const
    2124              : {
    2125            0 :   w.add_child (m_index->make_dump_widget (dwi, "m_index"));
    2126            0 : }
    2127              : 
    2128              : /* Implementation of region::get_relative_concrete_offset vfunc
    2129              :    for element_region.  */
    2130              : 
    2131              : bool
    2132        10814 : element_region::get_relative_concrete_offset (bit_offset_t *out) const
    2133              : {
    2134        10814 :   if (tree idx_cst = m_index->maybe_get_constant ())
    2135              :     {
    2136         9657 :       gcc_assert (TREE_CODE (idx_cst) == INTEGER_CST);
    2137              : 
    2138         9657 :       tree elem_type = get_type ();
    2139         9657 :       offset_int element_idx = wi::to_offset (idx_cst);
    2140              : 
    2141              :       /* First, use int_size_in_bytes, to reject the case where we
    2142              :          have an incomplete type, or a non-constant value.  */
    2143         9657 :       HOST_WIDE_INT hwi_byte_size = int_size_in_bytes (elem_type);
    2144         9657 :       if (hwi_byte_size > 0)
    2145              :         {
    2146         9655 :           offset_int element_bit_size
    2147         9655 :             = hwi_byte_size << LOG2_BITS_PER_UNIT;
    2148         9655 :           offset_int element_bit_offset
    2149         9655 :             = element_idx * element_bit_size;
    2150         9655 :           *out = element_bit_offset;
    2151         9655 :           return true;
    2152              :         }
    2153              :     }
    2154              :   return false;
    2155              : }
    2156              : 
    2157              : /* Implementation of region::get_relative_symbolic_offset vfunc
    2158              :    for element_region.  */
    2159              : 
    2160              : const svalue *
    2161         1187 : element_region::get_relative_symbolic_offset (region_model_manager *mgr) const
    2162              : {
    2163         1187 :   tree elem_type = get_type ();
    2164              : 
    2165              :   /* First, use int_size_in_bytes, to reject the case where we
    2166              :      have an incomplete type, or a non-constant value.  */
    2167         1187 :   HOST_WIDE_INT hwi_byte_size = int_size_in_bytes (elem_type);
    2168         1187 :   if (hwi_byte_size > 0)
    2169              :           {
    2170         1184 :       tree byte_size_tree = wide_int_to_tree (ptrdiff_type_node,
    2171         1184 :                                               hwi_byte_size);
    2172         1184 :       const svalue *byte_size_sval
    2173         1184 :         = mgr->get_or_create_constant_svalue (byte_size_tree);
    2174         1184 :       return mgr->get_or_create_binop (NULL_TREE, MULT_EXPR,
    2175         1184 :                                        m_index, byte_size_sval);
    2176              :     }
    2177            3 :   return mgr->get_or_create_unknown_svalue (ptrdiff_type_node);
    2178              : }
    2179              : 
    2180              : /* class offset_region : public region.  */
    2181              : 
    2182              : /* Implementation of region::accept vfunc for offset_region.  */
    2183              : 
    2184              : void
    2185        84074 : offset_region::accept (visitor *v) const
    2186              : {
    2187        84074 :   region::accept (v);
    2188        84074 :   m_byte_offset->accept (v);
    2189        84074 : }
    2190              : 
    2191              : /* Implementation of region::dump_to_pp vfunc for offset_region.  */
    2192              : 
    2193              : void
    2194         2800 : offset_region::dump_to_pp (pretty_printer *pp, bool simple) const
    2195              : {
    2196         2800 :   if (simple)
    2197              :     {
    2198              :       //pp_string (pp, "(");
    2199         2731 :       get_parent_region ()->dump_to_pp (pp, simple);
    2200         2731 :       pp_string (pp, "+");
    2201         2731 :       m_byte_offset->dump_to_pp (pp, simple);
    2202              :       //pp_string (pp, ")");
    2203              :     }
    2204              :   else
    2205              :     {
    2206           69 :       pp_string (pp, "offset_region(");
    2207           69 :       get_parent_region ()->dump_to_pp (pp, simple);
    2208           69 :       pp_string (pp, ", ");
    2209           69 :       print_quoted_type (pp, get_type ());
    2210           69 :       pp_string (pp, ", ");
    2211           69 :       m_byte_offset->dump_to_pp (pp, simple);
    2212           69 :       pp_printf (pp, ")");
    2213              :     }
    2214         2800 : }
    2215              : 
    2216              : void
    2217            0 : offset_region::print_dump_widget_label (pretty_printer *pp) const
    2218              : {
    2219            0 :   pp_printf (pp, "offset_region");
    2220            0 : }
    2221              : 
    2222              : void
    2223            0 : offset_region::
    2224              : add_dump_widget_children (text_art::tree_widget &w,
    2225              :                           const text_art::dump_widget_info &dwi) const
    2226              : {
    2227            0 :   w.add_child (m_byte_offset->make_dump_widget (dwi, "m_byte_offset"));
    2228            0 : }
    2229              : 
    2230              : const svalue *
    2231            0 : offset_region::get_bit_offset (region_model_manager *mgr) const
    2232              : {
    2233            0 :   const svalue *bits_per_byte_sval
    2234            0 :     = mgr->get_or_create_int_cst (NULL_TREE, BITS_PER_UNIT);
    2235            0 :   return mgr->get_or_create_binop (NULL_TREE, MULT_EXPR,
    2236            0 :                                    m_byte_offset, bits_per_byte_sval);
    2237              : }
    2238              : 
    2239              : /* Implementation of region::get_relative_concrete_offset vfunc
    2240              :    for offset_region.  */
    2241              : 
    2242              : bool
    2243         3795 : offset_region::get_relative_concrete_offset (bit_offset_t *out) const
    2244              : {
    2245         3795 :   if (tree byte_offset_cst = m_byte_offset->maybe_get_constant ())
    2246              :     {
    2247         2265 :       gcc_assert (TREE_CODE (byte_offset_cst) == INTEGER_CST);
    2248              :       /* Use a signed value for the byte offset, to handle
    2249              :          negative offsets.  */
    2250         2265 :       HOST_WIDE_INT byte_offset
    2251         2265 :         = wi::to_offset (byte_offset_cst).to_shwi ();
    2252         2265 :       HOST_WIDE_INT bit_offset = byte_offset * BITS_PER_UNIT;
    2253         2265 :       *out = bit_offset;
    2254         2265 :       return true;
    2255              :     }
    2256              :   return false;
    2257              : }
    2258              : 
    2259              : /* Implementation of region::get_relative_symbolic_offset vfunc
    2260              :    for offset_region.  */
    2261              : 
    2262              : const svalue *
    2263         1534 : offset_region::get_relative_symbolic_offset (region_model_manager *mgr
    2264              :                                               ATTRIBUTE_UNUSED) const
    2265              : {
    2266         1534 :   return get_byte_offset ();
    2267              : }
    2268              : 
    2269              : /* class sized_region : public region.  */
    2270              : 
    2271              : /* Implementation of region::accept vfunc for sized_region.  */
    2272              : 
    2273              : void
    2274        40986 : sized_region::accept (visitor *v) const
    2275              : {
    2276        40986 :   region::accept (v);
    2277        40986 :   m_byte_size_sval->accept (v);
    2278        40986 : }
    2279              : 
    2280              : /* Implementation of region::dump_to_pp vfunc for sized_region.  */
    2281              : 
    2282              : void
    2283          114 : sized_region::dump_to_pp (pretty_printer *pp, bool simple) const
    2284              : {
    2285          114 :   if (simple)
    2286              :     {
    2287          105 :       pp_string (pp, "SIZED_REG(");
    2288          105 :       get_parent_region ()->dump_to_pp (pp, simple);
    2289          105 :       pp_string (pp, ", ");
    2290          105 :       m_byte_size_sval->dump_to_pp (pp, simple);
    2291          105 :       pp_string (pp, ")");
    2292              :     }
    2293              :   else
    2294              :     {
    2295            9 :       pp_string (pp, "sized_region(");
    2296            9 :       get_parent_region ()->dump_to_pp (pp, simple);
    2297            9 :       pp_string (pp, ", ");
    2298            9 :       m_byte_size_sval->dump_to_pp (pp, simple);
    2299            9 :       pp_printf (pp, ")");
    2300              :     }
    2301          114 : }
    2302              : 
    2303              : void
    2304            0 : sized_region::print_dump_widget_label (pretty_printer *pp) const
    2305              : {
    2306            0 :   pp_printf (pp, "sized_region");
    2307            0 : }
    2308              : 
    2309              : void
    2310            0 : sized_region::
    2311              : add_dump_widget_children (text_art::tree_widget &w,
    2312              :                           const text_art::dump_widget_info &dwi) const
    2313              : {
    2314            0 :   w.add_child (m_byte_size_sval->make_dump_widget (dwi, "m_byte_size_sval"));
    2315            0 : }
    2316              : 
    2317              : /* Implementation of region::get_byte_size vfunc for sized_region.  */
    2318              : 
    2319              : bool
    2320        35416 : sized_region::get_byte_size (byte_size_t *out) const
    2321              : {
    2322        35416 :   if (tree cst = m_byte_size_sval->maybe_get_constant ())
    2323              :     {
    2324        25245 :       gcc_assert (TREE_CODE (cst) == INTEGER_CST);
    2325        25245 :       *out = tree_to_uhwi (cst);
    2326        25245 :       return true;
    2327              :     }
    2328              :   return false;
    2329              : }
    2330              : 
    2331              : /* Implementation of region::get_bit_size vfunc for sized_region.  */
    2332              : 
    2333              : bool
    2334        35416 : sized_region::get_bit_size (bit_size_t *out) const
    2335              : {
    2336        35416 :   byte_size_t byte_size;
    2337        35416 :   if (!get_byte_size (&byte_size))
    2338              :     return false;
    2339        25245 :   *out = byte_size * BITS_PER_UNIT;
    2340        25245 :   return true;
    2341              : }
    2342              : 
    2343              : /* Implementation of region::get_bit_size_sval vfunc for sized_region.  */
    2344              : 
    2345              : const svalue *
    2346         5811 : sized_region::get_bit_size_sval (region_model_manager *mgr) const
    2347              : {
    2348         5811 :   const svalue *bits_per_byte_sval
    2349         5811 :     = mgr->get_or_create_int_cst (NULL_TREE, BITS_PER_UNIT);
    2350         5811 :   return mgr->get_or_create_binop (NULL_TREE, MULT_EXPR,
    2351         5811 :                                    m_byte_size_sval, bits_per_byte_sval);
    2352              : }
    2353              : 
    2354              : /* class cast_region : public region.  */
    2355              : 
    2356              : /* Implementation of region::dump_to_pp vfunc for cast_region.  */
    2357              : 
    2358              : void
    2359         1378 : cast_region::dump_to_pp (pretty_printer *pp, bool simple) const
    2360              : {
    2361         1378 :   if (simple)
    2362              :     {
    2363         1320 :       pp_string (pp, "CAST_REG(");
    2364         1320 :       print_quoted_type (pp, get_type ());
    2365         1320 :       pp_string (pp, ", ");
    2366         1320 :       get_parent_region ()->dump_to_pp (pp, simple);
    2367         1320 :       pp_string (pp, ")");
    2368              :     }
    2369              :   else
    2370              :     {
    2371           58 :       pp_string (pp, "cast_region(");
    2372           58 :       get_parent_region ()->dump_to_pp (pp, simple);
    2373           58 :       pp_string (pp, ", ");
    2374           58 :       print_quoted_type (pp, get_type ());
    2375           58 :       pp_printf (pp, ")");
    2376              :     }
    2377         1378 : }
    2378              : 
    2379              : void
    2380            0 : cast_region::print_dump_widget_label (pretty_printer *pp) const
    2381              : {
    2382            0 :   pp_printf (pp, "cast_region");
    2383            0 : }
    2384              : 
    2385              : /* Implementation of region::get_relative_concrete_offset vfunc
    2386              :    for cast_region.  */
    2387              : 
    2388              : bool
    2389           23 : cast_region::get_relative_concrete_offset (bit_offset_t *out) const
    2390              : {
    2391           23 :   *out = (int) 0;
    2392           23 :   return true;
    2393              : }
    2394              : 
    2395              : /* class heap_allocated_region : public region.  */
    2396              : 
    2397              : /* Implementation of region::dump_to_pp vfunc for heap_allocated_region.  */
    2398              : 
    2399              : void
    2400         2076 : heap_allocated_region::dump_to_pp (pretty_printer *pp, bool simple) const
    2401              : {
    2402         2076 :   if (simple)
    2403         2076 :     pp_printf (pp, "HEAP_ALLOCATED_REGION(%i)", get_id ());
    2404              :   else
    2405            0 :     pp_printf (pp, "heap_allocated_region(%i)", get_id ());
    2406         2076 : }
    2407              : 
    2408              : void
    2409            0 : heap_allocated_region::print_dump_widget_label (pretty_printer *pp) const
    2410              : {
    2411            0 :   pp_printf (pp, "heap_allocated_region");
    2412            0 : }
    2413              : 
    2414              : /* class alloca_region : public region.  */
    2415              : 
    2416              : /* Implementation of region::dump_to_pp vfunc for alloca_region.  */
    2417              : 
    2418              : void
    2419            0 : alloca_region::dump_to_pp (pretty_printer *pp, bool simple) const
    2420              : {
    2421            0 :   if (simple)
    2422            0 :     pp_printf (pp, "ALLOCA_REGION(%i)", get_id ());
    2423              :   else
    2424            0 :     pp_printf (pp, "alloca_region(%i)", get_id ());
    2425            0 : }
    2426              : 
    2427              : void
    2428            0 : alloca_region::print_dump_widget_label (pretty_printer *pp) const
    2429              : {
    2430            0 :   pp_printf (pp, "alloca_region");
    2431            0 : }
    2432              : 
    2433              : /* class string_region : public region.  */
    2434              : 
    2435              : /* Implementation of region::dump_to_pp vfunc for string_region.  */
    2436              : 
    2437              : void
    2438            0 : string_region::dump_to_pp (pretty_printer *pp, bool simple) const
    2439              : {
    2440            0 :   if (simple)
    2441            0 :     dump_tree (pp, m_string_cst);
    2442              :   else
    2443              :     {
    2444            0 :       pp_string (pp, "string_region(");
    2445            0 :       dump_tree (pp, m_string_cst);
    2446            0 :       if (!flag_dump_noaddr)
    2447              :         {
    2448            0 :           pp_string (pp, " (");
    2449            0 :           pp_pointer (pp, m_string_cst);
    2450            0 :           pp_string (pp, "))");
    2451              :         }
    2452              :     }
    2453            0 : }
    2454              : 
    2455              : void
    2456            0 : string_region::print_dump_widget_label (pretty_printer *pp) const
    2457              : {
    2458            0 :   pp_string (pp, "string_region(");
    2459            0 :   dump_tree (pp, m_string_cst);
    2460            0 :   pp_string (pp, ")");
    2461            0 : }
    2462              : 
    2463              : /* class bit_range_region : public region.  */
    2464              : 
    2465              : /* Implementation of region::dump_to_pp vfunc for bit_range_region.  */
    2466              : 
    2467              : void
    2468            0 : bit_range_region::dump_to_pp (pretty_printer *pp, bool simple) const
    2469              : {
    2470            0 :   if (simple)
    2471              :     {
    2472            0 :       pp_string (pp, "BIT_RANGE_REG(");
    2473            0 :       get_parent_region ()->dump_to_pp (pp, simple);
    2474            0 :       pp_string (pp, ", ");
    2475            0 :       m_bits.dump_to_pp (pp);
    2476            0 :       pp_string (pp, ")");
    2477              :     }
    2478              :   else
    2479              :     {
    2480            0 :       pp_string (pp, "bit_range_region(");
    2481            0 :       get_parent_region ()->dump_to_pp (pp, simple);
    2482            0 :       pp_string (pp, ", ");
    2483            0 :       m_bits.dump_to_pp (pp);
    2484            0 :       pp_printf (pp, ")");
    2485              :     }
    2486            0 : }
    2487              : 
    2488              : void
    2489            0 : bit_range_region::print_dump_widget_label (pretty_printer *pp) const
    2490              : {
    2491            0 :   pp_printf (pp, "bit_range_region(m_bits: ");
    2492            0 :   m_bits.dump_to_pp (pp);
    2493            0 :   pp_string (pp, ")");
    2494            0 : }
    2495              : 
    2496              : /* Implementation of region::get_byte_size vfunc for bit_range_region.  */
    2497              : 
    2498              : bool
    2499            0 : bit_range_region::get_byte_size (byte_size_t *out) const
    2500              : {
    2501            0 :   if (m_bits.m_size_in_bits % BITS_PER_UNIT == 0)
    2502              :     {
    2503            0 :       *out = m_bits.m_size_in_bits / BITS_PER_UNIT;
    2504            0 :       return true;
    2505              :     }
    2506              :   return false;
    2507              : }
    2508              : 
    2509              : /* Implementation of region::get_bit_size vfunc for bit_range_region.  */
    2510              : 
    2511              : bool
    2512          812 : bit_range_region::get_bit_size (bit_size_t *out) const
    2513              : {
    2514          812 :   *out = m_bits.m_size_in_bits;
    2515          812 :   return true;
    2516              : }
    2517              : 
    2518              : /* Implementation of region::get_byte_size_sval vfunc for bit_range_region.  */
    2519              : 
    2520              : const svalue *
    2521           48 : bit_range_region::get_byte_size_sval (region_model_manager *mgr) const
    2522              : {
    2523           48 :   if (m_bits.m_size_in_bits % BITS_PER_UNIT != 0)
    2524            0 :     return mgr->get_or_create_unknown_svalue (size_type_node);
    2525              : 
    2526           48 :   HOST_WIDE_INT num_bytes = m_bits.m_size_in_bits.to_shwi () / BITS_PER_UNIT;
    2527           48 :   return mgr->get_or_create_int_cst (size_type_node, num_bytes);
    2528              : }
    2529              : 
    2530              : /* Implementation of region::get_bit_size_sval vfunc for bit_range_region.  */
    2531              : 
    2532              : const svalue *
    2533          136 : bit_range_region::get_bit_size_sval (region_model_manager *mgr) const
    2534              : {
    2535          272 :   return mgr->get_or_create_int_cst (size_type_node,
    2536          136 :                                      m_bits.m_size_in_bits);
    2537              : }
    2538              : 
    2539              : /* Implementation of region::get_relative_concrete_offset vfunc for
    2540              :    bit_range_region.  */
    2541              : 
    2542              : bool
    2543          155 : bit_range_region::get_relative_concrete_offset (bit_offset_t *out) const
    2544              : {
    2545          155 :   *out = m_bits.get_start_bit_offset ();
    2546          155 :   return true;
    2547              : }
    2548              : 
    2549              : /* Implementation of region::get_relative_symbolic_offset vfunc for
    2550              :    bit_range_region.
    2551              :    The returned svalue is equal to the offset converted to bytes and
    2552              :    rounded off.  */
    2553              : 
    2554              : const svalue *
    2555            0 : bit_range_region::get_relative_symbolic_offset (region_model_manager *mgr)
    2556              :   const
    2557              : {
    2558            0 :   byte_offset_t start_byte = m_bits.get_start_bit_offset () / BITS_PER_UNIT;
    2559            0 :   tree start_bit_tree = wide_int_to_tree (ptrdiff_type_node, start_byte);
    2560            0 :   return mgr->get_or_create_constant_svalue (start_bit_tree);
    2561              : }
    2562              : 
    2563              : /* class var_arg_region : public region.  */
    2564              : 
    2565              : void
    2566            0 : var_arg_region::dump_to_pp (pretty_printer *pp, bool simple) const
    2567              : {
    2568            0 :   if (simple)
    2569              :     {
    2570            0 :       pp_string (pp, "VAR_ARG_REG(");
    2571            0 :       get_parent_region ()->dump_to_pp (pp, simple);
    2572            0 :       pp_printf (pp, ", arg_idx: %d)", m_idx);
    2573              :     }
    2574              :   else
    2575              :     {
    2576            0 :       pp_string (pp, "var_arg_region(");
    2577            0 :       get_parent_region ()->dump_to_pp (pp, simple);
    2578            0 :       pp_printf (pp, ", arg_idx: %d)", m_idx);
    2579              :     }
    2580            0 : }
    2581              : 
    2582              : void
    2583            0 : var_arg_region::print_dump_widget_label (pretty_printer *pp) const
    2584              : {
    2585            0 :   pp_printf (pp, "var_arg_region(arg_idx: %i)", m_idx);
    2586            0 : }
    2587              : 
    2588              : /* Get the frame_region for this var_arg_region.  */
    2589              : 
    2590              : const frame_region *
    2591          625 : var_arg_region::get_frame_region () const
    2592              : {
    2593          625 :   gcc_assert (get_parent_region ());
    2594          625 :   return as_a <const frame_region *> (get_parent_region ());
    2595              : }
    2596              : 
    2597              : /* class errno_region : public region.  */
    2598              : 
    2599              : void
    2600            0 : errno_region::dump_to_pp (pretty_printer *pp, bool simple) const
    2601              : {
    2602            0 :   if (simple)
    2603            0 :     pp_string (pp, "errno_region");
    2604              :   else
    2605            0 :     pp_string (pp, "errno_region()");
    2606            0 : }
    2607              : 
    2608              : void
    2609            0 : errno_region::print_dump_widget_label (pretty_printer *pp) const
    2610              : {
    2611            0 :   pp_printf (pp, "errno_region");
    2612            0 : }
    2613              : 
    2614              : /* class private_region : public region.  */
    2615              : 
    2616              : void
    2617            0 : private_region::dump_to_pp (pretty_printer *pp, bool simple) const
    2618              : {
    2619            0 :   if (simple)
    2620            0 :     pp_printf (pp, "PRIVATE_REG(%qs)", m_desc);
    2621              :   else
    2622            0 :     pp_printf (pp, "private_region(%qs)", m_desc);
    2623            0 : }
    2624              : 
    2625              : void
    2626            0 : private_region::print_dump_widget_label (pretty_printer *pp) const
    2627              : {
    2628            0 :   pp_printf (pp, "private_region(%qs)", m_desc);
    2629            0 : }
    2630              : 
    2631              : /* class unknown_region : public region.  */
    2632              : 
    2633              : /* Implementation of region::dump_to_pp vfunc for unknown_region.  */
    2634              : 
    2635              : void
    2636           35 : unknown_region::dump_to_pp (pretty_printer *pp, bool /*simple*/) const
    2637              : {
    2638           35 :   pp_string (pp, "UNKNOWN_REGION");
    2639           35 : }
    2640              : 
    2641              : void
    2642            0 : unknown_region::print_dump_widget_label (pretty_printer *pp) const
    2643              : {
    2644            0 :   pp_printf (pp, "unknown_region");
    2645            0 : }
    2646              : 
    2647              : } // namespace ana
    2648              : 
    2649              : #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.