2 Copyright (C) 2019-2022 Free Software Foundation, Inc.
3 Contributed by David Malcolm <dmalcolm@redhat.com>.
5 This file is part of GCC.
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)
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.
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/>. */
21 #ifndef GCC_ANALYZER_REGION_H
22 #define GCC_ANALYZER_REGION_H
24 #include "analyzer/complexity.h"
28 /* An enum for identifying different spaces within memory. */
37 MEMSPACE_READONLY_DATA
40 /* An enum for discriminating between the different concrete subclasses
68 /* Region and its subclasses.
70 The class hierarchy looks like this (using indentation to show
71 inheritance, and with region_kinds shown for the concrete subclasses):
75 frame_region (RK_FRAME): a function frame on the stack
76 globals_region (RK_GLOBALS): holds globals variables (data and bss)
77 code_region (RK_CODE): represents the code segment, containing functions
78 stack_region (RK_STACK): a stack, containing all stack frames
79 heap_region (RK_HEAP): the heap, containing heap_allocated_regions
80 root_region (RK_ROOT): the top-level region
81 function_region (RK_FUNCTION): the code for a particular function
82 label_region (RK_LABEL): a particular label within a function
83 symbolic_region (RK_SYMBOLIC): dereferencing a symbolic pointer
84 decl_region (RK_DECL): the memory occupied by a particular global, local,
86 field_region (RK_FIELD): the memory occupied by a field within a struct
88 element_region (RK_ELEMENT): an element within an array
89 offset_region (RK_OFFSET): a byte-offset within another region, for
90 handling pointer arithmetic as a region
91 sized_region (RK_SIZED): a subregion of symbolic size (in bytes)
93 cast_region (RK_CAST): a region that views another region using a
95 heap_allocated_region (RK_HEAP_ALLOCATED): an untyped region dynamically
96 allocated on the heap via
98 alloca_region (RK_ALLOCA): an untyped region dynamically allocated on the
100 string_region (RK_STRING): a region for a STRING_CST
101 bit_range_region (RK_BIT_RANGE): a region for a specific range of bits
102 within another region
103 var_arg_region (RK_VAR_ARG): a region for the N-th vararg within a
104 frame_region for a variadic call
105 unknown_region (RK_UNKNOWN): for handling unimplemented tree codes. */
107 /* Abstract base class for representing ways of accessing chunks of memory.
109 Regions form a tree-like hierarchy, with a root region at the base,
110 with memory space regions within it, representing the stack and
111 globals, with frames within the stack, and regions for variables
112 within the frames and the "globals" region. Regions for structs
113 can have subregions for fields. */
120 unsigned get_id () const { return m_id; }
121 static int cmp_ids (const region *reg1, const region *reg2);
123 virtual enum region_kind get_kind () const = 0;
124 virtual const frame_region *
125 dyn_cast_frame_region () const { return NULL; }
126 virtual const function_region *
127 dyn_cast_function_region () const { return NULL; }
128 virtual const symbolic_region *
129 dyn_cast_symbolic_region () const { return NULL; }
130 virtual const decl_region *
131 dyn_cast_decl_region () const { return NULL; }
132 virtual const field_region *
133 dyn_cast_field_region () const { return NULL; }
134 virtual const element_region *
135 dyn_cast_element_region () const { return NULL; }
136 virtual const offset_region *
137 dyn_cast_offset_region () const { return NULL; }
138 virtual const sized_region *
139 dyn_cast_sized_region () const { return NULL; }
140 virtual const cast_region *
141 dyn_cast_cast_region () const { return NULL; }
142 virtual const string_region *
143 dyn_cast_string_region () const { return NULL; }
144 virtual const bit_range_region *
145 dyn_cast_bit_range_region () const { return NULL; }
146 virtual const var_arg_region *
147 dyn_cast_var_arg_region () const { return NULL; }
149 virtual void accept (visitor *v) const;
151 const region *get_parent_region () const { return m_parent; }
152 const region *get_base_region () const;
153 bool base_region_p () const;
154 bool descendent_of_p (const region *elder) const;
155 const frame_region *maybe_get_frame_region () const;
156 enum memory_space get_memory_space () const;
157 bool can_have_initial_svalue_p () const;
159 tree maybe_get_decl () const;
161 tree get_type () const { return m_type; }
163 void print (const region_model &model,
164 pretty_printer *pp) const;
165 label_text get_desc (bool simple=true) const;
167 virtual void dump_to_pp (pretty_printer *pp, bool simple) const = 0;
168 void dump (bool simple) const;
170 json::value *to_json () const;
172 bool non_null_p () const;
174 static int cmp_ptr_ptr (const void *, const void *);
176 bool involves_p (const svalue *sval) const;
178 region_offset get_offset (region_model_manager *mgr) const;
180 /* Attempt to get the size of this region as a concrete number of bytes.
181 If successful, return true and write the size to *OUT.
182 Otherwise return false. */
183 virtual bool get_byte_size (byte_size_t *out) const;
185 /* Attempt to get the size of this region as a concrete number of bits.
186 If successful, return true and write the size to *OUT.
187 Otherwise return false. */
188 virtual bool get_bit_size (bit_size_t *out) const;
190 /* Get a symbolic value describing the size of this region in bytes
191 (which could be "unknown"). */
192 virtual const svalue *get_byte_size_sval (region_model_manager *mgr) const;
194 /* Attempt to get the offset in bits of this region relative to its parent.
195 If successful, return true and write to *OUT.
196 Otherwise return false. */
197 virtual bool get_relative_concrete_offset (bit_offset_t *out) const;
199 /* Get the offset in bytes of this region relative to its parent as a svalue.
200 Might return an unknown_svalue. */
201 virtual const svalue *
202 get_relative_symbolic_offset (region_model_manager *mgr) const;
204 /* Attempt to get the position and size of this region expressed as a
205 concrete range of bytes relative to its parent.
206 If successful, return true and write to *OUT.
207 Otherwise return false. */
208 bool get_relative_concrete_byte_range (byte_range *out) const;
211 get_subregions_for_binding (region_model_manager *mgr,
212 bit_offset_t start_bit_offset,
213 bit_size_t size_in_bits,
215 auto_vec <const region *> *out) const;
217 bool symbolic_for_unknown_ptr_p () const;
219 bool symbolic_p () const;
221 /* For most base regions it makes sense to track the bindings of the region
222 within the store. As an optimization, some are not tracked (to avoid
223 bloating the store object with redundant binding clusters). */
224 virtual bool tracked_p () const { return true; }
226 const complexity &get_complexity () const { return m_complexity; }
228 bool is_named_decl_p (const char *decl_name) const;
231 region (complexity c, unsigned id, const region *parent, tree type);
234 region_offset calc_offset (region_model_manager *mgr) const;
236 complexity m_complexity;
237 unsigned m_id; // purely for deterministic sorting at this stage, for dumps
238 const region *m_parent;
241 mutable region_offset *m_cached_offset;
249 is_a_helper <const region *>::test (const region *)
256 /* Abstract subclass of region, for regions that represent an untyped
257 space within memory, such as the stack or the heap. */
259 class space_region : public region
262 space_region (unsigned id, const region *parent)
263 : region (complexity (parent), id, parent, NULL_TREE)
267 /* Concrete space_region subclass, representing a function frame on the stack,
268 to contain the locals.
269 The parent is the stack region; there's also a hierarchy of call-stack
270 prefixes expressed via m_calling_frame.
271 For example, given "oldest" calling "middle" called "newest" we would have
273 - frame (A) for "oldest" with index 0 for depth 1, calling_frame == NULL
274 - frame (B) for "middle" with index 1 for depth 2, calling_frame == (A)
275 - frame (C) for "newest" with index 2 for depth 3, calling_frame == (B)
276 where the parent region for each of the frames is the "stack" region.
277 The index is the count of frames earlier than this in the stack. */
279 class frame_region : public space_region
282 /* A support class for uniquifying instances of frame_region. */
285 key_t (const frame_region *calling_frame, function *fun)
286 : m_calling_frame (calling_frame), m_fun (fun)
288 /* calling_frame can be NULL. */
292 hashval_t hash () const
294 inchash::hash hstate;
295 hstate.add_ptr (m_calling_frame);
296 hstate.add_ptr (m_fun);
297 return hstate.end ();
300 bool operator== (const key_t &other) const
302 return (m_calling_frame == other.m_calling_frame && m_fun == other.m_fun);
305 void mark_deleted () { m_fun = reinterpret_cast<function *> (1); }
306 void mark_empty () { m_fun = NULL; }
307 bool is_deleted () const
309 return m_fun == reinterpret_cast<function *> (1);
311 bool is_empty () const { return m_fun == NULL; }
313 const frame_region *m_calling_frame;
317 frame_region (unsigned id, const region *parent,
318 const frame_region *calling_frame,
319 function *fun, int index)
320 : space_region (id, parent), m_calling_frame (calling_frame),
321 m_fun (fun), m_index (index)
326 enum region_kind get_kind () const final override { return RK_FRAME; }
327 const frame_region * dyn_cast_frame_region () const final override
331 void accept (visitor *v) const final override;
332 void dump_to_pp (pretty_printer *pp, bool simple) const final override;
335 const frame_region *get_calling_frame () const { return m_calling_frame; }
336 function *get_function () const { return m_fun; }
337 tree get_fndecl () const { return get_function ()->decl; }
338 int get_index () const { return m_index; }
339 int get_stack_depth () const { return m_index + 1; }
342 get_region_for_local (region_model_manager *mgr,
344 const region_model_context *ctxt) const;
346 unsigned get_num_locals () const { return m_locals.elements (); }
348 /* Implemented in region-model-manager.cc. */
349 void dump_untracked_regions () const;
352 const frame_region *m_calling_frame;
356 /* The regions for the decls within this frame are managed by this
357 object, rather than the region_model_manager, to make it a simple
359 typedef hash_map<tree, decl_region *> map_t;
368 is_a_helper <const frame_region *>::test (const region *reg)
370 return reg->get_kind () == RK_FRAME;
373 template <> struct default_hash_traits<frame_region::key_t>
374 : public member_function_hash_traits<frame_region::key_t>
376 static const bool empty_zero_p = true;
381 /* Concrete space_region subclass, to hold global variables (data and bss). */
383 class globals_region : public space_region
386 globals_region (unsigned id, const region *parent)
387 : space_region (id, parent)
391 enum region_kind get_kind () const final override { return RK_GLOBALS; }
392 void dump_to_pp (pretty_printer *pp, bool simple) const final override;
400 is_a_helper <const globals_region *>::test (const region *reg)
402 return reg->get_kind () == RK_GLOBALS;
407 /* Concrete space_region subclass, representing the code segment
408 containing functions. */
410 class code_region : public space_region
413 code_region (unsigned id, const region *parent)
414 : space_region (id, parent)
418 void dump_to_pp (pretty_printer *pp, bool simple) const final override;
419 enum region_kind get_kind () const final override { return RK_CODE; }
427 is_a_helper <const code_region *>::test (const region *reg)
429 return reg->get_kind () == RK_CODE;
434 /* Concrete region subclass. A region representing the code for
435 a particular function. */
437 class function_region : public region
440 function_region (unsigned id, const code_region *parent, tree fndecl)
441 : region (complexity (parent), id, parent, TREE_TYPE (fndecl)),
444 gcc_assert (FUNC_OR_METHOD_TYPE_P (TREE_TYPE (fndecl)));
448 void dump_to_pp (pretty_printer *pp, bool simple) const final override;
449 enum region_kind get_kind () const final override { return RK_FUNCTION; }
450 const function_region *
451 dyn_cast_function_region () const final override{ return this; }
453 tree get_fndecl () const { return m_fndecl; }
464 is_a_helper <const function_region *>::test (const region *reg)
466 return reg->get_kind () == RK_FUNCTION;
471 /* Concrete region subclass. A region representing a particular label
472 within a function. */
474 class label_region : public region
477 label_region (unsigned id, const function_region *parent, tree label)
478 : region (complexity (parent), id, parent, NULL_TREE), m_label (label)
480 gcc_assert (TREE_CODE (label) == LABEL_DECL);
484 void dump_to_pp (pretty_printer *pp, bool simple) const final override;
485 enum region_kind get_kind () const final override { return RK_LABEL; }
487 tree get_label () const { return m_label; }
498 is_a_helper <const label_region *>::test (const region *reg)
500 return reg->get_kind () == RK_LABEL;
505 /* Concrete space_region subclass representing a stack, containing all stack
508 class stack_region : public space_region
511 stack_region (unsigned id, region *parent)
512 : space_region (id, parent)
515 void dump_to_pp (pretty_printer *pp, bool simple) const final override;
517 enum region_kind get_kind () const final override { return RK_STACK; }
525 is_a_helper <const stack_region *>::test (const region *reg)
527 return reg->get_kind () == RK_STACK;
532 /* Concrete space_region subclass: a region within which regions can be
533 dynamically allocated. */
535 class heap_region : public space_region
538 heap_region (unsigned id, region *parent)
539 : space_region (id, parent)
542 enum region_kind get_kind () const final override { return RK_HEAP; }
543 void dump_to_pp (pretty_printer *pp, bool simple) const final override;
551 is_a_helper <const heap_region *>::test (const region *reg)
553 return reg->get_kind () == RK_HEAP;
558 /* Concrete region subclass. The root region, containing all regions
559 (either directly, or as descendents).
560 Unique within a region_model_manager. */
562 class root_region : public region
565 root_region (unsigned id);
567 enum region_kind get_kind () const final override { return RK_ROOT; }
568 void dump_to_pp (pretty_printer *pp, bool simple) const final override;
576 is_a_helper <const root_region *>::test (const region *reg)
578 return reg->get_kind () == RK_ROOT;
583 /* Concrete region subclass: a region to use when dereferencing an unknown
586 class symbolic_region : public region
589 /* A support class for uniquifying instances of symbolic_region. */
592 key_t (const region *parent, const svalue *sval_ptr)
593 : m_parent (parent), m_sval_ptr (sval_ptr)
595 gcc_assert (sval_ptr);
598 hashval_t hash () const
600 inchash::hash hstate;
601 hstate.add_ptr (m_parent);
602 hstate.add_ptr (m_sval_ptr);
603 return hstate.end ();
606 bool operator== (const key_t &other) const
608 return (m_parent == other.m_parent && m_sval_ptr == other.m_sval_ptr);
611 void mark_deleted () { m_sval_ptr = reinterpret_cast<const svalue *> (1); }
612 void mark_empty () { m_sval_ptr = NULL; }
613 bool is_deleted () const
615 return m_sval_ptr == reinterpret_cast<const svalue *> (1);
617 bool is_empty () const { return m_sval_ptr == NULL; }
619 const region *m_parent;
620 const svalue *m_sval_ptr;
623 symbolic_region (unsigned id, region *parent, const svalue *sval_ptr);
625 const symbolic_region *
626 dyn_cast_symbolic_region () const final override { return this; }
628 enum region_kind get_kind () const final override { return RK_SYMBOLIC; }
629 void accept (visitor *v) const final override;
630 void dump_to_pp (pretty_printer *pp, bool simple) const final override;
632 const svalue *get_pointer () const { return m_sval_ptr; }
635 const svalue *m_sval_ptr;
643 is_a_helper <const symbolic_region *>::test (const region *reg)
645 return reg->get_kind () == RK_SYMBOLIC;
648 template <> struct default_hash_traits<symbolic_region::key_t>
649 : public member_function_hash_traits<symbolic_region::key_t>
651 static const bool empty_zero_p = true;
656 /* Concrete region subclass representing the memory occupied by a
657 variable (whether for a global or a local).
658 Also used for representing SSA names, as if they were locals. */
660 class decl_region : public region
663 decl_region (unsigned id, const region *parent, tree decl)
664 : region (complexity (parent), id, parent, TREE_TYPE (decl)), m_decl (decl),
665 m_tracked (calc_tracked_p (decl))
668 enum region_kind get_kind () const final override { return RK_DECL; }
670 dyn_cast_decl_region () const final override { return this; }
672 void dump_to_pp (pretty_printer *pp, bool simple) const final override;
674 bool tracked_p () const final override { return m_tracked; }
676 tree get_decl () const { return m_decl; }
677 int get_stack_depth () const;
679 const svalue *maybe_get_constant_value (region_model_manager *mgr) const;
680 const svalue *get_svalue_for_constructor (tree ctor,
681 region_model_manager *mgr) const;
682 const svalue *get_svalue_for_initializer (region_model_manager *mgr) const;
685 static bool calc_tracked_p (tree decl);
689 /* Cached result of calc_tracked_p, so that we can quickly determine when
690 we don't to track a binding_cluster for this decl (to avoid bloating
692 This can be debugged using -fdump-analyzer-untracked. */
701 is_a_helper <const decl_region *>::test (const region *reg)
703 return reg->get_kind () == RK_DECL;
708 /* Concrete region subclass representing the memory occupied by a
709 field within a struct or union. */
711 class field_region : public region
714 /* A support class for uniquifying instances of field_region. */
717 key_t (const region *parent, tree field)
718 : m_parent (parent), m_field (field)
723 hashval_t hash () const
725 inchash::hash hstate;
726 hstate.add_ptr (m_parent);
727 hstate.add_ptr (m_field);
728 return hstate.end ();
731 bool operator== (const key_t &other) const
733 return (m_parent == other.m_parent && m_field == other.m_field);
736 void mark_deleted () { m_field = reinterpret_cast<tree> (1); }
737 void mark_empty () { m_field = NULL_TREE; }
738 bool is_deleted () const { return m_field == reinterpret_cast<tree> (1); }
739 bool is_empty () const { return m_field == NULL_TREE; }
741 const region *m_parent;
745 field_region (unsigned id, const region *parent, tree field)
746 : region (complexity (parent), id, parent, TREE_TYPE (field)),
750 enum region_kind get_kind () const final override { return RK_FIELD; }
752 void dump_to_pp (pretty_printer *pp, bool simple) const final override;
754 dyn_cast_field_region () const final override { return this; }
756 tree get_field () const { return m_field; }
758 bool get_relative_concrete_offset (bit_offset_t *out) const final override;
759 const svalue *get_relative_symbolic_offset (region_model_manager *mgr)
760 const final override;
771 is_a_helper <const field_region *>::test (const region *reg)
773 return reg->get_kind () == RK_FIELD;
776 template <> struct default_hash_traits<field_region::key_t>
777 : public member_function_hash_traits<field_region::key_t>
779 static const bool empty_zero_p = true;
784 /* An element within an array. */
786 class element_region : public region
789 /* A support class for uniquifying instances of element_region. */
792 key_t (const region *parent, tree element_type, const svalue *index)
793 : m_parent (parent), m_element_type (element_type), m_index (index)
798 hashval_t hash () const
800 inchash::hash hstate;
801 hstate.add_ptr (m_parent);
802 hstate.add_ptr (m_element_type);
803 hstate.add_ptr (m_index);
804 return hstate.end ();
807 bool operator== (const key_t &other) const
809 return (m_parent == other.m_parent
810 && m_element_type == other.m_element_type
811 && m_index == other.m_index);
814 void mark_deleted () { m_index = reinterpret_cast<const svalue *> (1); }
815 void mark_empty () { m_index = NULL; }
816 bool is_deleted () const
818 return m_index == reinterpret_cast<const svalue *> (1);
820 bool is_empty () const { return m_index == NULL; }
822 const region *m_parent;
824 const svalue *m_index;
827 element_region (unsigned id, const region *parent, tree element_type,
829 : region (complexity::from_pair (parent, index), id, parent, element_type),
833 enum region_kind get_kind () const final override { return RK_ELEMENT; }
834 const element_region *
835 dyn_cast_element_region () const final override { return this; }
837 void accept (visitor *v) const final override;
839 void dump_to_pp (pretty_printer *pp, bool simple) const final override;
841 const svalue *get_index () const { return m_index; }
844 get_relative_concrete_offset (bit_offset_t *out) const final override;
845 const svalue *get_relative_symbolic_offset (region_model_manager *mgr)
846 const final override;
849 const svalue *m_index;
857 is_a_helper <const element_region *>::test (const region *reg)
859 return reg->get_kind () == RK_ELEMENT;
862 template <> struct default_hash_traits<element_region::key_t>
863 : public member_function_hash_traits<element_region::key_t>
865 static const bool empty_zero_p = true;
870 /* A byte-offset within another region, for handling pointer arithmetic
873 class offset_region : public region
876 /* A support class for uniquifying instances of offset_region. */
879 key_t (const region *parent, tree element_type, const svalue *byte_offset)
880 : m_parent (parent), m_element_type (element_type), m_byte_offset (byte_offset)
882 gcc_assert (byte_offset);
885 hashval_t hash () const
887 inchash::hash hstate;
888 hstate.add_ptr (m_parent);
889 hstate.add_ptr (m_element_type);
890 hstate.add_ptr (m_byte_offset);
891 return hstate.end ();
894 bool operator== (const key_t &other) const
896 return (m_parent == other.m_parent
897 && m_element_type == other.m_element_type
898 && m_byte_offset == other.m_byte_offset);
901 void mark_deleted () { m_byte_offset = reinterpret_cast<const svalue *> (1); }
902 void mark_empty () { m_byte_offset = NULL; }
903 bool is_deleted () const
905 return m_byte_offset == reinterpret_cast<const svalue *> (1);
907 bool is_empty () const { return m_byte_offset == NULL; }
909 const region *m_parent;
911 const svalue *m_byte_offset;
914 offset_region (unsigned id, const region *parent, tree type,
915 const svalue *byte_offset)
916 : region (complexity::from_pair (parent, byte_offset), id, parent, type),
917 m_byte_offset (byte_offset)
920 enum region_kind get_kind () const final override { return RK_OFFSET; }
921 const offset_region *
922 dyn_cast_offset_region () const final override { return this; }
924 void accept (visitor *v) const final override;
926 void dump_to_pp (pretty_printer *pp, bool simple) const final override;
928 const svalue *get_byte_offset () const { return m_byte_offset; }
930 bool get_relative_concrete_offset (bit_offset_t *out) const final override;
931 const svalue *get_relative_symbolic_offset (region_model_manager *mgr)
932 const final override;
933 const svalue * get_byte_size_sval (region_model_manager *mgr)
934 const final override;
938 const svalue *m_byte_offset;
946 is_a_helper <const offset_region *>::test (const region *reg)
948 return reg->get_kind () == RK_OFFSET;
951 template <> struct default_hash_traits<offset_region::key_t>
952 : public member_function_hash_traits<offset_region::key_t>
954 static const bool empty_zero_p = true;
959 /* A region that is size BYTES_SIZE_SVAL in size within its parent
960 region (or possibly larger, which would lead to an overflow. */
962 class sized_region : public region
965 /* A support class for uniquifying instances of sized_region. */
968 key_t (const region *parent, tree element_type,
969 const svalue *byte_size_sval)
970 : m_parent (parent), m_element_type (element_type),
971 m_byte_size_sval (byte_size_sval)
973 gcc_assert (byte_size_sval);
976 hashval_t hash () const
978 inchash::hash hstate;
979 hstate.add_ptr (m_parent);
980 hstate.add_ptr (m_element_type);
981 hstate.add_ptr (m_byte_size_sval);
982 return hstate.end ();
985 bool operator== (const key_t &other) const
987 return (m_parent == other.m_parent
988 && m_element_type == other.m_element_type
989 && m_byte_size_sval == other.m_byte_size_sval);
992 void mark_deleted () { m_byte_size_sval = reinterpret_cast<const svalue *> (1); }
993 void mark_empty () { m_byte_size_sval = NULL; }
994 bool is_deleted () const
996 return m_byte_size_sval == reinterpret_cast<const svalue *> (1);
998 bool is_empty () const { return m_byte_size_sval == NULL; }
1000 const region *m_parent;
1001 tree m_element_type;
1002 const svalue *m_byte_size_sval;
1003 const svalue *m_end_offset;
1006 sized_region (unsigned id, const region *parent, tree type,
1007 const svalue *byte_size_sval)
1008 : region (complexity::from_pair (parent, byte_size_sval),
1010 m_byte_size_sval (byte_size_sval)
1013 enum region_kind get_kind () const final override { return RK_SIZED; }
1014 const sized_region *
1015 dyn_cast_sized_region () const final override { return this; }
1017 void accept (visitor *v) const final override;
1019 void dump_to_pp (pretty_printer *pp, bool simple) const final override;
1021 bool get_byte_size (byte_size_t *out) const final override;
1022 bool get_bit_size (bit_size_t *out) const final override;
1025 get_byte_size_sval (region_model_manager *) const final override
1027 return m_byte_size_sval;
1031 const svalue *m_byte_size_sval;
1039 is_a_helper <const sized_region *>::test (const region *reg)
1041 return reg->get_kind () == RK_SIZED;
1044 template <> struct default_hash_traits<sized_region::key_t>
1045 : public member_function_hash_traits<sized_region::key_t>
1047 static const bool empty_zero_p = true;
1052 /* A region that views another region using a different type. */
1054 class cast_region : public region
1057 /* A support class for uniquifying instances of cast_region. */
1060 key_t (const region *original_region, tree type)
1061 : m_original_region (original_region), m_type (type)
1066 hashval_t hash () const
1068 inchash::hash hstate;
1069 hstate.add_ptr (m_original_region);
1070 hstate.add_ptr (m_type);
1071 return hstate.end ();
1074 bool operator== (const key_t &other) const
1076 return (m_original_region == other.m_original_region
1077 && m_type == other.m_type);
1080 void mark_deleted () { m_type = reinterpret_cast<tree> (1); }
1081 void mark_empty () { m_type = NULL_TREE; }
1082 bool is_deleted () const { return m_type == reinterpret_cast<tree> (1); }
1083 bool is_empty () const { return m_type == NULL_TREE; }
1085 const region *m_original_region;
1089 cast_region (unsigned id, const region *original_region, tree type)
1090 : region (complexity (original_region), id,
1091 original_region->get_parent_region (), type),
1092 m_original_region (original_region)
1095 enum region_kind get_kind () const final override { return RK_CAST; }
1097 dyn_cast_cast_region () const final override { return this; }
1098 void accept (visitor *v) const final override;
1099 void dump_to_pp (pretty_printer *pp, bool simple) const final override;
1101 bool get_relative_concrete_offset (bit_offset_t *out) const final override;
1103 const region *get_original_region () const { return m_original_region; }
1106 const region *m_original_region;
1114 is_a_helper <const cast_region *>::test (const region *reg)
1116 return reg->get_kind () == RK_CAST;
1119 template <> struct default_hash_traits<cast_region::key_t>
1120 : public member_function_hash_traits<cast_region::key_t>
1122 static const bool empty_zero_p = true;
1127 /* An untyped region dynamically allocated on the heap via "malloc"
1130 class heap_allocated_region : public region
1133 heap_allocated_region (unsigned id, const region *parent)
1134 : region (complexity (parent), id, parent, NULL_TREE)
1138 get_kind () const final override { return RK_HEAP_ALLOCATED; }
1140 void dump_to_pp (pretty_printer *pp, bool simple) const final override;
1143 /* An untyped region dynamically allocated on the stack via "alloca". */
1145 class alloca_region : public region
1148 alloca_region (unsigned id, const frame_region *parent)
1149 : region (complexity (parent), id, parent, NULL_TREE)
1152 enum region_kind get_kind () const final override { return RK_ALLOCA; }
1154 void dump_to_pp (pretty_printer *pp, bool simple) const final override;
1157 /* A region for a STRING_CST. */
1159 class string_region : public region
1162 string_region (unsigned id, const region *parent, tree string_cst)
1163 : region (complexity (parent), id, parent, TREE_TYPE (string_cst)),
1164 m_string_cst (string_cst)
1167 const string_region *
1168 dyn_cast_string_region () const final override { return this; }
1170 enum region_kind get_kind () const final override { return RK_STRING; }
1172 void dump_to_pp (pretty_printer *pp, bool simple) const final override;
1174 /* We assume string literals are immutable, so we don't track them in
1176 bool tracked_p () const final override { return false; }
1178 tree get_string_cst () const { return m_string_cst; }
1189 is_a_helper <const string_region *>::test (const region *reg)
1191 return reg->get_kind () == RK_STRING;
1196 /* A region for a specific range of bits within another region. */
1198 class bit_range_region : public region
1201 /* A support class for uniquifying instances of bit_range_region. */
1204 key_t (const region *parent, tree type, const bit_range &bits)
1205 : m_parent (parent), m_type (type), m_bits (bits)
1207 gcc_assert (parent);
1210 hashval_t hash () const
1212 inchash::hash hstate;
1213 hstate.add_ptr (m_parent);
1214 hstate.add_ptr (m_type);
1215 hstate.add_wide_int (m_bits.m_start_bit_offset);
1216 hstate.add_wide_int (m_bits.m_size_in_bits);
1217 return hstate.end ();
1220 bool operator== (const key_t &other) const
1222 return (m_parent == other.m_parent
1223 && m_type == other.m_type
1224 && m_bits == other.m_bits);
1227 void mark_deleted () { m_parent = reinterpret_cast<const region *> (1); }
1228 void mark_empty () { m_parent = NULL; }
1229 bool is_deleted () const
1231 return m_parent == reinterpret_cast<const region *> (1);
1233 bool is_empty () const { return m_parent == NULL; }
1235 const region *m_parent;
1240 bit_range_region (unsigned id, const region *parent, tree type,
1241 const bit_range &bits)
1242 : region (complexity (parent), id, parent, type),
1246 const bit_range_region *
1247 dyn_cast_bit_range_region () const final override { return this; }
1249 enum region_kind get_kind () const final override { return RK_BIT_RANGE; }
1251 void dump_to_pp (pretty_printer *pp, bool simple) const final override;
1253 const bit_range &get_bits () const { return m_bits; }
1255 bool get_byte_size (byte_size_t *out) const final override;
1256 bool get_bit_size (bit_size_t *out) const final override;
1257 const svalue *get_byte_size_sval (region_model_manager *mgr) const final override;
1258 bool get_relative_concrete_offset (bit_offset_t *out) const final override;
1259 const svalue *get_relative_symbolic_offset (region_model_manager *mgr)
1260 const final override;
1271 is_a_helper <const bit_range_region *>::test (const region *reg)
1273 return reg->get_kind () == RK_BIT_RANGE;
1276 template <> struct default_hash_traits<bit_range_region::key_t>
1277 : public member_function_hash_traits<bit_range_region::key_t>
1279 static const bool empty_zero_p = true;
1284 /* A region for the N-th vararg within a frame_region for a variadic call. */
1286 class var_arg_region : public region
1289 /* A support class for uniquifying instances of var_arg_region. */
1292 key_t (const frame_region *parent, unsigned idx)
1293 : m_parent (parent), m_idx (idx)
1295 gcc_assert (parent);
1298 hashval_t hash () const
1300 inchash::hash hstate;
1301 hstate.add_ptr (m_parent);
1302 hstate.add_int (m_idx);
1303 return hstate.end ();
1306 bool operator== (const key_t &other) const
1308 return (m_parent == other.m_parent
1309 && m_idx == other.m_idx);
1312 void mark_deleted ()
1314 m_parent = reinterpret_cast<const frame_region *> (1);
1316 void mark_empty () { m_parent = NULL; }
1317 bool is_deleted () const
1319 return m_parent == reinterpret_cast<const frame_region *> (1);
1321 bool is_empty () const { return m_parent == NULL; }
1323 const frame_region *m_parent;
1327 var_arg_region (unsigned id, const frame_region *parent,
1329 : region (complexity (parent), id, parent, NULL_TREE),
1333 const var_arg_region *
1334 dyn_cast_var_arg_region () const final override { return this; }
1336 enum region_kind get_kind () const final override { return RK_VAR_ARG; }
1338 void dump_to_pp (pretty_printer *pp, bool simple) const final override;
1340 const frame_region *get_frame_region () const;
1341 unsigned get_index () const { return m_idx; }
1352 is_a_helper <const var_arg_region *>::test (const region *reg)
1354 return reg->get_kind () == RK_VAR_ARG;
1357 template <> struct default_hash_traits<var_arg_region::key_t>
1358 : public member_function_hash_traits<var_arg_region::key_t>
1360 static const bool empty_zero_p = true;
1365 /* An unknown region, for handling unimplemented tree codes. */
1367 class unknown_region : public region
1370 unknown_region (unsigned id, const region *parent, tree type)
1371 : region (complexity (parent), id, parent, type)
1374 enum region_kind get_kind () const final override { return RK_UNKNOWN; }
1376 void dump_to_pp (pretty_printer *pp, bool simple) const final override;
1381 #endif /* GCC_ANALYZER_REGION_H */