GCC Middle and Back End API Reference
store.h
Go to the documentation of this file.
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
5This file is part of GCC.
6
7GCC is free software; you can redistribute it and/or modify it
8under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 3, or (at your option)
10any later version.
11
12GCC is distributed in the hope that it will be useful, but
13WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with GCC; see the file COPYING3. If not see
19<http://www.gnu.org/licenses/>. */
20
21#ifndef GCC_ANALYZER_STORE_H
22#define GCC_ANALYZER_STORE_H
23
24/* Implementation of the region-based ternary model described in:
25 "A Memory Model for Static Analysis of C Programs"
26 (Zhongxing Xu, Ted Kremenek, and Jian Zhang)
27 http://lcs.ios.ac.cn/~xuzb/canalyze/memmodel.pdf */
28
29/* The store models memory as a collection of "clusters", where regions
30 are partitioned into clusters via their base region.
31
32 For example, given:
33 int a, b, c;
34 struct coord { double x; double y; } verts[3];
35 then "verts[0].y" and "verts[1].x" both have "verts" as their base region.
36 Each of a, b, c, and verts will have their own clusters, so that we
37 know that writes to e.g. "verts[1].x".don't affect e.g. "a".
38
39 Within each cluster we store a map of bindings to values, where the
40 binding keys can be either concrete or symbolic.
41
42 Concrete bindings affect a specific range of bits relative to the start
43 of the base region of the cluster, whereas symbolic bindings affect
44 a specific subregion within the cluster.
45
46 Consider (from the symbolic-1.c testcase):
47
48 char arr[1024];
49 arr[2] = a; (1)
50 arr[3] = b; (2)
51 After (1) and (2), the cluster for "arr" has concrete bindings
52 for bits 16-23 and for bits 24-31, with svalues "INIT_VAL(a)"
53 and "INIT_VAL(b)" respectively:
54 cluster: {bits 16-23: "INIT_VAL(a)",
55 bits 24-31: "INIT_VAL(b)";
56 flags: {}}
57 Attempting to query unbound subregions e.g. arr[4] will
58 return "UNINITIALIZED".
59 "a" and "b" are each in their own clusters, with no explicit
60 bindings, and thus implicitly have value INIT_VAL(a) and INIT_VAL(b).
61
62 arr[3] = c; (3)
63 After (3), the concrete binding for bits 24-31 is replaced with the
64 svalue "INIT_VAL(c)":
65 cluster: {bits 16-23: "INIT_VAL(a)", (from before)
66 bits 24-31: "INIT_VAL(c)"; (updated)
67 flags: {}}
68
69 arr[i] = d; (4)
70 After (4), we lose the concrete bindings and replace them with a
71 symbolic binding for "arr[i]", with svalue "INIT_VAL(d)". We also
72 mark the cluster as having been "symbolically touched": future
73 attempts to query the values of subregions other than "arr[i]",
74 such as "arr[3]" are "UNKNOWN", since we don't know if the write
75 to arr[i] affected them.
76 cluster: {symbolic_key(arr[i]): "INIT_VAL(d)";
77 flags: {TOUCHED}}
78
79 arr[j] = e; (5)
80 After (5), we lose the symbolic binding for "arr[i]" since we could
81 have overwritten it, and add a symbolic binding for "arr[j]".
82 cluster: {symbolic_key(arr[j]): "INIT_VAL(d)"; (different symbolic
83 flags: {TOUCHED}} binding)
84
85 arr[3] = f; (6)
86 After (6), we lose the symbolic binding for "arr[j]" since we could
87 have overwritten it, and gain a concrete binding for bits 24-31
88 again, this time with svalue "INIT_VAL(e)":
89 cluster: {bits 24-31: "INIT_VAL(d)";
90 flags: {TOUCHED}}
91 The cluster is still flagged as touched, so that we know that
92 accesses to other elements are "UNKNOWN" rather than
93 "UNINITIALIZED".
94
95 Handling symbolic regions requires us to handle aliasing.
96
97 In the first example above, each of a, b, c and verts are non-symbolic
98 base regions and so their clusters are "concrete clusters", whereas given:
99 struct coord *p, *q;
100 then "*p" and "*q" are symbolic base regions, and thus "*p" and "*q"
101 have "symbolic clusters".
102
103 In the above, "verts[i].x" will have a symbolic *binding* within a
104 concrete cluster for "verts", whereas "*p" is a symbolic *cluster*.
105
106 Writes to concrete clusters can't affect other concrete clusters,
107 but can affect symbolic clusters; e.g. after:
108 verts[0].x = 42;
109 we bind 42 in the cluster for "verts", but the clusters for "b" and "c"
110 can't be affected. Any symbolic clusters for *p and for *q can be
111 affected, *p and *q could alias verts.
112
113 Writes to a symbolic cluster can affect other clusters, both
114 concrete and symbolic; e.g. after:
115 p->x = 17;
116 we bind 17 within the cluster for "*p". The concrete clusters for a, b,
117 c, and verts could be affected, depending on whether *p aliases them.
118 Similarly, the symbolic cluster to *q could be affected. */
119
120namespace ana {
121
122/* A class for keeping track of aspects of a program_state that we don't
123 know about, to avoid false positives about leaks.
124
125 Consider:
126
127 p->field = malloc (1024);
128 q->field = NULL;
129
130 where we don't know whether or not p and q point to the same memory,
131 and:
132
133 p->field = malloc (1024);
134 unknown_fn (p);
135
136 In both cases, the svalue for the address of the allocated buffer
137 goes from being bound to p->field to not having anything explicitly bound
138 to it.
139
140 Given that we conservatively discard bindings due to possible aliasing or
141 calls to unknown function, the store loses references to svalues,
142 but these svalues could still be live. We don't want to warn about
143 them leaking - they're effectively in a "maybe live" state.
144
145 This "maybe live" information is somewhat transient.
146
147 We don't want to store this "maybe live" information in the program_state,
148 region_model, or store, since we don't want to bloat these objects (and
149 potentially bloat the exploded_graph with more nodes).
150 However, we can't store it in the region_model_context, as these context
151 objects sometimes don't last long enough to be around when comparing the
152 old vs the new state.
153
154 This class is a way to track a set of such svalues, so that we can
155 temporarily capture that they are in a "maybe live" state whilst
156 comparing old and new states. */
157
159{
160public:
162
163 void on_maybe_bound_sval (const svalue *sval)
164 {
166 }
171
172 bool unknown_sm_state_p (const svalue *sval)
173 {
174 return (m_maybe_bound_svals.contains (sval)
176 }
177
178 void dump_to_pp (pretty_printer *pp, bool simple) const;
179 void dump (bool simple) const;
180
182 {
183 return m_maybe_bound_svals.begin ();
184 }
186 {
187 return m_maybe_bound_svals.end ();
188 }
189
190private:
191
192 /* svalues that might or might not still be bound. */
194
195 /* svalues that have mutable sm-state at unknown calls. */
197};
198
199class byte_range;
200class concrete_binding;
201class symbolic_binding;
202
203/* Abstract base class for describing ranges of bits within a binding_map
204 that can have svalues bound to them. */
205
207{
208public:
209 virtual ~binding_key () {}
210 virtual bool concrete_p () const = 0;
211 bool symbolic_p () const { return !concrete_p (); }
212
213 static const binding_key *make (store_manager *mgr, const region *r);
214
215 virtual void dump_to_pp (pretty_printer *pp, bool simple) const = 0;
216 void dump (bool simple) const;
217 label_text get_desc (bool simple=true) const;
218
219 static int cmp_ptrs (const void *, const void *);
220 static int cmp (const binding_key *, const binding_key *);
221
223 { return NULL; }
225 { return NULL; }
226};
227
228/* A concrete range of bits. */
229
231{
236
237 void dump_to_pp (pretty_printer *pp) const;
238 void dump () const;
239
241
242 bool empty_p () const
243 {
244 return m_size_in_bits == 0;
245 }
246
248 {
249 return m_start_bit_offset;
250 }
256 {
257 gcc_assert (!empty_p ());
258 return get_next_bit_offset () - 1;
259 }
260
262 {
263 return (offset >= get_start_bit_offset ()
265 }
266
267 bool contains_p (const bit_range &other, bit_range *out) const;
268
269 bool operator== (const bit_range &other) const
270 {
272 && m_size_in_bits == other.m_size_in_bits);
273 }
274
275 bool intersects_p (const bit_range &other) const
276 {
277 return (get_start_bit_offset () < other.get_next_bit_offset ()
279 }
280 bool intersects_p (const bit_range &other,
282 bool intersects_p (const bit_range &other,
284 bit_range *out_other) const;
285
286 bool exceeds_p (const bit_range &other,
288
291
292 static int cmp (const bit_range &br1, const bit_range &br2);
293
295
296 static bool from_mask (unsigned HOST_WIDE_INT mask, bit_range *out);
297
298 bool as_byte_range (byte_range *out) const;
299
302};
303
304/* A concrete range of bytes. */
305
307{
312
313 void dump_to_pp (pretty_printer *pp) const;
314 void dump () const;
315
317
318 bool empty_p () const
319 {
320 return m_size_in_bytes == 0;
321 }
322
324 {
325 return (offset >= get_start_byte_offset ()
327 }
328 bool contains_p (const byte_range &other, byte_range *out) const;
329
330 bool operator== (const byte_range &other) const
331 {
333 && m_size_in_bytes == other.m_size_in_bytes);
334 }
335
349
355
364
365 static int cmp (const byte_range &br1, const byte_range &br2);
366
369};
370
371/* Concrete subclass of binding_key, for describing a non-empty
372 concrete range of bits within the binding_map (e.g. "bits 8-15"). */
373
375{
376public:
377 /* This class is its own key for the purposes of consolidation. */
379
385 bool concrete_p () const final override { return true; }
386
388 {
391 hstate.add_wide_int (m_bit_range.m_size_in_bits);
392 return hstate.end ();
393 }
394 bool operator== (const concrete_binding &other) const
395 {
396 return m_bit_range == other.m_bit_range;
397 }
398
399 void dump_to_pp (pretty_printer *pp, bool simple) const final override;
400
402 { return this; }
403
404 const bit_range &get_bit_range () const { return m_bit_range; }
405 bool get_byte_range (byte_range *out) const;
406
412 {
414 }
415 /* Return the next bit offset after the end of this binding. */
420
421 bool overlaps_p (const concrete_binding &other) const;
422
423 static int cmp_ptr_ptr (const void *, const void *);
424
427 bool is_deleted () const { return m_bit_range.m_size_in_bits == -1; }
428 bool is_empty () const { return m_bit_range.m_size_in_bits == -2; }
429
430private:
432};
433
434} // namespace ana
435
436template <>
437template <>
438inline bool
440{
441 return key->concrete_p ();
442}
443
444template <> struct default_hash_traits<ana::concrete_binding>
445: public member_function_hash_traits<ana::concrete_binding>
446{
447 static const bool empty_zero_p = false;
448};
449
450namespace ana {
451
452/* Concrete subclass of binding_key, for describing a symbolic set of
453 bits within the binding_map in terms of a region (e.g. "arr[i]"). */
454
456{
457public:
458 /* This class is its own key for the purposes of consolidation. */
460
462 bool concrete_p () const final override { return false; }
463
465 {
466 return (intptr_t)m_region;
467 }
468 bool operator== (const symbolic_binding &other) const
469 {
470 return m_region == other.m_region;
471 }
472
473 void dump_to_pp (pretty_printer *pp, bool simple) const final override;
474
476 { return this; }
477
478 const region *get_region () const { return m_region; }
479
480 static int cmp_ptr_ptr (const void *, const void *);
481
482 void mark_deleted () { m_region = reinterpret_cast<const region *> (1); }
483 void mark_empty () { m_region = NULL; }
484 bool is_deleted () const
485 { return m_region == reinterpret_cast<const region *> (1); }
486 bool is_empty () const { return m_region == NULL; }
487
488private:
490};
491
492} // namespace ana
493
494template <> struct default_hash_traits<ana::symbolic_binding>
495: public member_function_hash_traits<ana::symbolic_binding>
496{
497 static const bool empty_zero_p = true;
498};
499
500namespace ana {
501
502/* A mapping from binding_keys to svalues, for use by binding_cluster
503 and compound_svalue. */
504
506{
507public:
508 typedef hash_map <const binding_key *, const svalue *> map_t;
509 typedef map_t::iterator iterator_t;
510
512 binding_map (const binding_map &other);
514
515 bool operator== (const binding_map &other) const;
516 bool operator!= (const binding_map &other) const
517 {
518 return !(*this == other);
519 }
520
521 hashval_t hash () const;
522
523 const svalue *get (const binding_key *key) const
524 {
525 const svalue **slot = const_cast<map_t &> (m_map).get (key);
526 if (slot)
527 return *slot;
528 else
529 return NULL;
530 }
531 bool put (const binding_key *k, const svalue *v)
532 {
533 gcc_assert (v);
534 return m_map.put (k, v);
535 }
536
537 void remove (const binding_key *k) { m_map.remove (k); }
538 void empty () { m_map.empty (); }
539
540 iterator_t begin () const { return m_map.begin (); }
541 iterator_t end () const { return m_map.end (); }
542 size_t elements () const { return m_map.elements (); }
543
544 void dump_to_pp (pretty_printer *pp, bool simple, bool multiline) const;
545 void dump (bool simple) const;
546
548
551
552 static int cmp (const binding_map &map1, const binding_map &map2);
553
555 const binding_key *drop_key,
558 bool always_overlap);
559
560private:
565 tree min_index, tree max_index,
566 tree val);
569 tree index, tree val);
570
572};
573
574/* Concept: BindingVisitor, for use by binding_cluster::for_each_binding
575 and store::for_each_binding.
576
577 Should implement:
578 void on_binding (const binding_key *key, const svalue *&sval);
579*/
580
581/* All of the bindings within a store for regions that share the same
582 base region. */
583
585{
586public:
587 friend class store;
588
589 typedef hash_map <const binding_key *, const svalue *> map_t;
590 typedef map_t::iterator iterator_t;
591
595
596 bool operator== (const binding_cluster &other) const;
597 bool operator!= (const binding_cluster &other) const
598 {
599 return !(*this == other);
600 }
601
602 hashval_t hash () const;
603
604 bool symbolic_p () const;
605
606 const region *get_base_region () const { return m_base_region; }
607
608 void dump_to_pp (pretty_printer *pp, bool simple, bool multiline) const;
609 void dump (bool simple) const;
610
611 void validate () const;
612
614
615 void bind (store_manager *mgr, const region *, const svalue *);
616
619 void fill_region (store_manager *mgr, const region *reg, const svalue *sval);
622 const region *reg_to_bind,
623 const region *reg_for_overlap,
626 void purge_state_involving (const svalue *sval,
628
629 const svalue *get_binding (store_manager *mgr, const region *reg) const;
631 const region *reg) const;
633 const region *reg) const;
635 const region *reg) const;
636
640
641 template <typename T>
642 void for_each_value (void (*cb) (const svalue *sval, T user_data),
643 T user_data) const
644 {
645 for (map_t::iterator iter = m_map.begin (); iter != m_map.end (); ++iter)
646 cb ((*iter).second, user_data);
647 }
648
658
661 const conjured_purge &p);
662 void on_asm (const gasm *stmt, store_manager *mgr,
663 const conjured_purge &p);
664
665 bool escaped_p () const;
666 bool touched_p () const { return m_touched; }
667
668 bool redundant_p () const;
669 bool empty_p () const { return m_map.elements () == 0; }
670
673 const region *base_reg,
674 const svalue *sval,
676
678
679 template <typename BindingVisitor>
681 {
682 for (map_t::iterator iter = m_map.begin (); iter != m_map.end (); ++iter)
683 {
684 const binding_key *key = (*iter).first;
685 const svalue *&sval = (*iter).second;
686 v.on_binding (key, sval);
687 }
688 }
689
690 iterator_t begin () const { return m_map.begin (); }
691 iterator_t end () const { return m_map.end (); }
692
693 const binding_map &get_map () const { return m_map; }
694
695private:
696 const svalue *get_any_value (const binding_key *key) const;
698 const region *reg,
700 void bind_key (const binding_key *key, const svalue *sval);
701
703
705
706 /* Has a pointer to this cluster "escaped" into a part of the program
707 we don't know about (via a call to a function with an unknown body,
708 or by being passed in as a pointer param of a "top-level" function call).
709 Such regions could be overwritten when other such functions are called,
710 even if the region is no longer reachable by pointers that we are
711 tracking. */
713
714 /* Has this cluster been written to via a symbolic binding?
715 If so, then we don't know anything about unbound subregions,
716 so we can't use initial_svalue, treat them as uninitialized, or
717 inherit values from a parent region. */
719};
720
721/* The mapping from regions to svalues.
722 This is actually expressed by subdividing into clusters, to better
723 handle aliasing. */
724
725class store
726{
727public:
728 typedef hash_map <const region *, binding_cluster *> cluster_map_t;
729
731 store (const store &other);
733
734 store &operator= (const store &other);
735
736 bool operator== (const store &other) const;
737 bool operator!= (const store &other) const
738 {
739 return !(*this == other);
740 }
741
742 hashval_t hash () const;
743
745 store_manager *mgr) const;
746 void dump (bool simple) const;
747 void summarize_to_pp (pretty_printer *pp, bool simple) const;
748
749 void validate () const;
750
752
753 const svalue *get_any_binding (store_manager *mgr, const region *reg) const;
754
755 bool called_unknown_fn_p () const { return m_called_unknown_fn; }
756
758 const svalue *rhs_sval,
762 void fill_region (store_manager *mgr, const region *reg, const svalue *sval);
767 void purge_state_involving (const svalue *sval,
769
774
775 template <typename T>
776 void for_each_cluster (void (*cb) (const region *base_reg, T user_data),
777 T user_data) const
778 {
779 for (cluster_map_t::iterator iter = m_cluster_map.begin ();
780 iter != m_cluster_map.end (); ++iter)
781 cb ((*iter).first, user_data);
782 }
783
784 static bool can_merge_p (const store *store_a, const store *store_b,
787
790 const conjured_purge &p);
791 bool escaped_p (const region *reg) const;
792
795 const svalue *sval,
797
798 cluster_map_t::iterator begin () const { return m_cluster_map.begin (); }
799 cluster_map_t::iterator end () const { return m_cluster_map.end (); }
800
802 const region *base_reg_b) const;
803
804 template <typename BindingVisitor>
806 {
807 for (cluster_map_t::iterator iter = m_cluster_map.begin ();
808 iter != m_cluster_map.end (); ++iter)
809 (*iter).second->for_each_binding (v);
810 }
811
815
817 const store &summary);
819 const store &summary,
820 const region *base_reg);
822
823private:
827 const region *base_reg_b) const;
828
830
831 /* If this is true, then unknown code has been called, and so
832 any global variable that isn't currently modelled by the store
833 has unknown state, rather than being in an "initial state".
834 This is to avoid having to mark (and thus explicitly track)
835 every global when an unknown function is called; instead, they
836 can be tracked implicitly. */
838};
839
840/* A class responsible for owning and consolidating binding keys
841 (both concrete and symbolic).
842 Key instances are immutable as far as clients are concerned, so they
843 are provided as "const" ptrs. */
844
883
884} // namespace ana
885
886#endif /* GCC_ANALYZER_STORE_H */
Definition store.h:585
binding_map m_map
Definition store.h:704
void bind(store_manager *mgr, const region *, const svalue *)
void dump(bool simple) const
void fill_region(store_manager *mgr, const region *reg, const svalue *sval)
void on_asm(const gasm *stmt, store_manager *mgr, const conjured_purge &p)
const svalue * get_binding_recursive(store_manager *mgr, const region *reg) const
map_t::iterator iterator_t
Definition store.h:590
void for_each_value(void(*cb)(const svalue *sval, T user_data), T user_data) const
Definition store.h:642
void bind_compound_sval(store_manager *mgr, const region *reg, const compound_svalue *compound_sval)
bool m_escaped
Definition store.h:712
void mark_region_as_unknown(store_manager *mgr, const region *reg_to_bind, const region *reg_for_overlap, uncertainty_t *uncertainty, svalue_set *maybe_live_values)
binding_cluster(const binding_cluster &other)
hashval_t hash() const
void validate() const
bool symbolic_p() const
void purge_region(store_manager *mgr, const region *reg)
void clobber_region(store_manager *mgr, const region *reg)
void make_unknown_relative_to(const binding_cluster *other_cluster, store *out_store, store_manager *mgr)
void on_unknown_fncall(const gcall *call, store_manager *mgr, const conjured_purge &p)
bool operator==(const binding_cluster &other) const
void bind_key(const binding_key *key, const svalue *sval)
json::object * to_json() const
bool empty_p() const
Definition store.h:669
const svalue * get_any_binding(store_manager *mgr, const region *reg) const
iterator_t end() const
Definition store.h:691
bool operator!=(const binding_cluster &other) const
Definition store.h:597
hash_map< const binding_key *, const svalue * > map_t
Definition store.h:589
binding_cluster & operator=(const binding_cluster &other)
void purge_state_involving(const svalue *sval, region_model_manager *sval_mgr)
const svalue * get_any_value(const binding_key *key) const
void dump_to_pp(pretty_printer *pp, bool simple, bool multiline) const
const region * get_base_region() const
Definition store.h:606
void get_representative_path_vars(const region_model *model, svalue_set *visited, const region *base_reg, const svalue *sval, auto_vec< path_var > *out_pvs) const
const region * m_base_region
Definition store.h:702
const svalue * maybe_get_compound_binding(store_manager *mgr, const region *reg) const
bool touched_p() const
Definition store.h:666
const binding_map & get_map() const
Definition store.h:693
void for_each_binding(BindingVisitor &v) const
Definition store.h:680
bool escaped_p() const
iterator_t begin() const
Definition store.h:690
void remove_overlapping_bindings(store_manager *mgr, const region *reg, uncertainty_t *uncertainty, svalue_set *maybe_live_values)
void zero_fill_region(store_manager *mgr, const region *reg)
const svalue * get_binding(store_manager *mgr, const region *reg) const
static bool can_merge_p(const binding_cluster *cluster_a, const binding_cluster *cluster_b, binding_cluster *out_cluster, store *out_store, store_manager *mgr, model_merger *merger)
bool redundant_p() const
bool m_touched
Definition store.h:718
const svalue * maybe_get_simple_value(store_manager *mgr) const
binding_cluster(const region *base_region)
Definition store.h:207
void dump(bool simple) const
static const binding_key * make(store_manager *mgr, const region *r)
static int cmp_ptrs(const void *, const void *)
virtual const symbolic_binding * dyn_cast_symbolic_binding() const
Definition store.h:224
virtual bool concrete_p() const =0
virtual void dump_to_pp(pretty_printer *pp, bool simple) const =0
virtual ~binding_key()
Definition store.h:209
bool symbolic_p() const
Definition store.h:211
static int cmp(const binding_key *, const binding_key *)
label_text get_desc(bool simple=true) const
virtual const concrete_binding * dyn_cast_concrete_binding() const
Definition store.h:222
Definition store.h:506
size_t elements() const
Definition store.h:542
binding_map & operator=(const binding_map &other)
map_t m_map
Definition store.h:571
static int cmp(const binding_map &map1, const binding_map &map2)
iterator_t begin() const
Definition store.h:540
void dump_to_pp(pretty_printer *pp, bool simple, bool multiline) const
void get_overlapping_bindings(const binding_key *key, auto_vec< const binding_key * > *out)
bool operator==(const binding_map &other) const
hash_map< const binding_key *, const svalue * > map_t
Definition store.h:508
bool apply_ctor_pair_to_child_region(const region *parent_reg, region_model_manager *mgr, tree index, tree val)
void dump(bool simple) const
hashval_t hash() const
void empty()
Definition store.h:538
const svalue * get(const binding_key *key) const
Definition store.h:523
bool apply_ctor_val_to_range(const region *parent_reg, region_model_manager *mgr, tree min_index, tree max_index, tree val)
bool apply_ctor_to_region(const region *parent_reg, tree ctor, region_model_manager *mgr)
bool operator!=(const binding_map &other) const
Definition store.h:516
void remove_overlapping_bindings(store_manager *mgr, const binding_key *drop_key, uncertainty_t *uncertainty, svalue_set *maybe_live_values, bool always_overlap)
json::object * to_json() const
binding_map()
Definition store.h:511
void remove(const binding_key *k)
Definition store.h:537
bool put(const binding_key *k, const svalue *v)
Definition store.h:531
iterator_t end() const
Definition store.h:541
map_t::iterator iterator_t
Definition store.h:509
binding_map(const binding_map &other)
Definition call-summary.h:68
Definition svalue.h:1276
Definition store.h:375
bit_size_t get_size_in_bits() const
Definition store.h:411
bool get_byte_range(byte_range *out) const
void mark_empty()
Definition store.h:426
concrete_binding(bit_offset_t start_bit_offset, bit_size_t size_in_bits)
Definition store.h:380
concrete_binding key_t
Definition store.h:378
const bit_range & get_bit_range() const
Definition store.h:404
void dump_to_pp(pretty_printer *pp, bool simple) const final override
bit_offset_t get_next_bit_offset() const
Definition store.h:416
bool operator==(const concrete_binding &other) const
Definition store.h:394
bool concrete_p() const final override
Definition store.h:385
bit_range m_bit_range
Definition store.h:431
bool is_empty() const
Definition store.h:428
bit_offset_t get_start_bit_offset() const
Definition store.h:407
bool is_deleted() const
Definition store.h:427
void mark_deleted()
Definition store.h:425
bool overlaps_p(const concrete_binding &other) const
hashval_t hash() const
Definition store.h:387
const concrete_binding * dyn_cast_concrete_binding() const final override
Definition store.h:401
static int cmp_ptr_ptr(const void *, const void *)
Definition svalue.h:1370
Definition analyzer-logging.h:34
Definition region-model-manager.h:32
Definition region-model.h:258
Definition region.h:125
Definition store.h:846
consolidation_map< symbolic_binding > m_symbolic_binding_key_mgr
Definition store.h:881
const concrete_binding * get_concrete_binding(const bit_range &bits)
Definition store.h:857
const concrete_binding * get_concrete_binding(bit_offset_t start_bit_offset, bit_offset_t size_in_bits)
const concrete_binding * get_concrete_binding(const byte_range &bytes)
Definition store.h:863
region_model_manager * m_mgr
Definition store.h:879
logger * get_logger() const
region_model_manager * get_svalue_manager() const
Definition store.h:871
store_manager(region_model_manager *mgr)
Definition store.h:848
consolidation_map< concrete_binding > m_concrete_binding_key_mgr
Definition store.h:880
void log_stats(logger *logger, bool show_objs) const
const symbolic_binding * get_symbolic_binding(const region *region)
Definition store.h:726
void purge_state_involving(const svalue *sval, region_model_manager *sval_mgr)
void dump(bool simple) const
bool escaped_p(const region *reg) const
store(const store &other)
void fill_region(store_manager *mgr, const region *reg, const svalue *sval)
void mark_as_escaped(const region *base_reg)
void purge_region(store_manager *mgr, const region *reg)
json::object * to_json() const
tristate eval_alias(const region *base_reg_a, const region *base_reg_b) const
void summarize_to_pp(pretty_printer *pp, bool simple) const
bool operator==(const store &other) const
store & operator=(const store &other)
hash_map< const region *, binding_cluster * > cluster_map_t
Definition store.h:728
void replay_call_summary_cluster(call_summary_replay &r, const store &summary, const region *base_reg)
void for_each_binding(BindingVisitor &v)
Definition store.h:805
cluster_map_t::iterator end() const
Definition store.h:799
bool m_called_unknown_fn
Definition store.h:837
void loop_replay_fixup(const store *other_store, region_model_manager *mgr)
binding_cluster * get_or_create_cluster(const region *base_reg)
static bool can_merge_p(const store *store_a, const store *store_b, store *out_store, store_manager *mgr, model_merger *merger)
bool operator!=(const store &other) const
Definition store.h:737
bool called_unknown_fn_p() const
Definition store.h:755
void on_maybe_live_values(const svalue_set &maybe_live_values)
void set_value(store_manager *mgr, const region *lhs_reg, const svalue *rhs_sval, uncertainty_t *uncertainty)
cluster_map_t m_cluster_map
Definition store.h:829
const binding_cluster * get_cluster(const region *base_reg) const
void zero_fill_region(store_manager *mgr, const region *reg)
tristate eval_alias_1(const region *base_reg_a, const region *base_reg_b) const
void validate() const
void mark_region_as_unknown(store_manager *mgr, const region *reg, uncertainty_t *uncertainty, svalue_set *maybe_live_values)
void canonicalize(store_manager *mgr)
cluster_map_t::iterator begin() const
Definition store.h:798
const svalue * get_any_binding(store_manager *mgr, const region *reg) const
void get_representative_path_vars(const region_model *model, svalue_set *visited, const svalue *sval, auto_vec< path_var > *out_pvs) const
hashval_t hash() const
binding_cluster * get_cluster(const region *base_reg)
void replay_call_summary(call_summary_replay &r, const store &summary)
void dump_to_pp(pretty_printer *pp, bool summarize, bool multiline, store_manager *mgr) const
void on_unknown_fncall(const gcall *call, store_manager *mgr, const conjured_purge &p)
void purge_cluster(const region *base_reg)
void for_each_cluster(void(*cb)(const region *base_reg, T user_data), T user_data) const
Definition store.h:776
void remove_overlapping_bindings(store_manager *mgr, const region *reg, uncertainty_t *uncertainty)
void clobber_region(store_manager *mgr, const region *reg)
Definition svalue.h:90
Definition store.h:456
void dump_to_pp(pretty_printer *pp, bool simple) const final override
bool is_empty() const
Definition store.h:486
void mark_empty()
Definition store.h:483
bool operator==(const symbolic_binding &other) const
Definition store.h:468
bool concrete_p() const final override
Definition store.h:462
symbolic_binding(const region *region)
Definition store.h:461
symbolic_binding key_t
Definition store.h:459
const symbolic_binding * dyn_cast_symbolic_binding() const final override
Definition store.h:475
const region * get_region() const
Definition store.h:478
bool is_deleted() const
Definition store.h:484
hashval_t hash() const
Definition store.h:464
const region * m_region
Definition store.h:489
static int cmp_ptr_ptr(const void *, const void *)
void mark_deleted()
Definition store.h:482
Definition store.h:159
bool unknown_sm_state_p(const svalue *sval)
Definition store.h:172
void dump(bool simple) const
void dump_to_pp(pretty_printer *pp, bool simple) const
void on_mutable_sval_at_unknown_call(const svalue *sval)
Definition store.h:167
iterator end_maybe_bound_svals() const
Definition store.h:185
hash_set< const svalue * > m_mutable_at_unknown_call_svals
Definition store.h:196
void on_maybe_bound_sval(const svalue *sval)
Definition store.h:163
hash_set< constsvalue * >::iterator iterator
Definition store.h:161
iterator begin_maybe_bound_svals() const
Definition store.h:181
hash_set< const svalue * > m_maybe_bound_svals
Definition store.h:193
Definition vec.h:1656
Definition analyzer.h:529
iterator begin() const
Definition hash-map.h:302
void empty()
Definition hash-map.h:249
size_t elements() const
Definition hash-map.h:247
void remove(const Key &k)
Definition hash-map.h:218
iterator end() const
Definition hash-map.h:303
bool put(const Key &k, const Value &v)
Definition hash-map.h:168
Definition hash-set.h:110
Definition hash-set.h:37
iterator begin() const
Definition hash-set.h:140
iterator end() const
Definition hash-set.h:141
bool contains(const Key &k)
Definition hash-set.h:73
bool add(const Key &k)
Definition hash-set.h:56
Definition inchash.h:38
Definition json.h:95
Definition pretty-print.h:244
Definition lra-spills.cc:101
Definition tristate.h:26
union tree_node * tree
Definition coretypes.h:97
void final(rtx_insn *first, FILE *file, int optimize_p)
Definition final.cc:2002
T * ggc_alloc(ALONE_CXX_MEM_STAT_INFO)
Definition ggc.h:184
Definition access-diagram.h:30
offset_int byte_size_t
Definition analyzer.h:182
offset_int bit_offset_t
Definition analyzer.h:179
offset_int byte_offset_t
Definition analyzer.h:181
offset_int bit_size_t
Definition analyzer.h:180
poly_int< N, C > r
Definition poly-int.h:770
rtx offset
Definition postreload.cc:691
Definition store.h:231
bit_range operator-(bit_offset_t offset) const
bool operator==(const bit_range &other) const
Definition store.h:269
bool exceeds_p(const bit_range &other, bit_range *out_overhanging_bit_range) const
json::object * to_json() const
bool empty_p() const
Definition store.h:242
bool intersects_p(const bit_range &other) const
Definition store.h:275
static bool from_mask(unsigned HOST_WIDE_INT mask, bit_range *out)
bool falls_short_of_p(bit_offset_t offset, bit_range *out_fall_short_bits) const
bool intersects_p(const bit_range &other, bit_range *out_this, bit_range *out_other) const
bit_size_t m_size_in_bits
Definition store.h:301
bool contains_p(bit_offset_t offset) const
Definition store.h:261
bit_offset_t get_next_bit_offset() const
Definition store.h:251
bit_offset_t m_start_bit_offset
Definition store.h:300
bool intersects_p(const bit_range &other, bit_size_t *out_num_overlap_bits) const
void dump_to_pp(pretty_printer *pp) const
bit_range(bit_offset_t start_bit_offset, bit_size_t size_in_bits)
Definition store.h:232
bool as_byte_range(byte_range *out) const
void dump() const
static int cmp(const bit_range &br1, const bit_range &br2)
bool contains_p(const bit_range &other, bit_range *out) const
bit_offset_t get_start_bit_offset() const
Definition store.h:247
bit_offset_t get_last_bit_offset() const
Definition store.h:255
Definition store.h:307
bool operator==(const byte_range &other) const
Definition store.h:330
byte_offset_t get_next_byte_offset() const
Definition store.h:340
byte_size_t m_size_in_bytes
Definition store.h:368
byte_offset_t get_last_byte_offset() const
Definition store.h:344
bool contains_p(byte_offset_t offset) const
Definition store.h:323
byte_offset_t get_start_byte_offset() const
Definition store.h:336
json::object * to_json() const
void dump_to_pp(pretty_printer *pp) const
void dump() const
byte_range(byte_offset_t start_byte_offset, byte_size_t size_in_bytes)
Definition store.h:308
static int cmp(const byte_range &br1, const byte_range &br2)
bit_offset_t get_start_bit_offset() const
Definition store.h:356
byte_offset_t m_start_byte_offset
Definition store.h:367
bool contains_p(const byte_range &other, byte_range *out) const
bool empty_p() const
Definition store.h:318
bit_offset_t get_next_bit_offset() const
Definition store.h:360
bit_range as_bit_range() const
Definition store.h:350
Definition region-model.h:1116
Definition hash-traits.h:466
Definition gimple.h:550
Definition gimple.h:353
static bool test(U *p)
Definition analyzer.h:508
#define NULL
Definition system.h:50
#define gcc_assert(EXPR)
Definition system.h:821
static bitmap visited
Definition tree-ssa-dce.cc:536
tree size_in_bytes(const_tree t)
Definition tree.h:5089