2 Copyright (C) 2019-2024 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/symbol.h"
28 /* An enum for identifying different spaces within memory. */
37 MEMSPACE_READONLY_DATA
,
38 MEMSPACE_THREAD_LOCAL
,
42 /* An enum for discriminating between the different concrete subclasses
73 /* Region and its subclasses.
75 The class hierarchy looks like this (using indentation to show
76 inheritance, and with region_kinds shown for the concrete subclasses):
80 frame_region (RK_FRAME): a function frame on the stack
81 globals_region (RK_GLOBALS): holds globals variables (data and bss)
82 code_region (RK_CODE): represents the code segment, containing functions
83 stack_region (RK_STACK): a stack, containing all stack frames
84 heap_region (RK_HEAP): the heap, containing heap_allocated_regions
85 thread_local_region (RK_THREAD_LOCAL): thread-local data for the thread
87 root_region (RK_ROOT): the top-level region
88 function_region (RK_FUNCTION): the code for a particular function
89 label_region (RK_LABEL): a particular label within a function
90 symbolic_region (RK_SYMBOLIC): dereferencing a symbolic pointer
91 decl_region (RK_DECL): the memory occupied by a particular global, local,
93 field_region (RK_FIELD): the memory occupied by a field within a struct
95 element_region (RK_ELEMENT): an element within an array
96 offset_region (RK_OFFSET): a byte-offset within another region, for
97 handling pointer arithmetic as a region
98 sized_region (RK_SIZED): a subregion of symbolic size (in bytes)
100 cast_region (RK_CAST): a region that views another region using a
102 heap_allocated_region (RK_HEAP_ALLOCATED): an untyped region dynamically
103 allocated on the heap via
105 alloca_region (RK_ALLOCA): an untyped region dynamically allocated on the
107 string_region (RK_STRING): a region for a STRING_CST
108 bit_range_region (RK_BIT_RANGE): a region for a specific range of bits
109 within another region
110 var_arg_region (RK_VAR_ARG): a region for the N-th vararg within a
111 frame_region for a variadic call
112 errno_region (RK_ERRNO): a region for holding "errno"
113 private_region (RK_PRIVATE): a region for internal state of an API
114 unknown_region (RK_UNKNOWN): for handling unimplemented tree codes. */
116 /* Abstract base class for representing ways of accessing chunks of memory.
118 Regions form a tree-like hierarchy, with a root region at the base,
119 with memory space regions within it, representing the stack and
120 globals, with frames within the stack, and regions for variables
121 within the frames and the "globals" region. Regions for structs
122 can have subregions for fields. */
124 class region
: public symbol
129 virtual enum region_kind
get_kind () const = 0;
130 virtual const frame_region
*
131 dyn_cast_frame_region () const { return NULL
; }
132 virtual const function_region
*
133 dyn_cast_function_region () const { return NULL
; }
134 virtual const symbolic_region
*
135 dyn_cast_symbolic_region () const { return NULL
; }
136 virtual const decl_region
*
137 dyn_cast_decl_region () const { return NULL
; }
138 virtual const field_region
*
139 dyn_cast_field_region () const { return NULL
; }
140 virtual const element_region
*
141 dyn_cast_element_region () const { return NULL
; }
142 virtual const offset_region
*
143 dyn_cast_offset_region () const { return NULL
; }
144 virtual const sized_region
*
145 dyn_cast_sized_region () const { return NULL
; }
146 virtual const cast_region
*
147 dyn_cast_cast_region () const { return NULL
; }
148 virtual const string_region
*
149 dyn_cast_string_region () const { return NULL
; }
150 virtual const bit_range_region
*
151 dyn_cast_bit_range_region () const { return NULL
; }
152 virtual const var_arg_region
*
153 dyn_cast_var_arg_region () const { return NULL
; }
155 virtual void accept (visitor
*v
) const;
157 const region
*get_parent_region () const { return m_parent
; }
158 const region
*get_base_region () const;
159 bool base_region_p () const;
160 bool descendent_of_p (const region
*elder
) const;
161 const frame_region
*maybe_get_frame_region () const;
162 enum memory_space
get_memory_space () const;
163 bool can_have_initial_svalue_p () const;
164 const svalue
*get_initial_value_at_main (region_model_manager
*mgr
) const;
166 tree
maybe_get_decl () const;
168 tree
get_type () const { return m_type
; }
170 void print (const region_model
&model
,
171 pretty_printer
*pp
) const;
172 label_text
get_desc (bool simple
=true) const;
174 virtual void dump_to_pp (pretty_printer
*pp
, bool simple
) const = 0;
175 void dump (bool simple
) const;
177 json::value
*to_json () const;
179 bool non_null_p () const;
181 static int cmp_ptr_ptr (const void *, const void *);
183 bool involves_p (const svalue
*sval
) const;
185 region_offset
get_offset (region_model_manager
*mgr
) const;
186 region_offset
get_next_offset (region_model_manager
*mgr
) const;
188 /* Attempt to get the size of this region as a concrete number of bytes.
189 If successful, return true and write the size to *OUT.
190 Otherwise return false.
191 This is the accessed size, not necessarily the size that's valid to
193 virtual bool get_byte_size (byte_size_t
*out
) const;
195 /* Attempt to get the size of this region as a concrete number of bits.
196 If successful, return true and write the size to *OUT.
197 Otherwise return false.
198 This is the accessed size, not necessarily the size that's valid to
200 virtual bool get_bit_size (bit_size_t
*out
) const;
202 /* Get a symbolic value describing the size of this region in bytes
203 (which could be "unknown").
204 This is the accessed size, not necessarily the size that's valid to
206 virtual const svalue
*get_byte_size_sval (region_model_manager
*mgr
) const;
208 /* Get a symbolic value describing the size of this region in bits
209 (which could be "unknown").
210 This is the accessed size, not necessarily the size that's valid to
212 virtual const svalue
*get_bit_size_sval (region_model_manager
*mgr
) const;
214 /* Attempt to get the offset in bits of this region relative to its parent.
215 If successful, return true and write to *OUT.
216 Otherwise return false. */
217 virtual bool get_relative_concrete_offset (bit_offset_t
*out
) const;
219 /* Get the offset in bytes of this region relative to its parent as a svalue.
220 Might return an unknown_svalue. */
221 virtual const svalue
*
222 get_relative_symbolic_offset (region_model_manager
*mgr
) const;
224 /* Attempt to get the position and size of this region expressed as a
225 concrete range of bytes relative to its parent.
226 If successful, return true and write to *OUT.
227 Otherwise return false. */
228 bool get_relative_concrete_byte_range (byte_range
*out
) const;
231 get_subregions_for_binding (region_model_manager
*mgr
,
232 bit_offset_t start_bit_offset
,
233 bit_size_t size_in_bits
,
235 auto_vec
<const region
*> *out
) const;
237 bool symbolic_for_unknown_ptr_p () const;
239 bool symbolic_p () const;
241 /* For most base regions it makes sense to track the bindings of the region
242 within the store. As an optimization, some are not tracked (to avoid
243 bloating the store object with redundant binding clusters). */
244 virtual bool tracked_p () const { return true; }
246 bool is_named_decl_p (const char *decl_name
) const;
248 bool empty_p () const;
251 region (complexity c
, symbol::id_t id
, const region
*parent
, tree type
);
254 region_offset
calc_offset (region_model_manager
*mgr
) const;
255 const svalue
*calc_initial_value_at_main (region_model_manager
*mgr
) const;
257 const region
*m_parent
;
260 mutable region_offset
*m_cached_offset
;
262 /* For regions within a global decl, a cache of the svalue for the initial
263 value of this region when the program starts. */
264 mutable const svalue
*m_cached_init_sval_at_main
;
272 is_a_helper
<const region
*>::test (const region
*)
279 /* Abstract subclass of region, for regions that represent an untyped
280 space within memory, such as the stack or the heap. */
282 class space_region
: public region
285 space_region (symbol::id_t id
, const region
*parent
)
286 : region (complexity (parent
), id
, parent
, NULL_TREE
)
290 /* Concrete space_region subclass, representing a function frame on the stack,
291 to contain the locals.
292 The parent is the stack region; there's also a hierarchy of call-stack
293 prefixes expressed via m_calling_frame.
294 For example, given "oldest" calling "middle" called "newest" we would have
296 - frame (A) for "oldest" with index 0 for depth 1, calling_frame == NULL
297 - frame (B) for "middle" with index 1 for depth 2, calling_frame == (A)
298 - frame (C) for "newest" with index 2 for depth 3, calling_frame == (B)
299 where the parent region for each of the frames is the "stack" region.
300 The index is the count of frames earlier than this in the stack. */
302 class frame_region
: public space_region
305 /* A support class for uniquifying instances of frame_region. */
308 key_t (const frame_region
*calling_frame
, const function
&fun
)
309 : m_calling_frame (calling_frame
), m_fun (&fun
)
311 /* calling_frame can be NULL. */
314 hashval_t
hash () const
316 inchash::hash hstate
;
317 hstate
.add_ptr (m_calling_frame
);
318 hstate
.add_ptr (m_fun
);
319 return hstate
.end ();
322 bool operator== (const key_t
&other
) const
324 return (m_calling_frame
== other
.m_calling_frame
325 && m_fun
== other
.m_fun
);
328 void mark_deleted () { m_fun
= reinterpret_cast<function
*> (1); }
329 void mark_empty () { m_fun
= NULL
; }
330 bool is_deleted () const
332 return m_fun
== reinterpret_cast<function
*> (1);
334 bool is_empty () const { return m_fun
== NULL
; }
336 const frame_region
*m_calling_frame
;
337 const function
*m_fun
;
340 frame_region (symbol::id_t id
, const region
*parent
,
341 const frame_region
*calling_frame
,
342 const function
&fun
, int index
)
343 : space_region (id
, parent
), m_calling_frame (calling_frame
),
344 m_fun (fun
), m_index (index
)
349 enum region_kind
get_kind () const final override
{ return RK_FRAME
; }
350 const frame_region
* dyn_cast_frame_region () const final override
354 void accept (visitor
*v
) const final override
;
355 void dump_to_pp (pretty_printer
*pp
, bool simple
) const final override
;
358 const frame_region
*get_calling_frame () const { return m_calling_frame
; }
359 const function
&get_function () const { return m_fun
; }
360 tree
get_fndecl () const { return get_function ().decl
; }
361 int get_index () const { return m_index
; }
362 int get_stack_depth () const { return m_index
+ 1; }
365 get_region_for_local (region_model_manager
*mgr
,
367 const region_model_context
*ctxt
) const;
369 unsigned get_num_locals () const { return m_locals
.elements (); }
371 /* Implemented in region-model-manager.cc. */
372 void dump_untracked_regions () const;
375 const frame_region
*m_calling_frame
;
376 const function
&m_fun
;
379 /* The regions for the decls within this frame are managed by this
380 object, rather than the region_model_manager, to make it a simple
382 typedef hash_map
<tree
, decl_region
*> map_t
;
391 is_a_helper
<const frame_region
*>::test (const region
*reg
)
393 return reg
->get_kind () == RK_FRAME
;
396 template <> struct default_hash_traits
<frame_region::key_t
>
397 : public member_function_hash_traits
<frame_region::key_t
>
399 static const bool empty_zero_p
= true;
404 /* Concrete space_region subclass, to hold global variables (data and bss). */
406 class globals_region
: public space_region
409 globals_region (symbol::id_t id
, const region
*parent
)
410 : space_region (id
, parent
)
414 enum region_kind
get_kind () const final override
{ return RK_GLOBALS
; }
415 void dump_to_pp (pretty_printer
*pp
, bool simple
) const final override
;
423 is_a_helper
<const globals_region
*>::test (const region
*reg
)
425 return reg
->get_kind () == RK_GLOBALS
;
430 /* Concrete space_region subclass, representing the code segment
431 containing functions. */
433 class code_region
: public space_region
436 code_region (symbol::id_t id
, const region
*parent
)
437 : space_region (id
, parent
)
441 void dump_to_pp (pretty_printer
*pp
, bool simple
) const final override
;
442 enum region_kind
get_kind () const final override
{ return RK_CODE
; }
450 is_a_helper
<const code_region
*>::test (const region
*reg
)
452 return reg
->get_kind () == RK_CODE
;
457 /* Concrete region subclass. A region representing the code for
458 a particular function. */
460 class function_region
: public region
463 function_region (symbol::id_t id
, const code_region
*parent
, tree fndecl
)
464 : region (complexity (parent
), id
, parent
, TREE_TYPE (fndecl
)),
467 gcc_assert (FUNC_OR_METHOD_TYPE_P (TREE_TYPE (fndecl
)));
471 void dump_to_pp (pretty_printer
*pp
, bool simple
) const final override
;
472 enum region_kind
get_kind () const final override
{ return RK_FUNCTION
; }
473 const function_region
*
474 dyn_cast_function_region () const final override
{ return this; }
476 tree
get_fndecl () const { return m_fndecl
; }
487 is_a_helper
<const function_region
*>::test (const region
*reg
)
489 return reg
->get_kind () == RK_FUNCTION
;
494 /* Concrete region subclass. A region representing a particular label
495 within a function. */
497 class label_region
: public region
500 label_region (symbol::id_t id
, const function_region
*parent
, tree label
)
501 : region (complexity (parent
), id
, parent
, NULL_TREE
), m_label (label
)
503 gcc_assert (TREE_CODE (label
) == LABEL_DECL
);
507 void dump_to_pp (pretty_printer
*pp
, bool simple
) const final override
;
508 enum region_kind
get_kind () const final override
{ return RK_LABEL
; }
510 tree
get_label () const { return m_label
; }
521 is_a_helper
<const label_region
*>::test (const region
*reg
)
523 return reg
->get_kind () == RK_LABEL
;
528 /* Concrete space_region subclass representing a stack, containing all stack
531 class stack_region
: public space_region
534 stack_region (symbol::id_t id
, region
*parent
)
535 : space_region (id
, parent
)
538 void dump_to_pp (pretty_printer
*pp
, bool simple
) const final override
;
540 enum region_kind
get_kind () const final override
{ return RK_STACK
; }
548 is_a_helper
<const stack_region
*>::test (const region
*reg
)
550 return reg
->get_kind () == RK_STACK
;
555 /* Concrete space_region subclass: a region within which regions can be
556 dynamically allocated. */
558 class heap_region
: public space_region
561 heap_region (symbol::id_t id
, region
*parent
)
562 : space_region (id
, parent
)
565 enum region_kind
get_kind () const final override
{ return RK_HEAP
; }
566 void dump_to_pp (pretty_printer
*pp
, bool simple
) const final override
;
574 is_a_helper
<const heap_region
*>::test (const region
*reg
)
576 return reg
->get_kind () == RK_HEAP
;
581 /* Concrete space_region subclass: thread-local data for the thread
584 class thread_local_region
: public space_region
587 thread_local_region (symbol::id_t id
, region
*parent
)
588 : space_region (id
, parent
)
591 enum region_kind
get_kind () const final override
{ return RK_THREAD_LOCAL
; }
592 void dump_to_pp (pretty_printer
*pp
, bool simple
) const final override
;
600 is_a_helper
<const thread_local_region
*>::test (const region
*reg
)
602 return reg
->get_kind () == RK_THREAD_LOCAL
;
607 /* Concrete region subclass. The root region, containing all regions
608 (either directly, or as descendents).
609 Unique within a region_model_manager. */
611 class root_region
: public region
614 root_region (symbol::id_t id
);
616 enum region_kind
get_kind () const final override
{ return RK_ROOT
; }
617 void dump_to_pp (pretty_printer
*pp
, bool simple
) const final override
;
625 is_a_helper
<const root_region
*>::test (const region
*reg
)
627 return reg
->get_kind () == RK_ROOT
;
632 /* Concrete region subclass: a region to use when dereferencing an unknown
635 class symbolic_region
: public region
638 /* A support class for uniquifying instances of symbolic_region. */
641 key_t (const region
*parent
, const svalue
*sval_ptr
)
642 : m_parent (parent
), m_sval_ptr (sval_ptr
)
644 gcc_assert (sval_ptr
);
647 hashval_t
hash () const
649 inchash::hash hstate
;
650 hstate
.add_ptr (m_parent
);
651 hstate
.add_ptr (m_sval_ptr
);
652 return hstate
.end ();
655 bool operator== (const key_t
&other
) const
657 return (m_parent
== other
.m_parent
&& m_sval_ptr
== other
.m_sval_ptr
);
660 void mark_deleted () { m_sval_ptr
= reinterpret_cast<const svalue
*> (1); }
661 void mark_empty () { m_sval_ptr
= NULL
; }
662 bool is_deleted () const
664 return m_sval_ptr
== reinterpret_cast<const svalue
*> (1);
666 bool is_empty () const { return m_sval_ptr
== NULL
; }
668 const region
*m_parent
;
669 const svalue
*m_sval_ptr
;
672 symbolic_region (symbol::id_t id
, region
*parent
, const svalue
*sval_ptr
);
674 const symbolic_region
*
675 dyn_cast_symbolic_region () const final override
{ return this; }
677 enum region_kind
get_kind () const final override
{ return RK_SYMBOLIC
; }
678 void accept (visitor
*v
) const final override
;
679 void dump_to_pp (pretty_printer
*pp
, bool simple
) const final override
;
681 const svalue
*get_pointer () const { return m_sval_ptr
; }
684 const svalue
*m_sval_ptr
;
692 is_a_helper
<const symbolic_region
*>::test (const region
*reg
)
694 return reg
->get_kind () == RK_SYMBOLIC
;
697 template <> struct default_hash_traits
<symbolic_region::key_t
>
698 : public member_function_hash_traits
<symbolic_region::key_t
>
700 static const bool empty_zero_p
= true;
705 /* Concrete region subclass representing the memory occupied by a
706 variable (whether for a global or a local).
707 Also used for representing SSA names, as if they were locals. */
709 class decl_region
: public region
712 decl_region (symbol::id_t id
, const region
*parent
, tree decl
)
713 : region (complexity (parent
), id
, parent
, TREE_TYPE (decl
)), m_decl (decl
),
714 m_tracked (calc_tracked_p (decl
)),
718 enum region_kind
get_kind () const final override
{ return RK_DECL
; }
720 dyn_cast_decl_region () const final override
{ return this; }
722 void dump_to_pp (pretty_printer
*pp
, bool simple
) const final override
;
724 bool tracked_p () const final override
{ return m_tracked
; }
726 tree
get_decl () const { return m_decl
; }
727 int get_stack_depth () const;
729 const svalue
*maybe_get_constant_value (region_model_manager
*mgr
) const;
730 const svalue
*get_svalue_for_constructor (tree ctor
,
731 region_model_manager
*mgr
) const;
732 const svalue
*get_svalue_for_initializer (region_model_manager
*mgr
) const;
735 const svalue
*calc_svalue_for_constructor (tree ctor
,
736 region_model_manager
*mgr
) const;
737 static bool calc_tracked_p (tree decl
);
741 /* Cached result of calc_tracked_p, so that we can quickly determine when
742 we don't to track a binding_cluster for this decl (to avoid bloating
744 This can be debugged using -fdump-analyzer-untracked. */
747 /* Cached result of get_svalue_for_constructor. */
748 mutable const svalue
*m_ctor_svalue
;
756 is_a_helper
<const decl_region
*>::test (const region
*reg
)
758 return reg
->get_kind () == RK_DECL
;
763 /* Concrete region subclass representing the memory occupied by a
764 field within a struct or union. */
766 class field_region
: public region
769 /* A support class for uniquifying instances of field_region. */
772 key_t (const region
*parent
, tree field
)
773 : m_parent (parent
), m_field (field
)
778 hashval_t
hash () const
780 inchash::hash hstate
;
781 hstate
.add_ptr (m_parent
);
782 hstate
.add_ptr (m_field
);
783 return hstate
.end ();
786 bool operator== (const key_t
&other
) const
788 return (m_parent
== other
.m_parent
&& m_field
== other
.m_field
);
791 void mark_deleted () { m_field
= reinterpret_cast<tree
> (1); }
792 void mark_empty () { m_field
= NULL_TREE
; }
793 bool is_deleted () const { return m_field
== reinterpret_cast<tree
> (1); }
794 bool is_empty () const { return m_field
== NULL_TREE
; }
796 const region
*m_parent
;
800 field_region (symbol::id_t id
, const region
*parent
, tree field
)
801 : region (complexity (parent
), id
, parent
, TREE_TYPE (field
)),
805 enum region_kind
get_kind () const final override
{ return RK_FIELD
; }
807 void dump_to_pp (pretty_printer
*pp
, bool simple
) const final override
;
809 dyn_cast_field_region () const final override
{ return this; }
811 tree
get_field () const { return m_field
; }
813 bool get_relative_concrete_offset (bit_offset_t
*out
) const final override
;
814 const svalue
*get_relative_symbolic_offset (region_model_manager
*mgr
)
815 const final override
;
826 is_a_helper
<const field_region
*>::test (const region
*reg
)
828 return reg
->get_kind () == RK_FIELD
;
831 template <> struct default_hash_traits
<field_region::key_t
>
832 : public member_function_hash_traits
<field_region::key_t
>
834 static const bool empty_zero_p
= true;
839 /* An element within an array. */
841 class element_region
: public region
844 /* A support class for uniquifying instances of element_region. */
847 key_t (const region
*parent
, tree element_type
, const svalue
*index
)
848 : m_parent (parent
), m_element_type (element_type
), m_index (index
)
853 hashval_t
hash () const
855 inchash::hash hstate
;
856 hstate
.add_ptr (m_parent
);
857 hstate
.add_ptr (m_element_type
);
858 hstate
.add_ptr (m_index
);
859 return hstate
.end ();
862 bool operator== (const key_t
&other
) const
864 return (m_parent
== other
.m_parent
865 && m_element_type
== other
.m_element_type
866 && m_index
== other
.m_index
);
869 void mark_deleted () { m_index
= reinterpret_cast<const svalue
*> (1); }
870 void mark_empty () { m_index
= NULL
; }
871 bool is_deleted () const
873 return m_index
== reinterpret_cast<const svalue
*> (1);
875 bool is_empty () const { return m_index
== NULL
; }
877 const region
*m_parent
;
879 const svalue
*m_index
;
882 element_region (symbol::id_t id
, const region
*parent
, tree element_type
,
884 : region (complexity::from_pair (parent
, index
), id
, parent
, element_type
),
888 enum region_kind
get_kind () const final override
{ return RK_ELEMENT
; }
889 const element_region
*
890 dyn_cast_element_region () const final override
{ return this; }
892 void accept (visitor
*v
) const final override
;
894 void dump_to_pp (pretty_printer
*pp
, bool simple
) const final override
;
896 const svalue
*get_index () const { return m_index
; }
899 get_relative_concrete_offset (bit_offset_t
*out
) const final override
;
900 const svalue
*get_relative_symbolic_offset (region_model_manager
*mgr
)
901 const final override
;
904 const svalue
*m_index
;
912 is_a_helper
<const element_region
*>::test (const region
*reg
)
914 return reg
->get_kind () == RK_ELEMENT
;
917 template <> struct default_hash_traits
<element_region::key_t
>
918 : public member_function_hash_traits
<element_region::key_t
>
920 static const bool empty_zero_p
= true;
925 /* A byte-offset within another region, for handling pointer arithmetic
928 class offset_region
: public region
931 /* A support class for uniquifying instances of offset_region. */
934 key_t (const region
*parent
, tree element_type
, const svalue
*byte_offset
)
935 : m_parent (parent
), m_element_type (element_type
), m_byte_offset (byte_offset
)
937 gcc_assert (byte_offset
);
940 hashval_t
hash () const
942 inchash::hash hstate
;
943 hstate
.add_ptr (m_parent
);
944 hstate
.add_ptr (m_element_type
);
945 hstate
.add_ptr (m_byte_offset
);
946 return hstate
.end ();
949 bool operator== (const key_t
&other
) const
951 return (m_parent
== other
.m_parent
952 && m_element_type
== other
.m_element_type
953 && m_byte_offset
== other
.m_byte_offset
);
956 void mark_deleted () { m_byte_offset
= reinterpret_cast<const svalue
*> (1); }
957 void mark_empty () { m_byte_offset
= NULL
; }
958 bool is_deleted () const
960 return m_byte_offset
== reinterpret_cast<const svalue
*> (1);
962 bool is_empty () const { return m_byte_offset
== NULL
; }
964 const region
*m_parent
;
966 const svalue
*m_byte_offset
;
969 offset_region (symbol::id_t id
, const region
*parent
, tree type
,
970 const svalue
*byte_offset
)
971 : region (complexity::from_pair (parent
, byte_offset
), id
, parent
, type
),
972 m_byte_offset (byte_offset
)
975 enum region_kind
get_kind () const final override
{ return RK_OFFSET
; }
976 const offset_region
*
977 dyn_cast_offset_region () const final override
{ return this; }
979 void accept (visitor
*v
) const final override
;
981 void dump_to_pp (pretty_printer
*pp
, bool simple
) const final override
;
983 const svalue
*get_byte_offset () const { return m_byte_offset
; }
984 const svalue
*get_bit_offset (region_model_manager
*mgr
) const;
986 bool get_relative_concrete_offset (bit_offset_t
*out
) const final override
;
987 const svalue
*get_relative_symbolic_offset (region_model_manager
*mgr
)
988 const final override
;
991 const svalue
*m_byte_offset
;
999 is_a_helper
<const offset_region
*>::test (const region
*reg
)
1001 return reg
->get_kind () == RK_OFFSET
;
1004 template <> struct default_hash_traits
<offset_region::key_t
>
1005 : public member_function_hash_traits
<offset_region::key_t
>
1007 static const bool empty_zero_p
= true;
1012 /* A region that is size BYTES_SIZE_SVAL in size within its parent
1013 region (or possibly larger, which would lead to an overflow. */
1015 class sized_region
: public region
1018 /* A support class for uniquifying instances of sized_region. */
1021 key_t (const region
*parent
, tree element_type
,
1022 const svalue
*byte_size_sval
)
1023 : m_parent (parent
), m_element_type (element_type
),
1024 m_byte_size_sval (byte_size_sval
)
1026 gcc_assert (byte_size_sval
);
1029 hashval_t
hash () const
1031 inchash::hash hstate
;
1032 hstate
.add_ptr (m_parent
);
1033 hstate
.add_ptr (m_element_type
);
1034 hstate
.add_ptr (m_byte_size_sval
);
1035 return hstate
.end ();
1038 bool operator== (const key_t
&other
) const
1040 return (m_parent
== other
.m_parent
1041 && m_element_type
== other
.m_element_type
1042 && m_byte_size_sval
== other
.m_byte_size_sval
);
1045 void mark_deleted () { m_byte_size_sval
= reinterpret_cast<const svalue
*> (1); }
1046 void mark_empty () { m_byte_size_sval
= NULL
; }
1047 bool is_deleted () const
1049 return m_byte_size_sval
== reinterpret_cast<const svalue
*> (1);
1051 bool is_empty () const { return m_byte_size_sval
== NULL
; }
1053 const region
*m_parent
;
1054 tree m_element_type
;
1055 const svalue
*m_byte_size_sval
;
1056 const svalue
*m_end_offset
;
1059 sized_region (symbol::id_t id
, const region
*parent
, tree type
,
1060 const svalue
*byte_size_sval
)
1061 : region (complexity::from_pair (parent
, byte_size_sval
),
1063 m_byte_size_sval (byte_size_sval
)
1066 enum region_kind
get_kind () const final override
{ return RK_SIZED
; }
1067 const sized_region
*
1068 dyn_cast_sized_region () const final override
{ return this; }
1070 void accept (visitor
*v
) const final override
;
1072 void dump_to_pp (pretty_printer
*pp
, bool simple
) const final override
;
1074 bool get_byte_size (byte_size_t
*out
) const final override
;
1075 bool get_bit_size (bit_size_t
*out
) const final override
;
1078 get_byte_size_sval (region_model_manager
*) const final override
1080 return m_byte_size_sval
;
1084 get_bit_size_sval (region_model_manager
*) const final override
;
1087 const svalue
*m_byte_size_sval
;
1095 is_a_helper
<const sized_region
*>::test (const region
*reg
)
1097 return reg
->get_kind () == RK_SIZED
;
1100 template <> struct default_hash_traits
<sized_region::key_t
>
1101 : public member_function_hash_traits
<sized_region::key_t
>
1103 static const bool empty_zero_p
= true;
1108 /* A region that views another region using a different type. */
1110 class cast_region
: public region
1113 /* A support class for uniquifying instances of cast_region. */
1116 key_t (const region
*original_region
, tree type
)
1117 : m_original_region (original_region
), m_type (type
)
1119 gcc_assert (original_region
);
1122 hashval_t
hash () const
1124 inchash::hash hstate
;
1125 hstate
.add_ptr (m_original_region
);
1126 hstate
.add_ptr (m_type
);
1127 return hstate
.end ();
1130 bool operator== (const key_t
&other
) const
1132 return (m_original_region
== other
.m_original_region
1133 && m_type
== other
.m_type
);
1136 void mark_deleted ()
1138 m_original_region
= reinterpret_cast<const region
*> (1);
1140 void mark_empty () { m_original_region
= nullptr; }
1141 bool is_deleted () const
1143 return m_original_region
== reinterpret_cast<const region
*> (1);
1145 bool is_empty () const { return m_original_region
== nullptr; }
1147 const region
*m_original_region
;
1151 cast_region (symbol::id_t id
, const region
*original_region
, tree type
)
1152 : region (complexity (original_region
), id
,
1153 original_region
->get_parent_region (), type
),
1154 m_original_region (original_region
)
1157 enum region_kind
get_kind () const final override
{ return RK_CAST
; }
1159 dyn_cast_cast_region () const final override
{ return this; }
1160 void accept (visitor
*v
) const final override
;
1161 void dump_to_pp (pretty_printer
*pp
, bool simple
) const final override
;
1163 bool get_relative_concrete_offset (bit_offset_t
*out
) const final override
;
1165 const region
*get_original_region () const { return m_original_region
; }
1168 const region
*m_original_region
;
1176 is_a_helper
<const cast_region
*>::test (const region
*reg
)
1178 return reg
->get_kind () == RK_CAST
;
1181 template <> struct default_hash_traits
<cast_region::key_t
>
1182 : public member_function_hash_traits
<cast_region::key_t
>
1184 static const bool empty_zero_p
= true;
1189 /* An untyped region dynamically allocated on the heap via "malloc"
1192 class heap_allocated_region
: public region
1195 heap_allocated_region (symbol::id_t id
, const region
*parent
)
1196 : region (complexity (parent
), id
, parent
, NULL_TREE
)
1200 get_kind () const final override
{ return RK_HEAP_ALLOCATED
; }
1202 void dump_to_pp (pretty_printer
*pp
, bool simple
) const final override
;
1205 /* An untyped region dynamically allocated on the stack via "alloca". */
1207 class alloca_region
: public region
1210 alloca_region (symbol::id_t id
, const frame_region
*parent
)
1211 : region (complexity (parent
), id
, parent
, NULL_TREE
)
1214 enum region_kind
get_kind () const final override
{ return RK_ALLOCA
; }
1216 void dump_to_pp (pretty_printer
*pp
, bool simple
) const final override
;
1219 /* A region for a STRING_CST. */
1221 class string_region
: public region
1224 string_region (symbol::id_t id
, const region
*parent
, tree string_cst
)
1225 : region (complexity (parent
), id
, parent
, TREE_TYPE (string_cst
)),
1226 m_string_cst (string_cst
)
1229 const string_region
*
1230 dyn_cast_string_region () const final override
{ return this; }
1232 enum region_kind
get_kind () const final override
{ return RK_STRING
; }
1234 void dump_to_pp (pretty_printer
*pp
, bool simple
) const final override
;
1236 /* We assume string literals are immutable, so we don't track them in
1238 bool tracked_p () const final override
{ return false; }
1240 tree
get_string_cst () const { return m_string_cst
; }
1251 is_a_helper
<const string_region
*>::test (const region
*reg
)
1253 return reg
->get_kind () == RK_STRING
;
1258 /* A region for a specific range of bits within another region. */
1260 class bit_range_region
: public region
1263 /* A support class for uniquifying instances of bit_range_region. */
1266 key_t (const region
*parent
, tree type
, const bit_range
&bits
)
1267 : m_parent (parent
), m_type (type
), m_bits (bits
)
1269 gcc_assert (parent
);
1272 hashval_t
hash () const
1274 inchash::hash hstate
;
1275 hstate
.add_ptr (m_parent
);
1276 hstate
.add_ptr (m_type
);
1277 hstate
.add_wide_int (m_bits
.m_start_bit_offset
);
1278 hstate
.add_wide_int (m_bits
.m_size_in_bits
);
1279 return hstate
.end ();
1282 bool operator== (const key_t
&other
) const
1284 return (m_parent
== other
.m_parent
1285 && m_type
== other
.m_type
1286 && m_bits
== other
.m_bits
);
1289 void mark_deleted () { m_parent
= reinterpret_cast<const region
*> (1); }
1290 void mark_empty () { m_parent
= NULL
; }
1291 bool is_deleted () const
1293 return m_parent
== reinterpret_cast<const region
*> (1);
1295 bool is_empty () const { return m_parent
== NULL
; }
1297 const region
*m_parent
;
1302 bit_range_region (symbol::id_t id
, const region
*parent
, tree type
,
1303 const bit_range
&bits
)
1304 : region (complexity (parent
), id
, parent
, type
),
1308 const bit_range_region
*
1309 dyn_cast_bit_range_region () const final override
{ return this; }
1311 enum region_kind
get_kind () const final override
{ return RK_BIT_RANGE
; }
1313 void dump_to_pp (pretty_printer
*pp
, bool simple
) const final override
;
1315 const bit_range
&get_bits () const { return m_bits
; }
1317 bool get_byte_size (byte_size_t
*out
) const final override
;
1318 bool get_bit_size (bit_size_t
*out
) const final override
;
1319 const svalue
*get_byte_size_sval (region_model_manager
*mgr
) const final override
;
1320 const svalue
*get_bit_size_sval (region_model_manager
*mgr
) const final override
;
1321 bool get_relative_concrete_offset (bit_offset_t
*out
) const final override
;
1322 const svalue
*get_relative_symbolic_offset (region_model_manager
*mgr
)
1323 const final override
;
1334 is_a_helper
<const bit_range_region
*>::test (const region
*reg
)
1336 return reg
->get_kind () == RK_BIT_RANGE
;
1339 template <> struct default_hash_traits
<bit_range_region::key_t
>
1340 : public member_function_hash_traits
<bit_range_region::key_t
>
1342 static const bool empty_zero_p
= true;
1347 /* A region for the N-th vararg within a frame_region for a variadic call. */
1349 class var_arg_region
: public region
1352 /* A support class for uniquifying instances of var_arg_region. */
1355 key_t (const frame_region
*parent
, unsigned idx
)
1356 : m_parent (parent
), m_idx (idx
)
1358 gcc_assert (parent
);
1361 hashval_t
hash () const
1363 inchash::hash hstate
;
1364 hstate
.add_ptr (m_parent
);
1365 hstate
.add_int (m_idx
);
1366 return hstate
.end ();
1369 bool operator== (const key_t
&other
) const
1371 return (m_parent
== other
.m_parent
1372 && m_idx
== other
.m_idx
);
1375 void mark_deleted ()
1377 m_parent
= reinterpret_cast<const frame_region
*> (1);
1379 void mark_empty () { m_parent
= NULL
; }
1380 bool is_deleted () const
1382 return m_parent
== reinterpret_cast<const frame_region
*> (1);
1384 bool is_empty () const { return m_parent
== NULL
; }
1386 const frame_region
*m_parent
;
1390 var_arg_region (symbol::id_t id
, const frame_region
*parent
,
1392 : region (complexity (parent
), id
, parent
, NULL_TREE
),
1396 const var_arg_region
*
1397 dyn_cast_var_arg_region () const final override
{ return this; }
1399 enum region_kind
get_kind () const final override
{ return RK_VAR_ARG
; }
1401 void dump_to_pp (pretty_printer
*pp
, bool simple
) const final override
;
1403 const frame_region
*get_frame_region () const;
1404 unsigned get_index () const { return m_idx
; }
1415 is_a_helper
<const var_arg_region
*>::test (const region
*reg
)
1417 return reg
->get_kind () == RK_VAR_ARG
;
1420 template <> struct default_hash_traits
<var_arg_region::key_t
>
1421 : public member_function_hash_traits
<var_arg_region::key_t
>
1423 static const bool empty_zero_p
= true;
1428 /* A region for errno for the current thread. */
1430 class errno_region
: public region
1433 errno_region (symbol::id_t id
, const thread_local_region
*parent
)
1434 : region (complexity (parent
), id
, parent
, integer_type_node
)
1437 enum region_kind
get_kind () const final override
{ return RK_ERRNO
; }
1439 void dump_to_pp (pretty_printer
*pp
, bool simple
) const final override
;
1447 is_a_helper
<const errno_region
*>::test (const region
*reg
)
1449 return reg
->get_kind () == RK_ERRNO
;
1454 /* Similar to a decl region, but we don't have the decl.
1455 For implementing e.g. static buffers of known_functions,
1456 or other internal state of an API.
1458 These are owned by known_function instances, rather than the
1459 region_model_manager. */
1461 class private_region
: public region
1464 private_region (unsigned id
, const region
*parent
, tree type
,
1466 : region (complexity (parent
), id
, parent
, type
),
1470 enum region_kind
get_kind () const final override
{ return RK_PRIVATE
; }
1472 void dump_to_pp (pretty_printer
*pp
, bool simple
) const final override
;
1483 is_a_helper
<const private_region
*>::test (const region
*reg
)
1485 return reg
->get_kind () == RK_PRIVATE
;
1490 /* An unknown region, for handling unimplemented tree codes. */
1492 class unknown_region
: public region
1495 unknown_region (symbol::id_t id
, const region
*parent
, tree type
)
1496 : region (complexity (parent
), id
, parent
, type
)
1499 enum region_kind
get_kind () const final override
{ return RK_UNKNOWN
; }
1501 void dump_to_pp (pretty_printer
*pp
, bool simple
) const final override
;
1506 #endif /* GCC_ANALYZER_REGION_H */