Branch data Line data Source code
1 : : /* Regions of memory.
2 : : Copyright (C) 2019-2024 Free Software Foundation, Inc.
3 : : Contributed by David Malcolm <dmalcolm@redhat.com>.
4 : :
5 : : This file is part of GCC.
6 : :
7 : : GCC is free software; you can redistribute it and/or modify it
8 : : under the terms of the GNU General Public License as published by
9 : : the Free Software Foundation; either version 3, or (at your option)
10 : : any later version.
11 : :
12 : : GCC is distributed in the hope that it will be useful, but
13 : : WITHOUT ANY WARRANTY; without even the implied warranty of
14 : : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 : : General Public License for more details.
16 : :
17 : : You should have received a copy of the GNU General Public License
18 : : along with GCC; see the file COPYING3. If not see
19 : : <http://www.gnu.org/licenses/>. */
20 : :
21 : : #ifndef GCC_ANALYZER_REGION_H
22 : : #define GCC_ANALYZER_REGION_H
23 : :
24 : : #include "analyzer/symbol.h"
25 : :
26 : : namespace ana {
27 : :
28 : : /* An enum for identifying different spaces within memory. */
29 : :
30 : : enum memory_space
31 : : {
32 : : MEMSPACE_UNKNOWN,
33 : : MEMSPACE_CODE,
34 : : MEMSPACE_GLOBALS,
35 : : MEMSPACE_STACK,
36 : : MEMSPACE_HEAP,
37 : : MEMSPACE_READONLY_DATA,
38 : : MEMSPACE_THREAD_LOCAL,
39 : : MEMSPACE_PRIVATE
40 : : };
41 : :
42 : : /* An enum for discriminating between the different concrete subclasses
43 : : of region. */
44 : :
45 : : enum region_kind
46 : : {
47 : : RK_FRAME,
48 : : RK_GLOBALS,
49 : : RK_CODE,
50 : : RK_FUNCTION,
51 : : RK_LABEL,
52 : : RK_STACK,
53 : : RK_HEAP,
54 : : RK_THREAD_LOCAL,
55 : : RK_ROOT,
56 : : RK_SYMBOLIC,
57 : : RK_DECL,
58 : : RK_FIELD,
59 : : RK_ELEMENT,
60 : : RK_OFFSET,
61 : : RK_SIZED,
62 : : RK_CAST,
63 : : RK_HEAP_ALLOCATED,
64 : : RK_ALLOCA,
65 : : RK_STRING,
66 : : RK_BIT_RANGE,
67 : : RK_VAR_ARG,
68 : : RK_ERRNO,
69 : : RK_PRIVATE,
70 : : RK_UNKNOWN,
71 : : };
72 : :
73 : : /* Region and its subclasses.
74 : :
75 : : The class hierarchy looks like this (using indentation to show
76 : : inheritance, and with region_kinds shown for the concrete subclasses):
77 : :
78 : : region
79 : : space_region
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
86 : : being analyzed
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,
92 : : or SSA name
93 : : field_region (RK_FIELD): the memory occupied by a field within a struct
94 : : or union
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)
99 : : within its parent
100 : : cast_region (RK_CAST): a region that views another region using a
101 : : different type
102 : : heap_allocated_region (RK_HEAP_ALLOCATED): an untyped region dynamically
103 : : allocated on the heap via
104 : : "malloc" or similar
105 : : alloca_region (RK_ALLOCA): an untyped region dynamically allocated on the
106 : : stack via "alloca"
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. */
115 : :
116 : : /* Abstract base class for representing ways of accessing chunks of memory.
117 : :
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. */
123 : :
124 : : class region : public symbol
125 : : {
126 : : public:
127 : : virtual ~region ();
128 : :
129 : : virtual enum region_kind get_kind () const = 0;
130 : : virtual const frame_region *
131 : 4822778 : dyn_cast_frame_region () const { return NULL; }
132 : : virtual const function_region *
133 : 37680 : dyn_cast_function_region () const { return NULL; }
134 : : virtual const symbolic_region *
135 : 14279958 : dyn_cast_symbolic_region () const { return NULL; }
136 : : virtual const decl_region *
137 : 1458330 : dyn_cast_decl_region () const { return NULL; }
138 : : virtual const field_region *
139 : 257 : dyn_cast_field_region () const { return NULL; }
140 : : virtual const element_region *
141 : 2981783 : dyn_cast_element_region () const { return NULL; }
142 : : virtual const offset_region *
143 : 2894031 : dyn_cast_offset_region () const { return NULL; }
144 : : virtual const sized_region *
145 : 0 : dyn_cast_sized_region () const { return NULL; }
146 : : virtual const cast_region *
147 : 6078114 : dyn_cast_cast_region () const { return NULL; }
148 : : virtual const string_region *
149 : 34156 : dyn_cast_string_region () const { return NULL; }
150 : : virtual const bit_range_region *
151 : 0 : dyn_cast_bit_range_region () const { return NULL; }
152 : : virtual const var_arg_region *
153 : 0 : dyn_cast_var_arg_region () const { return NULL; }
154 : :
155 : : virtual void accept (visitor *v) const;
156 : :
157 : 42726122 : 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;
165 : :
166 : : tree maybe_get_decl () const;
167 : :
168 : 19480005 : tree get_type () const { return m_type; }
169 : :
170 : : void print (const region_model &model,
171 : : pretty_printer *pp) const;
172 : : label_text get_desc (bool simple=true) const;
173 : :
174 : : virtual void dump_to_pp (pretty_printer *pp, bool simple) const = 0;
175 : : void dump (bool simple) const;
176 : :
177 : : json::value *to_json () const;
178 : :
179 : : bool maybe_print_for_user (pretty_printer *pp,
180 : : const region_model &model) const;
181 : :
182 : : bool non_null_p () const;
183 : :
184 : : static int cmp_ptr_ptr (const void *, const void *);
185 : :
186 : : bool involves_p (const svalue *sval) const;
187 : :
188 : : region_offset get_offset (region_model_manager *mgr) const;
189 : : region_offset get_next_offset (region_model_manager *mgr) const;
190 : :
191 : : /* Attempt to get the size of this region as a concrete number of bytes.
192 : : If successful, return true and write the size to *OUT.
193 : : Otherwise return false.
194 : : This is the accessed size, not necessarily the size that's valid to
195 : : access. */
196 : : virtual bool get_byte_size (byte_size_t *out) const;
197 : :
198 : : /* Attempt to get the size of this region as a concrete number of bits.
199 : : If successful, return true and write the size to *OUT.
200 : : Otherwise return false.
201 : : This is the accessed size, not necessarily the size that's valid to
202 : : access. */
203 : : virtual bool get_bit_size (bit_size_t *out) const;
204 : :
205 : : /* Get a symbolic value describing the size of this region in bytes
206 : : (which could be "unknown").
207 : : This is the accessed size, not necessarily the size that's valid to
208 : : access. */
209 : : virtual const svalue *get_byte_size_sval (region_model_manager *mgr) const;
210 : :
211 : : /* Get a symbolic value describing the size of this region in bits
212 : : (which could be "unknown").
213 : : This is the accessed size, not necessarily the size that's valid to
214 : : access. */
215 : : virtual const svalue *get_bit_size_sval (region_model_manager *mgr) const;
216 : :
217 : : /* Attempt to get the offset in bits of this region relative to its parent.
218 : : If successful, return true and write to *OUT.
219 : : Otherwise return false. */
220 : : virtual bool get_relative_concrete_offset (bit_offset_t *out) const;
221 : :
222 : : /* Get the offset in bytes of this region relative to its parent as a svalue.
223 : : Might return an unknown_svalue. */
224 : : virtual const svalue *
225 : : get_relative_symbolic_offset (region_model_manager *mgr) const;
226 : :
227 : : /* Attempt to get the position and size of this region expressed as a
228 : : concrete range of bytes relative to its parent.
229 : : If successful, return true and write to *OUT.
230 : : Otherwise return false. */
231 : : bool get_relative_concrete_byte_range (byte_range *out) const;
232 : :
233 : : void
234 : : get_subregions_for_binding (region_model_manager *mgr,
235 : : bit_offset_t start_bit_offset,
236 : : bit_size_t size_in_bits,
237 : : tree type,
238 : : auto_vec <const region *> *out) const;
239 : :
240 : : bool symbolic_for_unknown_ptr_p () const;
241 : :
242 : : bool symbolic_p () const;
243 : :
244 : : /* For most base regions it makes sense to track the bindings of the region
245 : : within the store. As an optimization, some are not tracked (to avoid
246 : : bloating the store object with redundant binding clusters). */
247 : 620127 : virtual bool tracked_p () const { return true; }
248 : :
249 : : bool is_named_decl_p (const char *decl_name) const;
250 : :
251 : : bool empty_p () const;
252 : :
253 : : protected:
254 : : region (complexity c, symbol::id_t id, const region *parent, tree type);
255 : :
256 : : private:
257 : : region_offset calc_offset (region_model_manager *mgr) const;
258 : : const svalue *calc_initial_value_at_main (region_model_manager *mgr) const;
259 : :
260 : : const region *m_parent;
261 : : tree m_type;
262 : :
263 : : mutable region_offset *m_cached_offset;
264 : :
265 : : /* For regions within a global decl, a cache of the svalue for the initial
266 : : value of this region when the program starts. */
267 : : mutable const svalue *m_cached_init_sval_at_main;
268 : : };
269 : :
270 : : } // namespace ana
271 : :
272 : : template <>
273 : : template <>
274 : : inline bool
275 : : is_a_helper <const region *>::test (const region *)
276 : : {
277 : : return true;
278 : : }
279 : :
280 : : namespace ana {
281 : :
282 : : /* Abstract subclass of region, for regions that represent an untyped
283 : : space within memory, such as the stack or the heap. */
284 : :
285 : 37367 : class space_region : public region
286 : : {
287 : : protected:
288 : 37367 : space_region (symbol::id_t id, const region *parent)
289 : 37367 : : region (complexity (parent), id, parent, NULL_TREE)
290 : 37367 : {}
291 : : };
292 : :
293 : : /* Concrete space_region subclass, representing a function frame on the stack,
294 : : to contain the locals.
295 : : The parent is the stack region; there's also a hierarchy of call-stack
296 : : prefixes expressed via m_calling_frame.
297 : : For example, given "oldest" calling "middle" called "newest" we would have
298 : : - a stack depth of 3
299 : : - frame (A) for "oldest" with index 0 for depth 1, calling_frame == NULL
300 : : - frame (B) for "middle" with index 1 for depth 2, calling_frame == (A)
301 : : - frame (C) for "newest" with index 2 for depth 3, calling_frame == (B)
302 : : where the parent region for each of the frames is the "stack" region.
303 : : The index is the count of frames earlier than this in the stack. */
304 : :
305 : : class frame_region : public space_region
306 : : {
307 : : public:
308 : : /* A support class for uniquifying instances of frame_region. */
309 : : struct key_t
310 : : {
311 : 38764 : key_t (const frame_region *calling_frame, const function &fun)
312 : 38764 : : m_calling_frame (calling_frame), m_fun (&fun)
313 : : {
314 : : /* calling_frame can be NULL. */
315 : : }
316 : :
317 : 244375 : hashval_t hash () const
318 : : {
319 : 244375 : inchash::hash hstate;
320 : 244375 : hstate.add_ptr (m_calling_frame);
321 : 244375 : hstate.add_ptr (m_fun);
322 : 244375 : return hstate.end ();
323 : : }
324 : :
325 : 218890 : bool operator== (const key_t &other) const
326 : : {
327 : 218890 : return (m_calling_frame == other.m_calling_frame
328 : 218890 : && m_fun == other.m_fun);
329 : : }
330 : :
331 : : void mark_deleted () { m_fun = reinterpret_cast<function *> (1); }
332 : 0 : void mark_empty () { m_fun = NULL; }
333 : 268491 : bool is_deleted () const
334 : : {
335 : 268491 : return m_fun == reinterpret_cast<function *> (1);
336 : : }
337 : 1120477 : bool is_empty () const { return m_fun == NULL; }
338 : :
339 : : const frame_region *m_calling_frame;
340 : : const function *m_fun;
341 : : };
342 : :
343 : 15822 : frame_region (symbol::id_t id, const region *parent,
344 : : const frame_region *calling_frame,
345 : : const function &fun, int index)
346 : 31644 : : space_region (id, parent), m_calling_frame (calling_frame),
347 : 15822 : m_fun (fun), m_index (index)
348 : 15822 : {}
349 : : ~frame_region ();
350 : :
351 : : /* region vfuncs. */
352 : 15184167 : enum region_kind get_kind () const final override { return RK_FRAME; }
353 : 1860052 : const frame_region * dyn_cast_frame_region () const final override
354 : : {
355 : 1860052 : return this;
356 : : }
357 : : void accept (visitor *v) const final override;
358 : : void dump_to_pp (pretty_printer *pp, bool simple) const final override;
359 : :
360 : : /* Accessors. */
361 : 2721324 : const frame_region *get_calling_frame () const { return m_calling_frame; }
362 : 1708384 : const function &get_function () const { return m_fun; }
363 : 1119 : tree get_fndecl () const { return get_function ().decl; }
364 : 5484612 : int get_index () const { return m_index; }
365 : 5998637 : int get_stack_depth () const { return m_index + 1; }
366 : :
367 : : const decl_region *
368 : : get_region_for_local (region_model_manager *mgr,
369 : : tree expr,
370 : : const region_model_context *ctxt) const;
371 : :
372 : 2 : unsigned get_num_locals () const { return m_locals.elements (); }
373 : :
374 : : /* Implemented in region-model-manager.cc. */
375 : : void dump_untracked_regions () const;
376 : :
377 : : private:
378 : : const frame_region *m_calling_frame;
379 : : const function &m_fun;
380 : : int m_index;
381 : :
382 : : /* The regions for the decls within this frame are managed by this
383 : : object, rather than the region_model_manager, to make it a simple
384 : : lookup by tree. */
385 : : typedef hash_map<tree, decl_region *> map_t;
386 : : map_t m_locals;
387 : : };
388 : :
389 : : } // namespace ana
390 : :
391 : : template <>
392 : : template <>
393 : : inline bool
394 : 566 : is_a_helper <const frame_region *>::test (const region *reg)
395 : : {
396 : 566 : return reg->get_kind () == RK_FRAME;
397 : : }
398 : :
399 : : template <> struct default_hash_traits<frame_region::key_t>
400 : : : public member_function_hash_traits<frame_region::key_t>
401 : : {
402 : : static const bool empty_zero_p = true;
403 : : };
404 : :
405 : : namespace ana {
406 : :
407 : : /* Concrete space_region subclass, to hold global variables (data and bss). */
408 : :
409 : 4309 : class globals_region : public space_region
410 : : {
411 : : public:
412 : 4309 : globals_region (symbol::id_t id, const region *parent)
413 : 4309 : : space_region (id, parent)
414 : : {}
415 : :
416 : : /* region vfuncs. */
417 : 4008407 : enum region_kind get_kind () const final override { return RK_GLOBALS; }
418 : : void dump_to_pp (pretty_printer *pp, bool simple) const final override;
419 : : };
420 : :
421 : : } // namespace ana
422 : :
423 : : template <>
424 : : template <>
425 : : inline bool
426 : : is_a_helper <const globals_region *>::test (const region *reg)
427 : : {
428 : : return reg->get_kind () == RK_GLOBALS;
429 : : }
430 : :
431 : : namespace ana {
432 : :
433 : : /* Concrete space_region subclass, representing the code segment
434 : : containing functions. */
435 : :
436 : 4309 : class code_region : public space_region
437 : : {
438 : : public:
439 : 4309 : code_region (symbol::id_t id, const region *parent)
440 : 4309 : : space_region (id, parent)
441 : : {}
442 : :
443 : : /* region vfuncs. */
444 : : void dump_to_pp (pretty_printer *pp, bool simple) const final override;
445 : 33165 : enum region_kind get_kind () const final override { return RK_CODE; }
446 : : };
447 : :
448 : : } // namespace ana
449 : :
450 : : template <>
451 : : template <>
452 : : inline bool
453 : : is_a_helper <const code_region *>::test (const region *reg)
454 : : {
455 : : return reg->get_kind () == RK_CODE;
456 : : }
457 : :
458 : : namespace ana {
459 : :
460 : : /* Concrete region subclass. A region representing the code for
461 : : a particular function. */
462 : :
463 : : class function_region : public region
464 : : {
465 : : public:
466 : 10152 : function_region (symbol::id_t id, const code_region *parent, tree fndecl)
467 : 10152 : : region (complexity (parent), id, parent, TREE_TYPE (fndecl)),
468 : 10152 : m_fndecl (fndecl)
469 : : {
470 : 10152 : gcc_assert (FUNC_OR_METHOD_TYPE_P (TREE_TYPE (fndecl)));
471 : 10152 : }
472 : :
473 : : /* region vfuncs. */
474 : : void dump_to_pp (pretty_printer *pp, bool simple) const final override;
475 : 156329 : enum region_kind get_kind () const final override { return RK_FUNCTION; }
476 : : const function_region *
477 : 1037651 : dyn_cast_function_region () const final override{ return this; }
478 : :
479 : 1037576 : tree get_fndecl () const { return m_fndecl; }
480 : :
481 : : private:
482 : : tree m_fndecl;
483 : : };
484 : :
485 : : } // namespace ana
486 : :
487 : : template <>
488 : : template <>
489 : : inline bool
490 : 12 : is_a_helper <const function_region *>::test (const region *reg)
491 : : {
492 : 12 : return reg->get_kind () == RK_FUNCTION;
493 : : }
494 : :
495 : : namespace ana {
496 : :
497 : : /* Concrete region subclass. A region representing a particular label
498 : : within a function. */
499 : :
500 : : class label_region : public region
501 : : {
502 : : public:
503 : 54 : label_region (symbol::id_t id, const function_region *parent, tree label)
504 : 54 : : region (complexity (parent), id, parent, NULL_TREE), m_label (label)
505 : : {
506 : 54 : gcc_assert (TREE_CODE (label) == LABEL_DECL);
507 : 54 : }
508 : :
509 : : /* region vfuncs. */
510 : : void dump_to_pp (pretty_printer *pp, bool simple) const final override;
511 : 30507 : enum region_kind get_kind () const final override { return RK_LABEL; }
512 : :
513 : 6 : tree get_label () const { return m_label; }
514 : :
515 : : private:
516 : : tree m_label;
517 : : };
518 : :
519 : : } // namespace ana
520 : :
521 : : template <>
522 : : template <>
523 : : inline bool
524 : 6 : is_a_helper <const label_region *>::test (const region *reg)
525 : : {
526 : 6 : return reg->get_kind () == RK_LABEL;
527 : : }
528 : :
529 : : namespace ana {
530 : :
531 : : /* Concrete space_region subclass representing a stack, containing all stack
532 : : frames. */
533 : :
534 : 4309 : class stack_region : public space_region
535 : : {
536 : : public:
537 : 4309 : stack_region (symbol::id_t id, region *parent)
538 : 4309 : : space_region (id, parent)
539 : : {}
540 : :
541 : : void dump_to_pp (pretty_printer *pp, bool simple) const final override;
542 : :
543 : 758067 : enum region_kind get_kind () const final override { return RK_STACK; }
544 : : };
545 : :
546 : : } // namespace ana
547 : :
548 : : template <>
549 : : template <>
550 : : inline bool
551 : : is_a_helper <const stack_region *>::test (const region *reg)
552 : : {
553 : : return reg->get_kind () == RK_STACK;
554 : : }
555 : :
556 : : namespace ana {
557 : :
558 : : /* Concrete space_region subclass: a region within which regions can be
559 : : dynamically allocated. */
560 : :
561 : 4309 : class heap_region : public space_region
562 : : {
563 : : public:
564 : 4309 : heap_region (symbol::id_t id, region *parent)
565 : 4309 : : space_region (id, parent)
566 : : {}
567 : :
568 : 1742319 : enum region_kind get_kind () const final override { return RK_HEAP; }
569 : : void dump_to_pp (pretty_printer *pp, bool simple) const final override;
570 : : };
571 : :
572 : : } // namespace ana
573 : :
574 : : template <>
575 : : template <>
576 : : inline bool
577 : : is_a_helper <const heap_region *>::test (const region *reg)
578 : : {
579 : : return reg->get_kind () == RK_HEAP;
580 : : }
581 : :
582 : : namespace ana {
583 : :
584 : : /* Concrete space_region subclass: thread-local data for the thread
585 : : being analyzed. */
586 : :
587 : 4309 : class thread_local_region : public space_region
588 : : {
589 : : public:
590 : 4309 : thread_local_region (symbol::id_t id, region *parent)
591 : 4309 : : space_region (id, parent)
592 : : {}
593 : :
594 : 279687 : enum region_kind get_kind () const final override { return RK_THREAD_LOCAL; }
595 : : void dump_to_pp (pretty_printer *pp, bool simple) const final override;
596 : : };
597 : :
598 : : } // namespace ana
599 : :
600 : : template <>
601 : : template <>
602 : : inline bool
603 : : is_a_helper <const thread_local_region *>::test (const region *reg)
604 : : {
605 : : return reg->get_kind () == RK_THREAD_LOCAL;
606 : : }
607 : :
608 : : namespace ana {
609 : :
610 : : /* Concrete region subclass. The root region, containing all regions
611 : : (either directly, or as descendents).
612 : : Unique within a region_model_manager. */
613 : :
614 : 4309 : class root_region : public region
615 : : {
616 : : public:
617 : : root_region (symbol::id_t id);
618 : :
619 : 7958976 : enum region_kind get_kind () const final override { return RK_ROOT; }
620 : : void dump_to_pp (pretty_printer *pp, bool simple) const final override;
621 : : };
622 : :
623 : : } // namespace ana
624 : :
625 : : template <>
626 : : template <>
627 : : inline bool
628 : : is_a_helper <const root_region *>::test (const region *reg)
629 : : {
630 : : return reg->get_kind () == RK_ROOT;
631 : : }
632 : :
633 : : namespace ana {
634 : :
635 : : /* Concrete region subclass: a region to use when dereferencing an unknown
636 : : pointer. */
637 : :
638 : : class symbolic_region : public region
639 : : {
640 : : public:
641 : : /* A support class for uniquifying instances of symbolic_region. */
642 : : struct key_t
643 : : {
644 : 109226 : key_t (const region *parent, const svalue *sval_ptr)
645 : 109226 : : m_parent (parent), m_sval_ptr (sval_ptr)
646 : : {
647 : 109226 : gcc_assert (sval_ptr);
648 : : }
649 : :
650 : 644664 : hashval_t hash () const
651 : : {
652 : 644664 : inchash::hash hstate;
653 : 644664 : hstate.add_ptr (m_parent);
654 : 644664 : hstate.add_ptr (m_sval_ptr);
655 : 644664 : return hstate.end ();
656 : : }
657 : :
658 : 627701 : bool operator== (const key_t &other) const
659 : : {
660 : 627701 : return (m_parent == other.m_parent && m_sval_ptr == other.m_sval_ptr);
661 : : }
662 : :
663 : : void mark_deleted () { m_sval_ptr = reinterpret_cast<const svalue *> (1); }
664 : 0 : void mark_empty () { m_sval_ptr = NULL; }
665 : 693585 : bool is_deleted () const
666 : : {
667 : 693585 : return m_sval_ptr == reinterpret_cast<const svalue *> (1);
668 : : }
669 : 2314266 : bool is_empty () const { return m_sval_ptr == NULL; }
670 : :
671 : : const region *m_parent;
672 : : const svalue *m_sval_ptr;
673 : : };
674 : :
675 : : symbolic_region (symbol::id_t id, region *parent, const svalue *sval_ptr);
676 : :
677 : : const symbolic_region *
678 : 2639281 : dyn_cast_symbolic_region () const final override { return this; }
679 : :
680 : 19531542 : enum region_kind get_kind () const final override { return RK_SYMBOLIC; }
681 : : void accept (visitor *v) const final override;
682 : : void dump_to_pp (pretty_printer *pp, bool simple) const final override;
683 : :
684 : 2647205 : const svalue *get_pointer () const { return m_sval_ptr; }
685 : :
686 : : private:
687 : : const svalue *m_sval_ptr;
688 : : };
689 : :
690 : : } // namespace ana
691 : :
692 : : template <>
693 : : template <>
694 : : inline bool
695 : 7924 : is_a_helper <const symbolic_region *>::test (const region *reg)
696 : : {
697 : 7924 : return reg->get_kind () == RK_SYMBOLIC;
698 : : }
699 : :
700 : : template <> struct default_hash_traits<symbolic_region::key_t>
701 : : : public member_function_hash_traits<symbolic_region::key_t>
702 : : {
703 : : static const bool empty_zero_p = true;
704 : : };
705 : :
706 : : namespace ana {
707 : :
708 : : /* Concrete region subclass representing the memory occupied by a
709 : : variable (whether for a global or a local).
710 : : Also used for representing SSA names, as if they were locals. */
711 : :
712 : : class decl_region : public region
713 : : {
714 : : public:
715 : 122265 : decl_region (symbol::id_t id, const region *parent, tree decl)
716 : 244530 : : region (complexity (parent), id, parent, TREE_TYPE (decl)), m_decl (decl),
717 : 244530 : m_tracked (calc_tracked_p (decl)),
718 : 122265 : m_ctor_svalue (NULL)
719 : 122265 : {}
720 : :
721 : 72971706 : enum region_kind get_kind () const final override { return RK_DECL; }
722 : : const decl_region *
723 : 8296023 : dyn_cast_decl_region () const final override { return this; }
724 : :
725 : : void dump_to_pp (pretty_printer *pp, bool simple) const final override;
726 : :
727 : 105 : bool tracked_p () const final override { return m_tracked; }
728 : :
729 : 5774301 : tree get_decl () const { return m_decl; }
730 : : int get_stack_depth () const;
731 : :
732 : : const svalue *maybe_get_constant_value (region_model_manager *mgr) const;
733 : : const svalue *get_svalue_for_constructor (tree ctor,
734 : : region_model_manager *mgr) const;
735 : : const svalue *get_svalue_for_initializer (region_model_manager *mgr) const;
736 : :
737 : : private:
738 : : const svalue *calc_svalue_for_constructor (tree ctor,
739 : : region_model_manager *mgr) const;
740 : : static bool calc_tracked_p (tree decl);
741 : :
742 : : tree m_decl;
743 : :
744 : : /* Cached result of calc_tracked_p, so that we can quickly determine when
745 : : we don't to track a binding_cluster for this decl (to avoid bloating
746 : : store objects).
747 : : This can be debugged using -fdump-analyzer-untracked. */
748 : : bool m_tracked;
749 : :
750 : : /* Cached result of get_svalue_for_constructor. */
751 : : mutable const svalue *m_ctor_svalue;
752 : : };
753 : :
754 : : } // namespace ana
755 : :
756 : : template <>
757 : : template <>
758 : : inline bool
759 : 990835 : is_a_helper <const decl_region *>::test (const region *reg)
760 : : {
761 : 990835 : return reg->get_kind () == RK_DECL;
762 : : }
763 : :
764 : : namespace ana {
765 : :
766 : : /* Concrete region subclass representing the memory occupied by a
767 : : field within a struct or union. */
768 : :
769 : : class field_region : public region
770 : : {
771 : : public:
772 : : /* A support class for uniquifying instances of field_region. */
773 : : struct key_t
774 : : {
775 : 63035 : key_t (const region *parent, tree field)
776 : 63035 : : m_parent (parent), m_field (field)
777 : : {
778 : 63035 : gcc_assert (field);
779 : : }
780 : :
781 : 388374 : hashval_t hash () const
782 : : {
783 : 388374 : inchash::hash hstate;
784 : 388374 : hstate.add_ptr (m_parent);
785 : 388374 : hstate.add_ptr (m_field);
786 : 388374 : return hstate.end ();
787 : : }
788 : :
789 : 377902 : bool operator== (const key_t &other) const
790 : : {
791 : 377902 : return (m_parent == other.m_parent && m_field == other.m_field);
792 : : }
793 : :
794 : : void mark_deleted () { m_field = reinterpret_cast<tree> (1); }
795 : 0 : void mark_empty () { m_field = NULL_TREE; }
796 : 423353 : bool is_deleted () const { return m_field == reinterpret_cast<tree> (1); }
797 : 1469745 : bool is_empty () const { return m_field == NULL_TREE; }
798 : :
799 : : const region *m_parent;
800 : : tree m_field;
801 : : };
802 : :
803 : 8424 : field_region (symbol::id_t id, const region *parent, tree field)
804 : 8424 : : region (complexity (parent), id, parent, TREE_TYPE (field)),
805 : 8424 : m_field (field)
806 : 8424 : {}
807 : :
808 : 1850625 : enum region_kind get_kind () const final override { return RK_FIELD; }
809 : :
810 : : void dump_to_pp (pretty_printer *pp, bool simple) const final override;
811 : : const field_region *
812 : 688 : dyn_cast_field_region () const final override { return this; }
813 : :
814 : 2524 : tree get_field () const { return m_field; }
815 : :
816 : : bool get_relative_concrete_offset (bit_offset_t *out) const final override;
817 : : const svalue *get_relative_symbolic_offset (region_model_manager *mgr)
818 : : const final override;
819 : :
820 : : private:
821 : : tree m_field;
822 : : };
823 : :
824 : : } // namespace ana
825 : :
826 : : template <>
827 : : template <>
828 : : inline bool
829 : 1909 : is_a_helper <const field_region *>::test (const region *reg)
830 : : {
831 : 1909 : return reg->get_kind () == RK_FIELD;
832 : : }
833 : :
834 : : template <> struct default_hash_traits<field_region::key_t>
835 : : : public member_function_hash_traits<field_region::key_t>
836 : : {
837 : : static const bool empty_zero_p = true;
838 : : };
839 : :
840 : : namespace ana {
841 : :
842 : : /* An element within an array. */
843 : :
844 : : class element_region : public region
845 : : {
846 : : public:
847 : : /* A support class for uniquifying instances of element_region. */
848 : : struct key_t
849 : : {
850 : 18261 : key_t (const region *parent, tree element_type, const svalue *index)
851 : 18261 : : m_parent (parent), m_element_type (element_type), m_index (index)
852 : : {
853 : 18261 : gcc_assert (index);
854 : : }
855 : :
856 : 113162 : hashval_t hash () const
857 : : {
858 : 113162 : inchash::hash hstate;
859 : 113162 : hstate.add_ptr (m_parent);
860 : 113162 : hstate.add_ptr (m_element_type);
861 : 113162 : hstate.add_ptr (m_index);
862 : 113162 : return hstate.end ();
863 : : }
864 : :
865 : 106539 : bool operator== (const key_t &other) const
866 : : {
867 : 106539 : return (m_parent == other.m_parent
868 : 49352 : && m_element_type == other.m_element_type
869 : 155891 : && m_index == other.m_index);
870 : : }
871 : :
872 : : void mark_deleted () { m_index = reinterpret_cast<const svalue *> (1); }
873 : 0 : void mark_empty () { m_index = NULL; }
874 : 123993 : bool is_deleted () const
875 : : {
876 : 123993 : return m_index == reinterpret_cast<const svalue *> (1);
877 : : }
878 : 538197 : bool is_empty () const { return m_index == NULL; }
879 : :
880 : : const region *m_parent;
881 : : tree m_element_type;
882 : : const svalue *m_index;
883 : : };
884 : :
885 : 4264 : element_region (symbol::id_t id, const region *parent, tree element_type,
886 : : const svalue *index)
887 : 4264 : : region (complexity::from_pair (parent, index), id, parent, element_type),
888 : 4264 : m_index (index)
889 : 4264 : {}
890 : :
891 : 150494 : enum region_kind get_kind () const final override { return RK_ELEMENT; }
892 : : const element_region *
893 : 13951 : dyn_cast_element_region () const final override { return this; }
894 : :
895 : : void accept (visitor *v) const final override;
896 : :
897 : : void dump_to_pp (pretty_printer *pp, bool simple) const final override;
898 : :
899 : 24487 : const svalue *get_index () const { return m_index; }
900 : :
901 : : virtual bool
902 : : get_relative_concrete_offset (bit_offset_t *out) const final override;
903 : : const svalue *get_relative_symbolic_offset (region_model_manager *mgr)
904 : : const final override;
905 : :
906 : : private:
907 : : const svalue *m_index;
908 : : };
909 : :
910 : : } // namespace ana
911 : :
912 : : template <>
913 : : template <>
914 : : inline bool
915 : 297 : is_a_helper <const element_region *>::test (const region *reg)
916 : : {
917 : 297 : return reg->get_kind () == RK_ELEMENT;
918 : : }
919 : :
920 : : template <> struct default_hash_traits<element_region::key_t>
921 : : : public member_function_hash_traits<element_region::key_t>
922 : : {
923 : : static const bool empty_zero_p = true;
924 : : };
925 : :
926 : : namespace ana {
927 : :
928 : : /* A byte-offset within another region, for handling pointer arithmetic
929 : : as a region. */
930 : :
931 : : class offset_region : public region
932 : : {
933 : : public:
934 : : /* A support class for uniquifying instances of offset_region. */
935 : : struct key_t
936 : : {
937 : 21939 : key_t (const region *parent, tree element_type, const svalue *byte_offset)
938 : 21939 : : m_parent (parent), m_element_type (element_type), m_byte_offset (byte_offset)
939 : : {
940 : 21939 : gcc_assert (byte_offset);
941 : : }
942 : :
943 : 140599 : hashval_t hash () const
944 : : {
945 : 140599 : inchash::hash hstate;
946 : 140599 : hstate.add_ptr (m_parent);
947 : 140599 : hstate.add_ptr (m_element_type);
948 : 140599 : hstate.add_ptr (m_byte_offset);
949 : 140599 : return hstate.end ();
950 : : }
951 : :
952 : 133738 : bool operator== (const key_t &other) const
953 : : {
954 : 133738 : return (m_parent == other.m_parent
955 : 53672 : && m_element_type == other.m_element_type
956 : 184310 : && m_byte_offset == other.m_byte_offset);
957 : : }
958 : :
959 : : void mark_deleted () { m_byte_offset = reinterpret_cast<const svalue *> (1); }
960 : 0 : void mark_empty () { m_byte_offset = NULL; }
961 : 154448 : bool is_deleted () const
962 : : {
963 : 154448 : return m_byte_offset == reinterpret_cast<const svalue *> (1);
964 : : }
965 : 620236 : bool is_empty () const { return m_byte_offset == NULL; }
966 : :
967 : : const region *m_parent;
968 : : tree m_element_type;
969 : : const svalue *m_byte_offset;
970 : : };
971 : :
972 : 4519 : offset_region (symbol::id_t id, const region *parent, tree type,
973 : : const svalue *byte_offset)
974 : 4519 : : region (complexity::from_pair (parent, byte_offset), id, parent, type),
975 : 4519 : m_byte_offset (byte_offset)
976 : 4519 : {}
977 : :
978 : 1028254 : enum region_kind get_kind () const final override { return RK_OFFSET; }
979 : : const offset_region *
980 : 215320 : dyn_cast_offset_region () const final override { return this; }
981 : :
982 : : void accept (visitor *v) const final override;
983 : :
984 : : void dump_to_pp (pretty_printer *pp, bool simple) const final override;
985 : :
986 : 231169 : const svalue *get_byte_offset () const { return m_byte_offset; }
987 : : const svalue *get_bit_offset (region_model_manager *mgr) const;
988 : :
989 : : bool get_relative_concrete_offset (bit_offset_t *out) const final override;
990 : : const svalue *get_relative_symbolic_offset (region_model_manager *mgr)
991 : : const final override;
992 : :
993 : : private:
994 : : const svalue *m_byte_offset;
995 : : };
996 : :
997 : : } // namespace ana
998 : :
999 : : template <>
1000 : : template <>
1001 : : inline bool
1002 : 815 : is_a_helper <const offset_region *>::test (const region *reg)
1003 : : {
1004 : 815 : return reg->get_kind () == RK_OFFSET;
1005 : : }
1006 : :
1007 : : template <> struct default_hash_traits<offset_region::key_t>
1008 : : : public member_function_hash_traits<offset_region::key_t>
1009 : : {
1010 : : static const bool empty_zero_p = true;
1011 : : };
1012 : :
1013 : : namespace ana {
1014 : :
1015 : : /* A region that is size BYTES_SIZE_SVAL in size within its parent
1016 : : region (or possibly larger, which would lead to an overflow. */
1017 : :
1018 : : class sized_region : public region
1019 : : {
1020 : : public:
1021 : : /* A support class for uniquifying instances of sized_region. */
1022 : : struct key_t
1023 : : {
1024 : 8468 : key_t (const region *parent, tree element_type,
1025 : : const svalue *byte_size_sval)
1026 : 8468 : : m_parent (parent), m_element_type (element_type),
1027 : 8468 : m_byte_size_sval (byte_size_sval)
1028 : : {
1029 : 8468 : gcc_assert (byte_size_sval);
1030 : : }
1031 : :
1032 : 55302 : hashval_t hash () const
1033 : : {
1034 : 55302 : inchash::hash hstate;
1035 : 55302 : hstate.add_ptr (m_parent);
1036 : 55302 : hstate.add_ptr (m_element_type);
1037 : 55302 : hstate.add_ptr (m_byte_size_sval);
1038 : 55302 : return hstate.end ();
1039 : : }
1040 : :
1041 : 48590 : bool operator== (const key_t &other) const
1042 : : {
1043 : 48590 : return (m_parent == other.m_parent
1044 : 8376 : && m_element_type == other.m_element_type
1045 : 56960 : && m_byte_size_sval == other.m_byte_size_sval);
1046 : : }
1047 : :
1048 : : void mark_deleted () { m_byte_size_sval = reinterpret_cast<const svalue *> (1); }
1049 : 0 : void mark_empty () { m_byte_size_sval = NULL; }
1050 : 60956 : bool is_deleted () const
1051 : : {
1052 : 60956 : return m_byte_size_sval == reinterpret_cast<const svalue *> (1);
1053 : : }
1054 : 342230 : bool is_empty () const { return m_byte_size_sval == NULL; }
1055 : :
1056 : : const region *m_parent;
1057 : : tree m_element_type;
1058 : : const svalue *m_byte_size_sval;
1059 : : const svalue *m_end_offset;
1060 : : };
1061 : :
1062 : 3736 : sized_region (symbol::id_t id, const region *parent, tree type,
1063 : : const svalue *byte_size_sval)
1064 : 3736 : : region (complexity::from_pair (parent, byte_size_sval),
1065 : : id, parent, type),
1066 : 3736 : m_byte_size_sval (byte_size_sval)
1067 : 3736 : {}
1068 : :
1069 : 48329 : enum region_kind get_kind () const final override { return RK_SIZED; }
1070 : : const sized_region *
1071 : 0 : dyn_cast_sized_region () const final override { return this; }
1072 : :
1073 : : void accept (visitor *v) const final override;
1074 : :
1075 : : void dump_to_pp (pretty_printer *pp, bool simple) const final override;
1076 : :
1077 : : bool get_byte_size (byte_size_t *out) const final override;
1078 : : bool get_bit_size (bit_size_t *out) const final override;
1079 : :
1080 : : const svalue *
1081 : 10923 : get_byte_size_sval (region_model_manager *) const final override
1082 : : {
1083 : 10923 : return m_byte_size_sval;
1084 : : }
1085 : :
1086 : : const svalue *
1087 : : get_bit_size_sval (region_model_manager *) const final override;
1088 : :
1089 : : private:
1090 : : const svalue *m_byte_size_sval;
1091 : : };
1092 : :
1093 : : } // namespace ana
1094 : :
1095 : : template <>
1096 : : template <>
1097 : : inline bool
1098 : 0 : is_a_helper <const sized_region *>::test (const region *reg)
1099 : : {
1100 : 0 : return reg->get_kind () == RK_SIZED;
1101 : : }
1102 : :
1103 : : template <> struct default_hash_traits<sized_region::key_t>
1104 : : : public member_function_hash_traits<sized_region::key_t>
1105 : : {
1106 : : static const bool empty_zero_p = true;
1107 : : };
1108 : :
1109 : : namespace ana {
1110 : :
1111 : : /* A region that views another region using a different type. */
1112 : :
1113 : : class cast_region : public region
1114 : : {
1115 : : public:
1116 : : /* A support class for uniquifying instances of cast_region. */
1117 : : struct key_t
1118 : : {
1119 : 24330 : key_t (const region *original_region, tree type)
1120 : 24330 : : m_original_region (original_region), m_type (type)
1121 : : {
1122 : 24330 : gcc_assert (original_region);
1123 : : }
1124 : :
1125 : 109825 : hashval_t hash () const
1126 : : {
1127 : 109825 : inchash::hash hstate;
1128 : 109825 : hstate.add_ptr (m_original_region);
1129 : 109825 : hstate.add_ptr (m_type);
1130 : 109825 : return hstate.end ();
1131 : : }
1132 : :
1133 : 93107 : bool operator== (const key_t &other) const
1134 : : {
1135 : 93107 : return (m_original_region == other.m_original_region
1136 : 93107 : && m_type == other.m_type);
1137 : : }
1138 : :
1139 : : void mark_deleted ()
1140 : : {
1141 : : m_original_region = reinterpret_cast<const region *> (1);
1142 : : }
1143 : 0 : void mark_empty () { m_original_region = nullptr; }
1144 : 115015 : bool is_deleted () const
1145 : : {
1146 : 115015 : return m_original_region == reinterpret_cast<const region *> (1);
1147 : : }
1148 : 566109 : bool is_empty () const { return m_original_region == nullptr; }
1149 : :
1150 : : const region *m_original_region;
1151 : : tree m_type;
1152 : : };
1153 : :
1154 : 2857 : cast_region (symbol::id_t id, const region *original_region, tree type)
1155 : 2857 : : region (complexity (original_region), id,
1156 : : original_region->get_parent_region (), type),
1157 : 2857 : m_original_region (original_region)
1158 : 2857 : {}
1159 : :
1160 : 151397 : enum region_kind get_kind () const final override { return RK_CAST; }
1161 : : const cast_region *
1162 : 121896 : dyn_cast_cast_region () const final override { return this; }
1163 : : void accept (visitor *v) const final override;
1164 : : void dump_to_pp (pretty_printer *pp, bool simple) const final override;
1165 : :
1166 : : bool get_relative_concrete_offset (bit_offset_t *out) const final override;
1167 : :
1168 : 137959 : const region *get_original_region () const { return m_original_region; }
1169 : :
1170 : : private:
1171 : : const region *m_original_region;
1172 : : };
1173 : :
1174 : : } // namespace ana
1175 : :
1176 : : template <>
1177 : : template <>
1178 : : inline bool
1179 : 16063 : is_a_helper <const cast_region *>::test (const region *reg)
1180 : : {
1181 : 16063 : return reg->get_kind () == RK_CAST;
1182 : : }
1183 : :
1184 : : template <> struct default_hash_traits<cast_region::key_t>
1185 : : : public member_function_hash_traits<cast_region::key_t>
1186 : : {
1187 : : static const bool empty_zero_p = true;
1188 : : };
1189 : :
1190 : : namespace ana {
1191 : :
1192 : : /* An untyped region dynamically allocated on the heap via "malloc"
1193 : : or similar. */
1194 : :
1195 : : class heap_allocated_region : public region
1196 : : {
1197 : : public:
1198 : 1522 : heap_allocated_region (symbol::id_t id, const region *parent)
1199 : 1522 : : region (complexity (parent), id, parent, NULL_TREE)
1200 : 1522 : {}
1201 : :
1202 : : enum region_kind
1203 : 8019067 : get_kind () const final override { return RK_HEAP_ALLOCATED; }
1204 : :
1205 : : void dump_to_pp (pretty_printer *pp, bool simple) const final override;
1206 : : };
1207 : :
1208 : : /* An untyped region dynamically allocated on the stack via "alloca". */
1209 : :
1210 : : class alloca_region : public region
1211 : : {
1212 : : public:
1213 : 1262 : alloca_region (symbol::id_t id, const frame_region *parent)
1214 : 1262 : : region (complexity (parent), id, parent, NULL_TREE)
1215 : 1262 : {}
1216 : :
1217 : 403042 : enum region_kind get_kind () const final override { return RK_ALLOCA; }
1218 : :
1219 : : void dump_to_pp (pretty_printer *pp, bool simple) const final override;
1220 : : };
1221 : :
1222 : : /* A region for a STRING_CST. */
1223 : :
1224 : : class string_region : public region
1225 : : {
1226 : : public:
1227 : 4482 : string_region (symbol::id_t id, const region *parent, tree string_cst)
1228 : 4482 : : region (complexity (parent), id, parent, TREE_TYPE (string_cst)),
1229 : 4482 : m_string_cst (string_cst)
1230 : 4482 : {}
1231 : :
1232 : : const string_region *
1233 : 11764 : dyn_cast_string_region () const final override { return this; }
1234 : :
1235 : 271251 : enum region_kind get_kind () const final override { return RK_STRING; }
1236 : :
1237 : : void dump_to_pp (pretty_printer *pp, bool simple) const final override;
1238 : :
1239 : : /* We assume string literals are immutable, so we don't track them in
1240 : : the store. */
1241 : 1185 : bool tracked_p () const final override { return false; }
1242 : :
1243 : 12692 : tree get_string_cst () const { return m_string_cst; }
1244 : :
1245 : : private:
1246 : : tree m_string_cst;
1247 : : };
1248 : :
1249 : : } // namespace ana
1250 : :
1251 : : template <>
1252 : : template <>
1253 : : inline bool
1254 : 524 : is_a_helper <const string_region *>::test (const region *reg)
1255 : : {
1256 : 524 : return reg->get_kind () == RK_STRING;
1257 : : }
1258 : :
1259 : : namespace ana {
1260 : :
1261 : : /* A region for a specific range of bits within another region. */
1262 : :
1263 : : class bit_range_region : public region
1264 : : {
1265 : : public:
1266 : : /* A support class for uniquifying instances of bit_range_region. */
1267 : : struct key_t
1268 : : {
1269 : 194 : key_t (const region *parent, tree type, const bit_range &bits)
1270 : 194 : : m_parent (parent), m_type (type), m_bits (bits)
1271 : : {
1272 : 194 : gcc_assert (parent);
1273 : 194 : }
1274 : :
1275 : 1598 : hashval_t hash () const
1276 : : {
1277 : 1598 : inchash::hash hstate;
1278 : 1598 : hstate.add_ptr (m_parent);
1279 : 1598 : hstate.add_ptr (m_type);
1280 : 1598 : hstate.add_wide_int (m_bits.m_start_bit_offset);
1281 : 1598 : hstate.add_wide_int (m_bits.m_size_in_bits);
1282 : 1598 : return hstate.end ();
1283 : : }
1284 : :
1285 : 1378 : bool operator== (const key_t &other) const
1286 : : {
1287 : 1378 : return (m_parent == other.m_parent
1288 : 956 : && m_type == other.m_type
1289 : 2334 : && m_bits == other.m_bits);
1290 : : }
1291 : :
1292 : : void mark_deleted () { m_parent = reinterpret_cast<const region *> (1); }
1293 : 0 : void mark_empty () { m_parent = NULL; }
1294 : 1784 : bool is_deleted () const
1295 : : {
1296 : 1784 : return m_parent == reinterpret_cast<const region *> (1);
1297 : : }
1298 : 118798 : bool is_empty () const { return m_parent == NULL; }
1299 : :
1300 : : const region *m_parent;
1301 : : tree m_type;
1302 : : bit_range m_bits;
1303 : : };
1304 : :
1305 : 149 : bit_range_region (symbol::id_t id, const region *parent, tree type,
1306 : : const bit_range &bits)
1307 : 149 : : region (complexity (parent), id, parent, type),
1308 : 149 : m_bits (bits)
1309 : 149 : {}
1310 : :
1311 : : const bit_range_region *
1312 : 0 : dyn_cast_bit_range_region () const final override { return this; }
1313 : :
1314 : 1145 : enum region_kind get_kind () const final override { return RK_BIT_RANGE; }
1315 : :
1316 : : void dump_to_pp (pretty_printer *pp, bool simple) const final override;
1317 : :
1318 : 0 : const bit_range &get_bits () const { return m_bits; }
1319 : :
1320 : : bool get_byte_size (byte_size_t *out) const final override;
1321 : : bool get_bit_size (bit_size_t *out) const final override;
1322 : : const svalue *get_byte_size_sval (region_model_manager *mgr) const final override;
1323 : : const svalue *get_bit_size_sval (region_model_manager *mgr) const final override;
1324 : : bool get_relative_concrete_offset (bit_offset_t *out) const final override;
1325 : : const svalue *get_relative_symbolic_offset (region_model_manager *mgr)
1326 : : const final override;
1327 : :
1328 : : private:
1329 : : bit_range m_bits;
1330 : : };
1331 : :
1332 : : } // namespace ana
1333 : :
1334 : : template <>
1335 : : template <>
1336 : : inline bool
1337 : 0 : is_a_helper <const bit_range_region *>::test (const region *reg)
1338 : : {
1339 : 0 : return reg->get_kind () == RK_BIT_RANGE;
1340 : : }
1341 : :
1342 : : template <> struct default_hash_traits<bit_range_region::key_t>
1343 : : : public member_function_hash_traits<bit_range_region::key_t>
1344 : : {
1345 : : static const bool empty_zero_p = true;
1346 : : };
1347 : :
1348 : : namespace ana {
1349 : :
1350 : : /* A region for the N-th vararg within a frame_region for a variadic call. */
1351 : :
1352 : : class var_arg_region : public region
1353 : : {
1354 : : public:
1355 : : /* A support class for uniquifying instances of var_arg_region. */
1356 : : struct key_t
1357 : : {
1358 : 1240 : key_t (const frame_region *parent, unsigned idx)
1359 : 1240 : : m_parent (parent), m_idx (idx)
1360 : : {
1361 : 1240 : gcc_assert (parent);
1362 : : }
1363 : :
1364 : 8589 : hashval_t hash () const
1365 : : {
1366 : 8589 : inchash::hash hstate;
1367 : 8589 : hstate.add_ptr (m_parent);
1368 : 8589 : hstate.add_int (m_idx);
1369 : 8589 : return hstate.end ();
1370 : : }
1371 : :
1372 : 7904 : bool operator== (const key_t &other) const
1373 : : {
1374 : 7904 : return (m_parent == other.m_parent
1375 : 7904 : && m_idx == other.m_idx);
1376 : : }
1377 : :
1378 : : void mark_deleted ()
1379 : : {
1380 : : m_parent = reinterpret_cast<const frame_region *> (1);
1381 : : }
1382 : 0 : void mark_empty () { m_parent = NULL; }
1383 : 9683 : bool is_deleted () const
1384 : : {
1385 : 9683 : return m_parent == reinterpret_cast<const frame_region *> (1);
1386 : : }
1387 : 146639 : bool is_empty () const { return m_parent == NULL; }
1388 : :
1389 : : const frame_region *m_parent;
1390 : : unsigned m_idx;
1391 : : };
1392 : :
1393 : 537 : var_arg_region (symbol::id_t id, const frame_region *parent,
1394 : : unsigned idx)
1395 : 537 : : region (complexity (parent), id, parent, NULL_TREE),
1396 : 537 : m_idx (idx)
1397 : 537 : {}
1398 : :
1399 : : const var_arg_region *
1400 : 522 : dyn_cast_var_arg_region () const final override { return this; }
1401 : :
1402 : 277840 : enum region_kind get_kind () const final override { return RK_VAR_ARG; }
1403 : :
1404 : : void dump_to_pp (pretty_printer *pp, bool simple) const final override;
1405 : :
1406 : : const frame_region *get_frame_region () const;
1407 : 655 : unsigned get_index () const { return m_idx; }
1408 : :
1409 : : private:
1410 : : unsigned m_idx;
1411 : : };
1412 : :
1413 : : } // namespace ana
1414 : :
1415 : : template <>
1416 : : template <>
1417 : : inline bool
1418 : : is_a_helper <const var_arg_region *>::test (const region *reg)
1419 : : {
1420 : : return reg->get_kind () == RK_VAR_ARG;
1421 : : }
1422 : :
1423 : : template <> struct default_hash_traits<var_arg_region::key_t>
1424 : : : public member_function_hash_traits<var_arg_region::key_t>
1425 : : {
1426 : : static const bool empty_zero_p = true;
1427 : : };
1428 : :
1429 : : namespace ana {
1430 : :
1431 : : /* A region for errno for the current thread. */
1432 : :
1433 : 4309 : class errno_region : public region
1434 : : {
1435 : : public:
1436 : 4309 : errno_region (symbol::id_t id, const thread_local_region *parent)
1437 : 4309 : : region (complexity (parent), id, parent, integer_type_node)
1438 : 4309 : {}
1439 : :
1440 : 922965 : enum region_kind get_kind () const final override { return RK_ERRNO; }
1441 : :
1442 : : void dump_to_pp (pretty_printer *pp, bool simple) const final override;
1443 : : };
1444 : :
1445 : : } // namespace ana
1446 : :
1447 : : template <>
1448 : : template <>
1449 : : inline bool
1450 : : is_a_helper <const errno_region *>::test (const region *reg)
1451 : : {
1452 : : return reg->get_kind () == RK_ERRNO;
1453 : : }
1454 : :
1455 : : namespace ana {
1456 : :
1457 : : /* Similar to a decl region, but we don't have the decl.
1458 : : For implementing e.g. static buffers of known_functions,
1459 : : or other internal state of an API.
1460 : :
1461 : : These are owned by known_function instances, rather than the
1462 : : region_model_manager. */
1463 : :
1464 : : class private_region : public region
1465 : : {
1466 : : public:
1467 : 3737 : private_region (unsigned id, const region *parent, tree type,
1468 : : const char *desc)
1469 : 3737 : : region (complexity (parent), id, parent, type),
1470 : 3737 : m_desc (desc)
1471 : 3737 : {}
1472 : :
1473 : 45741 : enum region_kind get_kind () const final override { return RK_PRIVATE; }
1474 : :
1475 : : void dump_to_pp (pretty_printer *pp, bool simple) const final override;
1476 : :
1477 : : private:
1478 : : const char *m_desc;
1479 : : };
1480 : :
1481 : : } // namespace ana
1482 : :
1483 : : template <>
1484 : : template <>
1485 : : inline bool
1486 : : is_a_helper <const private_region *>::test (const region *reg)
1487 : : {
1488 : : return reg->get_kind () == RK_PRIVATE;
1489 : : }
1490 : :
1491 : : namespace ana {
1492 : :
1493 : : /* An unknown region, for handling unimplemented tree codes. */
1494 : :
1495 : : class unknown_region : public region
1496 : : {
1497 : : public:
1498 : 54 : unknown_region (symbol::id_t id, const region *parent, tree type)
1499 : 54 : : region (complexity (parent), id, parent, type)
1500 : 54 : {}
1501 : :
1502 : 1982 : enum region_kind get_kind () const final override { return RK_UNKNOWN; }
1503 : :
1504 : : void dump_to_pp (pretty_printer *pp, bool simple) const final override;
1505 : : };
1506 : :
1507 : : } // namespace ana
1508 : :
1509 : : #endif /* GCC_ANALYZER_REGION_H */
|