LCOV - code coverage report
Current view: top level - gcc/analyzer - store.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 85.6 % 1633 1398
Test Date: 2024-04-20 14:03:02 Functions: 87.7 % 130 114
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: - 0 0

             Branch data     Line data    Source code
       1                 :             : /* Classes for modeling the state of memory.
       2                 :             :    Copyright (C) 2020-2024 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 "config.h"
      22                 :             : #define INCLUDE_MEMORY
      23                 :             : #include "system.h"
      24                 :             : #include "coretypes.h"
      25                 :             : #include "tree.h"
      26                 :             : #include "function.h"
      27                 :             : #include "basic-block.h"
      28                 :             : #include "gimple.h"
      29                 :             : #include "gimple-iterator.h"
      30                 :             : #include "diagnostic-core.h"
      31                 :             : #include "graphviz.h"
      32                 :             : #include "options.h"
      33                 :             : #include "cgraph.h"
      34                 :             : #include "tree-dfa.h"
      35                 :             : #include "stringpool.h"
      36                 :             : #include "convert.h"
      37                 :             : #include "target.h"
      38                 :             : #include "fold-const.h"
      39                 :             : #include "tree-pretty-print.h"
      40                 :             : #include "diagnostic-color.h"
      41                 :             : #include "bitmap.h"
      42                 :             : #include "selftest.h"
      43                 :             : #include "analyzer/analyzer.h"
      44                 :             : #include "analyzer/analyzer-logging.h"
      45                 :             : #include "ordered-hash-map.h"
      46                 :             : #include "options.h"
      47                 :             : #include "cfg.h"
      48                 :             : #include "analyzer/supergraph.h"
      49                 :             : #include "sbitmap.h"
      50                 :             : #include "analyzer/call-string.h"
      51                 :             : #include "analyzer/program-point.h"
      52                 :             : #include "analyzer/store.h"
      53                 :             : #include "analyzer/region-model.h"
      54                 :             : #include "analyzer/call-summary.h"
      55                 :             : #include "analyzer/analyzer-selftests.h"
      56                 :             : #include "stor-layout.h"
      57                 :             : 
      58                 :             : #if ENABLE_ANALYZER
      59                 :             : 
      60                 :             : namespace ana {
      61                 :             : 
      62                 :             : /* Dump SVALS to PP, sorting them to ensure determinism.  */
      63                 :             : 
      64                 :             : static void
      65                 :         496 : dump_svalue_set (const hash_set <const svalue *> &svals,
      66                 :             :                  pretty_printer *pp, bool simple)
      67                 :             : {
      68                 :         496 :   auto_vec <const svalue *> v;
      69                 :         496 :   for (hash_set<const svalue *>::iterator iter = svals.begin ();
      70                 :         560 :        iter != svals.end (); ++iter)
      71                 :             :     {
      72                 :          32 :       v.safe_push (*iter);
      73                 :             :     }
      74                 :         496 :   v.qsort (svalue::cmp_ptr_ptr);
      75                 :             : 
      76                 :         496 :   pp_character (pp, '{');
      77                 :         496 :   const svalue *sval;
      78                 :         496 :   unsigned i;
      79                 :        1024 :   FOR_EACH_VEC_ELT (v, i, sval)
      80                 :             :     {
      81                 :          32 :       if (i > 0)
      82                 :          19 :         pp_string (pp, ", ");
      83                 :          32 :       sval->dump_to_pp (pp, simple);
      84                 :             :     }
      85                 :         496 :   pp_character (pp, '}');
      86                 :         496 : }
      87                 :             : 
      88                 :             : /* class uncertainty_t.  */
      89                 :             : 
      90                 :             : /* Dump this object to PP.  */
      91                 :             : 
      92                 :             : void
      93                 :         248 : uncertainty_t::dump_to_pp (pretty_printer *pp, bool simple) const
      94                 :             : {
      95                 :         248 :   pp_string (pp, "{m_maybe_bound_svals: ");
      96                 :         248 :   dump_svalue_set (m_maybe_bound_svals, pp, simple);
      97                 :             : 
      98                 :         248 :   pp_string (pp, ", m_mutable_at_unknown_call_svals: ");
      99                 :         248 :   dump_svalue_set (m_mutable_at_unknown_call_svals, pp, simple);
     100                 :         248 :   pp_string (pp, "}");
     101                 :         248 : }
     102                 :             : 
     103                 :             : /* Dump this object to stderr.  */
     104                 :             : 
     105                 :             : DEBUG_FUNCTION void
     106                 :           0 : uncertainty_t::dump (bool simple) const
     107                 :             : {
     108                 :           0 :   pretty_printer pp;
     109                 :           0 :   pp_format_decoder (&pp) = default_tree_printer;
     110                 :           0 :   pp_show_color (&pp) = pp_show_color (global_dc->printer);
     111                 :           0 :   pp.buffer->stream = stderr;
     112                 :           0 :   dump_to_pp (&pp, simple);
     113                 :           0 :   pp_newline (&pp);
     114                 :           0 :   pp_flush (&pp);
     115                 :           0 : }
     116                 :             : 
     117                 :             : /* class binding_key.  */
     118                 :             : 
     119                 :             : const binding_key *
     120                 :     4163734 : binding_key::make (store_manager *mgr, const region *r)
     121                 :             : {
     122                 :     4163734 :   region_offset offset = r->get_offset (mgr->get_svalue_manager ());
     123                 :     4163734 :   if (offset.symbolic_p ())
     124                 :       44783 :     return mgr->get_symbolic_binding (r);
     125                 :             :   else
     126                 :             :     {
     127                 :     4118951 :       bit_size_t bit_size;
     128                 :     4118951 :       if (r->get_bit_size (&bit_size))
     129                 :             :         {
     130                 :             :           /* Must be non-empty.  */
     131                 :     2603629 :           gcc_assert (bit_size > 0);
     132                 :     2603629 :           return mgr->get_concrete_binding (offset.get_bit_offset (),
     133                 :     2603629 :                                             bit_size);
     134                 :             :         }
     135                 :             :       else
     136                 :     1515322 :         return mgr->get_symbolic_binding (r);
     137                 :             :     }
     138                 :             : }
     139                 :             : 
     140                 :             : /* Dump this binding_key to stderr.  */
     141                 :             : 
     142                 :             : DEBUG_FUNCTION void
     143                 :           0 : binding_key::dump (bool simple) const
     144                 :             : {
     145                 :           0 :   pretty_printer pp;
     146                 :           0 :   pp_format_decoder (&pp) = default_tree_printer;
     147                 :           0 :   pp_show_color (&pp) = pp_show_color (global_dc->printer);
     148                 :           0 :   pp.buffer->stream = stderr;
     149                 :           0 :   dump_to_pp (&pp, simple);
     150                 :           0 :   pp_newline (&pp);
     151                 :           0 :   pp_flush (&pp);
     152                 :           0 : }
     153                 :             : 
     154                 :             : /* Get a description of this binding_key.  */
     155                 :             : 
     156                 :             : label_text
     157                 :           0 : binding_key::get_desc (bool simple) const
     158                 :             : {
     159                 :           0 :   pretty_printer pp;
     160                 :           0 :   pp_format_decoder (&pp) = default_tree_printer;
     161                 :           0 :   dump_to_pp (&pp, simple);
     162                 :           0 :   return label_text::take (xstrdup (pp_formatted_text (&pp)));
     163                 :           0 : }
     164                 :             : 
     165                 :             : /* qsort callback.  */
     166                 :             : 
     167                 :             : int
     168                 :        5090 : binding_key::cmp_ptrs (const void *p1, const void *p2)
     169                 :             : {
     170                 :        5090 :   const binding_key * const *pk1 = (const binding_key * const *)p1;
     171                 :        5090 :   const binding_key * const *pk2 = (const binding_key * const *)p2;
     172                 :        5090 :   return cmp (*pk1, *pk2);
     173                 :             : }
     174                 :             : 
     175                 :             : /* Comparator for binding_keys.  */
     176                 :             : 
     177                 :             : int
     178                 :        5090 : binding_key::cmp (const binding_key *k1, const binding_key *k2)
     179                 :             : {
     180                 :        5090 :   int concrete1 = k1->concrete_p ();
     181                 :        5090 :   int concrete2 = k2->concrete_p ();
     182                 :        5090 :   if (int concrete_cmp = concrete1 - concrete2)
     183                 :             :     return concrete_cmp;
     184                 :        5090 :   if (concrete1)
     185                 :             :     {
     186                 :        5090 :       const concrete_binding *b1 = (const concrete_binding *)k1;
     187                 :        5090 :       const concrete_binding *b2 = (const concrete_binding *)k2;
     188                 :        5090 :       if (int start_cmp = wi::cmp (b1->get_start_bit_offset (),
     189                 :        5090 :                                    b2->get_start_bit_offset (),
     190                 :             :                                    SIGNED))
     191                 :             :         return start_cmp;
     192                 :        1536 :       return wi::cmp (b1->get_next_bit_offset (), b2->get_next_bit_offset (),
     193                 :             :                       SIGNED);
     194                 :             :     }
     195                 :             :   else
     196                 :             :     {
     197                 :           0 :       const symbolic_binding *s1 = (const symbolic_binding *)k1;
     198                 :           0 :       const symbolic_binding *s2 = (const symbolic_binding *)k2;
     199                 :           0 :       if (s1 > s2)
     200                 :             :         return 1;
     201                 :           0 :       if (s1 < s2)
     202                 :             :         return -1;
     203                 :           0 :       return 0;
     204                 :             :     }
     205                 :             : }
     206                 :             : 
     207                 :             : /* struct bit_range.  */
     208                 :             : 
     209                 :             : void
     210                 :        2395 : bit_range::dump_to_pp (pretty_printer *pp) const
     211                 :             : {
     212                 :        2395 :   byte_range bytes (0, 0);
     213                 :        2395 :   if (as_byte_range (&bytes))
     214                 :        2395 :     bytes.dump_to_pp (pp);
     215                 :             :   else
     216                 :             :     {
     217                 :           0 :       pp_string (pp, "start: ");
     218                 :           0 :       pp_wide_int (pp, m_start_bit_offset, SIGNED);
     219                 :           0 :       pp_string (pp, ", size: ");
     220                 :           0 :       pp_wide_int (pp, m_size_in_bits, SIGNED);
     221                 :           0 :       pp_string (pp, ", next: ");
     222                 :           0 :       pp_wide_int (pp, get_next_bit_offset (), SIGNED);
     223                 :             :     }
     224                 :        2395 : }
     225                 :             : 
     226                 :             : /* Dump this object to stderr.  */
     227                 :             : 
     228                 :             : DEBUG_FUNCTION void
     229                 :           0 : bit_range::dump () const
     230                 :             : {
     231                 :           0 :   pretty_printer pp;
     232                 :           0 :   pp.buffer->stream = stderr;
     233                 :           0 :   dump_to_pp (&pp);
     234                 :           0 :   pp_newline (&pp);
     235                 :           0 :   pp_flush (&pp);
     236                 :           0 : }
     237                 :             : 
     238                 :             : /* Generate a JSON value for this bit_range.
     239                 :             :    This is intended for debugging the analyzer rather
     240                 :             :    than serialization.  */
     241                 :             : 
     242                 :             : json::object *
     243                 :           5 : bit_range::to_json () const
     244                 :             : {
     245                 :           5 :   json::object *obj = new json::object ();
     246                 :           5 :   obj->set ("start_bit_offset",
     247                 :           5 :             bit_offset_to_json (m_start_bit_offset));
     248                 :           5 :   obj->set ("size_in_bits",
     249                 :           5 :             bit_offset_to_json (m_size_in_bits));
     250                 :           5 :   return obj;
     251                 :             : }
     252                 :             : 
     253                 :             : /* If OTHER is a subset of this, return true and, if OUT is
     254                 :             :    non-null, write to *OUT the relative range of OTHER within this.
     255                 :             :    Otherwise return false.  */
     256                 :             : 
     257                 :             : bool
     258                 :       49757 : bit_range::contains_p (const bit_range &other, bit_range *out) const
     259                 :             : {
     260                 :       49757 :   if (contains_p (other.get_start_bit_offset ())
     261                 :       49757 :       && contains_p (other.get_last_bit_offset ()))
     262                 :             :     {
     263                 :       33095 :       if (out)
     264                 :             :         {
     265                 :       33095 :           out->m_start_bit_offset = other.m_start_bit_offset - m_start_bit_offset;
     266                 :       33095 :           out->m_size_in_bits = other.m_size_in_bits;
     267                 :             :         }
     268                 :       33095 :       return true;
     269                 :             :     }
     270                 :             :   else
     271                 :       16662 :     return false;
     272                 :             : }
     273                 :             : 
     274                 :             : /* If OTHER intersects this, return true and write
     275                 :             :    the relative range of OTHER within THIS to *OUT_THIS,
     276                 :             :    and the relative range of THIS within OTHER to *OUT_OTHER.
     277                 :             :    Otherwise return false.  */
     278                 :             : 
     279                 :             : bool
     280                 :         102 : bit_range::intersects_p (const bit_range &other,
     281                 :             :                          bit_range *out_this,
     282                 :             :                          bit_range *out_other) const
     283                 :             : {
     284                 :         102 :   if (get_start_bit_offset () < other.get_next_bit_offset ()
     285                 :         204 :       && other.get_start_bit_offset () < get_next_bit_offset ())
     286                 :             :     {
     287                 :         102 :       bit_offset_t overlap_start
     288                 :         102 :         = MAX (get_start_bit_offset (),
     289                 :             :                other.get_start_bit_offset ());
     290                 :         102 :       bit_offset_t overlap_next
     291                 :         102 :         = MIN (get_next_bit_offset (),
     292                 :             :                other.get_next_bit_offset ());
     293                 :         102 :       if (overlap_next <= overlap_start)
     294                 :             :         /* If this has happened, some kind of overflow has happened in
     295                 :             :            our arithmetic.  For now, reject such cases.  */
     296                 :             :         return false;
     297                 :         102 :       bit_range abs_overlap_bits (overlap_start, overlap_next - overlap_start);
     298                 :         102 :       *out_this = abs_overlap_bits - get_start_bit_offset ();
     299                 :         102 :       *out_other = abs_overlap_bits - other.get_start_bit_offset ();
     300                 :         102 :       return true;
     301                 :             :     }
     302                 :             :   else
     303                 :           0 :     return false;
     304                 :             : }
     305                 :             : 
     306                 :             : /* Return true if THIS and OTHER intersect and write the number
     307                 :             :    of bits both buffers overlap to *OUT_NUM_OVERLAP_BITS.
     308                 :             : 
     309                 :             :    Otherwise return false.  */
     310                 :             : 
     311                 :             : bool
     312                 :           0 : bit_range::intersects_p (const bit_range &other,
     313                 :             :                          bit_size_t *out_num_overlap_bits) const
     314                 :             : {
     315                 :           0 :   if (get_start_bit_offset () < other.get_next_bit_offset ()
     316                 :           0 :       && other.get_start_bit_offset () < get_next_bit_offset ())
     317                 :             :     {
     318                 :           0 :       bit_offset_t overlap_start = MAX (get_start_bit_offset (),
     319                 :             :                                          other.get_start_bit_offset ());
     320                 :           0 :       bit_offset_t overlap_next = MIN (get_next_bit_offset (),
     321                 :             :                                         other.get_next_bit_offset ());
     322                 :           0 :       if (overlap_next <= overlap_start)
     323                 :             :         /* If this has happened, some kind of overflow has happened in
     324                 :             :            our arithmetic.  For now, reject such cases.  */
     325                 :             :         return false;
     326                 :           0 :       *out_num_overlap_bits = overlap_next - overlap_start;
     327                 :           0 :       return true;
     328                 :             :     }
     329                 :             :   else
     330                 :           0 :     return false;
     331                 :             : }
     332                 :             : 
     333                 :             : /* Return true if THIS exceeds OTHER and write the overhanging
     334                 :             :    bit range to OUT_OVERHANGING_BIT_RANGE.  */
     335                 :             : 
     336                 :             : bool
     337                 :      752194 : bit_range::exceeds_p (const bit_range &other,
     338                 :             :                       bit_range *out_overhanging_bit_range) const
     339                 :             : {
     340                 :      752194 :   gcc_assert (!empty_p ());
     341                 :             : 
     342                 :      752194 :   if (other.get_next_bit_offset () < get_next_bit_offset ())
     343                 :             :     {
     344                 :             :       /* THIS definitely exceeds OTHER.  */
     345                 :         554 :       bit_offset_t start = MAX (get_start_bit_offset (),
     346                 :             :                                  other.get_next_bit_offset ());
     347                 :         554 :       bit_offset_t size = get_next_bit_offset () - start;
     348                 :         554 :       if (size <= 0)
     349                 :             :         /* If this has happened, some kind of overflow has happened in
     350                 :             :            our arithmetic.  For now, reject such cases.  */
     351                 :             :         return false;
     352                 :         529 :       out_overhanging_bit_range->m_start_bit_offset = start;
     353                 :         529 :       out_overhanging_bit_range->m_size_in_bits = size;
     354                 :         529 :       return true;
     355                 :             :     }
     356                 :             :   else
     357                 :             :     return false;
     358                 :             : }
     359                 :             : 
     360                 :             : /* Return true if THIS falls short of OFFSET and write the
     361                 :             :    bit range fallen short to OUT_FALL_SHORT_BITS.  */
     362                 :             : 
     363                 :             : bool
     364                 :      755729 : bit_range::falls_short_of_p (bit_offset_t offset,
     365                 :             :                              bit_range *out_fall_short_bits) const
     366                 :             : {
     367                 :      755729 :   gcc_assert (!empty_p ());
     368                 :             : 
     369                 :      755729 :   if (get_start_bit_offset () < offset)
     370                 :             :     {
     371                 :             :       /* THIS falls short of OFFSET.  */
     372                 :         210 :       bit_offset_t start = get_start_bit_offset ();
     373                 :         210 :       bit_offset_t size = MIN (offset, get_next_bit_offset ()) - start;
     374                 :         210 :       if (size <= 0)
     375                 :             :         /* If this has happened, some kind of overflow has happened in
     376                 :             :            our arithmetic.  For now, reject such cases.  */
     377                 :             :         return false;
     378                 :         185 :       out_fall_short_bits->m_start_bit_offset = start;
     379                 :         185 :       out_fall_short_bits->m_size_in_bits = size;
     380                 :         185 :       return true;
     381                 :             :     }
     382                 :             :   else
     383                 :             :     return false;
     384                 :             : }
     385                 :             : 
     386                 :             : int
     387                 :         335 : bit_range::cmp (const bit_range &br1, const bit_range &br2)
     388                 :             : {
     389                 :         335 :   if (int start_cmp = wi::cmps (br1.m_start_bit_offset,
     390                 :         335 :                                 br2.m_start_bit_offset))
     391                 :             :     return start_cmp;
     392                 :             : 
     393                 :          12 :   return wi::cmpu (br1.m_size_in_bits, br2.m_size_in_bits);
     394                 :             : }
     395                 :             : 
     396                 :             : /* Offset this range by OFFSET.  */
     397                 :             : 
     398                 :             : bit_range
     399                 :         204 : bit_range::operator- (bit_offset_t offset) const
     400                 :             : {
     401                 :         204 :   return bit_range (m_start_bit_offset - offset, m_size_in_bits);
     402                 :             : }
     403                 :             : 
     404                 :             : /* If MASK is a contiguous range of set bits, write them
     405                 :             :    to *OUT and return true.
     406                 :             :    Otherwise return false.  */
     407                 :             : 
     408                 :             : bool
     409                 :         144 : bit_range::from_mask (unsigned HOST_WIDE_INT mask, bit_range *out)
     410                 :             : {
     411                 :         144 :   unsigned iter_bit_idx = 0;
     412                 :         144 :   unsigned HOST_WIDE_INT iter_bit_mask = 1;
     413                 :             : 
     414                 :             :   /* Find the first contiguous run of set bits in MASK.  */
     415                 :             : 
     416                 :             :   /* Find first set bit in MASK.  */
     417                 :         780 :   while (iter_bit_idx < HOST_BITS_PER_WIDE_INT)
     418                 :             :     {
     419                 :         776 :       if (mask & iter_bit_mask)
     420                 :             :         break;
     421                 :         636 :       iter_bit_idx++;
     422                 :         636 :       iter_bit_mask <<= 1;
     423                 :             :     }
     424                 :         144 :   if (iter_bit_idx == HOST_BITS_PER_WIDE_INT)
     425                 :             :     /* MASK is zero.  */
     426                 :             :     return false;
     427                 :             : 
     428                 :         140 :   unsigned first_set_iter_bit_idx = iter_bit_idx;
     429                 :         140 :   unsigned num_set_bits = 1;
     430                 :         140 :   iter_bit_idx++;
     431                 :         140 :   iter_bit_mask <<= 1;
     432                 :             : 
     433                 :             :   /* Find next unset bit in MASK.  */
     434                 :         396 :   while (iter_bit_idx < HOST_BITS_PER_WIDE_INT)
     435                 :             :     {
     436                 :         396 :       if (!(mask & iter_bit_mask))
     437                 :             :         break;
     438                 :         256 :       num_set_bits++;
     439                 :         256 :       iter_bit_idx++;
     440                 :         256 :       iter_bit_mask <<= 1;
     441                 :             :     }
     442                 :         140 :   if (iter_bit_idx == HOST_BITS_PER_WIDE_INT)
     443                 :             :     {
     444                 :           0 :       *out = bit_range (first_set_iter_bit_idx, num_set_bits);
     445                 :           0 :       return true;
     446                 :             :     }
     447                 :             : 
     448                 :             :   /* We now have the first contiguous run of set bits in MASK.
     449                 :             :      Fail if any other bits are set.  */
     450                 :        7892 :   while (iter_bit_idx < HOST_BITS_PER_WIDE_INT)
     451                 :             :     {
     452                 :        7760 :       if (mask & iter_bit_mask)
     453                 :             :         return false;
     454                 :        7752 :       iter_bit_idx++;
     455                 :        7752 :       iter_bit_mask <<= 1;
     456                 :             :     }
     457                 :             : 
     458                 :         132 :   *out = bit_range (first_set_iter_bit_idx, num_set_bits);
     459                 :         132 :   return true;
     460                 :             : }
     461                 :             : 
     462                 :             : /* Attempt to convert this bit_range to a byte_range.
     463                 :             :    Return true if it is possible, writing the result to *OUT.
     464                 :             :    Otherwise return false.  */
     465                 :             : 
     466                 :             : bool
     467                 :        8702 : bit_range::as_byte_range (byte_range *out) const
     468                 :             : {
     469                 :        8702 :   if (m_start_bit_offset % BITS_PER_UNIT == 0
     470                 :        8702 :       && m_size_in_bits % BITS_PER_UNIT == 0)
     471                 :             :     {
     472                 :        8687 :       out->m_start_byte_offset = m_start_bit_offset / BITS_PER_UNIT;
     473                 :        8687 :       out->m_size_in_bytes = m_size_in_bits / BITS_PER_UNIT;
     474                 :        8687 :       return true;
     475                 :             :     }
     476                 :             :   return false;
     477                 :             : }
     478                 :             : 
     479                 :             : /* Dump this object to PP.  */
     480                 :             : 
     481                 :             : void
     482                 :        2395 : byte_range::dump_to_pp (pretty_printer *pp) const
     483                 :             : {
     484                 :        2395 :   if (m_size_in_bytes == 0)
     485                 :             :     {
     486                 :           0 :       pp_string (pp, "empty");
     487                 :             :     }
     488                 :        2395 :   else if (m_size_in_bytes == 1)
     489                 :             :     {
     490                 :        1595 :       pp_string (pp, "byte ");
     491                 :        1595 :       pp_wide_int (pp, m_start_byte_offset, SIGNED);
     492                 :             :     }
     493                 :             :   else
     494                 :             :     {
     495                 :         800 :       pp_string (pp, "bytes ");
     496                 :         800 :       pp_wide_int (pp, m_start_byte_offset, SIGNED);
     497                 :         800 :       pp_string (pp, "-");
     498                 :         800 :       pp_wide_int (pp, get_last_byte_offset (), SIGNED);
     499                 :             :     }
     500                 :        2395 : }
     501                 :             : 
     502                 :             : /* Dump this object to stderr.  */
     503                 :             : 
     504                 :             : DEBUG_FUNCTION void
     505                 :           0 : byte_range::dump () const
     506                 :             : {
     507                 :           0 :   pretty_printer pp;
     508                 :           0 :   pp.buffer->stream = stderr;
     509                 :           0 :   dump_to_pp (&pp);
     510                 :           0 :   pp_newline (&pp);
     511                 :           0 :   pp_flush (&pp);
     512                 :           0 : }
     513                 :             : 
     514                 :             : /* Generate a JSON value for this byte_range.
     515                 :             :    This is intended for debugging the analyzer rather
     516                 :             :    than serialization.  */
     517                 :             : 
     518                 :             : json::object *
     519                 :           5 : byte_range::to_json () const
     520                 :             : {
     521                 :           5 :   json::object *obj = new json::object ();
     522                 :           5 :   obj->set ("start_byte_offset",
     523                 :           5 :             byte_offset_to_json (m_start_byte_offset));
     524                 :           5 :   obj->set ("size_in_bytes",
     525                 :           5 :             byte_offset_to_json (m_size_in_bytes));
     526                 :           5 :   return obj;
     527                 :             : }
     528                 :             : 
     529                 :             : /* If OTHER is a subset of this, return true and write
     530                 :             :    to *OUT the relative range of OTHER within this.
     531                 :             :    Otherwise return false.  */
     532                 :             : 
     533                 :             : bool
     534                 :         765 : byte_range::contains_p (const byte_range &other, byte_range *out) const
     535                 :             : {
     536                 :         765 :   if (contains_p (other.get_start_byte_offset ())
     537                 :         765 :       && contains_p (other.get_last_byte_offset ()))
     538                 :             :     {
     539                 :         382 :       out->m_start_byte_offset = other.m_start_byte_offset - m_start_byte_offset;
     540                 :         382 :       out->m_size_in_bytes = other.m_size_in_bytes;
     541                 :         382 :       return true;
     542                 :             :     }
     543                 :             :   else
     544                 :         383 :     return false;
     545                 :             : }
     546                 :             : 
     547                 :             : /* qsort comparator for byte ranges.  */
     548                 :             : 
     549                 :             : int
     550                 :         630 : byte_range::cmp (const byte_range &br1, const byte_range &br2)
     551                 :             : {
     552                 :             :   /* Order first by offset.  */
     553                 :         630 :   if (int start_cmp = wi::cmps (br1.m_start_byte_offset,
     554                 :         630 :                                 br2.m_start_byte_offset))
     555                 :             :     return start_cmp;
     556                 :             : 
     557                 :             :   /* ...then by size.  */
     558                 :           0 :   return wi::cmpu (br1.m_size_in_bytes, br2.m_size_in_bytes);
     559                 :             : }
     560                 :             : 
     561                 :             : /* class concrete_binding : public binding_key.  */
     562                 :             : 
     563                 :             : /* Implementation of binding_key::dump_to_pp vfunc for concrete_binding.  */
     564                 :             : 
     565                 :             : void
     566                 :        1730 : concrete_binding::dump_to_pp (pretty_printer *pp, bool) const
     567                 :             : {
     568                 :        1730 :   m_bit_range.dump_to_pp (pp);
     569                 :        1730 : }
     570                 :             : 
     571                 :             : /* Return true if this binding overlaps with OTHER.  */
     572                 :             : 
     573                 :             : bool
     574                 :      122297 : concrete_binding::overlaps_p (const concrete_binding &other) const
     575                 :             : {
     576                 :      122297 :   if (get_start_bit_offset () < other.get_next_bit_offset ()
     577                 :      122297 :       && get_next_bit_offset () > other.get_start_bit_offset ())
     578                 :       77420 :     return true;
     579                 :             :   return false;
     580                 :             : }
     581                 :             : 
     582                 :             : /* If this is expressible as a concrete byte range, return true
     583                 :             :    and write it to *OUT.  Otherwise return false.  */
     584                 :             : 
     585                 :             : bool
     586                 :         808 : concrete_binding::get_byte_range (byte_range *out) const
     587                 :             : {
     588                 :         808 :   return m_bit_range.as_byte_range (out);
     589                 :             : }
     590                 :             : 
     591                 :             : /* Comparator for use by vec<const concrete_binding *>::qsort.  */
     592                 :             : 
     593                 :             : int
     594                 :          48 : concrete_binding::cmp_ptr_ptr (const void *p1, const void *p2)
     595                 :             : {
     596                 :          48 :   const concrete_binding *b1 = *(const concrete_binding * const *)p1;
     597                 :          48 :   const concrete_binding *b2 = *(const concrete_binding * const *)p2;
     598                 :             : 
     599                 :          48 :   return bit_range::cmp (b1->m_bit_range, b2->m_bit_range);
     600                 :             : }
     601                 :             : 
     602                 :             : /* class symbolic_binding : public binding_key.  */
     603                 :             : 
     604                 :             : void
     605                 :           3 : symbolic_binding::dump_to_pp (pretty_printer *pp, bool simple) const
     606                 :             : {
     607                 :             :   //binding_key::dump_to_pp (pp, simple);
     608                 :           3 :   pp_string (pp, "region: ");
     609                 :           3 :   m_region->dump_to_pp (pp, simple);
     610                 :           3 : }
     611                 :             : 
     612                 :             : /* Comparator for use by vec<const symbolic_binding *>::qsort.  */
     613                 :             : 
     614                 :             : int
     615                 :          11 : symbolic_binding::cmp_ptr_ptr (const void *p1, const void *p2)
     616                 :             : {
     617                 :          11 :   const symbolic_binding *b1 = *(const symbolic_binding * const *)p1;
     618                 :          11 :   const symbolic_binding *b2 = *(const symbolic_binding * const *)p2;
     619                 :             : 
     620                 :          11 :   return region::cmp_ids (b1->get_region (), b2->get_region ());
     621                 :             : }
     622                 :             : 
     623                 :             : /* The store is oblivious to the types of the svalues bound within
     624                 :             :    it: any type can get bound at any location.
     625                 :             :    Simplify any casts before binding.
     626                 :             : 
     627                 :             :    For example, if we have:
     628                 :             :      struct big { int ia[1024]; };
     629                 :             :      struct big src, dst;
     630                 :             :      memcpy (&dst, &src, sizeof (struct big));
     631                 :             :    this reaches us in gimple form as:
     632                 :             :      MEM <unsigned char[4096]> [(char * {ref-all})&dst]
     633                 :             :        = MEM <unsigned char[4096]> [(char * {ref-all})&src];
     634                 :             :    Using cast_region when handling the MEM_REF would give us:
     635                 :             :      INIT_VAL(CAST_REG(unsigned char[4096], src))
     636                 :             :    as rhs_sval, but we can fold that into a cast svalue:
     637                 :             :      CAST(unsigned char[4096], INIT_VAL(src))
     638                 :             :    We can discard that cast from the svalue when binding it in
     639                 :             :    the store for "dst", and simply store:
     640                 :             :      cluster for: dst
     641                 :             :        key:   {kind: direct, start: 0, size: 32768, next: 32768}
     642                 :             :        value: ‘struct big’ {INIT_VAL(src)}.  */
     643                 :             : 
     644                 :             : static const svalue *
     645                 :      455518 : simplify_for_binding (const svalue *sval)
     646                 :             : {
     647                 :      455518 :   if (const svalue *cast_sval = sval->maybe_undo_cast ())
     648                 :           0 :     sval = cast_sval;
     649                 :       71764 :   return sval;
     650                 :             : }
     651                 :             : 
     652                 :             : /* class binding_map.  */
     653                 :             : 
     654                 :             : /* binding_map's copy ctor.  */
     655                 :             : 
     656                 :    28448885 : binding_map::binding_map (const binding_map &other)
     657                 :    28448885 : : m_map (other.m_map)
     658                 :             : {
     659                 :    28448885 : }
     660                 :             : 
     661                 :             : /* binding_map's assignment operator.  */
     662                 :             : 
     663                 :             : binding_map&
     664                 :           0 : binding_map::operator=(const binding_map &other)
     665                 :             : {
     666                 :             :   /* For now, assume we only ever copy to an empty cluster.  */
     667                 :           0 :   gcc_assert (m_map.elements () == 0);
     668                 :           0 :   for (map_t::iterator iter = other.m_map.begin (); iter != other.m_map.end ();
     669                 :           0 :        ++iter)
     670                 :             :     {
     671                 :           0 :       const binding_key *key = (*iter).first;
     672                 :           0 :       const svalue *sval = (*iter).second;
     673                 :           0 :       m_map.put (key, sval);
     674                 :             :     }
     675                 :           0 :   return *this;
     676                 :             : }
     677                 :             : 
     678                 :             : /* binding_map's equality operator.  */
     679                 :             : 
     680                 :             : bool
     681                 :     2372086 : binding_map::operator== (const binding_map &other) const
     682                 :             : {
     683                 :     2372086 :   if (m_map.elements () != other.m_map.elements ())
     684                 :             :     return false;
     685                 :             : 
     686                 :     7182272 :   for (map_t::iterator iter = m_map.begin (); iter != m_map.end (); ++iter)
     687                 :             :     {
     688                 :     2456641 :       const binding_key *key = (*iter).first;
     689                 :     2456641 :       const svalue *sval = (*iter).second;
     690                 :     2456641 :       const svalue **other_slot
     691                 :     2456641 :         = const_cast <map_t &> (other.m_map).get (key);
     692                 :     2456641 :       if (other_slot == NULL)
     693                 :       42045 :         return false;
     694                 :     2448334 :       if (sval != *other_slot)
     695                 :             :         return false;
     696                 :             :     }
     697                 :     2311035 :   gcc_checking_assert (hash () == other.hash ());
     698                 :             :   return true;
     699                 :             : }
     700                 :             : 
     701                 :             : /* Generate a hash value for this binding_map.  */
     702                 :             : 
     703                 :             : hashval_t
     704                 :    20980741 : binding_map::hash () const
     705                 :             : {
     706                 :    20980741 :   hashval_t result = 0;
     707                 :    42810315 :   for (map_t::iterator iter = m_map.begin (); iter != m_map.end (); ++iter)
     708                 :             :     {
     709                 :             :       /* Use a new hasher for each key to avoid depending on the ordering
     710                 :             :          of keys when accumulating the result.  */
     711                 :    21829574 :       inchash::hash hstate;
     712                 :    21829574 :       hstate.add_ptr ((*iter).first);
     713                 :    21829574 :       hstate.add_ptr ((*iter).second);
     714                 :    21829574 :       result ^= hstate.end ();
     715                 :             :     }
     716                 :    20980741 :   return result;
     717                 :             : }
     718                 :             : 
     719                 :             : /* Dump a representation of this binding_map to PP.
     720                 :             :    SIMPLE controls how values and regions are to be printed.
     721                 :             :    If MULTILINE, then split the dump over multiple lines and
     722                 :             :    use whitespace for readability, otherwise put all on one line.  */
     723                 :             : 
     724                 :             : void
     725                 :        2529 : binding_map::dump_to_pp (pretty_printer *pp, bool simple,
     726                 :             :                          bool multiline) const
     727                 :             : {
     728                 :        2529 :   auto_vec <const binding_key *> binding_keys;
     729                 :        4254 :   for (map_t::iterator iter = m_map.begin ();
     730                 :        5979 :        iter != m_map.end (); ++iter)
     731                 :             :     {
     732                 :        1725 :       const binding_key *key = (*iter).first;
     733                 :        1725 :       binding_keys.safe_push (key);
     734                 :             :     }
     735                 :        2529 :   binding_keys.qsort (binding_key::cmp_ptrs);
     736                 :             : 
     737                 :             :   const binding_key *key;
     738                 :             :   unsigned i;
     739                 :        5228 :   FOR_EACH_VEC_ELT (binding_keys, i, key)
     740                 :             :     {
     741                 :        1725 :       const svalue *value = *const_cast <map_t &> (m_map).get (key);
     742                 :        1725 :       if (multiline)
     743                 :             :         {
     744                 :         410 :           pp_string (pp, "    key:   {");
     745                 :         410 :           key->dump_to_pp (pp, simple);
     746                 :         410 :           pp_string (pp, "}");
     747                 :         410 :           pp_newline (pp);
     748                 :         410 :           pp_string (pp, "    value: ");
     749                 :         410 :           if (tree t = value->get_type ())
     750                 :         410 :             dump_quoted_tree (pp, t);
     751                 :         410 :           pp_string (pp, " {");
     752                 :         410 :           value->dump_to_pp (pp, simple);
     753                 :         410 :           pp_string (pp, "}");
     754                 :         410 :           pp_newline (pp);
     755                 :             :         }
     756                 :             :       else
     757                 :             :         {
     758                 :        1315 :           if (i > 0)
     759                 :         566 :             pp_string (pp, ", ");
     760                 :        1315 :           pp_string (pp, "binding key: {");
     761                 :        1315 :           key->dump_to_pp (pp, simple);
     762                 :        1315 :           pp_string (pp, "}, value: {");
     763                 :        1315 :           value->dump_to_pp (pp, simple);
     764                 :        1315 :           pp_string (pp, "}");
     765                 :             :         }
     766                 :             :     }
     767                 :        2529 : }
     768                 :             : 
     769                 :             : /* Dump a multiline representation of this binding_map to stderr.  */
     770                 :             : 
     771                 :             : DEBUG_FUNCTION void
     772                 :           0 : binding_map::dump (bool simple) const
     773                 :             : {
     774                 :           0 :   pretty_printer pp;
     775                 :           0 :   pp_format_decoder (&pp) = default_tree_printer;
     776                 :           0 :   pp_show_color (&pp) = pp_show_color (global_dc->printer);
     777                 :           0 :   pp.buffer->stream = stderr;
     778                 :           0 :   dump_to_pp (&pp, simple, true);
     779                 :           0 :   pp_newline (&pp);
     780                 :           0 :   pp_flush (&pp);
     781                 :           0 : }
     782                 :             : 
     783                 :             : /* Return a new json::object of the form
     784                 :             :    {KEY_DESC : SVALUE_DESC,
     785                 :             :     ...for the various key/value pairs in this binding_map}.  */
     786                 :             : 
     787                 :             : json::object *
     788                 :           0 : binding_map::to_json () const
     789                 :             : {
     790                 :           0 :   json::object *map_obj = new json::object ();
     791                 :             : 
     792                 :           0 :   auto_vec <const binding_key *> binding_keys;
     793                 :           0 :   for (map_t::iterator iter = m_map.begin ();
     794                 :           0 :        iter != m_map.end (); ++iter)
     795                 :             :     {
     796                 :           0 :       const binding_key *key = (*iter).first;
     797                 :           0 :       binding_keys.safe_push (key);
     798                 :             :     }
     799                 :           0 :   binding_keys.qsort (binding_key::cmp_ptrs);
     800                 :             : 
     801                 :             :   const binding_key *key;
     802                 :             :   unsigned i;
     803                 :           0 :   FOR_EACH_VEC_ELT (binding_keys, i, key)
     804                 :             :     {
     805                 :           0 :       const svalue *value = *const_cast <map_t &> (m_map).get (key);
     806                 :           0 :       label_text key_desc = key->get_desc ();
     807                 :           0 :       map_obj->set (key_desc.get (), value->to_json ());
     808                 :           0 :     }
     809                 :             : 
     810                 :           0 :   return map_obj;
     811                 :           0 : }
     812                 :             : 
     813                 :             : /* Comparator for imposing an order on binding_maps.  */
     814                 :             : 
     815                 :             : int
     816                 :           0 : binding_map::cmp (const binding_map &map1, const binding_map &map2)
     817                 :             : {
     818                 :           0 :   if (int count_cmp = map1.elements () - map2.elements ())
     819                 :             :     return count_cmp;
     820                 :             : 
     821                 :           0 :   auto_vec <const binding_key *> keys1 (map1.elements ());
     822                 :           0 :   for (map_t::iterator iter = map1.begin ();
     823                 :           0 :        iter != map1.end (); ++iter)
     824                 :           0 :     keys1.quick_push ((*iter).first);
     825                 :           0 :   keys1.qsort (binding_key::cmp_ptrs);
     826                 :             : 
     827                 :           0 :   auto_vec <const binding_key *> keys2 (map2.elements ());
     828                 :           0 :   for (map_t::iterator iter = map2.begin ();
     829                 :           0 :        iter != map2.end (); ++iter)
     830                 :           0 :     keys2.quick_push ((*iter).first);
     831                 :           0 :   keys2.qsort (binding_key::cmp_ptrs);
     832                 :             : 
     833                 :           0 :   for (size_t i = 0; i < keys1.length (); i++)
     834                 :             :     {
     835                 :           0 :       const binding_key *k1 = keys1[i];
     836                 :           0 :       const binding_key *k2 = keys2[i];
     837                 :           0 :       if (int key_cmp = binding_key::cmp (k1, k2))
     838                 :           0 :         return key_cmp;
     839                 :           0 :       gcc_assert (k1 == k2);
     840                 :           0 :       if (int sval_cmp = svalue::cmp_ptr (map1.get (k1), map2.get (k2)))
     841                 :           0 :         return sval_cmp;
     842                 :             :     }
     843                 :             : 
     844                 :             :   return 0;
     845                 :           0 : }
     846                 :             : 
     847                 :             : /* Get the child region of PARENT_REG based upon INDEX within a
     848                 :             :    CONSTRUCTOR.   */
     849                 :             : 
     850                 :             : static const region *
     851                 :         517 : get_subregion_within_ctor (const region *parent_reg, tree index,
     852                 :             :                            region_model_manager *mgr)
     853                 :             : {
     854                 :         517 :   switch (TREE_CODE (index))
     855                 :             :     {
     856                 :           0 :     default:
     857                 :           0 :       gcc_unreachable ();
     858                 :         459 :     case INTEGER_CST:
     859                 :         459 :       {
     860                 :         459 :         const svalue *index_sval
     861                 :         459 :           = mgr->get_or_create_constant_svalue (index);
     862                 :         459 :         return mgr->get_element_region (parent_reg,
     863                 :         459 :                                         TREE_TYPE (parent_reg->get_type ()),
     864                 :         459 :                                         index_sval);
     865                 :             :       }
     866                 :          58 :       break;
     867                 :          58 :     case FIELD_DECL:
     868                 :          58 :       return mgr->get_field_region (parent_reg, index);
     869                 :             :     }
     870                 :             : }
     871                 :             : 
     872                 :             : /* Get the svalue for VAL, a non-CONSTRUCTOR value within a CONSTRUCTOR.  */
     873                 :             : 
     874                 :             : static const svalue *
     875                 :         477 : get_svalue_for_ctor_val (tree val, region_model_manager *mgr)
     876                 :             : {
     877                 :             :   /* Reuse the get_rvalue logic from region_model.  */
     878                 :         477 :   region_model m (mgr);
     879                 :         477 :   return m.get_rvalue (path_var (val, 0), NULL);
     880                 :         477 : }
     881                 :             : 
     882                 :             : /* Bind values from CONSTRUCTOR to this map, relative to
     883                 :             :    PARENT_REG's relationship to its base region.
     884                 :             :    Return true if successful, false if there was a problem (e.g. due
     885                 :             :    to hitting a complexity limit).  */
     886                 :             : 
     887                 :             : bool
     888                 :         167 : binding_map::apply_ctor_to_region (const region *parent_reg, tree ctor,
     889                 :             :                                    region_model_manager *mgr)
     890                 :             : {
     891                 :         167 :   gcc_assert (parent_reg);
     892                 :         167 :   gcc_assert (TREE_CODE (ctor) == CONSTRUCTOR);
     893                 :             : 
     894                 :         167 :   unsigned ix;
     895                 :         167 :   tree index;
     896                 :         167 :   tree val;
     897                 :         167 :   tree parent_type = parent_reg->get_type ();
     898                 :         167 :   tree field;
     899                 :         167 :   if (TREE_CODE (parent_type) == RECORD_TYPE)
     900                 :          51 :     field = TYPE_FIELDS (parent_type);
     901                 :             :   else
     902                 :             :     field = NULL_TREE;
     903                 :         683 :   FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (ctor), ix, index, val)
     904                 :             :     {
     905                 :         517 :       if (!index)
     906                 :             :         {
     907                 :             :           /* If index is NULL, then iterate through the fields for
     908                 :             :              a RECORD_TYPE, or use an INTEGER_CST otherwise.
     909                 :             :              Compare with similar logic in output_constructor.  */
     910                 :         159 :           if (field)
     911                 :             :             {
     912                 :           0 :               index = field;
     913                 :           0 :               field = DECL_CHAIN (field);
     914                 :             :             }
     915                 :             :           else
     916                 :         159 :             index = build_int_cst (integer_type_node, ix);
     917                 :             :         }
     918                 :         358 :       else if (TREE_CODE (index) == RANGE_EXPR)
     919                 :             :         {
     920                 :           0 :           tree min_index = TREE_OPERAND (index, 0);
     921                 :           0 :           tree max_index = TREE_OPERAND (index, 1);
     922                 :           0 :           if (min_index == max_index)
     923                 :             :             {
     924                 :           0 :               if (!apply_ctor_pair_to_child_region (parent_reg, mgr,
     925                 :             :                                                     min_index, val))
     926                 :             :                 return false;
     927                 :             :             }
     928                 :             :           else
     929                 :             :             {
     930                 :           0 :               if (!apply_ctor_val_to_range (parent_reg, mgr,
     931                 :             :                                             min_index, max_index, val))
     932                 :             :                 return false;
     933                 :             :             }
     934                 :           0 :           continue;
     935                 :           0 :         }
     936                 :         517 :       if (!apply_ctor_pair_to_child_region (parent_reg, mgr, index, val))
     937                 :             :         return false;
     938                 :             :     }
     939                 :             :   return true;
     940                 :             : }
     941                 :             : 
     942                 :             : /* Bind the value VAL into the range of elements within PARENT_REF
     943                 :             :    from MIN_INDEX to MAX_INDEX (including endpoints).
     944                 :             :    For use in handling RANGE_EXPR within a CONSTRUCTOR.
     945                 :             :    Return true if successful, false if there was a problem (e.g. due
     946                 :             :    to hitting a complexity limit).  */
     947                 :             : 
     948                 :             : bool
     949                 :           0 : binding_map::apply_ctor_val_to_range (const region *parent_reg,
     950                 :             :                                       region_model_manager *mgr,
     951                 :             :                                       tree min_index, tree max_index,
     952                 :             :                                       tree val)
     953                 :             : {
     954                 :           0 :   gcc_assert (TREE_CODE (min_index) == INTEGER_CST);
     955                 :           0 :   gcc_assert (TREE_CODE (max_index) == INTEGER_CST);
     956                 :             : 
     957                 :             :   /* Generate a binding key for the range.  */
     958                 :           0 :   const region *min_element
     959                 :           0 :     = get_subregion_within_ctor (parent_reg, min_index, mgr);
     960                 :           0 :   const region *max_element
     961                 :           0 :     = get_subregion_within_ctor (parent_reg, max_index, mgr);
     962                 :           0 :   region_offset min_offset = min_element->get_offset (mgr);
     963                 :           0 :   if (min_offset.symbolic_p ())
     964                 :             :     return false;
     965                 :           0 :   bit_offset_t start_bit_offset = min_offset.get_bit_offset ();
     966                 :           0 :   store_manager *smgr = mgr->get_store_manager ();
     967                 :           0 :   if (max_element->empty_p ())
     968                 :             :     return false;
     969                 :           0 :   const binding_key *max_element_key = binding_key::make (smgr, max_element);
     970                 :           0 :   if (max_element_key->symbolic_p ())
     971                 :             :     return false;
     972                 :           0 :   const concrete_binding *max_element_ckey
     973                 :           0 :     = max_element_key->dyn_cast_concrete_binding ();
     974                 :           0 :   bit_size_t range_size_in_bits
     975                 :           0 :     = max_element_ckey->get_next_bit_offset () - start_bit_offset;
     976                 :           0 :   const concrete_binding *range_key
     977                 :           0 :     = smgr->get_concrete_binding (start_bit_offset, range_size_in_bits);
     978                 :           0 :   if (range_key->symbolic_p ())
     979                 :             :     return false;
     980                 :             : 
     981                 :             :   /* Get the value.  */
     982                 :           0 :   if (TREE_CODE (val) == CONSTRUCTOR)
     983                 :             :     return false;
     984                 :           0 :   const svalue *sval = get_svalue_for_ctor_val (val, mgr);
     985                 :             : 
     986                 :             :   /* Bind the value to the range.  */
     987                 :           0 :   put (range_key, sval);
     988                 :           0 :   return true;
     989                 :             : }
     990                 :             : 
     991                 :             : /* Bind the value VAL into INDEX within PARENT_REF.
     992                 :             :    For use in handling a pair of entries within a CONSTRUCTOR.
     993                 :             :    Return true if successful, false if there was a problem (e.g. due
     994                 :             :    to hitting a complexity limit).  */
     995                 :             : 
     996                 :             : bool
     997                 :         517 : binding_map::apply_ctor_pair_to_child_region (const region *parent_reg,
     998                 :             :                                               region_model_manager *mgr,
     999                 :             :                                               tree index, tree val)
    1000                 :             : {
    1001                 :         517 :   const region *child_reg
    1002                 :         517 :     = get_subregion_within_ctor (parent_reg, index, mgr);
    1003                 :         517 :   if (TREE_CODE (val) == CONSTRUCTOR)
    1004                 :          40 :     return apply_ctor_to_region (child_reg, val, mgr);
    1005                 :             :   else
    1006                 :             :     {
    1007                 :         477 :       const svalue *sval = get_svalue_for_ctor_val (val, mgr);
    1008                 :         477 :       if (child_reg->empty_p ())
    1009                 :             :         return false;
    1010                 :         477 :       const binding_key *k
    1011                 :         477 :         = binding_key::make (mgr->get_store_manager (), child_reg);
    1012                 :             :       /* Handle the case where we have an unknown size for child_reg
    1013                 :             :          (e.g. due to it being a trailing field with incomplete array
    1014                 :             :          type.  */
    1015                 :         477 :       if (!k->concrete_p ())
    1016                 :             :         {
    1017                 :             :           /* Assume that sval has a well-defined size for this case.  */
    1018                 :           6 :           tree sval_type = sval->get_type ();
    1019                 :           6 :           gcc_assert (sval_type);
    1020                 :           6 :           HOST_WIDE_INT sval_byte_size = int_size_in_bytes (sval_type);
    1021                 :           6 :           gcc_assert (sval_byte_size != -1);
    1022                 :           6 :           bit_size_t sval_bit_size = sval_byte_size * BITS_PER_UNIT;
    1023                 :             :           /* Get offset of child relative to base region.  */
    1024                 :           6 :           region_offset child_base_offset = child_reg->get_offset (mgr);
    1025                 :           6 :           if (child_base_offset.symbolic_p ())
    1026                 :           1 :             return false;
    1027                 :             :           /* Convert to an offset relative to the parent region.  */
    1028                 :           5 :           region_offset parent_base_offset = parent_reg->get_offset (mgr);
    1029                 :           5 :           gcc_assert (!parent_base_offset.symbolic_p ());
    1030                 :           5 :           bit_offset_t child_parent_offset
    1031                 :           5 :             = (child_base_offset.get_bit_offset ()
    1032                 :           5 :                - parent_base_offset.get_bit_offset ());
    1033                 :             :           /* Create a concrete key for the child within the parent.  */
    1034                 :           5 :           k = mgr->get_store_manager ()->get_concrete_binding
    1035                 :           5 :             (child_parent_offset, sval_bit_size);
    1036                 :             :         }
    1037                 :         476 :       gcc_assert (k->concrete_p ());
    1038                 :         476 :       put (k, sval);
    1039                 :         476 :       return true;
    1040                 :             :     }
    1041                 :             : }
    1042                 :             : 
    1043                 :             : /* Populate OUT with all bindings within this map that overlap KEY.  */
    1044                 :             : 
    1045                 :             : void
    1046                 :       49073 : binding_map::get_overlapping_bindings (const binding_key *key,
    1047                 :             :                                        auto_vec<const binding_key *> *out)
    1048                 :             : {
    1049                 :      223765 :   for (auto iter : *this)
    1050                 :             :     {
    1051                 :       87346 :       const binding_key *iter_key = iter.first;
    1052                 :      174692 :       if (const concrete_binding *ckey
    1053                 :       87346 :             = key->dyn_cast_concrete_binding ())
    1054                 :             :         {
    1055                 :      168662 :           if (const concrete_binding *iter_ckey
    1056                 :       84331 :               = iter_key->dyn_cast_concrete_binding ())
    1057                 :             :             {
    1058                 :       83491 :               if (ckey->overlaps_p (*iter_ckey))
    1059                 :       38654 :                 out->safe_push (iter_key);
    1060                 :             :             }
    1061                 :             :           else
    1062                 :             :             {
    1063                 :             :               /* Assume overlap.  */
    1064                 :         840 :               out->safe_push (iter_key);
    1065                 :             :             }
    1066                 :             :         }
    1067                 :             :       else
    1068                 :             :         {
    1069                 :             :           /* Assume overlap.  */
    1070                 :        3015 :           out->safe_push (iter_key);
    1071                 :             :         }
    1072                 :             :     }
    1073                 :       49073 : }
    1074                 :             : 
    1075                 :             : /* Remove, truncate, and/or split any bindings within this map that
    1076                 :             :    overlap DROP_KEY.
    1077                 :             : 
    1078                 :             :    For example, if we have:
    1079                 :             : 
    1080                 :             :      +------------------------------------+
    1081                 :             :      |             old binding            |
    1082                 :             :      +------------------------------------+
    1083                 :             : 
    1084                 :             :    which is to be overwritten with:
    1085                 :             : 
    1086                 :             :      .......+----------------------+.......
    1087                 :             :      .......|      new binding     |.......
    1088                 :             :      .......+----------------------+.......
    1089                 :             : 
    1090                 :             :    this function "cuts a hole" out of the old binding:
    1091                 :             : 
    1092                 :             :      +------+......................+------+
    1093                 :             :      |prefix| hole for new binding |suffix|
    1094                 :             :      +------+......................+------+
    1095                 :             : 
    1096                 :             :    into which the new binding can be added without
    1097                 :             :    overlapping the prefix or suffix.
    1098                 :             : 
    1099                 :             :    The prefix and suffix (if added) will be bound to the pertinent
    1100                 :             :    parts of the value of the old binding.
    1101                 :             : 
    1102                 :             :    For example, given:
    1103                 :             :      struct s5
    1104                 :             :      {
    1105                 :             :        char arr[8];
    1106                 :             :      };
    1107                 :             :      void test_5 (struct s5 *p)
    1108                 :             :      {
    1109                 :             :        struct s5 f = *p;
    1110                 :             :        f.arr[3] = 42;
    1111                 :             :      }
    1112                 :             :    then after the "f = *p;" we have:
    1113                 :             :      cluster for: f: INIT_VAL((*INIT_VAL(p_33(D))))
    1114                 :             :    and at the "f.arr[3] = 42;" we remove the bindings overlapping
    1115                 :             :    "f.arr[3]", replacing it with a prefix (bytes 0-2) and suffix (bytes 4-7)
    1116                 :             :    giving:
    1117                 :             :      cluster for: f
    1118                 :             :        key:   {bytes 0-2}
    1119                 :             :        value:  {BITS_WITHIN(bytes 0-2, inner_val: INIT_VAL((*INIT_VAL(p_33(D))).arr))}
    1120                 :             :        key:   {bytes 4-7}
    1121                 :             :        value:  {BITS_WITHIN(bytes 4-7, inner_val: INIT_VAL((*INIT_VAL(p_33(D))).arr))}
    1122                 :             :    punching a hole into which the new value can be written at byte 3:
    1123                 :             :      cluster for: f
    1124                 :             :        key:   {bytes 0-2}
    1125                 :             :        value:  {BITS_WITHIN(bytes 0-2, inner_val: INIT_VAL((*INIT_VAL(p_33(D))).arr))}
    1126                 :             :        key:   {byte 3}
    1127                 :             :        value: 'char' {(char)42}
    1128                 :             :        key:   {bytes 4-7}
    1129                 :             :        value:  {BITS_WITHIN(bytes 4-7, inner_val: INIT_VAL((*INIT_VAL(p_33(D))).arr))}
    1130                 :             : 
    1131                 :             :    If UNCERTAINTY is non-NULL, use it to record any svalues that
    1132                 :             :    were removed, as being maybe-bound.
    1133                 :             : 
    1134                 :             :    If MAYBE_LIVE_VALUES is non-NULL, then use it to record any svalues that
    1135                 :             :    were removed as being maybe-live.
    1136                 :             : 
    1137                 :             :    If ALWAYS_OVERLAP, then assume that DROP_KEY can overlap anything
    1138                 :             :    in the map, due to one or both of the underlying clusters being
    1139                 :             :    symbolic (but not the same symbolic region).  Hence even if DROP_KEY is a
    1140                 :             :    concrete binding it could actually be referring to the same memory as
    1141                 :             :    distinct concrete bindings in the map.  Remove all bindings, but
    1142                 :             :    register any svalues with *UNCERTAINTY.  */
    1143                 :             : 
    1144                 :             : void
    1145                 :      126225 : binding_map::remove_overlapping_bindings (store_manager *mgr,
    1146                 :             :                                           const binding_key *drop_key,
    1147                 :             :                                           uncertainty_t *uncertainty,
    1148                 :             :                                           svalue_set *maybe_live_values,
    1149                 :             :                                           bool always_overlap)
    1150                 :             : {
    1151                 :             :   /* Get the bindings of interest within this map.  */
    1152                 :      126225 :   auto_vec<const binding_key *> bindings;
    1153                 :      126225 :   if (always_overlap)
    1154                 :      232728 :     for (auto iter : *this)
    1155                 :       78424 :       bindings.safe_push (iter.first); /* Add all bindings.  */
    1156                 :             :   else
    1157                 :             :     /* Just add overlapping bindings.  */
    1158                 :       49073 :     get_overlapping_bindings (drop_key, &bindings);
    1159                 :             : 
    1160                 :             :   unsigned i;
    1161                 :             :   const binding_key *iter_binding;
    1162                 :      359442 :   FOR_EACH_VEC_ELT (bindings, i, iter_binding)
    1163                 :             :     {
    1164                 :             :       /* Record any svalues that were removed to *UNCERTAINTY as being
    1165                 :             :          maybe-bound, provided at least some part of the binding is symbolic.
    1166                 :             : 
    1167                 :             :          Specifically, if at least one of the bindings is symbolic, or we
    1168                 :             :          have ALWAYS_OVERLAP for the case where we have possibly aliasing
    1169                 :             :          regions, then we don't know that the svalue has been overwritten,
    1170                 :             :          and should record that to *UNCERTAINTY.
    1171                 :             : 
    1172                 :             :          However, if we have concrete keys accessing within the same symbolic
    1173                 :             :          region, then we *know* that the symbolic region has been overwritten,
    1174                 :             :          so we don't record it to *UNCERTAINTY, as this could be a genuine
    1175                 :             :          leak.  */
    1176                 :      120933 :       const svalue *old_sval = get (iter_binding);
    1177                 :      120933 :       if (uncertainty
    1178                 :      157126 :           && (drop_key->symbolic_p ()
    1179                 :       33484 :               || iter_binding->symbolic_p ()
    1180                 :       28561 :               || always_overlap))
    1181                 :       31503 :         uncertainty->on_maybe_bound_sval (old_sval);
    1182                 :             : 
    1183                 :             :       /* Record any svalues that were removed to *MAYBE_LIVE_VALUES as being
    1184                 :             :          maybe-live. */
    1185                 :      120933 :       if (maybe_live_values)
    1186                 :       78424 :         maybe_live_values->add (old_sval);
    1187                 :             : 
    1188                 :             :       /* Begin by removing the old binding. */
    1189                 :      120933 :       m_map.remove (iter_binding);
    1190                 :             : 
    1191                 :             :       /* Don't attempt to handle prefixes/suffixes for the
    1192                 :             :          "always_overlap" case; everything's being removed.  */
    1193                 :      120933 :       if (always_overlap)
    1194                 :       78424 :         continue;
    1195                 :             : 
    1196                 :             :       /* Now potentially add the prefix and suffix.  */
    1197                 :       85018 :       if (const concrete_binding *drop_ckey
    1198                 :       42509 :           = drop_key->dyn_cast_concrete_binding ())
    1199                 :       78988 :         if (const concrete_binding *iter_ckey
    1200                 :       39494 :               = iter_binding->dyn_cast_concrete_binding ())
    1201                 :             :           {
    1202                 :       38654 :             gcc_assert (drop_ckey->overlaps_p (*iter_ckey));
    1203                 :             : 
    1204                 :       38654 :             const bit_range &drop_bits = drop_ckey->get_bit_range ();
    1205                 :       38654 :             const bit_range &iter_bits = iter_ckey->get_bit_range ();
    1206                 :             : 
    1207                 :       38654 :             if (iter_bits.get_start_bit_offset ()
    1208                 :       38654 :                   < drop_bits.get_start_bit_offset ())
    1209                 :             :               {
    1210                 :             :                 /* We have a truncated prefix.  */
    1211                 :        6489 :                 bit_range prefix_bits (iter_bits.get_start_bit_offset (),
    1212                 :       12978 :                                        (drop_bits.get_start_bit_offset ()
    1213                 :        6489 :                                         - iter_bits.get_start_bit_offset ()));
    1214                 :        6489 :                 const concrete_binding *prefix_key
    1215                 :        6489 :                   = mgr->get_concrete_binding (prefix_bits);
    1216                 :        6489 :                 bit_range rel_prefix (0, prefix_bits.m_size_in_bits);
    1217                 :        6489 :                 const svalue *prefix_sval
    1218                 :        6489 :                   = old_sval->extract_bit_range (NULL_TREE,
    1219                 :             :                                                  rel_prefix,
    1220                 :        6489 :                                                  mgr->get_svalue_manager ());
    1221                 :        6489 :                 m_map.put (prefix_key, prefix_sval);
    1222                 :             :               }
    1223                 :             : 
    1224                 :       77308 :             if (iter_bits.get_next_bit_offset ()
    1225                 :       77308 :                   > drop_bits.get_next_bit_offset ())
    1226                 :             :               {
    1227                 :             :                 /* We have a truncated suffix.  */
    1228                 :        8795 :                 bit_range suffix_bits (drop_bits.get_next_bit_offset (),
    1229                 :        8795 :                                        (iter_bits.get_next_bit_offset ()
    1230                 :       17590 :                                         - drop_bits.get_next_bit_offset ()));
    1231                 :        8795 :                 const concrete_binding *suffix_key
    1232                 :        8795 :                   = mgr->get_concrete_binding (suffix_bits);
    1233                 :        8795 :                 bit_range rel_suffix (drop_bits.get_next_bit_offset ()
    1234                 :        8795 :                                         - iter_bits.get_start_bit_offset (),
    1235                 :        8795 :                                       suffix_bits.m_size_in_bits);
    1236                 :        8795 :                 const svalue *suffix_sval
    1237                 :        8795 :                   = old_sval->extract_bit_range (NULL_TREE,
    1238                 :             :                                                  rel_suffix,
    1239                 :        8795 :                                                  mgr->get_svalue_manager ());
    1240                 :        8795 :                 m_map.put (suffix_key, suffix_sval);
    1241                 :             :               }
    1242                 :             :           }
    1243                 :             :     }
    1244                 :      126225 : }
    1245                 :             : 
    1246                 :             : /* class binding_cluster.  */
    1247                 :             : 
    1248                 :     1728783 : binding_cluster::binding_cluster (const region *base_region)
    1249                 :     1728783 : : m_base_region (base_region), m_map (),
    1250                 :     1728783 :   m_escaped (false), m_touched (false)
    1251                 :             : {
    1252                 :     1728783 : }
    1253                 :             : 
    1254                 :             : /* binding_cluster's copy ctor.  */
    1255                 :             : 
    1256                 :    28448166 : binding_cluster::binding_cluster (const binding_cluster &other)
    1257                 :    28448166 : : m_base_region (other.m_base_region), m_map (other.m_map),
    1258                 :    28448166 :   m_escaped (other.m_escaped), m_touched (other.m_touched)
    1259                 :             : {
    1260                 :    28448166 : }
    1261                 :             : 
    1262                 :             : /* binding_cluster's assignment operator.  */
    1263                 :             : 
    1264                 :             : binding_cluster&
    1265                 :           0 : binding_cluster::operator= (const binding_cluster &other)
    1266                 :             : {
    1267                 :           0 :   gcc_assert (m_base_region == other.m_base_region);
    1268                 :           0 :   m_map = other.m_map;
    1269                 :           0 :   m_escaped = other.m_escaped;
    1270                 :           0 :   m_touched = other.m_touched;
    1271                 :           0 :   return *this;
    1272                 :             : }
    1273                 :             : 
    1274                 :             : /* binding_cluster's equality operator.  */
    1275                 :             : 
    1276                 :             : bool
    1277                 :     2340333 : binding_cluster::operator== (const binding_cluster &other) const
    1278                 :             : {
    1279                 :     2340333 :   if (m_map != other.m_map)
    1280                 :             :     return false;
    1281                 :             : 
    1282                 :     2304529 :   if (m_base_region != other.m_base_region)
    1283                 :             :     return false;
    1284                 :             : 
    1285                 :     2304529 :   if (m_escaped != other.m_escaped)
    1286                 :             :     return false;
    1287                 :             : 
    1288                 :     2303827 :   if (m_touched != other.m_touched)
    1289                 :             :     return false;
    1290                 :             : 
    1291                 :     2302160 :   gcc_checking_assert (hash () == other.hash ());
    1292                 :             : 
    1293                 :             :   return true;
    1294                 :             : }
    1295                 :             : 
    1296                 :             : /* Generate a hash value for this binding_cluster.  */
    1297                 :             : 
    1298                 :             : hashval_t
    1299                 :    16358671 : binding_cluster::hash () const
    1300                 :             : {
    1301                 :    16358671 :   return m_map.hash ();
    1302                 :             : }
    1303                 :             : 
    1304                 :             : /* Return true if this binding_cluster is symbolic
    1305                 :             :    i.e. its base region is symbolic.  */
    1306                 :             : 
    1307                 :             : bool
    1308                 :     9147956 : binding_cluster::symbolic_p () const
    1309                 :             : {
    1310                 :     9147956 :   return m_base_region->get_kind () == RK_SYMBOLIC;
    1311                 :             : }
    1312                 :             : 
    1313                 :             : /* Dump a representation of this binding_cluster to PP.
    1314                 :             :    SIMPLE controls how values and regions are to be printed.
    1315                 :             :    If MULTILINE, then split the dump over multiple lines and
    1316                 :             :    use whitespace for readability, otherwise put all on one line.  */
    1317                 :             : 
    1318                 :             : void
    1319                 :        2529 : binding_cluster::dump_to_pp (pretty_printer *pp, bool simple,
    1320                 :             :                              bool multiline) const
    1321                 :             : {
    1322                 :        2529 :   if (m_escaped)
    1323                 :             :     {
    1324                 :        1732 :       if (multiline)
    1325                 :             :         {
    1326                 :        1550 :           pp_string (pp, "    ESCAPED");
    1327                 :        1550 :           pp_newline (pp);
    1328                 :             :         }
    1329                 :             :       else
    1330                 :         182 :         pp_string (pp, "(ESCAPED)");
    1331                 :             :     }
    1332                 :        2529 :   if (m_touched)
    1333                 :             :     {
    1334                 :         337 :       if (multiline)
    1335                 :             :         {
    1336                 :         155 :           pp_string (pp, "    TOUCHED");
    1337                 :         155 :           pp_newline (pp);
    1338                 :             :         }
    1339                 :             :       else
    1340                 :         182 :         pp_string (pp, "(TOUCHED)");
    1341                 :             :     }
    1342                 :             : 
    1343                 :        2529 :   m_map.dump_to_pp (pp, simple, multiline);
    1344                 :        2529 : }
    1345                 :             : 
    1346                 :             : /* Dump a multiline representation of this binding_cluster to stderr.  */
    1347                 :             : 
    1348                 :             : DEBUG_FUNCTION void
    1349                 :           0 : binding_cluster::dump (bool simple) const
    1350                 :             : {
    1351                 :           0 :   pretty_printer pp;
    1352                 :           0 :   pp_format_decoder (&pp) = default_tree_printer;
    1353                 :           0 :   pp_show_color (&pp) = pp_show_color (global_dc->printer);
    1354                 :           0 :   pp.buffer->stream = stderr;
    1355                 :           0 :   pp_string (&pp, "  cluster for: ");
    1356                 :           0 :   m_base_region->dump_to_pp (&pp, simple);
    1357                 :           0 :   pp_string (&pp, ": ");
    1358                 :           0 :   pp_newline (&pp);
    1359                 :           0 :   dump_to_pp (&pp, simple, true);
    1360                 :           0 :   pp_newline (&pp);
    1361                 :           0 :   pp_flush (&pp);
    1362                 :           0 : }
    1363                 :             : 
    1364                 :             : /* Assert that this object is valid.  */
    1365                 :             : 
    1366                 :             : void
    1367                 :    10621314 : binding_cluster::validate () const
    1368                 :             : {
    1369                 :    10621314 :   int num_symbolic = 0;
    1370                 :    10621314 :   int num_concrete = 0;
    1371                 :    32785602 :   for (auto iter : m_map)
    1372                 :             :     {
    1373                 :    11082144 :       if (iter.first->symbolic_p ())
    1374                 :     1030967 :         num_symbolic++;
    1375                 :             :       else
    1376                 :    10051177 :         num_concrete++;
    1377                 :             :     }
    1378                 :             :   /* We shouldn't have more than one symbolic key per cluster
    1379                 :             :      (or one would have clobbered the other).  */
    1380                 :    10621314 :   gcc_assert (num_symbolic < 2);
    1381                 :             :   /* We can't have both concrete and symbolic keys.  */
    1382                 :    10621314 :   gcc_assert (num_concrete == 0 || num_symbolic == 0);
    1383                 :    10621314 : }
    1384                 :             : 
    1385                 :             : /* Return a new json::object of the form
    1386                 :             :    {"escaped": true/false,
    1387                 :             :     "touched": true/false,
    1388                 :             :     "map" : object for the binding_map.  */
    1389                 :             : 
    1390                 :             : json::object *
    1391                 :           0 : binding_cluster::to_json () const
    1392                 :             : {
    1393                 :           0 :   json::object *cluster_obj = new json::object ();
    1394                 :             : 
    1395                 :           0 :   cluster_obj->set ("escaped", new json::literal (m_escaped));
    1396                 :           0 :   cluster_obj->set ("touched", new json::literal (m_touched));
    1397                 :           0 :   cluster_obj->set ("map", m_map.to_json ());
    1398                 :             : 
    1399                 :           0 :   return cluster_obj;
    1400                 :             : }
    1401                 :             : 
    1402                 :             : /* Add a binding of SVAL of kind KIND to REG, unpacking SVAL if it is a
    1403                 :             :    compound_sval.  */
    1404                 :             : 
    1405                 :             : void
    1406                 :      499569 : binding_cluster::bind (store_manager *mgr,
    1407                 :             :                        const region *reg, const svalue *sval)
    1408                 :             : {
    1409                 :      999138 :   if (const compound_svalue *compound_sval
    1410                 :      499569 :         = sval->dyn_cast_compound_svalue ())
    1411                 :             :     {
    1412                 :        1004 :       bind_compound_sval (mgr, reg, compound_sval);
    1413                 :        1004 :       return;
    1414                 :             :     }
    1415                 :             : 
    1416                 :      498565 :   if (reg->empty_p ())
    1417                 :             :     return;
    1418                 :      498565 :   const binding_key *binding = binding_key::make (mgr, reg);
    1419                 :      498565 :   bind_key (binding, sval);
    1420                 :             : }
    1421                 :             : 
    1422                 :             : /* Bind SVAL to KEY.
    1423                 :             :    Unpacking of compound_svalues should already have been done by the
    1424                 :             :    time this is called.  */
    1425                 :             : 
    1426                 :             : void
    1427                 :      503674 : binding_cluster::bind_key (const binding_key *key, const svalue *sval)
    1428                 :             : {
    1429                 :      503674 :   gcc_assert (sval->get_kind () != SK_COMPOUND);
    1430                 :             : 
    1431                 :      503674 :   m_map.put (key, sval);
    1432                 :      503674 :   if (key->symbolic_p ())
    1433                 :       36409 :     m_touched = true;
    1434                 :      503674 : }
    1435                 :             : 
    1436                 :             : /* Subroutine of binding_cluster::bind.
    1437                 :             :    Unpack compound_svals when binding them, so that we bind them
    1438                 :             :    element-wise.  */
    1439                 :             : 
    1440                 :             : void
    1441                 :        1004 : binding_cluster::bind_compound_sval (store_manager *mgr,
    1442                 :             :                                      const region *reg,
    1443                 :             :                                      const compound_svalue *compound_sval)
    1444                 :             : {
    1445                 :        1004 :   region_offset reg_offset
    1446                 :        1004 :     = reg->get_offset (mgr->get_svalue_manager ());
    1447                 :        1004 :   if (reg_offset.symbolic_p ())
    1448                 :             :     {
    1449                 :           5 :       m_touched = true;
    1450                 :           5 :       clobber_region (mgr, reg);
    1451                 :           5 :       return;
    1452                 :             :     }
    1453                 :             : 
    1454                 :        3811 :   for (map_t::iterator iter = compound_sval->begin ();
    1455                 :        7622 :        iter != compound_sval->end (); ++iter)
    1456                 :             :     {
    1457                 :        2812 :       const binding_key *iter_key = (*iter).first;
    1458                 :        2812 :       const svalue *iter_sval = (*iter).second;
    1459                 :             : 
    1460                 :        5624 :       if (const concrete_binding *concrete_key
    1461                 :        2812 :           = iter_key->dyn_cast_concrete_binding ())
    1462                 :             :         {
    1463                 :        2812 :           bit_offset_t effective_start
    1464                 :        2812 :             = (concrete_key->get_start_bit_offset ()
    1465                 :        2812 :                + reg_offset.get_bit_offset ());
    1466                 :        2812 :           const concrete_binding *effective_concrete_key
    1467                 :        2812 :             = mgr->get_concrete_binding (effective_start,
    1468                 :             :                                          concrete_key->get_size_in_bits ());
    1469                 :        2812 :           bind_key (effective_concrete_key, iter_sval);
    1470                 :             :         }
    1471                 :             :       else
    1472                 :           0 :         gcc_unreachable ();
    1473                 :             :     }
    1474                 :             : }
    1475                 :             : 
    1476                 :             : /* Remove all bindings overlapping REG within this cluster.  */
    1477                 :             : 
    1478                 :             : void
    1479                 :        7438 : binding_cluster::clobber_region (store_manager *mgr, const region *reg)
    1480                 :             : {
    1481                 :        7438 :   remove_overlapping_bindings (mgr, reg, NULL, NULL);
    1482                 :        7438 : }
    1483                 :             : 
    1484                 :             : /* Remove any bindings for REG within this cluster.  */
    1485                 :             : 
    1486                 :             : void
    1487                 :      214487 : binding_cluster::purge_region (store_manager *mgr, const region *reg)
    1488                 :             : {
    1489                 :      214487 :   gcc_assert (reg->get_kind () == RK_DECL);
    1490                 :      214487 :   if (reg->empty_p ())
    1491                 :             :     return;
    1492                 :      214487 :   const binding_key *binding
    1493                 :      214487 :     = binding_key::make (mgr, const_cast<region *> (reg));
    1494                 :      214487 :   m_map.remove (binding);
    1495                 :             : }
    1496                 :             : 
    1497                 :             : /* Clobber REG and fill it with repeated copies of SVAL.  */
    1498                 :             : 
    1499                 :             : void
    1500                 :        1720 : binding_cluster::fill_region (store_manager *mgr,
    1501                 :             :                               const region *reg,
    1502                 :             :                               const svalue *sval)
    1503                 :             : {
    1504                 :        1720 :   clobber_region (mgr, reg);
    1505                 :             : 
    1506                 :        1720 :   region_model_manager *sval_mgr = mgr->get_svalue_manager ();
    1507                 :        1720 :   const svalue *byte_size_sval = reg->get_byte_size_sval (sval_mgr);
    1508                 :        1720 :   const svalue *fill_sval
    1509                 :        1720 :     = sval_mgr->get_or_create_repeated_svalue (reg->get_type (),
    1510                 :             :                                                byte_size_sval, sval);
    1511                 :        1720 :   bind (mgr, reg, fill_sval);
    1512                 :        1720 : }
    1513                 :             : 
    1514                 :             : /* Clobber REG within this cluster and fill it with zeroes.  */
    1515                 :             : 
    1516                 :             : void
    1517                 :          40 : binding_cluster::zero_fill_region (store_manager *mgr, const region *reg)
    1518                 :             : {
    1519                 :          40 :   region_model_manager *sval_mgr = mgr->get_svalue_manager ();
    1520                 :          40 :   const svalue *zero_sval = sval_mgr->get_or_create_int_cst (char_type_node, 0);
    1521                 :          40 :   fill_region (mgr, reg, zero_sval);
    1522                 :          40 : }
    1523                 :             : 
    1524                 :             : /* Mark REG_TO_BIND within this cluster as being unknown.
    1525                 :             : 
    1526                 :             :    Remove any bindings overlapping REG_FOR_OVERLAP.
    1527                 :             :    If UNCERTAINTY is non-NULL, use it to record any svalues that
    1528                 :             :    had bindings to them removed, as being maybe-bound.
    1529                 :             :    If MAYBE_LIVE_VALUES is non-NULL, use it to record any svalues that
    1530                 :             :    had bindings to them removed, as being maybe-live.
    1531                 :             : 
    1532                 :             :    REG_TO_BIND and REG_FOR_OVERLAP are the same for
    1533                 :             :    store::mark_region_as_unknown, but are different in
    1534                 :             :    store::set_value's alias handling, for handling the case where
    1535                 :             :    we have a write to a symbolic REG_FOR_OVERLAP. */
    1536                 :             : 
    1537                 :             : void
    1538                 :       77506 : binding_cluster::mark_region_as_unknown (store_manager *mgr,
    1539                 :             :                                          const region *reg_to_bind,
    1540                 :             :                                          const region *reg_for_overlap,
    1541                 :             :                                          uncertainty_t *uncertainty,
    1542                 :             :                                          svalue_set *maybe_live_values)
    1543                 :             : {
    1544                 :       77506 :   if (reg_to_bind->empty_p ())
    1545                 :             :     return;
    1546                 :             : 
    1547                 :       77506 :   remove_overlapping_bindings (mgr, reg_for_overlap, uncertainty,
    1548                 :             :                                maybe_live_values);
    1549                 :             : 
    1550                 :             :   /* Add a default binding to "unknown".  */
    1551                 :       77506 :   region_model_manager *sval_mgr = mgr->get_svalue_manager ();
    1552                 :       77506 :   const svalue *sval
    1553                 :       77506 :     = sval_mgr->get_or_create_unknown_svalue (reg_to_bind->get_type ());
    1554                 :       77506 :   bind (mgr, reg_to_bind, sval);
    1555                 :             : }
    1556                 :             : 
    1557                 :             : /* Purge state involving SVAL.  */
    1558                 :             : 
    1559                 :             : void
    1560                 :      654147 : binding_cluster::purge_state_involving (const svalue *sval,
    1561                 :             :                                         region_model_manager *sval_mgr)
    1562                 :             : {
    1563                 :      654147 :   auto_vec<const binding_key *> to_remove;
    1564                 :      654147 :   auto_vec<std::pair<const binding_key *, tree> > to_make_unknown;
    1565                 :     1970913 :   for (auto iter : m_map)
    1566                 :             :     {
    1567                 :      658383 :       const binding_key *iter_key = iter.first;
    1568                 :     1316766 :       if (const symbolic_binding *symbolic_key
    1569                 :      658383 :             = iter_key->dyn_cast_symbolic_binding ())
    1570                 :             :         {
    1571                 :       75636 :           const region *reg = symbolic_key->get_region ();
    1572                 :       75636 :           if (reg->involves_p (sval))
    1573                 :           0 :             to_remove.safe_push (iter_key);
    1574                 :             :         }
    1575                 :      658383 :       const svalue *iter_sval = iter.second;
    1576                 :      658383 :       if (iter_sval->involves_p (sval))
    1577                 :        5432 :         to_make_unknown.safe_push (std::make_pair(iter_key,
    1578                 :        5432 :                                                   iter_sval->get_type ()));
    1579                 :             :     }
    1580                 :      654147 :   for (auto iter : to_remove)
    1581                 :             :     {
    1582                 :           0 :       m_map.remove (iter);
    1583                 :           0 :       m_touched = true;
    1584                 :             :     }
    1585                 :     1313726 :   for (auto iter : to_make_unknown)
    1586                 :             :     {
    1587                 :        5432 :       const svalue *new_sval
    1588                 :        5432 :         = sval_mgr->get_or_create_unknown_svalue (iter.second);
    1589                 :        5432 :       m_map.put (iter.first, new_sval);
    1590                 :             :     }
    1591                 :      654147 : }
    1592                 :             : 
    1593                 :             : /* Get any SVAL bound to REG within this cluster via kind KIND,
    1594                 :             :    without checking parent regions of REG.  */
    1595                 :             : 
    1596                 :             : const svalue *
    1597                 :     1686280 : binding_cluster::get_binding (store_manager *mgr,
    1598                 :             :                               const region *reg) const
    1599                 :             : {
    1600                 :     1686280 :   if (reg->empty_p ())
    1601                 :             :     return NULL;
    1602                 :     1686280 :   const binding_key *reg_binding = binding_key::make (mgr, reg);
    1603                 :     1686280 :   const svalue *sval = m_map.get (reg_binding);
    1604                 :     1686280 :   if (sval)
    1605                 :             :     {
    1606                 :             :       /* If we have a struct with a single field, then the binding of
    1607                 :             :          the field will equal that of the struct, and looking up e.g.
    1608                 :             :          PARENT_REG.field within:
    1609                 :             :             cluster for PARENT_REG: INIT_VAL(OTHER_REG)
    1610                 :             :          will erroneously return INIT_VAL(OTHER_REG), rather than
    1611                 :             :            SUB_VALUE(INIT_VAL(OTHER_REG), FIELD) == INIT_VAL(OTHER_REG.FIELD).
    1612                 :             :          Fix this issue by iterating upwards whilst the bindings are equal,
    1613                 :             :          expressing the lookups as subvalues.
    1614                 :             :          We have to gather a list of subregion accesses, then walk it
    1615                 :             :          in reverse to get the subvalues.  */
    1616                 :     1315171 :       auto_vec<const region *> regions;
    1617                 :     1327756 :       while (const region *parent_reg = reg->get_parent_region ())
    1618                 :             :         {
    1619                 :     1327756 :           const binding_key *parent_reg_binding
    1620                 :     1327756 :             = binding_key::make (mgr, parent_reg);
    1621                 :     1327756 :           if (parent_reg_binding == reg_binding
    1622                 :       15477 :               && sval->get_type ()
    1623                 :       15463 :               && reg->get_type ()
    1624                 :     1343219 :               && sval->get_type () != reg->get_type ())
    1625                 :             :             {
    1626                 :       12585 :               regions.safe_push (reg);
    1627                 :       12585 :               reg = parent_reg;
    1628                 :             :             }
    1629                 :             :           else
    1630                 :             :             break;
    1631                 :       12585 :         }
    1632                 :     1315171 :       if (sval->get_type ()
    1633                 :     1305664 :           && reg->get_type ()
    1634                 :     2619944 :           && sval->get_type () == reg->get_type ())
    1635                 :             :         {
    1636                 :     1085353 :           unsigned i;
    1637                 :     1085353 :           const region *iter_reg;
    1638                 :     1351322 :           FOR_EACH_VEC_ELT_REVERSE (regions, i, iter_reg)
    1639                 :             :             {
    1640                 :       12081 :               region_model_manager *rmm_mgr = mgr->get_svalue_manager ();
    1641                 :       12081 :               sval = rmm_mgr->get_or_create_sub_svalue (iter_reg->get_type (),
    1642                 :             :                                                         sval, iter_reg);
    1643                 :             :             }
    1644                 :             :         }
    1645                 :     1315171 :     }
    1646                 :             :   return sval;
    1647                 :             : }
    1648                 :             : 
    1649                 :             : /* Get any SVAL bound to REG within this cluster,
    1650                 :             :    either directly for REG, or recursively checking for bindings within
    1651                 :             :    parent regions and extracting subvalues if need be.  */
    1652                 :             : 
    1653                 :             : const svalue *
    1654                 :     1686280 : binding_cluster::get_binding_recursive (store_manager *mgr,
    1655                 :             :                                         const region *reg) const
    1656                 :             : {
    1657                 :     1686280 :   if (const svalue *sval = get_binding (mgr, reg))
    1658                 :             :     return sval;
    1659                 :      371109 :   if (reg != m_base_region)
    1660                 :      224184 :     if (const region *parent_reg = reg->get_parent_region ())
    1661                 :      438238 :       if (const svalue *parent_sval
    1662                 :      219119 :           = get_binding_recursive (mgr, parent_reg))
    1663                 :             :         {
    1664                 :             :           /* Extract child svalue from parent svalue.  */
    1665                 :       64665 :           region_model_manager *rmm_mgr = mgr->get_svalue_manager ();
    1666                 :       64665 :           return rmm_mgr->get_or_create_sub_svalue (reg->get_type (),
    1667                 :       64665 :                                                     parent_sval, reg);
    1668                 :             :         }
    1669                 :             :   return NULL;
    1670                 :             : }
    1671                 :             : 
    1672                 :             : /* Get any value bound for REG within this cluster.  */
    1673                 :             : 
    1674                 :             : const svalue *
    1675                 :     1467161 : binding_cluster::get_any_binding (store_manager *mgr,
    1676                 :             :                                   const region *reg) const
    1677                 :             : {
    1678                 :             :   /* Look for a direct binding.  */
    1679                 :     2934322 :   if (const svalue *direct_sval
    1680                 :     1467161 :       = get_binding_recursive (mgr, reg))
    1681                 :             :     return direct_sval;
    1682                 :             : 
    1683                 :             :   /* If we had a write to a cluster of unknown size, we might
    1684                 :             :      have a self-binding of the whole base region with an svalue,
    1685                 :             :      where the base region is symbolic.
    1686                 :             :      Handle such cases by returning sub_svalue instances.  */
    1687                 :      151990 :   if (const svalue *cluster_sval = maybe_get_simple_value (mgr))
    1688                 :             :     {
    1689                 :             :       /* Extract child svalue from parent svalue.  */
    1690                 :        1988 :       region_model_manager *rmm_mgr = mgr->get_svalue_manager ();
    1691                 :        1988 :       return rmm_mgr->get_or_create_sub_svalue (reg->get_type (),
    1692                 :        1988 :                                                 cluster_sval, reg);
    1693                 :             :     }
    1694                 :             : 
    1695                 :             :   /* If this cluster has been touched by a symbolic write, then the content
    1696                 :             :      of any subregion not currently specifically bound is "UNKNOWN".  */
    1697                 :      150002 :   if (m_touched)
    1698                 :             :     {
    1699                 :        5655 :       region_model_manager *rmm_mgr = mgr->get_svalue_manager ();
    1700                 :        5655 :       return rmm_mgr->get_or_create_unknown_svalue (reg->get_type ());
    1701                 :             :     }
    1702                 :             : 
    1703                 :             :   /* Alternatively, if this is a symbolic read and the cluster has any bindings,
    1704                 :             :      then we don't know if we're reading those values or not, so the result
    1705                 :             :      is also "UNKNOWN".  */
    1706                 :      144347 :   if (reg->get_offset (mgr->get_svalue_manager ()).symbolic_p ()
    1707                 :      144347 :       && m_map.elements () > 0)
    1708                 :             :     {
    1709                 :         681 :       region_model_manager *rmm_mgr = mgr->get_svalue_manager ();
    1710                 :         681 :       return rmm_mgr->get_or_create_unknown_svalue (reg->get_type ());
    1711                 :             :     }
    1712                 :             : 
    1713                 :      143666 :   if (const svalue *compound_sval = maybe_get_compound_binding (mgr, reg))
    1714                 :             :     return compound_sval;
    1715                 :             : 
    1716                 :             :   /* Otherwise, the initial value, or uninitialized.  */
    1717                 :             :   return NULL;
    1718                 :             : }
    1719                 :             : 
    1720                 :             : /* Attempt to get a compound_svalue for the bindings within the cluster
    1721                 :             :    affecting REG (which could be the base region itself).
    1722                 :             : 
    1723                 :             :    Create a compound_svalue with the subset of bindings the affect REG,
    1724                 :             :    offsetting them so that the offsets are relative to the start of REG
    1725                 :             :    within the cluster.
    1726                 :             : 
    1727                 :             :    For example, REG could be one element within an array of structs.
    1728                 :             : 
    1729                 :             :    Return the resulting compound_svalue, or NULL if there's a problem.  */
    1730                 :             : 
    1731                 :             : const svalue *
    1732                 :      143666 : binding_cluster::maybe_get_compound_binding (store_manager *mgr,
    1733                 :             :                                              const region *reg) const
    1734                 :             : {
    1735                 :      143666 :   region_offset cluster_offset
    1736                 :      143666 :     = m_base_region->get_offset (mgr->get_svalue_manager ());
    1737                 :      143666 :   if (cluster_offset.symbolic_p ())
    1738                 :             :     return NULL;
    1739                 :      143666 :   region_offset reg_offset = reg->get_offset (mgr->get_svalue_manager ());
    1740                 :      143666 :   if (reg_offset.symbolic_p ())
    1741                 :             :     return NULL;
    1742                 :             : 
    1743                 :      113354 :   if (reg->empty_p ())
    1744                 :             :     return NULL;
    1745                 :             : 
    1746                 :      113354 :   region_model_manager *sval_mgr = mgr->get_svalue_manager ();
    1747                 :             : 
    1748                 :             :   /* We will a build the result map in two parts:
    1749                 :             :      (a) result_map, holding the concrete keys from this cluster,
    1750                 :             : 
    1751                 :             :      (b) default_map, holding the initial values for the region
    1752                 :             :      (e.g. uninitialized, initializer values, or zero), unless this
    1753                 :             :      cluster has been touched.
    1754                 :             : 
    1755                 :             :      We will populate (a), and as we do, clobber (b), trimming and
    1756                 :             :      splitting its bindings as necessary.
    1757                 :             :      Finally, we will merge (b) into (a), giving a concrete map
    1758                 :             :      that merges both the initial values and the bound values from
    1759                 :             :      the binding_cluster.
    1760                 :             :      Doing it this way reduces N for the O(N^2) intersection-finding,
    1761                 :             :      perhaps we should have a spatial-organized data structure for
    1762                 :             :      concrete keys, though.  */
    1763                 :             : 
    1764                 :      113354 :   binding_map result_map;
    1765                 :      113354 :   binding_map default_map;
    1766                 :             : 
    1767                 :             :   /* Set up default values in default_map.  */
    1768                 :      113354 :   const svalue *default_sval;
    1769                 :      113354 :   if (m_touched)
    1770                 :           0 :     default_sval = sval_mgr->get_or_create_unknown_svalue (reg->get_type ());
    1771                 :             :   else
    1772                 :      113354 :     default_sval = sval_mgr->get_or_create_initial_value (reg);
    1773                 :      113354 :   const binding_key *default_key = binding_key::make (mgr, reg);
    1774                 :             : 
    1775                 :             :   /* Express the bit-range of the default key for REG relative to REG,
    1776                 :             :      rather than to the base region.  */
    1777                 :      113354 :   const concrete_binding *concrete_default_key
    1778                 :      113354 :     = default_key->dyn_cast_concrete_binding ();
    1779                 :      113354 :   if (!concrete_default_key)
    1780                 :             :     return nullptr;
    1781                 :      112309 :   const concrete_binding *default_key_relative_to_reg
    1782                 :      112309 :      = mgr->get_concrete_binding (0, concrete_default_key->get_size_in_bits ());
    1783                 :      112309 :   default_map.put (default_key_relative_to_reg, default_sval);
    1784                 :             : 
    1785                 :      363753 :   for (map_t::iterator iter = m_map.begin (); iter != m_map.end (); ++iter)
    1786                 :             :     {
    1787                 :      142196 :       const binding_key *key = (*iter).first;
    1788                 :      142196 :       const svalue *sval = (*iter).second;
    1789                 :             : 
    1790                 :      284392 :       if (const concrete_binding *concrete_key
    1791                 :      142196 :           = key->dyn_cast_concrete_binding ())
    1792                 :             :         {
    1793                 :      142196 :           const bit_range &bound_range = concrete_key->get_bit_range ();
    1794                 :             : 
    1795                 :      142196 :           bit_size_t reg_bit_size;
    1796                 :      142196 :           if (!reg->get_bit_size (&reg_bit_size))
    1797                 :       16474 :             return NULL;
    1798                 :             : 
    1799                 :      142196 :           bit_range reg_range (reg_offset.get_bit_offset (),
    1800                 :      142196 :                                reg_bit_size);
    1801                 :             : 
    1802                 :             :           /* Skip bindings that are outside the bit range of REG.  */
    1803                 :      142196 :           if (!bound_range.intersects_p (reg_range))
    1804                 :      109007 :             continue;
    1805                 :             : 
    1806                 :             :           /* We shouldn't have an exact match; that should have been
    1807                 :             :              handled already.  */
    1808                 :       33189 :           gcc_assert (!(reg_range == bound_range));
    1809                 :             : 
    1810                 :       33189 :           bit_range subrange (0, 0);
    1811                 :       33189 :           if (reg_range.contains_p (bound_range, &subrange))
    1812                 :             :             {
    1813                 :             :               /* We have a bound range fully within REG.
    1814                 :             :                  Add it to map, offsetting accordingly.  */
    1815                 :             : 
    1816                 :             :               /* Get offset of KEY relative to REG, rather than to
    1817                 :             :                  the cluster.  */
    1818                 :       16621 :               const concrete_binding *offset_concrete_key
    1819                 :       16621 :                 = mgr->get_concrete_binding (subrange);
    1820                 :       16621 :               result_map.put (offset_concrete_key, sval);
    1821                 :             : 
    1822                 :             :               /* Clobber default_map, removing/trimming/spliting where
    1823                 :             :                  it overlaps with offset_concrete_key.  */
    1824                 :       16621 :               default_map.remove_overlapping_bindings (mgr,
    1825                 :             :                                                        offset_concrete_key,
    1826                 :             :                                                        NULL, NULL, false);
    1827                 :             :             }
    1828                 :       16568 :           else if (bound_range.contains_p (reg_range, &subrange))
    1829                 :             :             {
    1830                 :             :               /* REG is fully within the bound range, but
    1831                 :             :                  is not equal to it; we're extracting a subvalue.  */
    1832                 :       16474 :               return sval->extract_bit_range (reg->get_type (),
    1833                 :             :                                               subrange,
    1834                 :       16474 :                                               mgr->get_svalue_manager ());
    1835                 :             :             }
    1836                 :             :           else
    1837                 :             :             {
    1838                 :             :               /* REG and the bound range partially overlap.  */
    1839                 :          94 :               bit_range reg_subrange (0, 0);
    1840                 :          94 :               bit_range bound_subrange (0, 0);
    1841                 :          94 :               reg_range.intersects_p (bound_range,
    1842                 :             :                                       &reg_subrange, &bound_subrange);
    1843                 :             : 
    1844                 :             :               /* Get the bits from the bound value for the bits at the
    1845                 :             :                  intersection (relative to the bound value).  */
    1846                 :          94 :               const svalue *overlap_sval
    1847                 :          94 :                 = sval->extract_bit_range (NULL_TREE,
    1848                 :             :                                            bound_subrange,
    1849                 :             :                                            mgr->get_svalue_manager ());
    1850                 :             : 
    1851                 :             :               /* Get key for overlap, relative to the REG.  */
    1852                 :          94 :               const concrete_binding *overlap_concrete_key
    1853                 :          94 :                 = mgr->get_concrete_binding (reg_subrange);
    1854                 :          94 :               result_map.put (overlap_concrete_key, overlap_sval);
    1855                 :             : 
    1856                 :             :               /* Clobber default_map, removing/trimming/spliting where
    1857                 :             :                  it overlaps with overlap_concrete_key.  */
    1858                 :          94 :               default_map.remove_overlapping_bindings (mgr,
    1859                 :             :                                                        overlap_concrete_key,
    1860                 :             :                                                        NULL, NULL, false);
    1861                 :             :             }
    1862                 :             :         }
    1863                 :             :       else
    1864                 :             :         /* Can't handle symbolic bindings.  */
    1865                 :             :         return NULL;
    1866                 :             :     }
    1867                 :             : 
    1868                 :       95835 :   if (result_map.elements () == 0)
    1869                 :             :     return NULL;
    1870                 :             : 
    1871                 :             :   /* Merge any bindings from default_map into result_map.  */
    1872                 :        6841 :   for (auto iter : default_map)
    1873                 :             :     {
    1874                 :         387 :       const binding_key *key = iter.first;
    1875                 :         387 :       const svalue *sval = iter.second;
    1876                 :         387 :       result_map.put (key, sval);
    1877                 :             :     }
    1878                 :             : 
    1879                 :        6454 :   return sval_mgr->get_or_create_compound_svalue (reg->get_type (), result_map);
    1880                 :      113354 : }
    1881                 :             : 
    1882                 :             : /* Remove, truncate, and/or split any bindings within this map that
    1883                 :             :    could overlap REG.
    1884                 :             : 
    1885                 :             :    If REG's base region or this cluster is symbolic and they're different
    1886                 :             :    base regions, then remove everything in this cluster's map, on the
    1887                 :             :    grounds that REG could be referring to the same memory as anything
    1888                 :             :    in the map.
    1889                 :             : 
    1890                 :             :    If UNCERTAINTY is non-NULL, use it to record any svalues that
    1891                 :             :    were removed, as being maybe-bound.
    1892                 :             : 
    1893                 :             :    If MAYBE_LIVE_VALUES is non-NULL, use it to record any svalues that
    1894                 :             :    were removed, as being maybe-live.  */
    1895                 :             : 
    1896                 :             : void
    1897                 :      109510 : binding_cluster::remove_overlapping_bindings (store_manager *mgr,
    1898                 :             :                                               const region *reg,
    1899                 :             :                                               uncertainty_t *uncertainty,
    1900                 :             :                                               svalue_set *maybe_live_values)
    1901                 :             : {
    1902                 :      109510 :   if (reg->empty_p ())
    1903                 :             :     return;
    1904                 :      109510 :   const binding_key *reg_binding = binding_key::make (mgr, reg);
    1905                 :             : 
    1906                 :      109510 :   const region *cluster_base_reg = get_base_region ();
    1907                 :      109510 :   const region *other_base_reg = reg->get_base_region ();
    1908                 :             :   /* If at least one of the base regions involved is symbolic, and they're
    1909                 :             :      not the same base region, then consider everything in the map as
    1910                 :             :      potentially overlapping with reg_binding (even if it's a concrete
    1911                 :             :      binding and things in the map are concrete - they could be referring
    1912                 :             :      to the same memory when the symbolic base regions are taken into
    1913                 :             :      account).  */
    1914                 :      109510 :   bool always_overlap = (cluster_base_reg != other_base_reg
    1915                 :      109510 :                          && (cluster_base_reg->get_kind () == RK_SYMBOLIC
    1916                 :       35591 :                              || other_base_reg->get_kind () == RK_SYMBOLIC));
    1917                 :      109510 :   m_map.remove_overlapping_bindings (mgr, reg_binding, uncertainty,
    1918                 :             :                                      maybe_live_values,
    1919                 :             :                                      always_overlap);
    1920                 :             : }
    1921                 :             : 
    1922                 :             : /* Attempt to merge CLUSTER_A and CLUSTER_B into OUT_CLUSTER, using
    1923                 :             :    MGR and MERGER.
    1924                 :             :    Return true if they can be merged, false otherwise.  */
    1925                 :             : 
    1926                 :             : bool
    1927                 :     1347734 : binding_cluster::can_merge_p (const binding_cluster *cluster_a,
    1928                 :             :                               const binding_cluster *cluster_b,
    1929                 :             :                               binding_cluster *out_cluster,
    1930                 :             :                               store *out_store,
    1931                 :             :                               store_manager *mgr,
    1932                 :             :                               model_merger *merger)
    1933                 :             : {
    1934                 :     1347734 :   gcc_assert (out_cluster);
    1935                 :             : 
    1936                 :             :   /* Merge flags ("ESCAPED" and "TOUCHED") by setting the merged flag to
    1937                 :             :      true if either of the inputs is true.  */
    1938                 :     1347734 :   if ((cluster_a && cluster_a->m_escaped)
    1939                 :      865244 :       || (cluster_b && cluster_b->m_escaped))
    1940                 :        4691 :     out_cluster->m_escaped = true;
    1941                 :     1347734 :   if ((cluster_a && cluster_a->m_touched)
    1942                 :      934294 :       || (cluster_b && cluster_b->m_touched))
    1943                 :       11446 :     out_cluster->m_touched = true;
    1944                 :             : 
    1945                 :             :   /* At least one of CLUSTER_A and CLUSTER_B are non-NULL, but either
    1946                 :             :      could be NULL.  Handle these cases.  */
    1947                 :     1347734 :   if (cluster_a == NULL)
    1948                 :             :     {
    1949                 :       25174 :       gcc_assert (cluster_b != NULL);
    1950                 :       25174 :       gcc_assert (cluster_b->m_base_region == out_cluster->m_base_region);
    1951                 :       25174 :       out_cluster->make_unknown_relative_to (cluster_b, out_store, mgr);
    1952                 :       25174 :       return true;
    1953                 :             :     }
    1954                 :     1322560 :   if (cluster_b == NULL)
    1955                 :             :     {
    1956                 :       93754 :       gcc_assert (cluster_a != NULL);
    1957                 :       93754 :       gcc_assert (cluster_a->m_base_region == out_cluster->m_base_region);
    1958                 :       93754 :       out_cluster->make_unknown_relative_to (cluster_a, out_store, mgr);
    1959                 :       93754 :       return true;
    1960                 :             :     }
    1961                 :             : 
    1962                 :             :   /* The "both inputs are non-NULL" case.  */
    1963                 :     1228806 :   gcc_assert (cluster_a != NULL && cluster_b != NULL);
    1964                 :     1228806 :   gcc_assert (cluster_a->m_base_region == out_cluster->m_base_region);
    1965                 :     1228806 :   gcc_assert (cluster_b->m_base_region == out_cluster->m_base_region);
    1966                 :             : 
    1967                 :     1228806 :   hash_set<const binding_key *> keys;
    1968                 :     2630302 :   for (map_t::iterator iter_a = cluster_a->m_map.begin ();
    1969                 :     4031798 :        iter_a != cluster_a->m_map.end (); ++iter_a)
    1970                 :             :     {
    1971                 :     1401496 :       const binding_key *key_a = (*iter_a).first;
    1972                 :     1401496 :       keys.add (key_a);
    1973                 :             :     }
    1974                 :     2610482 :   for (map_t::iterator iter_b = cluster_b->m_map.begin ();
    1975                 :     3992158 :        iter_b != cluster_b->m_map.end (); ++iter_b)
    1976                 :             :     {
    1977                 :     1381676 :       const binding_key *key_b = (*iter_b).first;
    1978                 :     1381676 :       keys.add (key_b);
    1979                 :             :     }
    1980                 :     1228806 :   int num_symbolic_keys = 0;
    1981                 :     1228806 :   int num_concrete_keys = 0;
    1982                 :     2506880 :   for (hash_set<const binding_key *>::iterator iter = keys.begin ();
    1983                 :     3784954 :        iter != keys.end (); ++iter)
    1984                 :             :     {
    1985                 :     1379191 :       region_model_manager *sval_mgr = mgr->get_svalue_manager ();
    1986                 :     1379191 :       const binding_key *key = *iter;
    1987                 :     1379191 :       const svalue *sval_a = cluster_a->get_any_value (key);
    1988                 :     1379191 :       const svalue *sval_b = cluster_b->get_any_value (key);
    1989                 :             : 
    1990                 :     1379191 :       if (key->symbolic_p ())
    1991                 :      134973 :         num_symbolic_keys++;
    1992                 :             :       else
    1993                 :     1244218 :         num_concrete_keys++;
    1994                 :             : 
    1995                 :     1379191 :       if (sval_a == sval_b)
    1996                 :             :         {
    1997                 :     1058001 :           gcc_assert (sval_a);
    1998                 :     1058001 :           out_cluster->m_map.put (key, sval_a);
    1999                 :     1058001 :           continue;
    2000                 :             :         }
    2001                 :      321190 :       else if (sval_a && sval_b)
    2002                 :             :         {
    2003                 :      612619 :           if (const svalue *merged_sval
    2004                 :      222331 :               = sval_a->can_merge_p (sval_b, sval_mgr, merger))
    2005                 :             :             {
    2006                 :      167957 :               out_cluster->m_map.put (key, merged_sval);
    2007                 :      167957 :               continue;
    2008                 :             :             }
    2009                 :             :           /* Merger of the svalues failed.  Reject merger of the cluster.   */
    2010                 :      101117 :           return false;
    2011                 :             :         }
    2012                 :             : 
    2013                 :             :       /* If we get here, then one cluster binds this key and the other
    2014                 :             :          doesn't; merge them as "UNKNOWN".  */
    2015                 :       98859 :       gcc_assert (sval_a || sval_b);
    2016                 :             : 
    2017                 :       98859 :       const svalue *bound_sval = sval_a ? sval_a : sval_b;
    2018                 :       98859 :       tree type = bound_sval->get_type ();
    2019                 :       98859 :       const svalue *unknown_sval
    2020                 :       98859 :         = mgr->get_svalue_manager ()->get_or_create_unknown_svalue (type);
    2021                 :             : 
    2022                 :             :       /* ...but reject the merger if this sval shouldn't be mergeable
    2023                 :             :          (e.g. reject merging svalues that have non-purgable sm-state,
    2024                 :             :          to avoid falsely reporting memory leaks by merging them
    2025                 :             :          with something else).  */
    2026                 :       98859 :       if (!bound_sval->can_merge_p (unknown_sval, sval_mgr, merger))
    2027                 :             :         return false;
    2028                 :             : 
    2029                 :       52116 :       out_cluster->m_map.put (key, unknown_sval);
    2030                 :             :     }
    2031                 :             : 
    2032                 :             :   /* We can only have at most one symbolic key per cluster,
    2033                 :             :      and if we do, we can't have any concrete keys.
    2034                 :             :      If this happens, mark the cluster as touched, with no keys.  */
    2035                 :     1127689 :   if (num_symbolic_keys >= 2
    2036                 :     1127097 :       || (num_concrete_keys > 0 && num_symbolic_keys > 0))
    2037                 :             :     {
    2038                 :        2040 :       out_cluster->m_touched = true;
    2039                 :     1230846 :       out_cluster->m_map.empty ();
    2040                 :             :     }
    2041                 :             : 
    2042                 :             :   /* We don't handle other kinds of overlaps yet.  */
    2043                 :             : 
    2044                 :             :   return true;
    2045                 :     1228806 : }
    2046                 :             : 
    2047                 :             : /* Update this cluster to reflect an attempt to merge OTHER where there
    2048                 :             :    is no other cluster to merge with, and so we're notionally merging the
    2049                 :             :    bound values in OTHER with the initial value of the relevant regions.
    2050                 :             : 
    2051                 :             :    Any bound keys in OTHER should be bound to unknown in this.  */
    2052                 :             : 
    2053                 :             : void
    2054                 :      118928 : binding_cluster::make_unknown_relative_to (const binding_cluster *other,
    2055                 :             :                                            store *out_store,
    2056                 :             :                                            store_manager *mgr)
    2057                 :             : {
    2058                 :      239816 :   for (map_t::iterator iter = other->m_map.begin ();
    2059                 :      360704 :        iter != other->m_map.end (); ++iter)
    2060                 :             :     {
    2061                 :      120888 :       const binding_key *iter_key = (*iter).first;
    2062                 :      120888 :       const svalue *iter_sval = (*iter).second;
    2063                 :      120888 :       const svalue *unknown_sval
    2064                 :             :         = mgr->get_svalue_manager ()->get_or_create_unknown_svalue
    2065                 :      120888 :           (iter_sval->get_type ());
    2066                 :      120888 :       m_map.put (iter_key, unknown_sval);
    2067                 :             : 
    2068                 :             :       /* For any pointers in OTHER, the merger means that the
    2069                 :             :          concrete pointer becomes an unknown value, which could
    2070                 :             :          show up as a false report of a leak when considering what
    2071                 :             :          pointers are live before vs after.
    2072                 :             :          Avoid this by marking the base regions they point to as having
    2073                 :             :          escaped.  */
    2074                 :      241776 :       if (const region_svalue *region_sval
    2075                 :      120888 :           = iter_sval->dyn_cast_region_svalue ())
    2076                 :             :         {
    2077                 :        6808 :           const region *base_reg
    2078                 :        6808 :             = region_sval->get_pointee ()->get_base_region ();
    2079                 :        6808 :           if (base_reg->tracked_p ()
    2080                 :        6808 :               && !base_reg->symbolic_for_unknown_ptr_p ())
    2081                 :             :             {
    2082                 :        6762 :               binding_cluster *c = out_store->get_or_create_cluster (base_reg);
    2083                 :        6762 :               c->mark_as_escaped ();
    2084                 :             :             }
    2085                 :             :         }
    2086                 :             :     }
    2087                 :      118928 : }
    2088                 :             : 
    2089                 :             : /* Mark this cluster as having escaped.  */
    2090                 :             : 
    2091                 :             : void
    2092                 :       52909 : binding_cluster::mark_as_escaped ()
    2093                 :             : {
    2094                 :       52909 :   m_escaped = true;
    2095                 :       52909 : }
    2096                 :             : 
    2097                 :             : /* If this cluster has escaped (by this call, or by an earlier one, or
    2098                 :             :    by being an external param), then unbind all values and mark it
    2099                 :             :    as "touched", so that it has a conjured value, rather than an
    2100                 :             :    initial_svalue.
    2101                 :             :    Use P to purge state involving conjured_svalues.  */
    2102                 :             : 
    2103                 :             : void
    2104                 :      191098 : binding_cluster::on_unknown_fncall (const gcall *call,
    2105                 :             :                                     store_manager *mgr,
    2106                 :             :                                     const conjured_purge &p)
    2107                 :             : {
    2108                 :      191098 :   if (m_escaped)
    2109                 :             :     {
    2110                 :       31758 :       m_map.empty ();
    2111                 :             : 
    2112                 :       31758 :       if (!m_base_region->empty_p ())
    2113                 :             :         {
    2114                 :             :           /* Bind it to a new "conjured" value using CALL.  */
    2115                 :       31758 :           const svalue *sval
    2116                 :             :             = mgr->get_svalue_manager ()->get_or_create_conjured_svalue
    2117                 :       31758 :             (m_base_region->get_type (), call, m_base_region, p);
    2118                 :       31758 :           bind (mgr, m_base_region, sval);
    2119                 :             :         }
    2120                 :             : 
    2121                 :       31758 :       m_touched = true;
    2122                 :             :     }
    2123                 :      191098 : }
    2124                 :             : 
    2125                 :             : /* Mark this cluster as having been clobbered by STMT.
    2126                 :             :    Use P to purge state involving conjured_svalues.  */
    2127                 :             : 
    2128                 :             : void
    2129                 :         535 : binding_cluster::on_asm (const gasm *stmt,
    2130                 :             :                          store_manager *mgr,
    2131                 :             :                          const conjured_purge &p)
    2132                 :             : {
    2133                 :         535 :   m_map.empty ();
    2134                 :             : 
    2135                 :             :   /* Bind it to a new "conjured" value using CALL.  */
    2136                 :         535 :   const svalue *sval
    2137                 :             :     = mgr->get_svalue_manager ()->get_or_create_conjured_svalue
    2138                 :         535 :     (m_base_region->get_type (), stmt, m_base_region, p);
    2139                 :         535 :   bind (mgr, m_base_region, sval);
    2140                 :             : 
    2141                 :         535 :   m_touched = true;
    2142                 :         535 : }
    2143                 :             : 
    2144                 :             : /* Return true if this cluster has escaped.  */
    2145                 :             : 
    2146                 :             : bool
    2147                 :     9927724 : binding_cluster::escaped_p () const
    2148                 :             : {
    2149                 :             :   /* Consider the "errno" region to always have escaped.  */
    2150                 :     9927724 :   if (m_base_region->get_kind () == RK_ERRNO)
    2151                 :             :     return true;
    2152                 :     9890003 :   return m_escaped;
    2153                 :             : }
    2154                 :             : 
    2155                 :             : /* Return true if this binding_cluster has no information
    2156                 :             :    i.e. if there are no bindings, and it hasn't been marked as having
    2157                 :             :    escaped, or touched symbolically.  */
    2158                 :             : 
    2159                 :             : bool
    2160                 :      220200 : binding_cluster::redundant_p () const
    2161                 :             : {
    2162                 :      220200 :   return (m_map.elements () == 0
    2163                 :      210757 :           && !m_escaped
    2164                 :      429623 :           && !m_touched);
    2165                 :             : }
    2166                 :             : 
    2167                 :             : /* Add PV to OUT_PVS, casting it to TYPE if it is not already of that type.  */
    2168                 :             : 
    2169                 :             : static void
    2170                 :        9733 : append_pathvar_with_type (path_var pv,
    2171                 :             :                           tree type,
    2172                 :             :                           auto_vec<path_var> *out_pvs)
    2173                 :             : {
    2174                 :        9733 :   gcc_assert (pv.m_tree);
    2175                 :             : 
    2176                 :        9733 :   if (TREE_TYPE (pv.m_tree) != type)
    2177                 :         582 :     pv.m_tree = build1 (NOP_EXPR, type, pv.m_tree);
    2178                 :             : 
    2179                 :        9733 :   out_pvs->safe_push (pv);
    2180                 :        9733 : }
    2181                 :             : 
    2182                 :             : /* Find representative path_vars for SVAL within this binding of BASE_REG,
    2183                 :             :    appending the results to OUT_PVS.  */
    2184                 :             : 
    2185                 :             : void
    2186                 :       71764 : binding_cluster::get_representative_path_vars (const region_model *model,
    2187                 :             :                                                svalue_set *visited,
    2188                 :             :                                                const region *base_reg,
    2189                 :             :                                                const svalue *sval,
    2190                 :             :                                                auto_vec<path_var> *out_pvs)
    2191                 :             :   const
    2192                 :             : {
    2193                 :       71764 :   sval = simplify_for_binding (sval);
    2194                 :             : 
    2195                 :      207426 :   for (map_t::iterator iter = m_map.begin (); iter != m_map.end (); ++iter)
    2196                 :             :     {
    2197                 :       67831 :       const binding_key *key = (*iter).first;
    2198                 :       67831 :       const svalue *bound_sval = (*iter).second;
    2199                 :       67831 :       if (bound_sval == sval)
    2200                 :             :         {
    2201                 :       20376 :           if (const concrete_binding *ckey
    2202                 :       10188 :                 = key->dyn_cast_concrete_binding ())
    2203                 :             :             {
    2204                 :       10112 :               auto_vec <const region *> subregions;
    2205                 :       10112 :               base_reg->get_subregions_for_binding
    2206                 :       10112 :                 (model->get_manager (),
    2207                 :             :                  ckey->get_start_bit_offset (),
    2208                 :             :                  ckey->get_size_in_bits (),
    2209                 :             :                  sval->get_type (),
    2210                 :             :                  &subregions);
    2211                 :       10112 :               unsigned i;
    2212                 :       10112 :               const region *subregion;
    2213                 :       29444 :               FOR_EACH_VEC_ELT (subregions, i, subregion)
    2214                 :             :                 {
    2215                 :       19332 :                   if (path_var pv
    2216                 :        9666 :                       = model->get_representative_path_var (subregion,
    2217                 :        9666 :                                                             visited))
    2218                 :        9657 :                     append_pathvar_with_type (pv, sval->get_type (), out_pvs);
    2219                 :             :                 }
    2220                 :       10112 :             }
    2221                 :             :           else
    2222                 :             :             {
    2223                 :          76 :               const symbolic_binding *skey = (const symbolic_binding *)key;
    2224                 :         152 :               if (path_var pv
    2225                 :          76 :                   = model->get_representative_path_var (skey->get_region (),
    2226                 :          76 :                                                         visited))
    2227                 :          76 :                 append_pathvar_with_type (pv, sval->get_type (), out_pvs);
    2228                 :             :             }
    2229                 :             :         }
    2230                 :             :     }
    2231                 :       71764 : }
    2232                 :             : 
    2233                 :             : /* Get any svalue bound to KEY, or NULL.  */
    2234                 :             : 
    2235                 :             : const svalue *
    2236                 :     2966341 : binding_cluster::get_any_value (const binding_key *key) const
    2237                 :             : {
    2238                 :     2966341 :   return m_map.get (key);
    2239                 :             : }
    2240                 :             : 
    2241                 :             : /* If this cluster has a single direct binding for the whole of the region,
    2242                 :             :    return it.
    2243                 :             :    For use in simplifying dumps.  */
    2244                 :             : 
    2245                 :             : const svalue *
    2246                 :      437980 : binding_cluster::maybe_get_simple_value (store_manager *mgr) const
    2247                 :             : {
    2248                 :             :   /* Fail gracefully if MGR is NULL to make it easier to dump store
    2249                 :             :      instances in the debugger.  */
    2250                 :      437980 :   if (mgr == NULL)
    2251                 :             :     return NULL;
    2252                 :             : 
    2253                 :      437980 :   if (m_map.elements () != 1)
    2254                 :             :     return NULL;
    2255                 :             : 
    2256                 :      207959 :   if (m_base_region->empty_p ())
    2257                 :             :     return NULL;
    2258                 :             : 
    2259                 :      207959 :   const binding_key *key = binding_key::make (mgr, m_base_region);
    2260                 :      207959 :   return get_any_value (key);
    2261                 :             : }
    2262                 :             : 
    2263                 :             : /* class store_manager.  */
    2264                 :             : 
    2265                 :             : logger *
    2266                 :      392091 : store_manager::get_logger () const
    2267                 :             : {
    2268                 :      392091 :   return m_mgr->get_logger ();
    2269                 :             : }
    2270                 :             : 
    2271                 :             : /* binding consolidation.  */
    2272                 :             : 
    2273                 :             : const concrete_binding *
    2274                 :     2751022 : store_manager::get_concrete_binding (bit_offset_t start_bit_offset,
    2275                 :             :                                      bit_offset_t size_in_bits)
    2276                 :             : {
    2277                 :     2751022 :   concrete_binding b (start_bit_offset, size_in_bits);
    2278                 :     5488449 :   if (concrete_binding *existing = m_concrete_binding_key_mgr.get (b))
    2279                 :             :     return existing;
    2280                 :             : 
    2281                 :       13595 :   concrete_binding *to_save = new concrete_binding (b);
    2282                 :       13595 :   m_concrete_binding_key_mgr.put (b, to_save);
    2283                 :       13595 :   return to_save;
    2284                 :     2751022 : }
    2285                 :             : 
    2286                 :             : const symbolic_binding *
    2287                 :     1560105 : store_manager::get_symbolic_binding (const region *reg)
    2288                 :             : {
    2289                 :     1560105 :   symbolic_binding b (reg);
    2290                 :     3098361 :   if (symbolic_binding *existing = m_symbolic_binding_key_mgr.get (b))
    2291                 :             :     return existing;
    2292                 :             : 
    2293                 :       21849 :   symbolic_binding *to_save = new symbolic_binding (b);
    2294                 :       21849 :   m_symbolic_binding_key_mgr.put (b, to_save);
    2295                 :       21849 :   return to_save;
    2296                 :     1560105 : }
    2297                 :             : 
    2298                 :             : /* class store.  */
    2299                 :             : 
    2300                 :             : /* store's default ctor.  */
    2301                 :             : 
    2302                 :      406614 : store::store ()
    2303                 :      406614 : : m_called_unknown_fn (false)
    2304                 :             : {
    2305                 :      406614 : }
    2306                 :             : 
    2307                 :             : /* store's copy ctor.  */
    2308                 :             : 
    2309                 :     4208731 : store::store (const store &other)
    2310                 :     4208731 : : m_cluster_map (other.m_cluster_map.elements ()),
    2311                 :     4208731 :   m_called_unknown_fn (other.m_called_unknown_fn)
    2312                 :             : {
    2313                 :     4208731 :   for (cluster_map_t::iterator iter = other.m_cluster_map.begin ();
    2314                 :    32509838 :        iter != other.m_cluster_map.end ();
    2315                 :    28301107 :        ++iter)
    2316                 :             :     {
    2317                 :    28301107 :       const region *reg = (*iter).first;
    2318                 :           0 :       gcc_assert (reg);
    2319                 :    28301107 :       binding_cluster *c = (*iter).second;
    2320                 :    28301107 :       gcc_assert (c);
    2321                 :    28301107 :       m_cluster_map.put (reg, new binding_cluster (*c));
    2322                 :             :     }
    2323                 :     4208731 : }
    2324                 :             : 
    2325                 :             : /* store's dtor.  */
    2326                 :             : 
    2327                 :     4615345 : store::~store ()
    2328                 :             : {
    2329                 :    34376334 :   for (cluster_map_t::iterator iter = m_cluster_map.begin ();
    2330                 :    34376334 :        iter != m_cluster_map.end ();
    2331                 :    29760989 :        ++iter)
    2332                 :    29760989 :     delete (*iter).second;
    2333                 :     4615345 : }
    2334                 :             : 
    2335                 :             : /* store's assignment operator.  */
    2336                 :             : 
    2337                 :             : store &
    2338                 :       20125 : store::operator= (const store &other)
    2339                 :             : {
    2340                 :             :   /* Delete existing cluster map.  */
    2341                 :      151468 :   for (cluster_map_t::iterator iter = m_cluster_map.begin ();
    2342                 :      151468 :        iter != m_cluster_map.end ();
    2343                 :      131343 :        ++iter)
    2344                 :      262686 :     delete (*iter).second;
    2345                 :       20125 :   m_cluster_map.empty ();
    2346                 :             : 
    2347                 :       20125 :   m_called_unknown_fn = other.m_called_unknown_fn;
    2348                 :             : 
    2349                 :       20125 :   for (cluster_map_t::iterator iter = other.m_cluster_map.begin ();
    2350                 :      167184 :        iter != other.m_cluster_map.end ();
    2351                 :      147059 :        ++iter)
    2352                 :             :     {
    2353                 :      147059 :       const region *reg = (*iter).first;
    2354                 :      147059 :       gcc_assert (reg);
    2355                 :      147059 :       binding_cluster *c = (*iter).second;
    2356                 :      147059 :       gcc_assert (c);
    2357                 :      147059 :       m_cluster_map.put (reg, new binding_cluster (*c));
    2358                 :             :     }
    2359                 :       20125 :   return *this;
    2360                 :             : }
    2361                 :             : 
    2362                 :             : /* store's equality operator.  */
    2363                 :             : 
    2364                 :             : bool
    2365                 :      515746 : store::operator== (const store &other) const
    2366                 :             : {
    2367                 :      515746 :   if (m_called_unknown_fn != other.m_called_unknown_fn)
    2368                 :             :     return false;
    2369                 :             : 
    2370                 :      512228 :   if (m_cluster_map.elements () != other.m_cluster_map.elements ())
    2371                 :             :     return false;
    2372                 :             : 
    2373                 :     2786546 :   for (cluster_map_t::iterator iter = m_cluster_map.begin ();
    2374                 :     2786546 :        iter != m_cluster_map.end ();
    2375                 :     2302160 :        ++iter)
    2376                 :             :     {
    2377                 :     2341789 :       const region *reg = (*iter).first;
    2378                 :     2341789 :       binding_cluster *c = (*iter).second;
    2379                 :     2341789 :       binding_cluster **other_slot
    2380                 :     2341789 :         = const_cast <cluster_map_t &> (other.m_cluster_map).get (reg);
    2381                 :     2341789 :       if (other_slot == NULL)
    2382                 :       39629 :         return false;
    2383                 :     2340333 :       if (*c != **other_slot)
    2384                 :             :         return false;
    2385                 :             :     }
    2386                 :             : 
    2387                 :      444757 :   gcc_checking_assert (hash () == other.hash ());
    2388                 :             : 
    2389                 :             :   return true;
    2390                 :             : }
    2391                 :             : 
    2392                 :             : /* Get a hash value for this store.  */
    2393                 :             : 
    2394                 :             : hashval_t
    2395                 :     2283719 : store::hash () const
    2396                 :             : {
    2397                 :     2283719 :   hashval_t result = 0;
    2398                 :     2283719 :   for (cluster_map_t::iterator iter = m_cluster_map.begin ();
    2399                 :    14038070 :        iter != m_cluster_map.end ();
    2400                 :    11754351 :        ++iter)
    2401                 :    11754351 :     result ^= (*iter).second->hash ();
    2402                 :     2283719 :   return result;
    2403                 :             : }
    2404                 :             : 
    2405                 :             : /* Populate OUT with a sorted list of parent regions for the regions in IN,
    2406                 :             :    removing duplicate parents.  */
    2407                 :             : 
    2408                 :             : static void
    2409                 :        2170 : get_sorted_parent_regions (auto_vec<const region *> *out,
    2410                 :             :                            auto_vec<const region *> &in)
    2411                 :             : {
    2412                 :             :   /* Get the set of parent regions.  */
    2413                 :        2170 :   hash_set<const region *> parent_regions;
    2414                 :        2170 :   const region *iter_reg;
    2415                 :        2170 :   unsigned i;
    2416                 :       10988 :   FOR_EACH_VEC_ELT (in, i, iter_reg)
    2417                 :             :     {
    2418                 :        8818 :       const region *parent_reg = iter_reg->get_parent_region ();
    2419                 :        8818 :       gcc_assert (parent_reg);
    2420                 :        8818 :       parent_regions.add (parent_reg);
    2421                 :             :     }
    2422                 :             : 
    2423                 :             :   /* Write to OUT.  */
    2424                 :        2170 :   for (hash_set<const region *>::iterator iter = parent_regions.begin();
    2425                 :       11246 :        iter != parent_regions.end(); ++iter)
    2426                 :        4538 :     out->safe_push (*iter);
    2427                 :             : 
    2428                 :             :   /* Sort OUT.  */
    2429                 :        4155 :   out->qsort (region::cmp_ptr_ptr);
    2430                 :        2170 : }
    2431                 :             : 
    2432                 :             : /* Dump a representation of this store to PP, using SIMPLE to control how
    2433                 :             :    svalues and regions are printed.
    2434                 :             :    MGR is used for simplifying dumps if non-NULL, but can also be NULL
    2435                 :             :    (to make it easier to use from the debugger).  */
    2436                 :             : 
    2437                 :             : void
    2438                 :        2165 : store::dump_to_pp (pretty_printer *pp, bool simple, bool multiline,
    2439                 :             :                    store_manager *mgr) const
    2440                 :             : {
    2441                 :             :   /* Sort into some deterministic order.  */
    2442                 :        2165 :   auto_vec<const region *> base_regions;
    2443                 :       10983 :   for (cluster_map_t::iterator iter = m_cluster_map.begin ();
    2444                 :       19801 :        iter != m_cluster_map.end (); ++iter)
    2445                 :             :     {
    2446                 :        8818 :       const region *base_reg = (*iter).first;
    2447                 :        8818 :       base_regions.safe_push (base_reg);
    2448                 :             :     }
    2449                 :        2165 :   base_regions.qsort (region::cmp_ptr_ptr);
    2450                 :             : 
    2451                 :             :   /* Gather clusters, organize by parent region, so that we can group
    2452                 :             :      together locals, globals, etc.  */
    2453                 :        2165 :   auto_vec<const region *> parent_regions;
    2454                 :        2165 :   get_sorted_parent_regions (&parent_regions, base_regions);
    2455                 :             : 
    2456                 :        2165 :   const region *parent_reg;
    2457                 :        2165 :   unsigned i;
    2458                 :        6703 :   FOR_EACH_VEC_ELT (parent_regions, i, parent_reg)
    2459                 :             :     {
    2460                 :        4538 :       gcc_assert (parent_reg);
    2461                 :        4538 :       pp_string (pp, "clusters within ");
    2462                 :        4538 :       parent_reg->dump_to_pp (pp, simple);
    2463                 :        4538 :       if (multiline)
    2464                 :        2050 :         pp_newline (pp);
    2465                 :             :       else
    2466                 :        2488 :         pp_string (pp, " {");
    2467                 :             : 
    2468                 :             :       const region *base_reg;
    2469                 :             :       unsigned j;
    2470                 :       26428 :       FOR_EACH_VEC_ELT (base_regions, j, base_reg)
    2471                 :             :         {
    2472                 :             :           /* This is O(N * M), but N ought to be small.  */
    2473                 :       21890 :           if (base_reg->get_parent_region () != parent_reg)
    2474                 :       13072 :             continue;
    2475                 :        8818 :           binding_cluster *cluster
    2476                 :        8818 :             = *const_cast<cluster_map_t &> (m_cluster_map).get (base_reg);
    2477                 :        8818 :           if (!multiline)
    2478                 :             :             {
    2479                 :        4153 :               if (j > 0)
    2480                 :        3153 :                 pp_string (pp, ", ");
    2481                 :             :             }
    2482                 :        8818 :           if (const svalue *sval = cluster->maybe_get_simple_value (mgr))
    2483                 :             :             {
    2484                 :             :               /* Special-case to simplify dumps for the common case where
    2485                 :             :                  we just have one value directly bound to the whole of a
    2486                 :             :                  region.  */
    2487                 :        6289 :               if (multiline)
    2488                 :             :                 {
    2489                 :        2885 :                   pp_string (pp, "  cluster for: ");
    2490                 :        2885 :                   base_reg->dump_to_pp (pp, simple);
    2491                 :        2885 :                   pp_string (pp, ": ");
    2492                 :        2885 :                   sval->dump_to_pp (pp, simple);
    2493                 :        2885 :                   if (cluster->escaped_p ())
    2494                 :         180 :                     pp_string (pp, " (ESCAPED)");
    2495                 :        2885 :                   if (cluster->touched_p ())
    2496                 :           0 :                     pp_string (pp, " (TOUCHED)");
    2497                 :        2885 :                   pp_newline (pp);
    2498                 :             :                 }
    2499                 :             :               else
    2500                 :             :                 {
    2501                 :        3404 :                   pp_string (pp, "region: {");
    2502                 :        3404 :                   base_reg->dump_to_pp (pp, simple);
    2503                 :        3404 :                   pp_string (pp, ", value: ");
    2504                 :        3404 :                   sval->dump_to_pp (pp, simple);
    2505                 :        3404 :                   if (cluster->escaped_p ())
    2506                 :         813 :                     pp_string (pp, " (ESCAPED)");
    2507                 :        3404 :                   if (cluster->touched_p ())
    2508                 :         813 :                     pp_string (pp, " (TOUCHED)");
    2509                 :        3404 :                   pp_string (pp, "}");
    2510                 :             :                 }
    2511                 :             :             }
    2512                 :        2529 :           else if (multiline)
    2513                 :             :             {
    2514                 :        1780 :               pp_string (pp, "  cluster for: ");
    2515                 :        1780 :               base_reg->dump_to_pp (pp, simple);
    2516                 :        1780 :               pp_newline (pp);
    2517                 :        1780 :               cluster->dump_to_pp (pp, simple, multiline);
    2518                 :             :             }
    2519                 :             :           else
    2520                 :             :             {
    2521                 :         749 :               pp_string (pp, "base region: {");
    2522                 :         749 :               base_reg->dump_to_pp (pp, simple);
    2523                 :         749 :               pp_string (pp, "} has cluster: {");
    2524                 :         749 :               cluster->dump_to_pp (pp, simple, multiline);
    2525                 :         749 :               pp_string (pp, "}");
    2526                 :             :             }
    2527                 :             :         }
    2528                 :        4538 :       if (!multiline)
    2529                 :        2488 :         pp_string (pp, "}");
    2530                 :             :     }
    2531                 :        2165 :   pp_printf (pp, "m_called_unknown_fn: %s",
    2532                 :        2165 :              m_called_unknown_fn ? "TRUE" : "FALSE");
    2533                 :        2165 :   if (multiline)
    2534                 :        1068 :     pp_newline (pp);
    2535                 :        2165 : }
    2536                 :             : 
    2537                 :             : /* Dump a multiline representation of this store to stderr.  */
    2538                 :             : 
    2539                 :             : DEBUG_FUNCTION void
    2540                 :           0 : store::dump (bool simple) const
    2541                 :             : {
    2542                 :           0 :   pretty_printer pp;
    2543                 :           0 :   pp_format_decoder (&pp) = default_tree_printer;
    2544                 :           0 :   pp_show_color (&pp) = pp_show_color (global_dc->printer);
    2545                 :           0 :   pp.buffer->stream = stderr;
    2546                 :           0 :   dump_to_pp (&pp, simple, true, NULL);
    2547                 :           0 :   pp_newline (&pp);
    2548                 :           0 :   pp_flush (&pp);
    2549                 :           0 : }
    2550                 :             : 
    2551                 :             : /* Assert that this object is valid.  */
    2552                 :             : 
    2553                 :             : void
    2554                 :     1969616 : store::validate () const
    2555                 :             : {
    2556                 :    12590930 :   for (auto iter : m_cluster_map)
    2557                 :    10621314 :     iter.second->validate ();
    2558                 :     1969616 : }
    2559                 :             : 
    2560                 :             : /* Return a new json::object of the form
    2561                 :             :    {PARENT_REGION_DESC: {BASE_REGION_DESC: object for binding_map,
    2562                 :             :                          ... for each cluster within parent region},
    2563                 :             :     ...for each parent region,
    2564                 :             :     "called_unknown_fn": true/false}.  */
    2565                 :             : 
    2566                 :             : json::object *
    2567                 :           5 : store::to_json () const
    2568                 :             : {
    2569                 :           5 :   json::object *store_obj = new json::object ();
    2570                 :             : 
    2571                 :             :   /* Sort into some deterministic order.  */
    2572                 :           5 :   auto_vec<const region *> base_regions;
    2573                 :           5 :   for (cluster_map_t::iterator iter = m_cluster_map.begin ();
    2574                 :           5 :        iter != m_cluster_map.end (); ++iter)
    2575                 :             :     {
    2576                 :           0 :       const region *base_reg = (*iter).first;
    2577                 :           0 :       base_regions.safe_push (base_reg);
    2578                 :             :     }
    2579                 :           5 :   base_regions.qsort (region::cmp_ptr_ptr);
    2580                 :             : 
    2581                 :             :   /* Gather clusters, organize by parent region, so that we can group
    2582                 :             :      together locals, globals, etc.  */
    2583                 :           5 :   auto_vec<const region *> parent_regions;
    2584                 :           5 :   get_sorted_parent_regions (&parent_regions, base_regions);
    2585                 :             : 
    2586                 :           5 :   const region *parent_reg;
    2587                 :           5 :   unsigned i;
    2588                 :           5 :   FOR_EACH_VEC_ELT (parent_regions, i, parent_reg)
    2589                 :             :     {
    2590                 :           0 :       gcc_assert (parent_reg);
    2591                 :             : 
    2592                 :           0 :       json::object *clusters_in_parent_reg_obj = new json::object ();
    2593                 :             : 
    2594                 :           0 :       const region *base_reg;
    2595                 :           0 :       unsigned j;
    2596                 :           0 :       FOR_EACH_VEC_ELT (base_regions, j, base_reg)
    2597                 :             :         {
    2598                 :             :           /* This is O(N * M), but N ought to be small.  */
    2599                 :           0 :           if (base_reg->get_parent_region () != parent_reg)
    2600                 :           0 :             continue;
    2601                 :           0 :           binding_cluster *cluster
    2602                 :           0 :             = *const_cast<cluster_map_t &> (m_cluster_map).get (base_reg);
    2603                 :           0 :           label_text base_reg_desc = base_reg->get_desc ();
    2604                 :           0 :           clusters_in_parent_reg_obj->set (base_reg_desc.get (),
    2605                 :           0 :                                            cluster->to_json ());
    2606                 :           0 :         }
    2607                 :           0 :       label_text parent_reg_desc = parent_reg->get_desc ();
    2608                 :           0 :       store_obj->set (parent_reg_desc.get (), clusters_in_parent_reg_obj);
    2609                 :           0 :     }
    2610                 :             : 
    2611                 :          10 :   store_obj->set ("called_unknown_fn", new json::literal (m_called_unknown_fn));
    2612                 :             : 
    2613                 :           5 :   return store_obj;
    2614                 :           5 : }
    2615                 :             : 
    2616                 :             : /* Get any svalue bound to REG, or NULL.  */
    2617                 :             : 
    2618                 :             : const svalue *
    2619                 :     4433645 : store::get_any_binding (store_manager *mgr, const region *reg) const
    2620                 :             : {
    2621                 :     4433645 :   const region *base_reg = reg->get_base_region ();
    2622                 :     4433645 :   binding_cluster **cluster_slot
    2623                 :     4433645 :     = const_cast <cluster_map_t &> (m_cluster_map).get (base_reg);
    2624                 :     4433645 :   if (!cluster_slot)
    2625                 :             :     return NULL;
    2626                 :     1466948 :   return (*cluster_slot)->get_any_binding (mgr, reg);
    2627                 :             : }
    2628                 :             : 
    2629                 :             : /* Set the value of LHS_REG to RHS_SVAL.  */
    2630                 :             : 
    2631                 :             : void
    2632                 :      392091 : store::set_value (store_manager *mgr, const region *lhs_reg,
    2633                 :             :                   const svalue *rhs_sval,
    2634                 :             :                   uncertainty_t *uncertainty)
    2635                 :             : {
    2636                 :      392091 :   logger *logger = mgr->get_logger ();
    2637                 :      392091 :   LOG_SCOPE (logger);
    2638                 :             : 
    2639                 :      392091 :   remove_overlapping_bindings (mgr, lhs_reg, uncertainty);
    2640                 :             : 
    2641                 :      392091 :   if (lhs_reg->get_type ())
    2642                 :      383754 :     rhs_sval = simplify_for_binding (rhs_sval);
    2643                 :             :   /* ...but if we have no type for the region, retain any cast.  */
    2644                 :             : 
    2645                 :      392091 :   const region *lhs_base_reg = lhs_reg->get_base_region ();
    2646                 :      392091 :   binding_cluster *lhs_cluster;
    2647                 :      392091 :   if (lhs_base_reg->symbolic_for_unknown_ptr_p ())
    2648                 :             :     {
    2649                 :             :       /* Reject attempting to bind values into a symbolic region
    2650                 :             :          for an unknown ptr; merely invalidate values below.  */
    2651                 :        4156 :       lhs_cluster = NULL;
    2652                 :             : 
    2653                 :             :       /* The LHS of the write is *UNKNOWN.  If the RHS is a pointer,
    2654                 :             :          then treat the region being pointed to as having escaped.  */
    2655                 :        4156 :       if (const region_svalue *ptr_sval = rhs_sval->dyn_cast_region_svalue ())
    2656                 :             :         {
    2657                 :         197 :           const region *ptr_dst = ptr_sval->get_pointee ();
    2658                 :         197 :           const region *ptr_base_reg = ptr_dst->get_base_region ();
    2659                 :         197 :           mark_as_escaped (ptr_base_reg);
    2660                 :             :         }
    2661                 :        4156 :       if (uncertainty)
    2662                 :        1911 :         uncertainty->on_maybe_bound_sval (rhs_sval);
    2663                 :             :     }
    2664                 :      387935 :   else if (lhs_base_reg->tracked_p ())
    2665                 :             :     {
    2666                 :      387837 :       lhs_cluster = get_or_create_cluster (lhs_base_reg);
    2667                 :      387837 :       lhs_cluster->bind (mgr, lhs_reg, rhs_sval);
    2668                 :             :     }
    2669                 :             :   else
    2670                 :             :     {
    2671                 :             :       /* Reject attempting to bind values into an untracked region;
    2672                 :             :          merely invalidate values below.  */
    2673                 :             :       lhs_cluster = NULL;
    2674                 :             :     }
    2675                 :             : 
    2676                 :             :   /* Bindings to a cluster can affect other clusters if a symbolic
    2677                 :             :      base region is involved.
    2678                 :             :      Writes to concrete clusters can't affect other concrete clusters,
    2679                 :             :      but can affect symbolic clusters.
    2680                 :             :      Writes to symbolic clusters can affect both concrete and symbolic
    2681                 :             :      clusters.
    2682                 :             :      Invalidate our knowledge of other clusters that might have been
    2683                 :             :      affected by the write.
    2684                 :             :      Gather the set of all svalues that might still be live even if
    2685                 :             :      the store doesn't refer to them.  */
    2686                 :      392091 :   svalue_set maybe_live_values;
    2687                 :     5472885 :   for (cluster_map_t::iterator iter = m_cluster_map.begin ();
    2688                 :    10553679 :        iter != m_cluster_map.end (); ++iter)
    2689                 :             :     {
    2690                 :     5080794 :       const region *iter_base_reg = (*iter).first;
    2691                 :     5080794 :       binding_cluster *iter_cluster = (*iter).second;
    2692                 :     5080794 :       if (iter_base_reg != lhs_base_reg
    2693                 :     5080794 :           && (lhs_cluster == NULL
    2694                 :     4623978 :               || lhs_cluster->symbolic_p ()
    2695                 :     4523978 :               || iter_cluster->symbolic_p ()))
    2696                 :             :         {
    2697                 :      681267 :           tristate t_alias = eval_alias (lhs_base_reg, iter_base_reg);
    2698                 :      681267 :           switch (t_alias.get_value ())
    2699                 :             :             {
    2700                 :           0 :             default:
    2701                 :           0 :               gcc_unreachable ();
    2702                 :             : 
    2703                 :       77152 :             case tristate::TS_UNKNOWN:
    2704                 :       77152 :               if (logger)
    2705                 :             :                 {
    2706                 :           7 :                   pretty_printer *pp = logger->get_printer ();
    2707                 :           7 :                   logger->start_log_line ();
    2708                 :           7 :                   logger->log_partial ("possible aliasing of ");
    2709                 :           7 :                   iter_base_reg->dump_to_pp (pp, true);
    2710                 :           7 :                   logger->log_partial (" when writing SVAL: ");
    2711                 :           7 :                   rhs_sval->dump_to_pp (pp, true);
    2712                 :           7 :                   logger->log_partial (" to LHS_REG: ");
    2713                 :           7 :                   lhs_reg->dump_to_pp (pp, true);
    2714                 :           7 :                   logger->end_log_line ();
    2715                 :             :                 }
    2716                 :             :               /* Mark all of iter_cluster's iter_base_reg as unknown,
    2717                 :             :                  using LHS_REG when considering overlaps, to handle
    2718                 :             :                  symbolic vs concrete issues.  */
    2719                 :       77152 :               iter_cluster->mark_region_as_unknown
    2720                 :       77152 :                 (mgr,
    2721                 :             :                  iter_base_reg, /* reg_to_bind */
    2722                 :             :                  lhs_reg, /* reg_for_overlap */
    2723                 :             :                  uncertainty,
    2724                 :             :                  &maybe_live_values);
    2725                 :       77152 :               break;
    2726                 :             : 
    2727                 :           0 :             case tristate::TS_TRUE:
    2728                 :           0 :               gcc_unreachable ();
    2729                 :             :               break;
    2730                 :             : 
    2731                 :             :             case tristate::TS_FALSE:
    2732                 :             :               /* If they can't be aliases, then don't invalidate this
    2733                 :             :                  cluster.  */
    2734                 :             :               break;
    2735                 :             :             }
    2736                 :             :         }
    2737                 :             :     }
    2738                 :             :   /* Given the set of svalues that might still be live, process them
    2739                 :             :      (e.g. marking regions as escaped).
    2740                 :             :      We do this after the iteration to avoid potentially changing
    2741                 :             :      m_cluster_map whilst iterating over it.  */
    2742                 :      392091 :   on_maybe_live_values (maybe_live_values);
    2743                 :      392091 : }
    2744                 :             : 
    2745                 :             : /* Determine if BASE_REG_A could be an alias of BASE_REG_B.  */
    2746                 :             : 
    2747                 :             : tristate
    2748                 :      681935 : store::eval_alias (const region *base_reg_a,
    2749                 :             :                    const region *base_reg_b) const
    2750                 :             : {
    2751                 :             :   /* SSA names can't alias.  */
    2752                 :      681935 :   tree decl_a = base_reg_a->maybe_get_decl ();
    2753                 :      681935 :   if (decl_a && TREE_CODE (decl_a) == SSA_NAME)
    2754                 :      444871 :     return tristate::TS_FALSE;
    2755                 :      237064 :   tree decl_b = base_reg_b->maybe_get_decl ();
    2756                 :      237064 :   if (decl_b && TREE_CODE (decl_b) == SSA_NAME)
    2757                 :       80461 :     return tristate::TS_FALSE;
    2758                 :             : 
    2759                 :             :   /* Try both ways, for symmetry.  */
    2760                 :      156603 :   tristate ts_ab = eval_alias_1 (base_reg_a, base_reg_b);
    2761                 :      156603 :   if (ts_ab.is_false ())
    2762                 :       29054 :     return tristate::TS_FALSE;
    2763                 :      127549 :   tristate ts_ba = eval_alias_1 (base_reg_b, base_reg_a);
    2764                 :      127549 :   if (ts_ba.is_false ())
    2765                 :       50095 :     return tristate::TS_FALSE;
    2766                 :       77454 :   return tristate::TS_UNKNOWN;
    2767                 :             : }
    2768                 :             : 
    2769                 :             : /* Half of store::eval_alias; called twice for symmetry.  */
    2770                 :             : 
    2771                 :             : tristate
    2772                 :      284152 : store::eval_alias_1 (const region *base_reg_a,
    2773                 :             :                      const region *base_reg_b) const
    2774                 :             : {
    2775                 :             :   /* If they're in different memory spaces, they can't alias.  */
    2776                 :      284152 :   {
    2777                 :      284152 :     enum memory_space memspace_a = base_reg_a->get_memory_space ();
    2778                 :      284152 :     if (memspace_a != MEMSPACE_UNKNOWN)
    2779                 :             :       {
    2780                 :       96945 :         enum memory_space memspace_b = base_reg_b->get_memory_space ();
    2781                 :       96945 :         if (memspace_b != MEMSPACE_UNKNOWN
    2782                 :       96945 :             && memspace_a != memspace_b)
    2783                 :         331 :           return tristate::TS_FALSE;
    2784                 :             :       }
    2785                 :             :   }
    2786                 :             : 
    2787                 :      567642 :   if (const symbolic_region *sym_reg_a
    2788                 :      283821 :       = base_reg_a->dyn_cast_symbolic_region ())
    2789                 :             :     {
    2790                 :      180047 :       const svalue *sval_a = sym_reg_a->get_pointer ();
    2791                 :      180047 :       if (tree decl_b = base_reg_b->maybe_get_decl ())
    2792                 :             :         {
    2793                 :       90796 :           if (!may_be_aliased (decl_b))
    2794                 :       53308 :             return tristate::TS_FALSE;
    2795                 :       37488 :           if (sval_a->get_kind () == SK_INITIAL)
    2796                 :       21301 :             if (!is_global_var (decl_b))
    2797                 :             :               {
    2798                 :             :                 /* The initial value of a pointer can't point to a local.  */
    2799                 :       13600 :                 return tristate::TS_FALSE;
    2800                 :             :               }
    2801                 :             :         }
    2802                 :      113139 :       if (sval_a->get_kind () == SK_INITIAL
    2803                 :      113139 :           && base_reg_b->get_kind () == RK_HEAP_ALLOCATED)
    2804                 :             :         {
    2805                 :             :           /* The initial value of a pointer can't point to a
    2806                 :             :              region that was allocated on the heap after the beginning of the
    2807                 :             :              path.  */
    2808                 :       11544 :           return tristate::TS_FALSE;
    2809                 :             :         }
    2810                 :      203190 :       if (const widening_svalue *widening_sval_a
    2811                 :      101595 :           = sval_a->dyn_cast_widening_svalue ())
    2812                 :             :         {
    2813                 :        4460 :           const svalue *base = widening_sval_a->get_base_svalue ();
    2814                 :        8920 :           if (const region_svalue *region_sval
    2815                 :        4460 :                 = base->dyn_cast_region_svalue ())
    2816                 :             :             {
    2817                 :         668 :               const region *pointee = region_sval->get_pointee ();
    2818                 :             :               /* If we have sval_a is WIDENING(&REGION, OP), and
    2819                 :             :                  B can't alias REGION, then B can't alias A either.
    2820                 :             :                  For example, A might arise from
    2821                 :             :                    for (ptr = &REGION; ...; ptr++)
    2822                 :             :                  where sval_a is ptr in the 2nd iteration of the loop.
    2823                 :             :                  We want to ensure that "*ptr" can only clobber things
    2824                 :             :                  within REGION's base region.  */
    2825                 :         668 :               tristate ts = eval_alias (pointee->get_base_region (),
    2826                 :             :                                         base_reg_b);
    2827                 :         668 :               if (ts.is_false ())
    2828                 :         366 :                 return tristate::TS_FALSE;
    2829                 :             :             }
    2830                 :             :         }
    2831                 :             :     }
    2832                 :      205003 :   return tristate::TS_UNKNOWN;
    2833                 :             : }
    2834                 :             : 
    2835                 :             : /* Record all of the values in MAYBE_LIVE_VALUES as being possibly live.  */
    2836                 :             : 
    2837                 :             : void
    2838                 :      392445 : store::on_maybe_live_values (const svalue_set &maybe_live_values)
    2839                 :             : {
    2840                 :      495263 :   for (auto sval : maybe_live_values)
    2841                 :             :     {
    2842                 :       51409 :       if (const region_svalue *ptr_sval = sval->dyn_cast_region_svalue ())
    2843                 :             :         {
    2844                 :         350 :           const region *base_reg = ptr_sval->get_pointee ()->get_base_region ();
    2845                 :         350 :           mark_as_escaped (base_reg);
    2846                 :             :         }
    2847                 :             :     }
    2848                 :      392445 : }
    2849                 :             : 
    2850                 :             : /* Remove all bindings overlapping REG within this store.  */
    2851                 :             : 
    2852                 :             : void
    2853                 :        7139 : store::clobber_region (store_manager *mgr, const region *reg)
    2854                 :             : {
    2855                 :        7139 :   const region *base_reg = reg->get_base_region ();
    2856                 :        7139 :   binding_cluster **slot = m_cluster_map.get (base_reg);
    2857                 :        7139 :   if (!slot)
    2858                 :        1426 :     return;
    2859                 :        5713 :   binding_cluster *cluster = *slot;
    2860                 :        5713 :   cluster->clobber_region (mgr, reg);
    2861                 :        5713 :   if (cluster->redundant_p ())
    2862                 :             :     {
    2863                 :        3624 :       delete cluster;
    2864                 :        3624 :       m_cluster_map.remove (base_reg);
    2865                 :             :     }
    2866                 :             : }
    2867                 :             : 
    2868                 :             : /* Remove any bindings for REG within this store.  */
    2869                 :             : 
    2870                 :             : void
    2871                 :      214487 : store::purge_region (store_manager *mgr, const region *reg)
    2872                 :             : {
    2873                 :      214487 :   const region *base_reg = reg->get_base_region ();
    2874                 :      214487 :   binding_cluster **slot = m_cluster_map.get (base_reg);
    2875                 :      214487 :   if (!slot)
    2876                 :           0 :     return;
    2877                 :      214487 :   binding_cluster *cluster = *slot;
    2878                 :      214487 :   cluster->purge_region (mgr, reg);
    2879                 :      214487 :   if (cluster->redundant_p ())
    2880                 :             :     {
    2881                 :      204696 :       delete cluster;
    2882                 :      204696 :       m_cluster_map.remove (base_reg);
    2883                 :             :     }
    2884                 :             : }
    2885                 :             : 
    2886                 :             : /* Fill REG with SVAL.  */
    2887                 :             : 
    2888                 :             : void
    2889                 :        1722 : store::fill_region (store_manager *mgr, const region *reg, const svalue *sval)
    2890                 :             : {
    2891                 :             :   /* Filling an empty region is a no-op.  */
    2892                 :        1722 :   if (reg->empty_p ())
    2893                 :             :     return;
    2894                 :             : 
    2895                 :        1687 :   const region *base_reg = reg->get_base_region ();
    2896                 :        1687 :   if (base_reg->symbolic_for_unknown_ptr_p ()
    2897                 :        1687 :       || !base_reg->tracked_p ())
    2898                 :           7 :     return;
    2899                 :        1680 :   binding_cluster *cluster = get_or_create_cluster (base_reg);
    2900                 :        1680 :   cluster->fill_region (mgr, reg, sval);
    2901                 :             : }
    2902                 :             : 
    2903                 :             : /* Zero-fill REG.  */
    2904                 :             : 
    2905                 :             : void
    2906                 :         928 : store::zero_fill_region (store_manager *mgr, const region *reg)
    2907                 :             : {
    2908                 :         928 :   region_model_manager *sval_mgr = mgr->get_svalue_manager ();
    2909                 :         928 :   const svalue *zero_sval = sval_mgr->get_or_create_int_cst (char_type_node, 0);
    2910                 :         928 :   fill_region (mgr, reg, zero_sval);
    2911                 :         928 : }
    2912                 :             : 
    2913                 :             : /* Mark REG as having unknown content.  */
    2914                 :             : 
    2915                 :             : void
    2916                 :         354 : store::mark_region_as_unknown (store_manager *mgr, const region *reg,
    2917                 :             :                                uncertainty_t *uncertainty,
    2918                 :             :                                svalue_set *maybe_live_values)
    2919                 :             : {
    2920                 :         354 :   const region *base_reg = reg->get_base_region ();
    2921                 :         354 :   if (base_reg->symbolic_for_unknown_ptr_p ()
    2922                 :         354 :       || !base_reg->tracked_p ())
    2923                 :           0 :     return;
    2924                 :         354 :   binding_cluster *cluster = get_or_create_cluster (base_reg);
    2925                 :         354 :   cluster->mark_region_as_unknown (mgr, reg, reg, uncertainty,
    2926                 :             :                                    maybe_live_values);
    2927                 :             : }
    2928                 :             : 
    2929                 :             : /* Purge state involving SVAL.  */
    2930                 :             : 
    2931                 :             : void
    2932                 :       39987 : store::purge_state_involving (const svalue *sval,
    2933                 :             :                               region_model_manager *sval_mgr)
    2934                 :             : {
    2935                 :       39987 :   auto_vec <const region *> base_regs_to_purge;
    2936                 :     1348729 :   for (auto iter : m_cluster_map)
    2937                 :             :     {
    2938                 :      654371 :       const region *base_reg = iter.first;
    2939                 :      654371 :       if (base_reg->involves_p (sval))
    2940                 :         224 :         base_regs_to_purge.safe_push (base_reg);
    2941                 :             :       else
    2942                 :             :         {
    2943                 :      654147 :           binding_cluster *cluster = iter.second;
    2944                 :      654147 :           cluster->purge_state_involving (sval, sval_mgr);
    2945                 :             :         }
    2946                 :             :     }
    2947                 :             : 
    2948                 :       40659 :   for (auto iter : base_regs_to_purge)
    2949                 :         224 :     purge_cluster (iter);
    2950                 :       39987 : }
    2951                 :             : 
    2952                 :             : /* Get the cluster for BASE_REG, or NULL (const version).  */
    2953                 :             : 
    2954                 :             : const binding_cluster *
    2955                 :     2868914 : store::get_cluster (const region *base_reg) const
    2956                 :             : {
    2957                 :     2868914 :   gcc_assert (base_reg);
    2958                 :     2868914 :   gcc_assert (base_reg->get_base_region () == base_reg);
    2959                 :     5737828 :   if (binding_cluster **slot
    2960                 :     2868914 :         = const_cast <cluster_map_t &> (m_cluster_map).get (base_reg))
    2961                 :     2723281 :     return *slot;
    2962                 :             :   else
    2963                 :             :     return NULL;
    2964                 :             : }
    2965                 :             : 
    2966                 :             : /* Get the cluster for BASE_REG, or NULL (non-const version).  */
    2967                 :             : 
    2968                 :             : binding_cluster *
    2969                 :    10833181 : store::get_cluster (const region *base_reg)
    2970                 :             : {
    2971                 :    10833181 :   gcc_assert (base_reg);
    2972                 :    10833181 :   gcc_assert (base_reg->get_base_region () == base_reg);
    2973                 :    10833181 :   if (binding_cluster **slot = m_cluster_map.get (base_reg))
    2974                 :     9222371 :     return *slot;
    2975                 :             :   else
    2976                 :             :     return NULL;
    2977                 :             : }
    2978                 :             : 
    2979                 :             : /* Get the cluster for BASE_REG, creating it if doesn't already exist.  */
    2980                 :             : 
    2981                 :             : binding_cluster *
    2982                 :     1794384 : store::get_or_create_cluster (const region *base_reg)
    2983                 :             : {
    2984                 :     1794384 :   gcc_assert (base_reg);
    2985                 :     1794384 :   gcc_assert (base_reg->get_base_region () == base_reg);
    2986                 :             : 
    2987                 :             :   /* We shouldn't create clusters for dereferencing an UNKNOWN ptr.  */
    2988                 :     1794384 :   gcc_assert (!base_reg->symbolic_for_unknown_ptr_p ());
    2989                 :             : 
    2990                 :             :   /* We shouldn't create clusters for base regions that aren't trackable.  */
    2991                 :     1794384 :   gcc_assert (base_reg->tracked_p ());
    2992                 :             : 
    2993                 :     1794384 :   if (binding_cluster **slot = m_cluster_map.get (base_reg))
    2994                 :       65854 :     return *slot;
    2995                 :             : 
    2996                 :     1728530 :   binding_cluster *cluster = new binding_cluster (base_reg);
    2997                 :     1728530 :   m_cluster_map.put (base_reg, cluster);
    2998                 :             : 
    2999                 :     1728530 :   return cluster;
    3000                 :             : }
    3001                 :             : 
    3002                 :             : /* Remove any cluster for BASE_REG, for use by
    3003                 :             :    region_model::unbind_region_and_descendents
    3004                 :             :    when popping stack frames and handling deleted heap regions.  */
    3005                 :             : 
    3006                 :             : void
    3007                 :       39459 : store::purge_cluster (const region *base_reg)
    3008                 :             : {
    3009                 :       39459 :   gcc_assert (base_reg->get_base_region () == base_reg);
    3010                 :       39459 :   binding_cluster **slot = m_cluster_map.get (base_reg);
    3011                 :       39459 :   if (!slot)
    3012                 :             :     return;
    3013                 :       39459 :   binding_cluster *cluster = *slot;
    3014                 :       78918 :   delete cluster;
    3015                 :       39459 :   m_cluster_map.remove (base_reg);
    3016                 :             : }
    3017                 :             : 
    3018                 :             : /* Attempt to merge STORE_A and STORE_B into OUT_STORE.
    3019                 :             :    Return true if successful, or false if the stores can't be merged.  */
    3020                 :             : 
    3021                 :             : bool
    3022                 :      181289 : store::can_merge_p (const store *store_a, const store *store_b,
    3023                 :             :                     store *out_store, store_manager *mgr,
    3024                 :             :                     model_merger *merger)
    3025                 :             : {
    3026                 :      181289 :   if (store_a->m_called_unknown_fn || store_b->m_called_unknown_fn)
    3027                 :       71599 :     out_store->m_called_unknown_fn = true;
    3028                 :             : 
    3029                 :             :   /* Get the union of all base regions for STORE_A and STORE_B.  */
    3030                 :      181289 :   hash_set<const region *> base_regions;
    3031                 :     1966212 :   for (cluster_map_t::iterator iter_a = store_a->m_cluster_map.begin ();
    3032                 :     3751135 :        iter_a != store_a->m_cluster_map.end (); ++iter_a)
    3033                 :             :     {
    3034                 :     1784923 :       const region *base_reg_a = (*iter_a).first;
    3035                 :     1784923 :       base_regions.add (base_reg_a);
    3036                 :             :     }
    3037                 :     1883778 :   for (cluster_map_t::iterator iter_b = store_b->m_cluster_map.begin ();
    3038                 :     3586267 :        iter_b != store_b->m_cluster_map.end (); ++iter_b)
    3039                 :             :     {
    3040                 :     1702489 :       const region *base_reg_b = (*iter_b).first;
    3041                 :     1702489 :       base_regions.add (base_reg_b);
    3042                 :             :     }
    3043                 :             : 
    3044                 :             :   /* Sort the base regions before considering them.  This ought not to
    3045                 :             :      affect the results, but can affect which types UNKNOWN_REGIONs are
    3046                 :             :      created for in a run; sorting them thus avoids minor differences
    3047                 :             :      in logfiles.  */
    3048                 :      181289 :   auto_vec<const region *> vec_base_regions (base_regions.elements ());
    3049                 :      181289 :   for (hash_set<const region *>::iterator iter = base_regions.begin ();
    3050                 :     3850607 :        iter != base_regions.end (); ++iter)
    3051                 :     1834659 :     vec_base_regions.quick_push (*iter);
    3052                 :      181289 :   vec_base_regions.qsort (region::cmp_ptr_ptr);
    3053                 :             :   unsigned i;
    3054                 :             :   const region *base_reg;
    3055                 :     1608065 :   FOR_EACH_VEC_ELT (vec_base_regions, i, base_reg)
    3056                 :             :     {
    3057                 :     1347734 :       const binding_cluster *cluster_a = store_a->get_cluster (base_reg);
    3058                 :     1347734 :       const binding_cluster *cluster_b = store_b->get_cluster (base_reg);
    3059                 :             :       /* At least one of cluster_a and cluster_b must be non-NULL.  */
    3060                 :     1347734 :       binding_cluster *out_cluster
    3061                 :     1347734 :         = out_store->get_or_create_cluster (base_reg);
    3062                 :     1347734 :       if (!binding_cluster::can_merge_p (cluster_a, cluster_b,
    3063                 :             :                                          out_cluster, out_store, mgr, merger))
    3064                 :             :         return false;
    3065                 :             :     }
    3066                 :             :   return true;
    3067                 :      181289 : }
    3068                 :             : 
    3069                 :             : /* Mark the cluster for BASE_REG as having escaped.
    3070                 :             :    For use when handling an unrecognized function call, and
    3071                 :             :    for params to "top-level" calls.
    3072                 :             :    Further unknown function calls could touch it, even if the cluster
    3073                 :             :    isn't reachable from args of those calls.  */
    3074                 :             : 
    3075                 :             : void
    3076                 :       48688 : store::mark_as_escaped (const region *base_reg)
    3077                 :             : {
    3078                 :       48688 :   gcc_assert (base_reg);
    3079                 :       48688 :   gcc_assert (base_reg->get_base_region () == base_reg);
    3080                 :             : 
    3081                 :       48688 :   if (base_reg->symbolic_for_unknown_ptr_p ()
    3082                 :       48688 :       || !base_reg->tracked_p ())
    3083                 :        6073 :     return;
    3084                 :             : 
    3085                 :       42615 :   binding_cluster *cluster = get_or_create_cluster (base_reg);
    3086                 :       42615 :   cluster->mark_as_escaped ();
    3087                 :             : }
    3088                 :             : 
    3089                 :             : /* Handle an unknown fncall by updating any clusters that have escaped
    3090                 :             :    (either in this fncall, or in a prior one).  */
    3091                 :             : 
    3092                 :             : void
    3093                 :       22083 : store::on_unknown_fncall (const gcall *call, store_manager *mgr,
    3094                 :             :                           const conjured_purge &p)
    3095                 :             : {
    3096                 :       22083 :   m_called_unknown_fn = true;
    3097                 :             : 
    3098                 :      213181 :   for (cluster_map_t::iterator iter = m_cluster_map.begin ();
    3099                 :      404279 :        iter != m_cluster_map.end (); ++iter)
    3100                 :      191098 :     (*iter).second->on_unknown_fncall (call, mgr, p);
    3101                 :       22083 : }
    3102                 :             : 
    3103                 :             : /* Return true if a non-const pointer to BASE_REG (or something within it)
    3104                 :             :    has escaped to code outside of the TU being analyzed.  */
    3105                 :             : 
    3106                 :             : bool
    3107                 :     9308500 : store::escaped_p (const region *base_reg) const
    3108                 :             : {
    3109                 :     9308500 :   gcc_assert (base_reg);
    3110                 :     9308500 :   gcc_assert (base_reg->get_base_region () == base_reg);
    3111                 :             : 
    3112                 :             :   /* "errno" can always be modified by external code.  */
    3113                 :     9308500 :   if (base_reg->get_kind () == RK_ERRNO)
    3114                 :             :     return true;
    3115                 :             : 
    3116                 :    18357314 :   if (binding_cluster **cluster_slot
    3117                 :     9178657 :       = const_cast <cluster_map_t &>(m_cluster_map).get (base_reg))
    3118                 :     9178657 :     return (*cluster_slot)->escaped_p ();
    3119                 :             :   return false;
    3120                 :             : }
    3121                 :             : 
    3122                 :             : /* Populate OUT_PVS with a list of path_vars for describing SVAL based on
    3123                 :             :    this store, using VISITED to ensure the traversal terminates.  */
    3124                 :             : 
    3125                 :             : void
    3126                 :       16387 : store::get_representative_path_vars (const region_model *model,
    3127                 :             :                                      svalue_set *visited,
    3128                 :             :                                      const svalue *sval,
    3129                 :             :                                      auto_vec<path_var> *out_pvs) const
    3130                 :             : {
    3131                 :       16387 :   gcc_assert (sval);
    3132                 :             : 
    3133                 :             :   /* Find all bindings that reference SVAL.  */
    3134                 :       88151 :   for (cluster_map_t::iterator iter = m_cluster_map.begin ();
    3135                 :      159915 :        iter != m_cluster_map.end (); ++iter)
    3136                 :             :     {
    3137                 :       71764 :       const region *base_reg = (*iter).first;
    3138                 :       71764 :       binding_cluster *cluster = (*iter).second;
    3139                 :       71764 :       cluster->get_representative_path_vars (model, visited, base_reg, sval,
    3140                 :             :                                              out_pvs);
    3141                 :             :     }
    3142                 :             : 
    3143                 :       16387 :   if (const initial_svalue *init_sval = sval->dyn_cast_initial_svalue ())
    3144                 :             :     {
    3145                 :        2944 :       const region *reg = init_sval->get_region ();
    3146                 :        2944 :       if (path_var pv = model->get_representative_path_var (reg,
    3147                 :        2944 :                                                             visited))
    3148                 :        2802 :         out_pvs->safe_push (pv);
    3149                 :             :     }
    3150                 :       16387 : }
    3151                 :             : 
    3152                 :             : /* Remove all bindings overlapping REG within this store, removing
    3153                 :             :    any clusters that become redundant.
    3154                 :             : 
    3155                 :             :    If UNCERTAINTY is non-NULL, use it to record any svalues that
    3156                 :             :    were removed, as being maybe-bound.  */
    3157                 :             : 
    3158                 :             : void
    3159                 :      392091 : store::remove_overlapping_bindings (store_manager *mgr, const region *reg,
    3160                 :             :                                     uncertainty_t *uncertainty)
    3161                 :             : {
    3162                 :      392091 :   const region *base_reg = reg->get_base_region ();
    3163                 :      392091 :   if (binding_cluster **cluster_slot = m_cluster_map.get (base_reg))
    3164                 :             :     {
    3165                 :       61151 :       binding_cluster *cluster = *cluster_slot;
    3166                 :       61151 :       if (reg == base_reg && !escaped_p (base_reg))
    3167                 :             :         {
    3168                 :             :           /* Remove whole cluster.  */
    3169                 :       36585 :           m_cluster_map.remove (base_reg);
    3170                 :       73170 :           delete cluster;
    3171                 :       36585 :           return;
    3172                 :             :         }
    3173                 :             :       /* Pass NULL for the maybe_live_values here, as we don't want to
    3174                 :             :          record the old svalues as being maybe-bound.  */
    3175                 :       24566 :       cluster->remove_overlapping_bindings (mgr, reg, uncertainty, NULL);
    3176                 :             :     }
    3177                 :             : }
    3178                 :             : 
    3179                 :             : /* Subclass of visitor that accumulates a hash_set of the regions that
    3180                 :             :    were visited.  */
    3181                 :             : 
    3182                 :     2441362 : struct region_finder : public visitor
    3183                 :             : {
    3184                 :    21500345 :   void visit_region (const region *reg) final override
    3185                 :             :   {
    3186                 :    21500345 :     m_regs.add (reg);
    3187                 :    21500345 :   }
    3188                 :             : 
    3189                 :             :   hash_set<const region *> m_regs;
    3190                 :             : };
    3191                 :             : 
    3192                 :             : /* Canonicalize this store, to maximize the chance of equality between
    3193                 :             :    instances.  */
    3194                 :             : 
    3195                 :             : void
    3196                 :     1220681 : store::canonicalize (store_manager *mgr)
    3197                 :             : {
    3198                 :             :   /* If we have e.g.:
    3199                 :             :          cluster for: HEAP_ALLOCATED_REGION(543)
    3200                 :             :            ESCAPED
    3201                 :             :            TOUCHED
    3202                 :             :      where the heap region is empty and unreferenced, then purge that
    3203                 :             :      cluster, to avoid unbounded state chains involving these.  */
    3204                 :             : 
    3205                 :             :   /* Find regions that are referenced by bound values in the store.  */
    3206                 :     1220681 :   region_finder s;
    3207                 :     1220681 :   for (cluster_map_t::iterator iter = m_cluster_map.begin ();
    3208                 :    14930491 :        iter != m_cluster_map.end (); ++iter)
    3209                 :             :     {
    3210                 :     6854905 :       binding_cluster *cluster = (*iter).second;
    3211                 :    14076113 :       for (binding_cluster::iterator_t bind_iter = cluster->m_map.begin ();
    3212                 :    28152226 :            bind_iter != cluster->m_map.end (); ++bind_iter)
    3213                 :     7221208 :         (*bind_iter).second->accept (&s);
    3214                 :             :     }
    3215                 :             : 
    3216                 :             :   /* Locate heap-allocated regions that have empty bindings that weren't
    3217                 :             :      found above.  */
    3218                 :     1220681 :   hash_set<const region *> purgeable_regions;
    3219                 :     8075586 :   for (cluster_map_t::iterator iter = m_cluster_map.begin ();
    3220                 :    14930491 :        iter != m_cluster_map.end (); ++iter)
    3221                 :             :     {
    3222                 :     6854905 :       const region *base_reg = (*iter).first;
    3223                 :     6854905 :       binding_cluster *cluster = (*iter).second;
    3224                 :     6854905 :       if (base_reg->get_kind () == RK_HEAP_ALLOCATED)
    3225                 :             :         {
    3226                 :             :           /* Don't purge a heap-allocated region that's been marked as
    3227                 :             :              escaping, since this could be recording that a ptr to it
    3228                 :             :              was written to an unknown symbolic region along this
    3229                 :             :              path, and so we don't know whether it's referenced or
    3230                 :             :              not, and hence should report it as leaking
    3231                 :             :              (PR analyzer/106473).  */
    3232                 :      593709 :           if (cluster->escaped_p ())
    3233                 :      316537 :             continue;
    3234                 :             : 
    3235                 :      277172 :           if (cluster->empty_p ())
    3236                 :         744 :             if (!s.m_regs.contains (base_reg))
    3237                 :           0 :               purgeable_regions.add (base_reg);
    3238                 :             : 
    3239                 :             :           /* Also cover the UNKNOWN case.  */
    3240                 :      277172 :           if (const svalue *sval = cluster->maybe_get_simple_value (mgr))
    3241                 :       52513 :             if (sval->get_kind () == SK_UNKNOWN)
    3242                 :       40340 :               if (!s.m_regs.contains (base_reg))
    3243                 :          44 :                 purgeable_regions.add (base_reg);
    3244                 :             :         }
    3245                 :             :     }
    3246                 :             : 
    3247                 :             :   /* Purge them.  */
    3248                 :     1220725 :   for (hash_set<const region *>::iterator iter = purgeable_regions.begin ();
    3249                 :     2441450 :        iter != purgeable_regions.end (); ++iter)
    3250                 :             :     {
    3251                 :          44 :       const region *base_reg = *iter;
    3252                 :          44 :       purge_cluster (base_reg);
    3253                 :             :     }
    3254                 :     1220681 : }
    3255                 :             : 
    3256                 :             : /* Subroutine for use by exploded_path::feasible_p.
    3257                 :             : 
    3258                 :             :    We need to deal with state differences between:
    3259                 :             :    (a) when the exploded_graph is being initially constructed and
    3260                 :             :    (b) when replaying the state changes along a specific path in
    3261                 :             :    in exploded_path::feasible_p.
    3262                 :             : 
    3263                 :             :    In (a), state merging happens, so when exploring a loop
    3264                 :             :      for (i = 0; i < 1024; i++)
    3265                 :             :    on successive iterations we have i == 0, then i == WIDENING.
    3266                 :             : 
    3267                 :             :    In (b), no state merging happens, so naively replaying the path
    3268                 :             :    that goes twice through the loop then exits it
    3269                 :             :    would lead to i == 0, then i == 1, and then a (i >= 1024) eedge
    3270                 :             :    that exits the loop, which would be found to be infeasible as i == 1,
    3271                 :             :    and the path would be rejected.
    3272                 :             : 
    3273                 :             :    We need to fix up state during replay.  This subroutine is
    3274                 :             :    called whenever we enter a supernode that we've already
    3275                 :             :    visited along this exploded_path, passing in OTHER_STORE
    3276                 :             :    from the destination enode's state.
    3277                 :             : 
    3278                 :             :    Find bindings to widening values in OTHER_STORE.
    3279                 :             :    For all that are found, update the binding in this store to UNKNOWN.  */
    3280                 :             : 
    3281                 :             : void
    3282                 :       11085 : store::loop_replay_fixup (const store *other_store,
    3283                 :             :                           region_model_manager *mgr)
    3284                 :             : {
    3285                 :       11085 :   gcc_assert (other_store);
    3286                 :       11085 :   for (cluster_map_t::iterator iter = other_store->m_cluster_map.begin ();
    3287                 :      186305 :        iter != other_store->m_cluster_map.end (); ++iter)
    3288                 :             :     {
    3289                 :       87610 :       const region *base_reg = (*iter).first;
    3290                 :       87610 :       binding_cluster *cluster = (*iter).second;
    3291                 :      189877 :       for (binding_cluster::iterator_t bind_iter = cluster->m_map.begin ();
    3292                 :      379754 :            bind_iter != cluster->m_map.end (); ++bind_iter)
    3293                 :             :         {
    3294                 :      102267 :           const binding_key *key = (*bind_iter).first;
    3295                 :      102267 :           const svalue *sval = (*bind_iter).second;
    3296                 :      102267 :           if (sval->get_kind () == SK_WIDENING)
    3297                 :             :             {
    3298                 :        2297 :               binding_cluster *this_cluster
    3299                 :        2297 :                 = get_or_create_cluster (base_reg);
    3300                 :        2297 :               const svalue *unknown
    3301                 :        2297 :                 = mgr->get_or_create_unknown_svalue (sval->get_type ());
    3302                 :        2297 :               this_cluster->bind_key (key, unknown);
    3303                 :             :             }
    3304                 :             :         }
    3305                 :             :     }
    3306                 :       11085 : }
    3307                 :             : 
    3308                 :             : /* Use R to replay the bindings from SUMMARY into this object.  */
    3309                 :             : 
    3310                 :             : void
    3311                 :        1951 : store::replay_call_summary (call_summary_replay &r,
    3312                 :             :                             const store &summary)
    3313                 :             : {
    3314                 :        1951 :   if (summary.m_called_unknown_fn)
    3315                 :             :     {
    3316                 :             :       /* A call to an external function occurred in the summary.
    3317                 :             :          Hence we need to invalidate our knownledge of globals,
    3318                 :             :          escaped regions, etc.  */
    3319                 :          82 :       on_unknown_fncall (r.get_call_stmt (),
    3320                 :             :                          r.get_store_manager (),
    3321                 :         164 :                          conjured_purge (r.get_caller_model (),
    3322                 :             :                                          r.get_ctxt ()));
    3323                 :             :     }
    3324                 :             : 
    3325                 :        1951 :   auto_vec<const region *> keys (summary.m_cluster_map.elements ());
    3326                 :       19797 :   for (auto kv : summary.m_cluster_map)
    3327                 :       17846 :     keys.quick_push (kv.first);
    3328                 :        1951 :   keys.qsort (region::cmp_ptr_ptr);
    3329                 :       23631 :   for (auto base_reg : keys)
    3330                 :       17846 :     replay_call_summary_cluster (r, summary, base_reg);
    3331                 :        1951 : }
    3332                 :             : 
    3333                 :             : /* Use R and SUMMARY to replay the bindings in SUMMARY_CLUSTER
    3334                 :             :    into this object.  */
    3335                 :             : 
    3336                 :             : void
    3337                 :       17846 : store::replay_call_summary_cluster (call_summary_replay &r,
    3338                 :             :                                     const store &summary,
    3339                 :             :                                     const region *summary_base_reg)
    3340                 :             : {
    3341                 :       17846 :   const call_details &cd = r.get_call_details ();
    3342                 :       17846 :   region_model_manager *reg_mgr = r.get_manager ();
    3343                 :       17846 :   store_manager *mgr = reg_mgr->get_store_manager ();
    3344                 :       17846 :   const binding_cluster *summary_cluster
    3345                 :       17846 :     = summary.get_cluster (summary_base_reg);
    3346                 :             : 
    3347                 :             :   /* Handle "ESCAPED" and "TOUCHED" flags.  */
    3348                 :       17846 :   if (summary_cluster->escaped_p () || summary_cluster->touched_p ())
    3349                 :       11726 :     if (const region *caller_reg
    3350                 :        5863 :         = r.convert_region_from_summary (summary_base_reg))
    3351                 :             :       {
    3352                 :        5854 :         const region *caller_base_reg = caller_reg->get_base_region ();
    3353                 :        5854 :         if (caller_base_reg->tracked_p ()
    3354                 :        5854 :             && !caller_base_reg->symbolic_for_unknown_ptr_p ())
    3355                 :             :           {
    3356                 :        4570 :             binding_cluster *caller_cluster
    3357                 :        4570 :               = get_or_create_cluster (caller_base_reg);
    3358                 :        4570 :             if (summary_cluster->escaped_p ())
    3359                 :        3532 :               caller_cluster->mark_as_escaped ();
    3360                 :        4570 :             if (summary_cluster->touched_p ())
    3361                 :        2822 :               caller_cluster->m_touched = true;
    3362                 :             :           }
    3363                 :             :       }
    3364                 :             : 
    3365                 :       17846 :   switch (summary_base_reg->get_kind ())
    3366                 :             :     {
    3367                 :             :     /* Top-level regions.  */
    3368                 :           0 :     case RK_FRAME:
    3369                 :           0 :     case RK_GLOBALS:
    3370                 :           0 :     case RK_CODE:
    3371                 :           0 :     case RK_STACK:
    3372                 :           0 :     case RK_HEAP:
    3373                 :           0 :     case RK_THREAD_LOCAL:
    3374                 :           0 :     case RK_ROOT:
    3375                 :             :     /* Child regions.  */
    3376                 :           0 :     case RK_FIELD:
    3377                 :           0 :     case RK_ELEMENT:
    3378                 :           0 :     case RK_OFFSET:
    3379                 :           0 :     case RK_SIZED:
    3380                 :           0 :     case RK_CAST:
    3381                 :           0 :     case RK_BIT_RANGE:
    3382                 :             :     /* Other regions.  */
    3383                 :           0 :     case RK_VAR_ARG:
    3384                 :           0 :     case RK_UNKNOWN:
    3385                 :             :       /* These should never be the base region of a binding cluster.  */
    3386                 :           0 :       gcc_unreachable ();
    3387                 :             :       break;
    3388                 :             : 
    3389                 :             :     case RK_FUNCTION:
    3390                 :             :     case RK_LABEL:
    3391                 :             :     case RK_STRING:
    3392                 :             :       /* These can be marked as escaping.  */
    3393                 :             :       break;
    3394                 :             : 
    3395                 :        4092 :     case RK_SYMBOLIC:
    3396                 :        4092 :       {
    3397                 :        4092 :         const symbolic_region *summary_symbolic_reg
    3398                 :        4092 :           = as_a <const symbolic_region *> (summary_base_reg);
    3399                 :        4092 :         const svalue *summary_ptr_sval = summary_symbolic_reg->get_pointer ();
    3400                 :        4092 :         const svalue *caller_ptr_sval
    3401                 :        4092 :           = r.convert_svalue_from_summary (summary_ptr_sval);
    3402                 :        4092 :         if (!caller_ptr_sval)
    3403                 :             :           return;
    3404                 :        3422 :         const region *caller_dest_reg
    3405                 :        3422 :           = cd.get_model ()->deref_rvalue (caller_ptr_sval,
    3406                 :             :                                            NULL_TREE,
    3407                 :             :                                            cd.get_ctxt ());
    3408                 :        3422 :         const svalue *summary_sval
    3409                 :        3422 :           = summary.get_any_binding (mgr, summary_base_reg);
    3410                 :        3422 :         if (!summary_sval)
    3411                 :             :           return;
    3412                 :        3093 :         const svalue *caller_sval
    3413                 :        3093 :           = r.convert_svalue_from_summary (summary_sval);
    3414                 :        3093 :         if (!caller_sval)
    3415                 :           2 :           caller_sval =
    3416                 :           2 :             reg_mgr->get_or_create_unknown_svalue (summary_sval->get_type ());
    3417                 :        3093 :         set_value (mgr, caller_dest_reg,
    3418                 :             :                    caller_sval, NULL /* uncertainty_t * */);
    3419                 :             :       }
    3420                 :        3093 :       break;
    3421                 :             : 
    3422                 :       13749 :     case RK_HEAP_ALLOCATED:
    3423                 :       13749 :     case RK_DECL:
    3424                 :       13749 :     case RK_ERRNO:
    3425                 :       13749 :     case RK_PRIVATE:
    3426                 :       13749 :       {
    3427                 :       13749 :         const region *caller_dest_reg
    3428                 :       13749 :           = r.convert_region_from_summary (summary_base_reg);
    3429                 :       13749 :         if (!caller_dest_reg)
    3430                 :             :           return;
    3431                 :       13465 :         const svalue *summary_sval
    3432                 :       13465 :           = summary.get_any_binding (mgr, summary_base_reg);
    3433                 :       13465 :         if (!summary_sval)
    3434                 :         263 :           summary_sval = reg_mgr->get_or_create_compound_svalue
    3435                 :         263 :             (summary_base_reg->get_type (),
    3436                 :             :              summary_cluster->get_map ());
    3437                 :       13465 :         const svalue *caller_sval
    3438                 :       13465 :           = r.convert_svalue_from_summary (summary_sval);
    3439                 :       13465 :         if (!caller_sval)
    3440                 :           2 :           caller_sval =
    3441                 :           2 :             reg_mgr->get_or_create_unknown_svalue (summary_sval->get_type ());
    3442                 :       13465 :         set_value (mgr, caller_dest_reg,
    3443                 :             :                    caller_sval, NULL /* uncertainty_t * */);
    3444                 :             :       }
    3445                 :       13465 :       break;
    3446                 :             : 
    3447                 :             :     case RK_ALLOCA:
    3448                 :             :       /* Ignore bindings of alloca regions in the summary.  */
    3449                 :             :       break;
    3450                 :             :     }
    3451                 :             : }
    3452                 :             : 
    3453                 :             : #if CHECKING_P
    3454                 :             : 
    3455                 :             : namespace selftest {
    3456                 :             : 
    3457                 :             : /* Verify that bit_range::intersects_p works as expected.  */
    3458                 :             : 
    3459                 :             : static void
    3460                 :           4 : test_bit_range_intersects_p ()
    3461                 :             : {
    3462                 :           4 :   bit_range b0 (0, 1);
    3463                 :           4 :   bit_range b1 (1, 1);
    3464                 :           4 :   bit_range b2 (2, 1);
    3465                 :           4 :   bit_range b3 (3, 1);
    3466                 :           4 :   bit_range b4 (4, 1);
    3467                 :           4 :   bit_range b5 (5, 1);
    3468                 :           4 :   bit_range b6 (6, 1);
    3469                 :           4 :   bit_range b7 (7, 1);
    3470                 :           4 :   bit_range b1_to_6 (1, 6);
    3471                 :           4 :   bit_range b0_to_7 (0, 8);
    3472                 :           4 :   bit_range b3_to_5 (3, 3);
    3473                 :           4 :   bit_range b6_to_7 (6, 2);
    3474                 :             : 
    3475                 :             :   /* self-intersection is true.  */
    3476                 :           4 :   ASSERT_TRUE (b0.intersects_p (b0));
    3477                 :           4 :   ASSERT_TRUE (b7.intersects_p (b7));
    3478                 :           4 :   ASSERT_TRUE (b1_to_6.intersects_p (b1_to_6));
    3479                 :           4 :   ASSERT_TRUE (b0_to_7.intersects_p (b0_to_7));
    3480                 :             : 
    3481                 :           4 :   ASSERT_FALSE (b0.intersects_p (b1));
    3482                 :           4 :   ASSERT_FALSE (b1.intersects_p (b0));
    3483                 :           4 :   ASSERT_FALSE (b0.intersects_p (b7));
    3484                 :           4 :   ASSERT_FALSE (b7.intersects_p (b0));
    3485                 :             : 
    3486                 :           4 :   ASSERT_TRUE (b0_to_7.intersects_p (b0));
    3487                 :           4 :   ASSERT_TRUE (b0_to_7.intersects_p (b7));
    3488                 :           4 :   ASSERT_TRUE (b0.intersects_p (b0_to_7));
    3489                 :           4 :   ASSERT_TRUE (b7.intersects_p (b0_to_7));
    3490                 :             : 
    3491                 :           4 :   ASSERT_FALSE (b0.intersects_p (b1_to_6));
    3492                 :           4 :   ASSERT_FALSE (b1_to_6.intersects_p (b0));
    3493                 :           4 :   ASSERT_TRUE (b1.intersects_p (b1_to_6));
    3494                 :           4 :   ASSERT_TRUE (b1_to_6.intersects_p (b1));
    3495                 :           4 :   ASSERT_TRUE (b1_to_6.intersects_p (b6));
    3496                 :           4 :   ASSERT_FALSE (b1_to_6.intersects_p (b7));
    3497                 :             : 
    3498                 :           4 :   ASSERT_TRUE (b1_to_6.intersects_p (b0_to_7));
    3499                 :           4 :   ASSERT_TRUE (b0_to_7.intersects_p (b1_to_6));
    3500                 :             : 
    3501                 :           4 :   ASSERT_FALSE (b3_to_5.intersects_p (b6_to_7));
    3502                 :           4 :   ASSERT_FALSE (b6_to_7.intersects_p (b3_to_5));
    3503                 :             : 
    3504                 :           4 :   bit_range r1 (0,0);
    3505                 :           4 :   bit_range r2 (0,0);
    3506                 :           4 :   ASSERT_TRUE (b1_to_6.intersects_p (b0_to_7, &r1, &r2));
    3507                 :           4 :   ASSERT_EQ (r1.get_start_bit_offset (), 0);
    3508                 :           4 :   ASSERT_EQ (r1.m_size_in_bits, 6);
    3509                 :           4 :   ASSERT_EQ (r2.get_start_bit_offset (), 1);
    3510                 :           4 :   ASSERT_EQ (r2.m_size_in_bits, 6);
    3511                 :             : 
    3512                 :           4 :   ASSERT_TRUE (b0_to_7.intersects_p (b1_to_6, &r1, &r2));
    3513                 :           4 :   ASSERT_EQ (r1.get_start_bit_offset (), 1);
    3514                 :           4 :   ASSERT_EQ (r1.m_size_in_bits, 6);
    3515                 :           4 :   ASSERT_EQ (r2.get_start_bit_offset (), 0);
    3516                 :           4 :   ASSERT_EQ (r2.m_size_in_bits, 6);
    3517                 :           4 : }
    3518                 :             : 
    3519                 :             : /* Implementation detail of ASSERT_BIT_RANGE_FROM_MASK_EQ.  */
    3520                 :             : 
    3521                 :             : static void
    3522                 :          76 : assert_bit_range_from_mask_eq (const location &loc,
    3523                 :             :                                unsigned HOST_WIDE_INT mask,
    3524                 :             :                                const bit_range &expected)
    3525                 :             : {
    3526                 :          76 :   bit_range actual (0, 0);
    3527                 :          76 :   bool ok = bit_range::from_mask (mask, &actual);
    3528                 :          76 :   ASSERT_TRUE_AT (loc, ok);
    3529                 :          76 :   ASSERT_EQ_AT (loc, actual, expected);
    3530                 :          76 : }
    3531                 :             : 
    3532                 :             : /* Assert that bit_range::from_mask (MASK) returns true, and writes
    3533                 :             :    out EXPECTED_BIT_RANGE.  */
    3534                 :             : 
    3535                 :             : #define ASSERT_BIT_RANGE_FROM_MASK_EQ(MASK, EXPECTED_BIT_RANGE) \
    3536                 :             :   SELFTEST_BEGIN_STMT                                                   \
    3537                 :             :   assert_bit_range_from_mask_eq (SELFTEST_LOCATION, MASK,               \
    3538                 :             :                                  EXPECTED_BIT_RANGE);                   \
    3539                 :             :   SELFTEST_END_STMT
    3540                 :             : 
    3541                 :             : /* Implementation detail of ASSERT_NO_BIT_RANGE_FROM_MASK.  */
    3542                 :             : 
    3543                 :             : static void
    3544                 :          12 : assert_no_bit_range_from_mask_eq (const location &loc,
    3545                 :             :                                   unsigned HOST_WIDE_INT mask)
    3546                 :             : {
    3547                 :          12 :   bit_range actual (0, 0);
    3548                 :          12 :   bool ok = bit_range::from_mask (mask, &actual);
    3549                 :          12 :   ASSERT_FALSE_AT (loc, ok);
    3550                 :          12 : }
    3551                 :             : 
    3552                 :             : /* Assert that bit_range::from_mask (MASK) returns false.  */
    3553                 :             : 
    3554                 :             : #define ASSERT_NO_BIT_RANGE_FROM_MASK(MASK) \
    3555                 :             :   SELFTEST_BEGIN_STMT                                                   \
    3556                 :             :   assert_no_bit_range_from_mask_eq (SELFTEST_LOCATION, MASK);           \
    3557                 :             :   SELFTEST_END_STMT
    3558                 :             : 
    3559                 :             : /* Verify that bit_range::from_mask works as expected.  */
    3560                 :             : 
    3561                 :             : static void
    3562                 :           4 : test_bit_range_from_mask ()
    3563                 :             : {
    3564                 :             :   /* Should fail on zero.  */
    3565                 :           4 :   ASSERT_NO_BIT_RANGE_FROM_MASK (0);
    3566                 :             : 
    3567                 :             :   /* Verify 1-bit masks.  */
    3568                 :           4 :   ASSERT_BIT_RANGE_FROM_MASK_EQ (1, bit_range (0, 1));
    3569                 :           4 :   ASSERT_BIT_RANGE_FROM_MASK_EQ (2, bit_range (1, 1));
    3570                 :           4 :   ASSERT_BIT_RANGE_FROM_MASK_EQ (4, bit_range (2, 1));
    3571                 :           4 :   ASSERT_BIT_RANGE_FROM_MASK_EQ (8, bit_range (3, 1));
    3572                 :           4 :   ASSERT_BIT_RANGE_FROM_MASK_EQ (16, bit_range (4, 1));
    3573                 :           4 :   ASSERT_BIT_RANGE_FROM_MASK_EQ (32, bit_range (5, 1));
    3574                 :           4 :   ASSERT_BIT_RANGE_FROM_MASK_EQ (64, bit_range (6, 1));
    3575                 :           4 :   ASSERT_BIT_RANGE_FROM_MASK_EQ (128, bit_range (7, 1));
    3576                 :             : 
    3577                 :             :   /* Verify N-bit masks starting at bit 0.  */
    3578                 :           4 :   ASSERT_BIT_RANGE_FROM_MASK_EQ (3, bit_range (0, 2));
    3579                 :           4 :   ASSERT_BIT_RANGE_FROM_MASK_EQ (7, bit_range (0, 3));
    3580                 :           4 :   ASSERT_BIT_RANGE_FROM_MASK_EQ (15, bit_range (0, 4));
    3581                 :           4 :   ASSERT_BIT_RANGE_FROM_MASK_EQ (31, bit_range (0, 5));
    3582                 :           4 :   ASSERT_BIT_RANGE_FROM_MASK_EQ (63, bit_range (0, 6));
    3583                 :           4 :   ASSERT_BIT_RANGE_FROM_MASK_EQ (127, bit_range (0, 7));
    3584                 :           4 :   ASSERT_BIT_RANGE_FROM_MASK_EQ (255, bit_range (0, 8));
    3585                 :           4 :   ASSERT_BIT_RANGE_FROM_MASK_EQ (0xffff, bit_range (0, 16));
    3586                 :             : 
    3587                 :             :   /* Various other tests. */
    3588                 :           4 :   ASSERT_BIT_RANGE_FROM_MASK_EQ (0x30, bit_range (4, 2));
    3589                 :           4 :   ASSERT_BIT_RANGE_FROM_MASK_EQ (0x700, bit_range (8, 3));
    3590                 :           4 :   ASSERT_BIT_RANGE_FROM_MASK_EQ (0x600, bit_range (9, 2));
    3591                 :             : 
    3592                 :             :   /* Multiple ranges of set bits should fail.  */
    3593                 :           4 :   ASSERT_NO_BIT_RANGE_FROM_MASK (0x101);
    3594                 :           4 :   ASSERT_NO_BIT_RANGE_FROM_MASK (0xf0f0f0f0);
    3595                 :           4 : }
    3596                 :             : 
    3597                 :             : /* Implementation detail of ASSERT_OVERLAP.  */
    3598                 :             : 
    3599                 :             : static void
    3600                 :          56 : assert_overlap (const location &loc,
    3601                 :             :                 const concrete_binding *b1,
    3602                 :             :                 const concrete_binding *b2)
    3603                 :             : {
    3604                 :          56 :   ASSERT_TRUE_AT (loc, b1->overlaps_p (*b2));
    3605                 :          56 :   ASSERT_TRUE_AT (loc, b2->overlaps_p (*b1));
    3606                 :          56 : }
    3607                 :             : 
    3608                 :             : /* Implementation detail of ASSERT_DISJOINT.  */
    3609                 :             : 
    3610                 :             : static void
    3611                 :          20 : assert_disjoint (const location &loc,
    3612                 :             :                  const concrete_binding *b1,
    3613                 :             :                  const concrete_binding *b2)
    3614                 :             : {
    3615                 :          20 :   ASSERT_FALSE_AT (loc, b1->overlaps_p (*b2));
    3616                 :          20 :   ASSERT_FALSE_AT (loc, b2->overlaps_p (*b1));
    3617                 :          20 : }
    3618                 :             : 
    3619                 :             : /* Assert that B1 and B2 overlap, checking both ways.  */
    3620                 :             : 
    3621                 :             : #define ASSERT_OVERLAP(B1, B2) \
    3622                 :             :   SELFTEST_BEGIN_STMT                           \
    3623                 :             :   assert_overlap (SELFTEST_LOCATION, B1, B2);   \
    3624                 :             :   SELFTEST_END_STMT
    3625                 :             : 
    3626                 :             : /* Assert that B1 and B2 do not overlap, checking both ways.  */
    3627                 :             : 
    3628                 :             : #define ASSERT_DISJOINT(B1, B2) \
    3629                 :             :   SELFTEST_BEGIN_STMT                           \
    3630                 :             :   assert_disjoint (SELFTEST_LOCATION, B1, B2);  \
    3631                 :             :   SELFTEST_END_STMT
    3632                 :             : 
    3633                 :             : /* Verify that concrete_binding::overlaps_p works as expected.  */
    3634                 :             : 
    3635                 :             : static void
    3636                 :           4 : test_binding_key_overlap ()
    3637                 :             : {
    3638                 :           4 :   store_manager mgr (NULL);
    3639                 :             : 
    3640                 :             :   /* Various 8-bit bindings.  */
    3641                 :           4 :   const concrete_binding *cb_0_7 = mgr.get_concrete_binding (0, 8);
    3642                 :           4 :   const concrete_binding *cb_8_15 = mgr.get_concrete_binding (8, 8);
    3643                 :           4 :   const concrete_binding *cb_16_23 = mgr.get_concrete_binding (16, 8);
    3644                 :           4 :   const concrete_binding *cb_24_31 = mgr.get_concrete_binding (24, 8);
    3645                 :             : 
    3646                 :             :   /* 16-bit bindings.  */
    3647                 :           4 :   const concrete_binding *cb_0_15 = mgr.get_concrete_binding (0, 16);
    3648                 :           4 :   const concrete_binding *cb_8_23 = mgr.get_concrete_binding (8, 16);
    3649                 :           4 :   const concrete_binding *cb_16_31 = mgr.get_concrete_binding (16, 16);
    3650                 :             : 
    3651                 :             :   /* 32-bit binding.  */
    3652                 :           4 :   const concrete_binding *cb_0_31 = mgr.get_concrete_binding (0, 32);
    3653                 :             : 
    3654                 :             :   /* Everything should self-overlap.  */
    3655                 :           4 :   ASSERT_OVERLAP (cb_0_7, cb_0_7);
    3656                 :           4 :   ASSERT_OVERLAP (cb_8_15, cb_8_15);
    3657                 :           4 :   ASSERT_OVERLAP (cb_16_23, cb_16_23);
    3658                 :           4 :   ASSERT_OVERLAP (cb_24_31, cb_24_31);
    3659                 :           4 :   ASSERT_OVERLAP (cb_0_15, cb_0_15);
    3660                 :           4 :   ASSERT_OVERLAP (cb_8_23, cb_8_23);
    3661                 :           4 :   ASSERT_OVERLAP (cb_16_31, cb_16_31);
    3662                 :           4 :   ASSERT_OVERLAP (cb_0_31, cb_0_31);
    3663                 :             : 
    3664                 :             :   /* Verify the 8-bit bindings that don't overlap each other.  */
    3665                 :           4 :   ASSERT_DISJOINT (cb_0_7, cb_8_15);
    3666                 :           4 :   ASSERT_DISJOINT (cb_8_15, cb_16_23);
    3667                 :             : 
    3668                 :             :   /* Check for overlap of differently-sized bindings.  */
    3669                 :           4 :   ASSERT_OVERLAP (cb_0_7, cb_0_31);
    3670                 :             :   /* ...and with differing start points.  */
    3671                 :           4 :   ASSERT_OVERLAP (cb_8_15, cb_0_31);
    3672                 :           4 :   ASSERT_DISJOINT (cb_8_15, cb_16_31);
    3673                 :           4 :   ASSERT_OVERLAP (cb_16_23, cb_0_31);
    3674                 :           4 :   ASSERT_OVERLAP (cb_16_31, cb_0_31);
    3675                 :             : 
    3676                 :           4 :   ASSERT_DISJOINT (cb_0_7, cb_8_23);
    3677                 :           4 :   ASSERT_OVERLAP (cb_8_23, cb_16_23);
    3678                 :           4 :   ASSERT_OVERLAP (cb_8_23, cb_16_31);
    3679                 :           4 :   ASSERT_DISJOINT (cb_8_23, cb_24_31);
    3680                 :           4 : }
    3681                 :             : 
    3682                 :             : /* Run all of the selftests within this file.  */
    3683                 :             : 
    3684                 :             : void
    3685                 :           4 : analyzer_store_cc_tests ()
    3686                 :             : {
    3687                 :           4 :   test_bit_range_intersects_p ();
    3688                 :           4 :   test_bit_range_from_mask ();
    3689                 :           4 :   test_binding_key_overlap ();
    3690                 :           4 : }
    3691                 :             : 
    3692                 :             : } // namespace selftest
    3693                 :             : 
    3694                 :             : #endif /* CHECKING_P */
    3695                 :             : 
    3696                 :             : } // namespace ana
    3697                 :             : 
    3698                 :             : #endif /* #if ENABLE_ANALYZER */
        

Generated by: LCOV version 2.1-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.