Line data Source code
1 : /* Regions of memory.
2 : Copyright (C) 2019-2026 Free Software Foundation, Inc.
3 : Contributed by David Malcolm <dmalcolm@redhat.com>.
4 :
5 : This file is part of GCC.
6 :
7 : GCC is free software; you can redistribute it and/or modify it
8 : under the terms of the GNU General Public License as published by
9 : the Free Software Foundation; either version 3, or (at your option)
10 : any later version.
11 :
12 : GCC is distributed in the hope that it will be useful, but
13 : WITHOUT ANY WARRANTY; without even the implied warranty of
14 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 : General Public License for more details.
16 :
17 : You should have received a copy of the GNU General Public License
18 : along with GCC; see the file COPYING3. If not see
19 : <http://www.gnu.org/licenses/>. */
20 :
21 : #include "analyzer/common.h"
22 :
23 : #include "ordered-hash-map.h"
24 : #include "options.h"
25 : #include "cgraph.h"
26 : #include "cfg.h"
27 : #include "digraph.h"
28 : #include "sbitmap.h"
29 : #include "fold-const.h"
30 : #include "tree-ssa.h"
31 :
32 : #include "analyzer/analyzer-logging.h"
33 : #include "analyzer/supergraph.h"
34 : #include "analyzer/call-string.h"
35 : #include "analyzer/program-point.h"
36 : #include "analyzer/store.h"
37 : #include "analyzer/region.h"
38 : #include "analyzer/region-model.h"
39 : #include "analyzer/sm.h"
40 : #include "analyzer/program-state.h"
41 : #include "text-art/dump.h"
42 :
43 : #if ENABLE_ANALYZER
44 :
45 : namespace ana {
46 :
47 : region_offset
48 1309 : region_offset::make_byte_offset (const region *base_region,
49 : const svalue *num_bytes_sval)
50 : {
51 1309 : if (tree num_bytes_cst = num_bytes_sval->maybe_get_constant ())
52 : {
53 977 : gcc_assert (TREE_CODE (num_bytes_cst) == INTEGER_CST);
54 977 : bit_offset_t num_bits = wi::to_offset (num_bytes_cst) * BITS_PER_UNIT;
55 977 : return make_concrete (base_region, num_bits);
56 : }
57 : else
58 : {
59 332 : return make_symbolic (base_region, num_bytes_sval);
60 : }
61 : }
62 :
63 : const svalue &
64 580 : region_offset::calc_symbolic_bit_offset (region_model_manager *mgr) const
65 : {
66 580 : if (symbolic_p ())
67 : {
68 127 : const svalue *bits_per_byte
69 127 : = mgr->get_or_create_int_cst (NULL_TREE, BITS_PER_UNIT);
70 127 : return *mgr->get_or_create_binop (NULL_TREE, MULT_EXPR,
71 127 : m_sym_offset, bits_per_byte);
72 : }
73 : else
74 453 : return *mgr->get_or_create_int_cst (NULL_TREE, m_offset);
75 : }
76 :
77 : const svalue *
78 206 : region_offset::calc_symbolic_byte_offset (region_model_manager *mgr) const
79 : {
80 206 : if (symbolic_p ())
81 : return m_sym_offset;
82 : else
83 : {
84 18 : byte_offset_t concrete_byte_offset;
85 18 : if (get_concrete_byte_offset (&concrete_byte_offset))
86 18 : return mgr->get_or_create_int_cst (size_type_node,
87 18 : concrete_byte_offset);
88 : else
89 : /* Can't handle bitfields; return UNKNOWN. */
90 0 : return mgr->get_or_create_unknown_svalue (size_type_node);
91 : }
92 : }
93 :
94 : void
95 0 : region_offset::dump_to_pp (pretty_printer *pp, bool simple) const
96 : {
97 0 : if (symbolic_p ())
98 : {
99 : /* We don't bother showing the base region. */
100 0 : pp_string (pp, "byte ");
101 0 : m_sym_offset->dump_to_pp (pp, simple);
102 : }
103 : else
104 : {
105 0 : if (m_offset % BITS_PER_UNIT == 0)
106 : {
107 0 : pp_string (pp, "byte ");
108 0 : pp_wide_int (pp, m_offset / BITS_PER_UNIT, SIGNED);
109 : }
110 : else
111 : {
112 0 : pp_string (pp, "bit ");
113 0 : pp_wide_int (pp, m_offset, SIGNED);
114 : }
115 : }
116 0 : }
117 :
118 : DEBUG_FUNCTION void
119 0 : region_offset::dump (bool simple) const
120 : {
121 0 : tree_dump_pretty_printer pp (stderr);
122 0 : dump_to_pp (&pp, simple);
123 0 : pp_newline (&pp);
124 0 : }
125 :
126 : /* An svalue that matches the pattern (BASE * FACTOR) + OFFSET
127 : where FACTOR or OFFSET could be the identity (represented as nullptr). */
128 :
129 : struct linear_op
130 : {
131 5470 : linear_op (const svalue *base,
132 : const svalue *factor,
133 : const svalue *offset)
134 1868 : : m_base (base), m_factor (factor), m_offset (offset)
135 : {
136 : }
137 :
138 3452 : bool maybe_get_cst_factor (bit_offset_t *out) const
139 : {
140 3452 : if (m_factor == nullptr)
141 : {
142 732 : *out = 1;
143 732 : return true;
144 : }
145 2720 : if (tree cst_factor = m_factor->maybe_get_constant ())
146 : {
147 2720 : *out = wi::to_offset (cst_factor);
148 2720 : return true;
149 : }
150 : return false;
151 : }
152 :
153 3126 : bool maybe_get_cst_offset (bit_offset_t *out) const
154 : {
155 3126 : if (m_offset == nullptr)
156 : {
157 842 : *out = 0;
158 842 : return true;
159 : }
160 2284 : if (tree cst_offset = m_offset->maybe_get_constant ())
161 : {
162 2222 : *out = wi::to_offset (cst_offset);
163 2222 : return true;
164 : }
165 : return false;
166 : }
167 :
168 : static tristate
169 1675 : less (const linear_op &a, const linear_op &b)
170 : {
171 : /* Same base. */
172 1675 : if (a.m_base == b.m_base)
173 : {
174 1611 : bit_offset_t a_wi_factor;
175 1611 : bit_offset_t b_wi_factor;
176 1611 : if (a.maybe_get_cst_factor (&a_wi_factor)
177 1611 : && b.maybe_get_cst_factor (&b_wi_factor))
178 : {
179 1611 : if (a_wi_factor != b_wi_factor)
180 172 : return tristate (a_wi_factor < b_wi_factor);
181 : else
182 : {
183 1495 : bit_offset_t a_wi_offset;
184 1495 : bit_offset_t b_wi_offset;
185 1495 : if (a.maybe_get_cst_offset (&a_wi_offset)
186 1495 : && b.maybe_get_cst_offset (&b_wi_offset))
187 2498 : return tristate (a_wi_offset < b_wi_offset);
188 : }
189 : }
190 : }
191 124 : return tristate::unknown ();
192 : }
193 :
194 : static tristate
195 115 : le (const linear_op &a, const linear_op &b)
196 : {
197 : /* Same base. */
198 115 : if (a.m_base == b.m_base)
199 : {
200 115 : bit_offset_t a_wi_factor;
201 115 : bit_offset_t b_wi_factor;
202 115 : if (a.maybe_get_cst_factor (&a_wi_factor)
203 115 : && b.maybe_get_cst_factor (&b_wi_factor))
204 : {
205 115 : if (a_wi_factor != b_wi_factor)
206 32 : return tristate (a_wi_factor <= b_wi_factor);
207 : else
208 : {
209 99 : bit_offset_t a_wi_offset;
210 99 : bit_offset_t b_wi_offset;
211 99 : if (a.maybe_get_cst_offset (&a_wi_offset)
212 99 : && b.maybe_get_cst_offset (&b_wi_offset))
213 140 : return tristate (a_wi_offset <= b_wi_offset);
214 : }
215 : }
216 : }
217 2 : return tristate::unknown ();
218 : }
219 :
220 : static bool
221 3680 : from_svalue (const svalue &sval, linear_op *out)
222 : {
223 3680 : switch (sval.get_kind ())
224 : {
225 : default:
226 : break;
227 3602 : case SK_BINOP:
228 3602 : {
229 3602 : const binop_svalue &binop_sval ((const binop_svalue &)sval);
230 3602 : if (binop_sval.get_op () == MULT_EXPR)
231 : {
232 1078 : *out = linear_op (binop_sval.get_arg0 (),
233 : binop_sval.get_arg1 (),
234 1078 : nullptr);
235 1078 : return true;
236 : }
237 2524 : else if (binop_sval.get_op () == PLUS_EXPR)
238 : {
239 2524 : if (binop_sval.get_arg0 ()->get_kind () == SK_BINOP)
240 : {
241 1786 : const binop_svalue &inner_binop_sval
242 1786 : ((const binop_svalue &)*binop_sval.get_arg0 ());
243 1786 : if (inner_binop_sval.get_op () == MULT_EXPR)
244 : {
245 1642 : *out = linear_op (inner_binop_sval.get_arg0 (),
246 : inner_binop_sval.get_arg1 (),
247 1642 : binop_sval.get_arg1 ());
248 1642 : return true;
249 : }
250 : }
251 :
252 882 : *out = linear_op (binop_sval.get_arg0 (),
253 : nullptr,
254 882 : binop_sval.get_arg1 ());
255 882 : return true;
256 : }
257 : }
258 : break;
259 : }
260 : return false;
261 : }
262 :
263 : const svalue *m_base;
264 : const svalue *m_factor;
265 : const svalue *m_offset;
266 : };
267 :
268 : bool
269 24035 : operator< (const region_offset &a, const region_offset &b)
270 : {
271 24035 : if (a.symbolic_p ())
272 : {
273 2152 : if (b.symbolic_p ())
274 : {
275 : /* Symbolic vs symbolic. */
276 1743 : const svalue &a_sval = *a.get_symbolic_byte_offset ();
277 1743 : const svalue &b_sval = *b.get_symbolic_byte_offset ();
278 :
279 1743 : linear_op op_a (nullptr, nullptr, nullptr);
280 1743 : linear_op op_b (nullptr, nullptr, nullptr);
281 1743 : if (linear_op::from_svalue (a_sval, &op_a)
282 1743 : && linear_op::from_svalue (b_sval, &op_b))
283 : {
284 1675 : tristate ts = linear_op::less (op_a, op_b);
285 1675 : if (ts.is_true ())
286 1743 : return true;
287 1243 : else if (ts.is_false ())
288 : return false;
289 : }
290 : /* Use svalue's deterministic order, for now. */
291 192 : return (svalue::cmp_ptr (a.get_symbolic_byte_offset (),
292 : b.get_symbolic_byte_offset ())
293 192 : < 0);
294 : }
295 : else
296 : /* Symbolic vs concrete: put all symbolic after all concrete. */
297 : return false;
298 : }
299 : else
300 : {
301 21883 : if (b.symbolic_p ())
302 : /* Concrete vs symbolic: put all concrete before all symbolic. */
303 : return true;
304 : else
305 : /* Concrete vs concrete. */
306 21526 : return a.get_bit_offset () < b.get_bit_offset ();
307 : }
308 : }
309 :
310 : bool
311 1567 : operator<= (const region_offset &a, const region_offset &b)
312 : {
313 1567 : if (a.symbolic_p ())
314 : {
315 168 : if (b.symbolic_p ())
316 : {
317 : /* Symbolic vs symbolic. */
318 125 : const svalue &a_sval = *a.get_symbolic_byte_offset ();
319 125 : const svalue &b_sval = *b.get_symbolic_byte_offset ();
320 :
321 125 : linear_op op_a (nullptr, nullptr, nullptr);
322 125 : linear_op op_b (nullptr, nullptr, nullptr);
323 125 : if (linear_op::from_svalue (a_sval, &op_a)
324 125 : && linear_op::from_svalue (b_sval, &op_b))
325 : {
326 115 : tristate ts = linear_op::le (op_a, op_b);
327 115 : if (ts.is_true ())
328 125 : return true;
329 61 : else if (ts.is_false ())
330 : return false;
331 : }
332 : /* Use svalue's deterministic order, for now. */
333 12 : return (svalue::cmp_ptr (a.get_symbolic_byte_offset (),
334 : b.get_symbolic_byte_offset ())
335 12 : <= 0);
336 : }
337 : else
338 : /* Symbolic vs concrete: put all symbolic after all concrete. */
339 : return false;
340 : }
341 : else
342 : {
343 1399 : if (b.symbolic_p ())
344 : /* Concrete vs symbolic: put all concrete before all symbolic. */
345 : return true;
346 : else
347 : /* Concrete vs concrete. */
348 1324 : return a.get_bit_offset () <= b.get_bit_offset ();
349 : }
350 : }
351 :
352 : bool
353 30 : operator> (const region_offset &a, const region_offset &b)
354 : {
355 30 : return b < a;
356 : }
357 :
358 : bool
359 136 : operator>= (const region_offset &a, const region_offset &b)
360 : {
361 136 : return b <= a;
362 : }
363 :
364 : region_offset
365 5166 : strip_types (const region_offset &offset, region_model_manager &mgr)
366 : {
367 5166 : if (offset.symbolic_p ())
368 877 : return region_offset::make_symbolic
369 877 : (offset.get_base_region (),
370 : strip_types (offset.get_symbolic_byte_offset (),
371 877 : mgr));
372 : else
373 4289 : return offset;
374 : }
375 :
376 : /* class region and its various subclasses. */
377 :
378 : /* class region. */
379 :
380 203952 : region::~region ()
381 : {
382 203952 : delete m_cached_offset;
383 203952 : }
384 :
385 : /* Determine the base region for this region: when considering bindings
386 : for this region, the base region is the ancestor which identifies
387 : which cluster they should be partitioned into.
388 : Regions within the same struct/union/array are in the same cluster.
389 : Different decls are in different clusters. */
390 :
391 : const region *
392 49951814 : region::get_base_region () const
393 : {
394 49951814 : const region *iter = this;
395 51665550 : while (iter)
396 : {
397 51665550 : switch (iter->get_kind ())
398 : {
399 1713736 : case RK_FIELD:
400 1713736 : case RK_ELEMENT:
401 1713736 : case RK_OFFSET:
402 1713736 : case RK_SIZED:
403 1713736 : case RK_BIT_RANGE:
404 1713736 : case RK_CAST:
405 1713736 : iter = iter->get_parent_region ();
406 1713736 : continue;
407 : default:
408 : return iter;
409 : }
410 : }
411 : return iter;
412 : }
413 :
414 : /* Return true if get_base_region() == this for this region. */
415 :
416 : bool
417 243913 : region::base_region_p () const
418 : {
419 243913 : switch (get_kind ())
420 : {
421 : /* Region kinds representing a descendent of a base region. */
422 : case RK_FIELD:
423 : case RK_ELEMENT:
424 : case RK_OFFSET:
425 : case RK_SIZED:
426 : case RK_CAST:
427 : case RK_BIT_RANGE:
428 : return false;
429 :
430 185474 : default:
431 185474 : return true;
432 : }
433 : }
434 :
435 : /* Return true if this region is ELDER or one of its descendents. */
436 :
437 : bool
438 218539 : region::descendent_of_p (const region *elder) const
439 : {
440 218539 : const region *iter = this;
441 820744 : while (iter)
442 : {
443 654851 : if (iter == elder)
444 : return true;
445 602205 : iter = iter->get_parent_region ();
446 : }
447 : return false;
448 : }
449 :
450 : /* If this region is a frame_region, or a descendent of one, return it.
451 : Otherwise return nullptr. */
452 :
453 : const frame_region *
454 2664386 : region::maybe_get_frame_region () const
455 : {
456 2664386 : const region *iter = this;
457 6530848 : while (iter)
458 : {
459 5937078 : if (const frame_region *frame_reg = iter->dyn_cast_frame_region ())
460 : return frame_reg;
461 3866462 : iter = iter->get_parent_region ();
462 : }
463 : return nullptr;
464 : }
465 :
466 : /* Get the memory space of this region. */
467 :
468 : enum memory_space
469 3793671 : region::get_memory_space () const
470 : {
471 3793671 : const region *iter = this;
472 7963704 : while (iter)
473 : {
474 7249405 : switch (iter->get_kind ())
475 : {
476 4170033 : default:
477 4170033 : break;
478 : case RK_GLOBALS:
479 : return MEMSPACE_GLOBALS;
480 : case RK_CODE:
481 : case RK_FUNCTION:
482 : case RK_LABEL:
483 : return MEMSPACE_CODE;
484 : case RK_FRAME:
485 : case RK_STACK:
486 : case RK_ALLOCA:
487 : return MEMSPACE_STACK;
488 : case RK_HEAP:
489 : case RK_HEAP_ALLOCATED:
490 : return MEMSPACE_HEAP;
491 : case RK_STRING:
492 : return MEMSPACE_READONLY_DATA;
493 : case RK_PRIVATE:
494 : return MEMSPACE_PRIVATE;
495 : }
496 4170033 : iter = iter->get_parent_region ();
497 : }
498 : return MEMSPACE_UNKNOWN;
499 : }
500 :
501 : /* Subroutine for use by region_model_manager::get_or_create_initial_value.
502 : Return true if this region has an initial_svalue.
503 : Return false if attempting to use INIT_VAL(this_region) should give
504 : the "UNINITIALIZED" poison value. */
505 :
506 : bool
507 3079695 : region::can_have_initial_svalue_p () const
508 : {
509 3079695 : const region *base_reg = get_base_region ();
510 :
511 : /* Check for memory spaces that are uninitialized by default. */
512 3079695 : enum memory_space mem_space = base_reg->get_memory_space ();
513 3079695 : switch (mem_space)
514 : {
515 0 : default:
516 0 : gcc_unreachable ();
517 : case MEMSPACE_UNKNOWN:
518 : case MEMSPACE_CODE:
519 : case MEMSPACE_GLOBALS:
520 : case MEMSPACE_READONLY_DATA:
521 : case MEMSPACE_PRIVATE:
522 : /* Such regions have initial_svalues. */
523 : return true;
524 :
525 : case MEMSPACE_HEAP:
526 : /* Heap allocations are uninitialized by default. */
527 : return false;
528 :
529 2195481 : case MEMSPACE_STACK:
530 2195481 : if (tree decl = base_reg->maybe_get_decl ())
531 : {
532 : /* See the assertion in frame_region::get_region_for_local for the
533 : tree codes we need to handle here. */
534 2189570 : switch (TREE_CODE (decl))
535 : {
536 0 : default:
537 0 : gcc_unreachable ();
538 :
539 : case PARM_DECL:
540 : /* Parameters have initial values. */
541 : return true;
542 :
543 : case VAR_DECL:
544 : case RESULT_DECL:
545 : /* Function locals don't have initial values. */
546 : return false;
547 :
548 2108856 : case SSA_NAME:
549 2108856 : {
550 : /* Some SSA names have an implicit default defined value. */
551 2108856 : tree ssa_name = decl;
552 2108856 : if (SSA_NAME_IS_DEFAULT_DEF (ssa_name))
553 2050475 : return ssa_defined_default_def_p (ssa_name);
554 : /* Others don't. */
555 : return false;
556 : }
557 : }
558 : }
559 :
560 : /* If we have an on-stack region that isn't associated with a decl
561 : or SSA name, then we have VLA/alloca, which is uninitialized. */
562 : return false;
563 : }
564 : }
565 :
566 : /* For regions within a global decl, get the svalue for the initial
567 : value of this region when the program starts, caching the result. */
568 :
569 : const svalue *
570 14660 : region::get_initial_value_at_main (region_model_manager *mgr) const
571 : {
572 14660 : if (!m_cached_init_sval_at_main)
573 421 : m_cached_init_sval_at_main = calc_initial_value_at_main (mgr);
574 14660 : return m_cached_init_sval_at_main;
575 : }
576 :
577 : /* Implementation of region::get_initial_value_at_main. */
578 :
579 : const svalue *
580 421 : region::calc_initial_value_at_main (region_model_manager *mgr) const
581 : {
582 421 : const decl_region *base_reg = get_base_region ()->dyn_cast_decl_region ();
583 421 : gcc_assert (base_reg);
584 :
585 : /* Attempt to get the initializer value for base_reg. */
586 842 : if (const svalue *base_reg_init
587 421 : = base_reg->get_svalue_for_initializer (mgr))
588 : {
589 304 : if (this == base_reg)
590 : return base_reg_init;
591 : else
592 : {
593 : /* Get the value for REG within base_reg_init. */
594 168 : binding_cluster c (*mgr->get_store_manager (), base_reg);
595 168 : c.bind (mgr->get_store_manager (), base_reg, base_reg_init);
596 168 : const svalue *sval
597 168 : = c.get_any_binding (mgr->get_store_manager (), this);
598 168 : if (sval)
599 : {
600 167 : if (get_type ())
601 147 : sval = mgr->get_or_create_cast (get_type (), sval);
602 167 : return sval;
603 : }
604 168 : }
605 : }
606 :
607 : /* Otherwise, return INIT_VAL(REG). */
608 118 : return mgr->get_or_create_initial_value (this);
609 : }
610 :
611 : /* If this region is a decl_region, return the decl.
612 : Otherwise return NULL_TREE. */
613 :
614 : tree
615 3348271 : region::maybe_get_decl () const
616 : {
617 3348271 : if (const decl_region *decl_reg = dyn_cast_decl_region ())
618 2995528 : return decl_reg->get_decl ();
619 : return NULL_TREE;
620 : }
621 :
622 : /* Get the region_offset for this region (calculating it on the
623 : first call and caching it internally). */
624 :
625 : region_offset
626 4633751 : region::get_offset (region_model_manager *mgr) const
627 : {
628 4633751 : if(!m_cached_offset)
629 137614 : m_cached_offset = new region_offset (calc_offset (mgr));
630 4633751 : return *m_cached_offset;
631 : }
632 :
633 : /* Get the region_offset for immediately beyond this region. */
634 :
635 : region_offset
636 1031 : region::get_next_offset (region_model_manager *mgr) const
637 : {
638 1031 : region_offset start = get_offset (mgr);
639 :
640 1031 : bit_size_t bit_size;
641 1031 : if (get_bit_size (&bit_size))
642 : {
643 1013 : if (start.concrete_p ())
644 : {
645 825 : bit_offset_t next_bit_offset = start.get_bit_offset () + bit_size;
646 825 : return region_offset::make_concrete (start.get_base_region (),
647 : next_bit_offset);
648 : }
649 : }
650 :
651 206 : const svalue *start_byte_offset_sval = start.calc_symbolic_byte_offset (mgr);
652 206 : const svalue *byte_size_sval = get_byte_size_sval (mgr);
653 206 : const svalue *sum_sval
654 206 : = mgr->get_or_create_binop (size_type_node,
655 : PLUS_EXPR,
656 : start_byte_offset_sval,
657 : byte_size_sval);
658 206 : return region_offset::make_symbolic (start.get_base_region (),
659 206 : sum_sval);
660 : }
661 :
662 : /* Base class implementation of region::get_byte_size vfunc.
663 : If the size of this region (in bytes) is known statically, write it to *OUT
664 : and return true.
665 : Otherwise return false. */
666 :
667 : bool
668 6173 : region::get_byte_size (byte_size_t *out) const
669 : {
670 6173 : tree type = get_type ();
671 :
672 : /* Bail out e.g. for heap-allocated regions. */
673 6173 : if (!type)
674 : return false;
675 :
676 6046 : HOST_WIDE_INT bytes = int_size_in_bytes (type);
677 6046 : if (bytes == -1)
678 : return false;
679 6046 : *out = bytes;
680 6046 : return true;
681 : }
682 :
683 : /* Base implementation of region::get_byte_size_sval vfunc. */
684 :
685 : const svalue *
686 54833 : region::get_byte_size_sval (region_model_manager *mgr) const
687 : {
688 54833 : tree type = get_type ();
689 :
690 : /* Bail out e.g. for heap-allocated regions. */
691 54833 : if (!type)
692 14051 : return mgr->get_or_create_unknown_svalue (size_type_node);
693 :
694 40782 : HOST_WIDE_INT bytes = int_size_in_bytes (type);
695 40782 : if (bytes == -1)
696 494 : return mgr->get_or_create_unknown_svalue (size_type_node);
697 :
698 40288 : tree byte_size = size_in_bytes (type);
699 40288 : if (TREE_TYPE (byte_size) != size_type_node)
700 40288 : byte_size = fold_build1 (NOP_EXPR, size_type_node, byte_size);
701 40288 : return mgr->get_or_create_constant_svalue (byte_size);
702 : }
703 :
704 : /* Attempt to get the size of TYPE in bits.
705 : If successful, return true and write the size to *OUT.
706 : Otherwise return false. */
707 :
708 : bool
709 9633464 : int_size_in_bits (const_tree type, bit_size_t *out)
710 : {
711 9633464 : if (INTEGRAL_TYPE_P (type))
712 : {
713 4052676 : *out = TYPE_PRECISION (type);
714 4052676 : return true;
715 : }
716 :
717 5580788 : tree sz = TYPE_SIZE (type);
718 5580788 : if (sz
719 5564543 : && tree_fits_uhwi_p (sz)
720 : /* If the size is zero, then we may have a zero-sized
721 : array; handle such cases by returning false. */
722 11145129 : && !integer_zerop (sz))
723 : {
724 5562179 : *out = TREE_INT_CST_LOW (sz);
725 5562179 : return true;
726 : }
727 : else
728 18609 : return false;
729 : }
730 :
731 : /* Base implementation of region::get_bit_size_sval vfunc. */
732 :
733 : const svalue *
734 831830 : region::get_bit_size_sval (region_model_manager *mgr) const
735 : {
736 831830 : tree type = get_type ();
737 :
738 : /* Bail out e.g. for heap-allocated regions. */
739 831830 : if (!type)
740 8184 : return mgr->get_or_create_unknown_svalue (size_type_node);
741 :
742 823646 : bit_size_t bits;
743 823646 : if (!int_size_in_bits (type, &bits))
744 71 : return mgr->get_or_create_unknown_svalue (size_type_node);
745 :
746 823575 : return mgr->get_or_create_int_cst (size_type_node, bits);
747 : }
748 :
749 : /* If the size of this region (in bits) is known statically, write it to *OUT
750 : and return true.
751 : Otherwise return false. */
752 :
753 : bool
754 10377686 : region::get_bit_size (bit_size_t *out) const
755 : {
756 10377686 : tree type = get_type ();
757 :
758 : /* Bail out e.g. for heap-allocated regions. */
759 10377686 : if (!type)
760 : return false;
761 :
762 8806811 : return int_size_in_bits (type, out);
763 : }
764 :
765 : /* Get the field within RECORD_TYPE at BIT_OFFSET. */
766 :
767 : tree
768 1425 : get_field_at_bit_offset (tree record_type, bit_offset_t bit_offset)
769 : {
770 1425 : gcc_assert (TREE_CODE (record_type) == RECORD_TYPE);
771 1425 : if (bit_offset < 0)
772 : return nullptr;
773 :
774 : /* Find the first field that has an offset > BIT_OFFSET,
775 : then return the one preceding it.
776 : Skip other trees within the chain, such as FUNCTION_DECLs. */
777 1425 : tree last_field = NULL_TREE;
778 18619 : for (tree iter = TYPE_FIELDS (record_type); iter != NULL_TREE;
779 17194 : iter = DECL_CHAIN (iter))
780 : {
781 17980 : if (TREE_CODE (iter) == FIELD_DECL)
782 : {
783 3984 : int iter_field_offset = int_bit_position (iter);
784 3984 : if (bit_offset < iter_field_offset)
785 786 : return last_field;
786 3198 : last_field = iter;
787 : }
788 : }
789 : return last_field;
790 : }
791 :
792 : /* Populate *OUT with descendent regions of type TYPE that match
793 : RELATIVE_BIT_OFFSET and SIZE_IN_BITS within this region. */
794 :
795 : void
796 7888 : region::get_subregions_for_binding (region_model_manager *mgr,
797 : bit_offset_t relative_bit_offset,
798 : bit_size_t size_in_bits,
799 : tree type,
800 : auto_vec <const region *> *out) const
801 : {
802 7888 : if (get_type () == NULL_TREE || type == NULL_TREE)
803 : return;
804 7618 : if (relative_bit_offset == 0
805 7618 : && types_compatible_p (get_type (), type))
806 : {
807 6920 : out->safe_push (this);
808 6920 : return;
809 : }
810 698 : switch (TREE_CODE (get_type ()))
811 : {
812 79 : case ARRAY_TYPE:
813 79 : {
814 79 : tree element_type = TREE_TYPE (get_type ());
815 79 : HOST_WIDE_INT hwi_byte_size = int_size_in_bytes (element_type);
816 79 : if (hwi_byte_size > 0)
817 : {
818 79 : HOST_WIDE_INT bits_per_element
819 : = hwi_byte_size << LOG2_BITS_PER_UNIT;
820 79 : HOST_WIDE_INT element_index
821 79 : = (relative_bit_offset.to_shwi () / bits_per_element);
822 79 : tree element_index_cst
823 79 : = build_int_cst (integer_type_node, element_index);
824 79 : HOST_WIDE_INT inner_bit_offset
825 79 : = relative_bit_offset.to_shwi () % bits_per_element;
826 79 : const region *subregion = mgr->get_element_region
827 79 : (this, element_type,
828 : mgr->get_or_create_constant_svalue (element_index_cst));
829 79 : subregion->get_subregions_for_binding (mgr, inner_bit_offset,
830 : size_in_bits, type, out);
831 : }
832 : }
833 : break;
834 494 : case RECORD_TYPE:
835 494 : {
836 : /* The bit offset might be *within* one of the fields (such as
837 : with nested structs).
838 : So we want to find the enclosing field, adjust the offset,
839 : and repeat. */
840 494 : if (tree field = get_field_at_bit_offset (get_type (),
841 : relative_bit_offset))
842 : {
843 494 : int field_bit_offset = int_bit_position (field);
844 494 : const region *subregion = mgr->get_field_region (this, field);
845 494 : subregion->get_subregions_for_binding
846 494 : (mgr, relative_bit_offset - field_bit_offset,
847 : size_in_bits, type, out);
848 : }
849 : }
850 : break;
851 4 : case UNION_TYPE:
852 4 : {
853 12 : for (tree field = TYPE_FIELDS (get_type ()); field != NULL_TREE;
854 8 : field = DECL_CHAIN (field))
855 : {
856 8 : if (TREE_CODE (field) != FIELD_DECL)
857 0 : continue;
858 8 : const region *subregion = mgr->get_field_region (this, field);
859 8 : subregion->get_subregions_for_binding (mgr,
860 : relative_bit_offset,
861 : size_in_bits,
862 : type,
863 : out);
864 : }
865 : }
866 : break;
867 : default:
868 : /* Do nothing. */
869 : break;
870 : }
871 : }
872 :
873 : /* Walk from this region up to the base region within its cluster, calculating
874 : the offset relative to the base region, either as an offset in bits,
875 : or a symbolic offset. */
876 :
877 : region_offset
878 137614 : region::calc_offset (region_model_manager *mgr) const
879 : {
880 137614 : const region *iter_region = this;
881 137614 : bit_offset_t accum_bit_offset = 0;
882 137614 : const svalue *accum_byte_sval = nullptr;
883 :
884 166245 : while (iter_region)
885 : {
886 166245 : switch (iter_region->get_kind ())
887 : {
888 20504 : case RK_FIELD:
889 20504 : case RK_ELEMENT:
890 20504 : case RK_OFFSET:
891 20504 : case RK_BIT_RANGE:
892 20504 : if (accum_byte_sval)
893 : {
894 2990 : const svalue *sval
895 2990 : = iter_region->get_relative_symbolic_offset (mgr);
896 2990 : accum_byte_sval
897 2990 : = mgr->get_or_create_binop (ptrdiff_type_node, PLUS_EXPR,
898 : accum_byte_sval, sval);
899 2990 : iter_region = iter_region->get_parent_region ();
900 : }
901 : else
902 : {
903 17514 : bit_offset_t rel_bit_offset;
904 17514 : if (iter_region->get_relative_concrete_offset (&rel_bit_offset))
905 : {
906 14973 : accum_bit_offset += rel_bit_offset;
907 14973 : iter_region = iter_region->get_parent_region ();
908 : }
909 : else
910 : {
911 : /* If the iter_region is not concrete anymore, convert the
912 : accumulated bits to a svalue in bytes and revisit the
913 : iter_region collecting the symbolic value. */
914 2541 : byte_offset_t byte_offset = accum_bit_offset / BITS_PER_UNIT;
915 2541 : tree offset_tree = wide_int_to_tree (ptrdiff_type_node,
916 2541 : byte_offset);
917 2541 : accum_byte_sval
918 2541 : = mgr->get_or_create_constant_svalue (offset_tree);
919 : }
920 : }
921 20504 : continue;
922 8127 : case RK_SIZED:
923 8127 : case RK_CAST:
924 8127 : iter_region = iter_region->get_parent_region ();
925 8127 : continue;
926 :
927 137614 : default:
928 137614 : return accum_byte_sval
929 137614 : ? region_offset::make_symbolic (iter_region,
930 : accum_byte_sval)
931 135073 : : region_offset::make_concrete (iter_region,
932 : accum_bit_offset);
933 28631 : }
934 : }
935 :
936 0 : return accum_byte_sval ? region_offset::make_symbolic (iter_region,
937 : accum_byte_sval)
938 0 : : region_offset::make_concrete (iter_region,
939 : accum_bit_offset);
940 : }
941 :
942 : /* Base implementation of region::get_relative_concrete_offset vfunc. */
943 :
944 : bool
945 32 : region::get_relative_concrete_offset (bit_offset_t *) const
946 : {
947 32 : return false;
948 : }
949 :
950 : /* Base implementation of region::get_relative_symbolic_offset vfunc. */
951 :
952 : const svalue *
953 0 : region::get_relative_symbolic_offset (region_model_manager *mgr) const
954 : {
955 0 : return mgr->get_or_create_unknown_svalue (ptrdiff_type_node);
956 : }
957 :
958 : /* Attempt to get the position and size of this region expressed as a
959 : concrete range of bytes relative to its parent.
960 : If successful, return true and write to *OUT.
961 : Otherwise return false. */
962 :
963 : bool
964 6275 : region::get_relative_concrete_byte_range (byte_range *out) const
965 : {
966 : /* We must have a concrete offset relative to the parent. */
967 6275 : bit_offset_t rel_bit_offset;
968 6275 : if (!get_relative_concrete_offset (&rel_bit_offset))
969 : return false;
970 : /* ...which must be a whole number of bytes. */
971 6173 : if (rel_bit_offset % BITS_PER_UNIT != 0)
972 : return false;
973 6173 : byte_offset_t start_byte_offset = rel_bit_offset / BITS_PER_UNIT;
974 :
975 : /* We must have a concrete size, which must be a whole number
976 : of bytes. */
977 6173 : byte_size_t num_bytes;
978 6173 : if (!get_byte_size (&num_bytes))
979 : return false;
980 :
981 : /* Success. */
982 6046 : *out = byte_range (start_byte_offset, num_bytes);
983 6046 : return true;
984 : }
985 :
986 : /* Dump a description of this region to stderr. */
987 :
988 : DEBUG_FUNCTION void
989 0 : region::dump (bool simple) const
990 : {
991 0 : tree_dump_pretty_printer pp (stderr);
992 0 : dump_to_pp (&pp, simple);
993 0 : pp_newline (&pp);
994 0 : }
995 :
996 : /* Dump a tree-like representation of this region and its constituent symbols
997 : to stderr, using global_dc's colorization and theming options.
998 :
999 : For example:
1000 : . (gdb) call reg->dump()
1001 : . (26): ‘int’: decl_region(‘x_10(D)’)
1002 : . ╰─ parent: (9): frame_region(‘test_bitmask_2’, index: 0, depth: 1)
1003 : . ╰─ parent: (1): stack region
1004 : . ╰─ parent: (0): root region
1005 : */
1006 :
1007 : DEBUG_FUNCTION void
1008 0 : region::dump () const
1009 : {
1010 0 : text_art::dump (*this);
1011 0 : }
1012 :
1013 : /* Return a new json::string describing the region. */
1014 :
1015 : std::unique_ptr<json::value>
1016 16 : region::to_json () const
1017 : {
1018 16 : label_text desc = get_desc (true);
1019 16 : auto reg_js = std::make_unique<json::string> (desc.get ());
1020 16 : return reg_js;
1021 16 : }
1022 :
1023 : bool
1024 34 : region::maybe_print_for_user (pretty_printer *pp,
1025 : const region_model &) const
1026 : {
1027 34 : switch (get_kind ())
1028 : {
1029 : default:
1030 : break;
1031 34 : case RK_DECL:
1032 34 : {
1033 34 : const decl_region *reg = (const decl_region *)this;
1034 34 : tree decl = reg->get_decl ();
1035 34 : if (TREE_CODE (decl) == SSA_NAME)
1036 34 : decl = SSA_NAME_VAR (decl);
1037 34 : print_expr_for_user (pp, decl);
1038 34 : return true;
1039 : }
1040 : }
1041 :
1042 : return false;
1043 : }
1044 :
1045 : /* Use DWI to create a text_art::widget describing this region in
1046 : a tree-like form, using PREFIX as a prefix (e.g. for field names). */
1047 :
1048 : std::unique_ptr<text_art::tree_widget>
1049 0 : region::make_dump_widget (const text_art::dump_widget_info &dwi,
1050 : const char *prefix) const
1051 : {
1052 0 : pretty_printer pp;
1053 0 : pp_format_decoder (&pp) = default_tree_printer;
1054 0 : pp_show_color (&pp) = true;
1055 :
1056 0 : if (prefix)
1057 0 : pp_printf (&pp, "%s: ", prefix);
1058 :
1059 0 : pp_printf (&pp, "(%i): ", get_id ());
1060 0 : if (get_type ())
1061 0 : pp_printf (&pp, "%qT: ", get_type ());
1062 :
1063 0 : print_dump_widget_label (&pp);
1064 :
1065 0 : std::unique_ptr<text_art::tree_widget> w
1066 0 : (text_art::tree_widget::make (dwi, &pp));
1067 :
1068 0 : add_dump_widget_children (*w, dwi);
1069 :
1070 0 : if (m_parent)
1071 0 : w->add_child (m_parent->make_dump_widget (dwi, "parent"));
1072 :
1073 0 : return w;
1074 0 : }
1075 :
1076 : void
1077 0 : region::add_dump_widget_children (text_art::tree_widget &,
1078 : const text_art::dump_widget_info &) const
1079 : {
1080 : /* By default, add nothing (parent is added in make_dump_widget). */
1081 0 : }
1082 :
1083 : /* Generate a description of this region. */
1084 :
1085 : DEBUG_FUNCTION label_text
1086 16 : region::get_desc (bool simple) const
1087 : {
1088 16 : pretty_printer pp;
1089 16 : pp_format_decoder (&pp) = default_tree_printer;
1090 16 : dump_to_pp (&pp, simple);
1091 16 : return label_text::take (xstrdup (pp_formatted_text (&pp)));
1092 16 : }
1093 :
1094 : /* Base implementation of region::accept vfunc.
1095 : Subclass implementations should chain up to this. */
1096 :
1097 : void
1098 50028514 : region::accept (visitor *v) const
1099 : {
1100 50028514 : v->visit_region (this);
1101 50028514 : if (m_parent)
1102 37965832 : m_parent->accept (v);
1103 50028514 : }
1104 :
1105 : /* Return true if this is a symbolic region for deferencing an
1106 : unknown ptr.
1107 : We shouldn't attempt to bind values for this region (but
1108 : can unbind values for other regions). */
1109 :
1110 : bool
1111 5122029 : region::symbolic_for_unknown_ptr_p () const
1112 : {
1113 5122029 : if (const symbolic_region *sym_reg = dyn_cast_symbolic_region ())
1114 609461 : if (sym_reg->get_pointer ()->get_kind () == SK_UNKNOWN)
1115 : return true;
1116 : return false;
1117 : }
1118 :
1119 : /* Return true if this is a symbolic region. */
1120 :
1121 : bool
1122 836962 : region::symbolic_p () const
1123 : {
1124 836962 : return get_kind () == RK_SYMBOLIC;
1125 : }
1126 :
1127 : /* Return true if this region is known to be zero bits in size. */
1128 :
1129 : bool
1130 6859954 : region::empty_p () const
1131 : {
1132 6859954 : bit_size_t num_bits;
1133 6859954 : if (get_bit_size (&num_bits))
1134 6544730 : if (num_bits == 0)
1135 : return true;
1136 : return false;
1137 : }
1138 :
1139 : /* Return true if this is a region for a decl with name DECL_NAME.
1140 : Intended for use when debugging (for assertions and conditional
1141 : breakpoints). */
1142 :
1143 : DEBUG_FUNCTION bool
1144 0 : region::is_named_decl_p (const char *decl_name) const
1145 : {
1146 0 : if (tree decl = maybe_get_decl ())
1147 0 : if (DECL_NAME (decl)
1148 0 : && !strcmp (IDENTIFIER_POINTER (DECL_NAME (decl)), decl_name))
1149 0 : return true;
1150 : return false;
1151 : }
1152 :
1153 : /* region's ctor. */
1154 :
1155 204008 : region::region (complexity c, symbol::id_t id, const region *parent, tree type)
1156 : : symbol (c, id),
1157 204008 : m_parent (parent), m_type (type),
1158 204008 : m_cached_offset (nullptr), m_cached_init_sval_at_main (nullptr)
1159 : {
1160 204008 : gcc_assert (type == NULL_TREE || TYPE_P (type));
1161 204008 : }
1162 :
1163 : /* Comparator for use by vec<const region *>::qsort,
1164 : using their IDs to order them. */
1165 :
1166 : int
1167 62881726 : region::cmp_ptr_ptr (const void *p1, const void *p2)
1168 : {
1169 62881726 : const region * const *reg1 = (const region * const *)p1;
1170 62881726 : const region * const *reg2 = (const region * const *)p2;
1171 :
1172 62881726 : return cmp_ids (*reg1, *reg2);
1173 : }
1174 :
1175 : /* Determine if a pointer to this region must be non-NULL.
1176 :
1177 : Generally, pointers to regions must be non-NULL, but pointers
1178 : to symbolic_regions might, in fact, be NULL.
1179 :
1180 : This allows us to simulate functions like malloc and calloc with:
1181 : - only one "outcome" from each statement,
1182 : - the idea that the pointer is on the heap if non-NULL
1183 : - the possibility that the pointer could be NULL
1184 : - the idea that successive values returned from malloc are non-equal
1185 : - to be able to zero-fill for calloc. */
1186 :
1187 : bool
1188 20181 : region::non_null_p () const
1189 : {
1190 20181 : switch (get_kind ())
1191 : {
1192 : default:
1193 : return true;
1194 : case RK_SYMBOLIC:
1195 : /* Are we within a symbolic_region? If so, it could be NULL, and we
1196 : have to fall back on the constraints. */
1197 : return false;
1198 : case RK_HEAP_ALLOCATED:
1199 : return false;
1200 : }
1201 : }
1202 :
1203 : /* Return true iff this region is defined in terms of SVAL. */
1204 :
1205 : bool
1206 420917 : region::involves_p (const svalue *sval) const
1207 : {
1208 420917 : if (const symbolic_region *symbolic_reg = dyn_cast_symbolic_region ())
1209 : {
1210 54621 : if (symbolic_reg->get_pointer ()->involves_p (sval))
1211 : return true;
1212 : }
1213 :
1214 : return false;
1215 : }
1216 :
1217 : /* Comparator for trees to impose a deterministic ordering on
1218 : T1 and T2. */
1219 :
1220 : static int
1221 73560 : tree_cmp (const_tree t1, const_tree t2)
1222 : {
1223 73560 : gcc_assert (t1);
1224 73560 : gcc_assert (t2);
1225 :
1226 : /* Test tree codes first. */
1227 73560 : if (TREE_CODE (t1) != TREE_CODE (t2))
1228 31744 : return TREE_CODE (t1) - TREE_CODE (t2);
1229 :
1230 : /* From this point on, we know T1 and T2 have the same tree code. */
1231 :
1232 41816 : if (DECL_P (t1))
1233 : {
1234 0 : if (DECL_NAME (t1) && DECL_NAME (t2))
1235 0 : return strcmp (IDENTIFIER_POINTER (DECL_NAME (t1)),
1236 0 : IDENTIFIER_POINTER (DECL_NAME (t2)));
1237 : else
1238 : {
1239 0 : if (DECL_NAME (t1))
1240 : return -1;
1241 0 : else if (DECL_NAME (t2))
1242 : return 1;
1243 : else
1244 0 : return DECL_UID (t1) - DECL_UID (t2);
1245 : }
1246 : }
1247 :
1248 41816 : switch (TREE_CODE (t1))
1249 : {
1250 0 : case SSA_NAME:
1251 0 : {
1252 0 : if (SSA_NAME_VAR (t1) && SSA_NAME_VAR (t2))
1253 : {
1254 0 : int var_cmp = tree_cmp (SSA_NAME_VAR (t1), SSA_NAME_VAR (t2));
1255 0 : if (var_cmp)
1256 : return var_cmp;
1257 0 : return SSA_NAME_VERSION (t1) - SSA_NAME_VERSION (t2);
1258 : }
1259 : else
1260 : {
1261 0 : if (SSA_NAME_VAR (t1))
1262 : return -1;
1263 0 : else if (SSA_NAME_VAR (t2))
1264 : return 1;
1265 : else
1266 0 : return SSA_NAME_VERSION (t1) - SSA_NAME_VERSION (t2);
1267 : }
1268 : }
1269 8384 : break;
1270 :
1271 8384 : case INTEGER_CST:
1272 8384 : return tree_int_cst_compare (t1, t2);
1273 :
1274 33432 : case REAL_CST:
1275 33432 : {
1276 33432 : const real_value *rv1 = TREE_REAL_CST_PTR (t1);
1277 33432 : const real_value *rv2 = TREE_REAL_CST_PTR (t2);
1278 33432 : if (real_compare (UNORDERED_EXPR, rv1, rv2))
1279 : {
1280 : /* Impose an arbitrary order on NaNs relative to other NaNs
1281 : and to non-NaNs. */
1282 25040 : if (int cmp_isnan = real_isnan (rv1) - real_isnan (rv2))
1283 : return cmp_isnan;
1284 16800 : if (int cmp_issignaling_nan
1285 8400 : = real_issignaling_nan (rv1) - real_issignaling_nan (rv2))
1286 : return cmp_issignaling_nan;
1287 4016 : return real_isneg (rv1) - real_isneg (rv2);
1288 : }
1289 8392 : if (real_compare (LT_EXPR, rv1, rv2))
1290 : return -1;
1291 5008 : if (real_compare (GT_EXPR, rv1, rv2))
1292 : return 1;
1293 : return 0;
1294 : }
1295 :
1296 0 : case STRING_CST:
1297 0 : return strcmp (TREE_STRING_POINTER (t1),
1298 0 : TREE_STRING_POINTER (t2));
1299 :
1300 0 : default:
1301 0 : gcc_unreachable ();
1302 : break;
1303 : }
1304 :
1305 : gcc_unreachable ();
1306 :
1307 : return 0;
1308 : }
1309 :
1310 : /* qsort comparator for trees to impose a deterministic ordering on
1311 : P1 and P2. */
1312 :
1313 : int
1314 73560 : tree_cmp (const void *p1, const void *p2)
1315 : {
1316 73560 : const_tree t1 = *(const_tree const *)p1;
1317 73560 : const_tree t2 = *(const_tree const *)p2;
1318 :
1319 73560 : return tree_cmp (t1, t2);
1320 : }
1321 :
1322 : /* class frame_region : public space_region. */
1323 :
1324 29816 : frame_region::~frame_region ()
1325 : {
1326 116519 : for (map_t::iterator iter = m_locals.begin ();
1327 116519 : iter != m_locals.end ();
1328 101611 : ++iter)
1329 101611 : delete (*iter).second;
1330 29816 : }
1331 :
1332 : void
1333 9902739 : frame_region::accept (visitor *v) const
1334 : {
1335 10448645 : region::accept (v);
1336 10448645 : if (m_calling_frame)
1337 : m_calling_frame->accept (v);
1338 9902739 : }
1339 :
1340 : /* Implementation of region::dump_to_pp vfunc for frame_region. */
1341 :
1342 : void
1343 4283 : frame_region::dump_to_pp (pretty_printer *pp, bool simple) const
1344 : {
1345 4283 : if (simple)
1346 4264 : pp_printf (pp, "frame: %qs@%i", function_name (&m_fun), get_stack_depth ());
1347 : else
1348 19 : pp_printf (pp, "frame_region(%qs, index: %i, depth: %i)",
1349 19 : function_name (&m_fun), m_index, get_stack_depth ());
1350 4283 : }
1351 :
1352 : void
1353 0 : frame_region::print_dump_widget_label (pretty_printer *pp) const
1354 : {
1355 0 : pp_printf (pp, "frame_region(%qs, index: %i, depth: %i)",
1356 0 : function_name (&m_fun), m_index, get_stack_depth ());
1357 0 : }
1358 :
1359 : const decl_region *
1360 1394207 : frame_region::get_region_for_local (region_model_manager *mgr,
1361 : tree expr,
1362 : const region_model_context *ctxt) const
1363 : {
1364 1394207 : if (CHECKING_P)
1365 : {
1366 : /* Verify that EXPR is a local or SSA name, and that it's for the
1367 : correct function for this stack frame. */
1368 1394207 : gcc_assert (TREE_CODE (expr) == PARM_DECL
1369 : || TREE_CODE (expr) == VAR_DECL
1370 : || TREE_CODE (expr) == SSA_NAME
1371 : || TREE_CODE (expr) == RESULT_DECL);
1372 1394207 : switch (TREE_CODE (expr))
1373 : {
1374 0 : default:
1375 0 : gcc_unreachable ();
1376 100795 : case VAR_DECL:
1377 100795 : gcc_assert (!is_global_var (expr));
1378 : /* Fall through. */
1379 129835 : case PARM_DECL:
1380 129835 : case RESULT_DECL:
1381 129835 : gcc_assert (DECL_CONTEXT (expr) == m_fun.decl);
1382 : break;
1383 1264372 : case SSA_NAME:
1384 1264372 : {
1385 1264372 : if (tree var = SSA_NAME_VAR (expr))
1386 : {
1387 602859 : if (DECL_P (var))
1388 602859 : gcc_assert (DECL_CONTEXT (var) == m_fun.decl);
1389 : }
1390 661513 : else if (ctxt)
1391 419781 : if (const extrinsic_state *ext_state = ctxt->get_ext_state ())
1392 355779 : if (const supergraph *sg
1393 355779 : = ext_state->get_engine ()->get_supergraph ())
1394 : {
1395 355779 : const gimple *def_stmt = SSA_NAME_DEF_STMT (expr);
1396 355779 : if (gimple_code (def_stmt) != GIMPLE_PHI)
1397 : {
1398 349425 : const supernode *snode
1399 349425 : = sg->get_supernode_for_stmt (def_stmt);
1400 349425 : gcc_assert (snode->get_function () == &m_fun);
1401 : }
1402 : }
1403 : }
1404 : break;
1405 : }
1406 : }
1407 :
1408 : /* Ideally we'd use mutable here. */
1409 1394207 : map_t &mutable_locals = const_cast <map_t &> (m_locals);
1410 :
1411 1394207 : if (decl_region **slot = mutable_locals.get (expr))
1412 1292596 : return *slot;
1413 101611 : decl_region *reg
1414 101611 : = new decl_region (mgr->alloc_symbol_id (), this, expr);
1415 101611 : mutable_locals.put (expr, reg);
1416 101611 : return reg;
1417 : }
1418 :
1419 : /* class globals_region : public space_region. */
1420 :
1421 : /* Implementation of region::dump_to_pp vfunc for globals_region. */
1422 :
1423 : void
1424 2347 : globals_region::dump_to_pp (pretty_printer *pp, bool simple) const
1425 : {
1426 2347 : if (simple)
1427 1278 : pp_string (pp, "::");
1428 : else
1429 1069 : pp_string (pp, "globals");
1430 2347 : }
1431 :
1432 : void
1433 0 : globals_region::print_dump_widget_label (pretty_printer *pp) const
1434 : {
1435 0 : pp_string (pp, "globals");
1436 0 : }
1437 :
1438 : /* class code_region : public map_region. */
1439 :
1440 : /* Implementation of region::dump_to_pp vfunc for code_region. */
1441 :
1442 : void
1443 0 : code_region::dump_to_pp (pretty_printer *pp, bool simple) const
1444 : {
1445 0 : if (simple)
1446 0 : pp_string (pp, "code region");
1447 : else
1448 0 : pp_string (pp, "code_region()");
1449 0 : }
1450 :
1451 : void
1452 0 : code_region::print_dump_widget_label (pretty_printer *pp) const
1453 : {
1454 0 : pp_string (pp, "code region");
1455 0 : }
1456 :
1457 : /* class function_region : public region. */
1458 :
1459 : /* Implementation of region::dump_to_pp vfunc for function_region. */
1460 :
1461 : void
1462 413 : function_region::dump_to_pp (pretty_printer *pp, bool simple) const
1463 : {
1464 413 : if (simple)
1465 : {
1466 413 : dump_quoted_tree (pp, m_fndecl);
1467 : }
1468 : else
1469 : {
1470 0 : pp_string (pp, "function_region(");
1471 0 : dump_quoted_tree (pp, m_fndecl);
1472 0 : pp_string (pp, ")");
1473 : }
1474 413 : }
1475 :
1476 : void
1477 0 : function_region::print_dump_widget_label (pretty_printer *pp) const
1478 : {
1479 0 : pp_string (pp, "function_region(");
1480 0 : dump_quoted_tree (pp, m_fndecl);
1481 0 : pp_string (pp, ")");
1482 0 : }
1483 :
1484 : /* class label_region : public region. */
1485 :
1486 : /* Implementation of region::dump_to_pp vfunc for label_region. */
1487 :
1488 : void
1489 0 : label_region::dump_to_pp (pretty_printer *pp, bool simple) const
1490 : {
1491 0 : if (simple)
1492 : {
1493 0 : dump_quoted_tree (pp, m_label);
1494 : }
1495 : else
1496 : {
1497 0 : pp_string (pp, "label_region(");
1498 0 : dump_quoted_tree (pp, m_label);
1499 0 : pp_string (pp, ")");
1500 : }
1501 0 : }
1502 :
1503 : void
1504 0 : label_region::print_dump_widget_label (pretty_printer *pp) const
1505 : {
1506 0 : pp_string (pp, "label_region(");
1507 0 : dump_quoted_tree (pp, m_label);
1508 0 : pp_string (pp, ")");
1509 0 : }
1510 :
1511 : /* class stack_region : public region. */
1512 :
1513 : /* Implementation of region::dump_to_pp vfunc for stack_region. */
1514 :
1515 : void
1516 0 : stack_region::dump_to_pp (pretty_printer *pp, bool simple) const
1517 : {
1518 0 : if (simple)
1519 0 : pp_string (pp, "stack region");
1520 : else
1521 0 : pp_string (pp, "stack_region()");
1522 0 : }
1523 :
1524 : void
1525 0 : stack_region::print_dump_widget_label (pretty_printer *pp) const
1526 : {
1527 0 : pp_string (pp, "stack region");
1528 0 : }
1529 :
1530 : /* class heap_region : public region. */
1531 :
1532 : /* Implementation of region::dump_to_pp vfunc for heap_region. */
1533 :
1534 : void
1535 190 : heap_region::dump_to_pp (pretty_printer *pp, bool simple) const
1536 : {
1537 190 : if (simple)
1538 190 : pp_string (pp, "heap region");
1539 : else
1540 0 : pp_string (pp, "heap_region()");
1541 190 : }
1542 :
1543 : void
1544 0 : heap_region::print_dump_widget_label (pretty_printer *pp) const
1545 : {
1546 0 : pp_string (pp, "heap_region");
1547 0 : }
1548 :
1549 : /* class root_region : public region. */
1550 :
1551 : /* root_region's ctor. */
1552 :
1553 3937 : root_region::root_region (symbol::id_t id)
1554 3937 : : region (complexity (1, 1), id, nullptr, NULL_TREE)
1555 : {
1556 3937 : }
1557 :
1558 : /* Implementation of region::dump_to_pp vfunc for root_region. */
1559 :
1560 : void
1561 1478 : root_region::dump_to_pp (pretty_printer *pp, bool simple) const
1562 : {
1563 1478 : if (simple)
1564 1370 : pp_string (pp, "root region");
1565 : else
1566 108 : pp_string (pp, "root_region()");
1567 1478 : }
1568 :
1569 : void
1570 0 : root_region::print_dump_widget_label (pretty_printer *pp) const
1571 : {
1572 0 : pp_string (pp, "root region");
1573 0 : }
1574 :
1575 : /* class thread_local_region : public space_region. */
1576 :
1577 : void
1578 0 : thread_local_region::dump_to_pp (pretty_printer *pp, bool simple) const
1579 : {
1580 0 : if (simple)
1581 0 : pp_string (pp, "thread_local_region");
1582 : else
1583 0 : pp_string (pp, "thread_local_region()");
1584 0 : }
1585 :
1586 : void
1587 0 : thread_local_region::print_dump_widget_label (pretty_printer *pp) const
1588 : {
1589 0 : pp_string (pp, "thread_local_region");
1590 0 : }
1591 :
1592 : /* class symbolic_region : public map_region. */
1593 :
1594 : /* symbolic_region's ctor. */
1595 :
1596 8215 : symbolic_region::symbolic_region (symbol::id_t id, region *parent,
1597 8215 : const svalue *sval_ptr)
1598 8215 : : region (complexity::from_pair (parent, sval_ptr), id, parent,
1599 8215 : (sval_ptr->get_type ()
1600 8132 : ? TREE_TYPE (sval_ptr->get_type ())
1601 : : NULL_TREE)),
1602 24562 : m_sval_ptr (sval_ptr)
1603 : {
1604 8215 : }
1605 :
1606 : /* Implementation of region::accept vfunc for symbolic_region. */
1607 :
1608 : void
1609 511753 : symbolic_region::accept (visitor *v) const
1610 : {
1611 511753 : region::accept (v);
1612 511753 : m_sval_ptr->accept (v);
1613 511753 : }
1614 :
1615 : /* Implementation of region::dump_to_pp vfunc for symbolic_region. */
1616 :
1617 : void
1618 6999 : symbolic_region::dump_to_pp (pretty_printer *pp, bool simple) const
1619 : {
1620 6999 : if (simple)
1621 : {
1622 6891 : pp_string (pp, "(*");
1623 6891 : m_sval_ptr->dump_to_pp (pp, simple);
1624 6891 : pp_string (pp, ")");
1625 : }
1626 : else
1627 : {
1628 108 : pp_string (pp, "symbolic_region(");
1629 108 : get_parent_region ()->dump_to_pp (pp, simple);
1630 108 : if (get_type ())
1631 : {
1632 108 : pp_string (pp, ", ");
1633 108 : print_quoted_type (pp, get_type ());
1634 : }
1635 108 : pp_string (pp, ", ");
1636 108 : m_sval_ptr->dump_to_pp (pp, simple);
1637 108 : pp_string (pp, ")");
1638 : }
1639 6999 : }
1640 :
1641 : void
1642 0 : symbolic_region::print_dump_widget_label (pretty_printer *pp) const
1643 : {
1644 0 : pp_string (pp, "symbolic_region: %<*%>");
1645 0 : }
1646 :
1647 : void
1648 0 : symbolic_region::
1649 : add_dump_widget_children (text_art::tree_widget &w,
1650 : const text_art::dump_widget_info &dwi) const
1651 : {
1652 0 : w.add_child (m_sval_ptr->make_dump_widget (dwi, "m_sval_ptr"));
1653 0 : }
1654 :
1655 : /* class decl_region : public region. */
1656 :
1657 : /* Implementation of region::dump_to_pp vfunc for decl_region. */
1658 :
1659 : void
1660 26142 : decl_region::dump_to_pp (pretty_printer *pp, bool simple) const
1661 : {
1662 26142 : if (simple)
1663 25054 : pp_printf (pp, "%E", m_decl);
1664 : else
1665 : {
1666 1088 : pp_string (pp, "decl_region(");
1667 1088 : get_parent_region ()->dump_to_pp (pp, simple);
1668 1088 : pp_string (pp, ", ");
1669 1088 : print_quoted_type (pp, get_type ());
1670 1088 : pp_printf (pp, ", %qE)", m_decl);
1671 : }
1672 26142 : }
1673 :
1674 : void
1675 0 : decl_region::print_dump_widget_label (pretty_printer *pp) const
1676 : {
1677 0 : pp_printf (pp, "decl_region(%qE)", m_decl);
1678 0 : }
1679 :
1680 : /* Get the stack depth for the frame containing this decl, or 0
1681 : for a global. */
1682 :
1683 : int
1684 9621 : decl_region::get_stack_depth () const
1685 : {
1686 9621 : if (get_parent_region () == nullptr)
1687 : return 0;
1688 19242 : if (const frame_region *frame_reg
1689 9621 : = get_parent_region ()->dyn_cast_frame_region ())
1690 9135 : return frame_reg->get_stack_depth ();
1691 : return 0;
1692 : }
1693 :
1694 : /* If the underlying decl is in the global constant pool,
1695 : return an svalue representing the constant value.
1696 : Otherwise return nullptr. */
1697 :
1698 : const svalue *
1699 3433599 : decl_region::maybe_get_constant_value (region_model_manager *mgr) const
1700 : {
1701 3433599 : if (VAR_P (m_decl)
1702 317051 : && DECL_IN_CONSTANT_POOL (m_decl)
1703 14 : && DECL_INITIAL (m_decl)
1704 3433613 : && TREE_CODE (DECL_INITIAL (m_decl)) == CONSTRUCTOR)
1705 14 : return get_svalue_for_constructor (DECL_INITIAL (m_decl), mgr);
1706 : return nullptr;
1707 : }
1708 :
1709 : /* Implementation of decl_region::get_svalue_for_constructor
1710 : for when the cached value hasn't yet been calculated. */
1711 :
1712 : const svalue *
1713 122 : decl_region::calc_svalue_for_constructor (tree ctor,
1714 : region_model_manager *mgr) const
1715 : {
1716 : /* Create a binding map, applying ctor to it, using this
1717 : decl_region as the base region when building child regions
1718 : for offset calculations. */
1719 122 : binding_map map (*mgr->get_store_manager ());
1720 122 : if (!map.apply_ctor_to_region (this, ctor, mgr))
1721 1 : return mgr->get_or_create_unknown_svalue (get_type ());
1722 :
1723 : /* Return a compound svalue for the map we built. */
1724 121 : return mgr->get_or_create_compound_svalue (get_type (), map);
1725 122 : }
1726 :
1727 : /* Get an svalue for CTOR, a CONSTRUCTOR for this region's decl. */
1728 :
1729 : const svalue *
1730 216 : decl_region::get_svalue_for_constructor (tree ctor,
1731 : region_model_manager *mgr) const
1732 : {
1733 216 : gcc_assert (!TREE_CLOBBER_P (ctor));
1734 216 : gcc_assert (ctor == DECL_INITIAL (m_decl));
1735 :
1736 216 : if (!m_ctor_svalue)
1737 122 : m_ctor_svalue = calc_svalue_for_constructor (ctor, mgr);
1738 :
1739 216 : return m_ctor_svalue;
1740 : }
1741 :
1742 : /* For use on decl_regions for global variables.
1743 :
1744 : Get an svalue for the initial value of this region at entry to
1745 : "main" (either based on DECL_INITIAL, or implicit initialization to
1746 : zero.
1747 :
1748 : Return nullptr if there is a problem. */
1749 :
1750 : const svalue *
1751 421 : decl_region::get_svalue_for_initializer (region_model_manager *mgr) const
1752 : {
1753 421 : tree init = DECL_INITIAL (m_decl);
1754 421 : if (!init)
1755 : {
1756 : /* If we have an "extern" decl then there may be an initializer in
1757 : another TU. */
1758 146 : if (DECL_EXTERNAL (m_decl))
1759 : return nullptr;
1760 :
1761 33 : if (empty_p ())
1762 : return nullptr;
1763 :
1764 : /* Implicit initialization to zero; use a compound_svalue for it.
1765 : Doing so requires that we have a concrete binding for this region,
1766 : which can fail if we have a region with unknown size
1767 : (e.g. "extern const char arr[];"). */
1768 33 : const binding_key *binding
1769 33 : = binding_key::make (mgr->get_store_manager (), this);
1770 33 : if (binding->symbolic_p ())
1771 : return nullptr;
1772 :
1773 : /* If we don't care about tracking the content of this region, then
1774 : it's unused, and the value doesn't matter. */
1775 33 : if (!tracked_p ())
1776 : return nullptr;
1777 :
1778 33 : binding_cluster c (*mgr->get_store_manager (), this);
1779 33 : c.zero_fill_region (mgr->get_store_manager (), this);
1780 33 : return mgr->get_or_create_compound_svalue (TREE_TYPE (m_decl),
1781 33 : c.get_map ());
1782 33 : }
1783 :
1784 : /* LTO can write out error_mark_node as the DECL_INITIAL for simple scalar
1785 : values (to avoid writing out an extra section). */
1786 275 : if (init == error_mark_node)
1787 : return nullptr;
1788 :
1789 271 : if (TREE_CODE (init) == CONSTRUCTOR)
1790 202 : return get_svalue_for_constructor (init, mgr);
1791 :
1792 : /* Reuse the get_rvalue logic from region_model. */
1793 69 : region_model m (mgr);
1794 69 : return m.get_rvalue (path_var (init, 0), nullptr);
1795 69 : }
1796 :
1797 : /* Subroutine of symnode_requires_tracking_p; return true if REF
1798 : might imply that we should be tracking the value of its decl. */
1799 :
1800 : static bool
1801 4172 : ipa_ref_requires_tracking (ipa_ref *ref)
1802 : {
1803 : /* If we have a load/store/alias of the symbol, then we'll track
1804 : the decl's value. */
1805 4172 : if (ref->use != IPA_REF_ADDR)
1806 : return true;
1807 :
1808 4141 : if (ref->stmt == nullptr)
1809 : return true;
1810 :
1811 4141 : switch (ref->stmt->code)
1812 : {
1813 : default:
1814 : return true;
1815 4109 : case GIMPLE_CALL:
1816 4109 : {
1817 4157 : cgraph_node *caller_cnode = dyn_cast <cgraph_node *> (ref->referring);
1818 4109 : if (caller_cnode == nullptr)
1819 : return true;
1820 4109 : cgraph_edge *edge = caller_cnode->get_edge (ref->stmt);
1821 4109 : if (!edge)
1822 : return true;
1823 4109 : if (edge->callee == nullptr)
1824 : return true; /* e.g. call through function ptr. */
1825 4108 : if (edge->callee->definition)
1826 : return true;
1827 : /* If we get here, then this ref is a pointer passed to
1828 : a function we don't have the definition for. */
1829 : return false;
1830 : }
1831 17 : break;
1832 17 : case GIMPLE_ASM:
1833 17 : {
1834 17 : const gasm *asm_stmt = as_a <const gasm *> (ref->stmt);
1835 17 : if (gimple_asm_noutputs (asm_stmt) > 0)
1836 : return true;
1837 17 : if (gimple_asm_nclobbers (asm_stmt) > 0)
1838 : return true;
1839 : /* If we get here, then this ref is the decl being passed
1840 : by pointer to asm with no outputs. */
1841 : return false;
1842 : }
1843 : break;
1844 : }
1845 : }
1846 :
1847 : /* Determine if the decl for SYMNODE should have binding_clusters
1848 : in our state objects; return false to optimize away tracking
1849 : certain decls in our state objects, as an optimization. */
1850 :
1851 : static bool
1852 5478 : symnode_requires_tracking_p (symtab_node *symnode)
1853 : {
1854 5478 : gcc_assert (symnode);
1855 5478 : if (symnode->externally_visible)
1856 : return true;
1857 4729 : tree context_fndecl = DECL_CONTEXT (symnode->decl);
1858 4729 : if (context_fndecl == nullptr)
1859 : return true;
1860 4715 : if (TREE_CODE (context_fndecl) != FUNCTION_DECL)
1861 : return true;
1862 16511 : for (auto ref : symnode->ref_list.referring)
1863 4172 : if (ipa_ref_requires_tracking (ref))
1864 : return true;
1865 :
1866 : /* If we get here, then we don't have uses of this decl that require
1867 : tracking; we never read from it or write to it explicitly. */
1868 : return false;
1869 : }
1870 :
1871 : /* Subroutine of decl_region ctor: determine whether this decl_region
1872 : can have binding_clusters; return false to optimize away tracking
1873 : of certain decls in our state objects, as an optimization. */
1874 :
1875 : bool
1876 107981 : decl_region::calc_tracked_p (tree decl)
1877 : {
1878 : /* Precondition of symtab_node::get. */
1879 107981 : if (TREE_CODE (decl) == VAR_DECL
1880 107981 : && (TREE_STATIC (decl) || DECL_EXTERNAL (decl) || in_lto_p))
1881 6372 : if (symtab_node *symnode = symtab_node::get (decl))
1882 5478 : return symnode_requires_tracking_p (symnode);
1883 : return true;
1884 : }
1885 :
1886 : /* class field_region : public region. */
1887 :
1888 : /* Implementation of region::dump_to_pp vfunc for field_region. */
1889 :
1890 : void
1891 1895 : field_region::dump_to_pp (pretty_printer *pp, bool simple) const
1892 : {
1893 1895 : if (simple)
1894 : {
1895 1895 : get_parent_region ()->dump_to_pp (pp, simple);
1896 1895 : pp_string (pp, ".");
1897 1895 : pp_printf (pp, "%E", m_field);
1898 : }
1899 : else
1900 : {
1901 0 : pp_string (pp, "field_region(");
1902 0 : get_parent_region ()->dump_to_pp (pp, simple);
1903 0 : pp_string (pp, ", ");
1904 0 : print_quoted_type (pp, get_type ());
1905 0 : pp_printf (pp, ", %qE)", m_field);
1906 : }
1907 1895 : }
1908 :
1909 : void
1910 0 : field_region::print_dump_widget_label (pretty_printer *pp) const
1911 : {
1912 0 : pp_printf (pp, "field_region(%qE)", m_field);
1913 0 : }
1914 :
1915 : /* Implementation of region::get_relative_concrete_offset vfunc
1916 : for field_region. */
1917 :
1918 : bool
1919 9644 : field_region::get_relative_concrete_offset (bit_offset_t *out) const
1920 : {
1921 : /* Compare with e.g. gimple-fold.cc's
1922 : fold_nonarray_ctor_reference. */
1923 9644 : tree byte_offset = DECL_FIELD_OFFSET (m_field);
1924 9644 : if (TREE_CODE (byte_offset) != INTEGER_CST)
1925 : return false;
1926 9642 : tree field_offset = DECL_FIELD_BIT_OFFSET (m_field);
1927 : /* Compute bit offset of the field. */
1928 9642 : offset_int bitoffset
1929 9642 : = (wi::to_offset (field_offset)
1930 9642 : + (wi::to_offset (byte_offset) << LOG2_BITS_PER_UNIT));
1931 9642 : *out = bitoffset;
1932 9642 : return true;
1933 : }
1934 :
1935 :
1936 : /* Implementation of region::get_relative_symbolic_offset vfunc
1937 : for field_region.
1938 : If known, the returned svalue is equal to the offset converted to bytes and
1939 : rounded off. */
1940 :
1941 : const svalue *
1942 348 : field_region::get_relative_symbolic_offset (region_model_manager *mgr) const
1943 : {
1944 348 : bit_offset_t out;
1945 348 : if (get_relative_concrete_offset (&out))
1946 : {
1947 347 : tree cst_tree
1948 347 : = wide_int_to_tree (ptrdiff_type_node, out / BITS_PER_UNIT);
1949 347 : return mgr->get_or_create_constant_svalue (cst_tree);
1950 : }
1951 1 : return mgr->get_or_create_unknown_svalue (ptrdiff_type_node);
1952 : }
1953 :
1954 : /* class element_region : public region. */
1955 :
1956 : /* Implementation of region::accept vfunc for element_region. */
1957 :
1958 : void
1959 3934846 : element_region::accept (visitor *v) const
1960 : {
1961 3934846 : region::accept (v);
1962 3934846 : m_index->accept (v);
1963 3934846 : }
1964 :
1965 : /* Implementation of region::dump_to_pp vfunc for element_region. */
1966 :
1967 : void
1968 276 : element_region::dump_to_pp (pretty_printer *pp, bool simple) const
1969 : {
1970 276 : if (simple)
1971 : {
1972 : //pp_string (pp, "(");
1973 276 : get_parent_region ()->dump_to_pp (pp, simple);
1974 276 : pp_string (pp, "[");
1975 276 : m_index->dump_to_pp (pp, simple);
1976 276 : pp_string (pp, "]");
1977 : //pp_string (pp, ")");
1978 : }
1979 : else
1980 : {
1981 0 : pp_string (pp, "element_region(");
1982 0 : get_parent_region ()->dump_to_pp (pp, simple);
1983 0 : pp_string (pp, ", ");
1984 0 : print_quoted_type (pp, get_type ());
1985 0 : pp_string (pp, ", ");
1986 0 : m_index->dump_to_pp (pp, simple);
1987 0 : pp_printf (pp, ")");
1988 : }
1989 276 : }
1990 :
1991 : void
1992 0 : element_region::print_dump_widget_label (pretty_printer *pp) const
1993 : {
1994 0 : pp_printf (pp, "element_region: %<[]%>");
1995 0 : }
1996 :
1997 : void
1998 0 : element_region::
1999 : add_dump_widget_children (text_art::tree_widget &w,
2000 : const text_art::dump_widget_info &dwi) const
2001 : {
2002 0 : w.add_child (m_index->make_dump_widget (dwi, "m_index"));
2003 0 : }
2004 :
2005 : /* Implementation of region::get_relative_concrete_offset vfunc
2006 : for element_region. */
2007 :
2008 : bool
2009 10606 : element_region::get_relative_concrete_offset (bit_offset_t *out) const
2010 : {
2011 10606 : if (tree idx_cst = m_index->maybe_get_constant ())
2012 : {
2013 9489 : gcc_assert (TREE_CODE (idx_cst) == INTEGER_CST);
2014 :
2015 9489 : tree elem_type = get_type ();
2016 9489 : offset_int element_idx = wi::to_offset (idx_cst);
2017 :
2018 : /* First, use int_size_in_bytes, to reject the case where we
2019 : have an incomplete type, or a non-constant value. */
2020 9489 : HOST_WIDE_INT hwi_byte_size = int_size_in_bytes (elem_type);
2021 9489 : if (hwi_byte_size > 0)
2022 : {
2023 9488 : offset_int element_bit_size
2024 9488 : = hwi_byte_size << LOG2_BITS_PER_UNIT;
2025 9488 : offset_int element_bit_offset
2026 9488 : = element_idx * element_bit_size;
2027 9488 : *out = element_bit_offset;
2028 9488 : return true;
2029 : }
2030 : }
2031 : return false;
2032 : }
2033 :
2034 : /* Implementation of region::get_relative_symbolic_offset vfunc
2035 : for element_region. */
2036 :
2037 : const svalue *
2038 1146 : element_region::get_relative_symbolic_offset (region_model_manager *mgr) const
2039 : {
2040 1146 : tree elem_type = get_type ();
2041 :
2042 : /* First, use int_size_in_bytes, to reject the case where we
2043 : have an incomplete type, or a non-constant value. */
2044 1146 : HOST_WIDE_INT hwi_byte_size = int_size_in_bytes (elem_type);
2045 1146 : if (hwi_byte_size > 0)
2046 : {
2047 1144 : tree byte_size_tree = wide_int_to_tree (ptrdiff_type_node,
2048 1144 : hwi_byte_size);
2049 1144 : const svalue *byte_size_sval
2050 1144 : = mgr->get_or_create_constant_svalue (byte_size_tree);
2051 1144 : return mgr->get_or_create_binop (NULL_TREE, MULT_EXPR,
2052 1144 : m_index, byte_size_sval);
2053 : }
2054 2 : return mgr->get_or_create_unknown_svalue (ptrdiff_type_node);
2055 : }
2056 :
2057 : /* class offset_region : public region. */
2058 :
2059 : /* Implementation of region::accept vfunc for offset_region. */
2060 :
2061 : void
2062 80499 : offset_region::accept (visitor *v) const
2063 : {
2064 80499 : region::accept (v);
2065 80499 : m_byte_offset->accept (v);
2066 80499 : }
2067 :
2068 : /* Implementation of region::dump_to_pp vfunc for offset_region. */
2069 :
2070 : void
2071 2754 : offset_region::dump_to_pp (pretty_printer *pp, bool simple) const
2072 : {
2073 2754 : if (simple)
2074 : {
2075 : //pp_string (pp, "(");
2076 2685 : get_parent_region ()->dump_to_pp (pp, simple);
2077 2685 : pp_string (pp, "+");
2078 2685 : m_byte_offset->dump_to_pp (pp, simple);
2079 : //pp_string (pp, ")");
2080 : }
2081 : else
2082 : {
2083 69 : pp_string (pp, "offset_region(");
2084 69 : get_parent_region ()->dump_to_pp (pp, simple);
2085 69 : pp_string (pp, ", ");
2086 69 : print_quoted_type (pp, get_type ());
2087 69 : pp_string (pp, ", ");
2088 69 : m_byte_offset->dump_to_pp (pp, simple);
2089 69 : pp_printf (pp, ")");
2090 : }
2091 2754 : }
2092 :
2093 : void
2094 0 : offset_region::print_dump_widget_label (pretty_printer *pp) const
2095 : {
2096 0 : pp_printf (pp, "offset_region");
2097 0 : }
2098 :
2099 : void
2100 0 : offset_region::
2101 : add_dump_widget_children (text_art::tree_widget &w,
2102 : const text_art::dump_widget_info &dwi) const
2103 : {
2104 0 : w.add_child (m_byte_offset->make_dump_widget (dwi, "m_byte_offset"));
2105 0 : }
2106 :
2107 : const svalue *
2108 0 : offset_region::get_bit_offset (region_model_manager *mgr) const
2109 : {
2110 0 : const svalue *bits_per_byte_sval
2111 0 : = mgr->get_or_create_int_cst (NULL_TREE, BITS_PER_UNIT);
2112 0 : return mgr->get_or_create_binop (NULL_TREE, MULT_EXPR,
2113 0 : m_byte_offset, bits_per_byte_sval);
2114 : }
2115 :
2116 : /* Implementation of region::get_relative_concrete_offset vfunc
2117 : for offset_region. */
2118 :
2119 : bool
2120 3678 : offset_region::get_relative_concrete_offset (bit_offset_t *out) const
2121 : {
2122 3678 : if (tree byte_offset_cst = m_byte_offset->maybe_get_constant ())
2123 : {
2124 2186 : gcc_assert (TREE_CODE (byte_offset_cst) == INTEGER_CST);
2125 : /* Use a signed value for the byte offset, to handle
2126 : negative offsets. */
2127 2186 : HOST_WIDE_INT byte_offset
2128 2186 : = wi::to_offset (byte_offset_cst).to_shwi ();
2129 2186 : HOST_WIDE_INT bit_offset = byte_offset * BITS_PER_UNIT;
2130 2186 : *out = bit_offset;
2131 2186 : return true;
2132 : }
2133 : return false;
2134 : }
2135 :
2136 : /* Implementation of region::get_relative_symbolic_offset vfunc
2137 : for offset_region. */
2138 :
2139 : const svalue *
2140 1496 : offset_region::get_relative_symbolic_offset (region_model_manager *mgr
2141 : ATTRIBUTE_UNUSED) const
2142 : {
2143 1496 : return get_byte_offset ();
2144 : }
2145 :
2146 : /* class sized_region : public region. */
2147 :
2148 : /* Implementation of region::accept vfunc for sized_region. */
2149 :
2150 : void
2151 36309 : sized_region::accept (visitor *v) const
2152 : {
2153 36309 : region::accept (v);
2154 36309 : m_byte_size_sval->accept (v);
2155 36309 : }
2156 :
2157 : /* Implementation of region::dump_to_pp vfunc for sized_region. */
2158 :
2159 : void
2160 114 : sized_region::dump_to_pp (pretty_printer *pp, bool simple) const
2161 : {
2162 114 : if (simple)
2163 : {
2164 105 : pp_string (pp, "SIZED_REG(");
2165 105 : get_parent_region ()->dump_to_pp (pp, simple);
2166 105 : pp_string (pp, ", ");
2167 105 : m_byte_size_sval->dump_to_pp (pp, simple);
2168 105 : pp_string (pp, ")");
2169 : }
2170 : else
2171 : {
2172 9 : pp_string (pp, "sized_region(");
2173 9 : get_parent_region ()->dump_to_pp (pp, simple);
2174 9 : pp_string (pp, ", ");
2175 9 : m_byte_size_sval->dump_to_pp (pp, simple);
2176 9 : pp_printf (pp, ")");
2177 : }
2178 114 : }
2179 :
2180 : void
2181 0 : sized_region::print_dump_widget_label (pretty_printer *pp) const
2182 : {
2183 0 : pp_printf (pp, "sized_region");
2184 0 : }
2185 :
2186 : void
2187 0 : sized_region::
2188 : add_dump_widget_children (text_art::tree_widget &w,
2189 : const text_art::dump_widget_info &dwi) const
2190 : {
2191 0 : w.add_child (m_byte_size_sval->make_dump_widget (dwi, "m_byte_size_sval"));
2192 0 : }
2193 :
2194 : /* Implementation of region::get_byte_size vfunc for sized_region. */
2195 :
2196 : bool
2197 30676 : sized_region::get_byte_size (byte_size_t *out) const
2198 : {
2199 30676 : if (tree cst = m_byte_size_sval->maybe_get_constant ())
2200 : {
2201 22278 : gcc_assert (TREE_CODE (cst) == INTEGER_CST);
2202 22278 : *out = tree_to_uhwi (cst);
2203 22278 : return true;
2204 : }
2205 : return false;
2206 : }
2207 :
2208 : /* Implementation of region::get_bit_size vfunc for sized_region. */
2209 :
2210 : bool
2211 30676 : sized_region::get_bit_size (bit_size_t *out) const
2212 : {
2213 30676 : byte_size_t byte_size;
2214 30676 : if (!get_byte_size (&byte_size))
2215 : return false;
2216 22278 : *out = byte_size * BITS_PER_UNIT;
2217 22278 : return true;
2218 : }
2219 :
2220 : /* Implementation of region::get_bit_size_sval vfunc for sized_region. */
2221 :
2222 : const svalue *
2223 5064 : sized_region::get_bit_size_sval (region_model_manager *mgr) const
2224 : {
2225 5064 : const svalue *bits_per_byte_sval
2226 5064 : = mgr->get_or_create_int_cst (NULL_TREE, BITS_PER_UNIT);
2227 5064 : return mgr->get_or_create_binop (NULL_TREE, MULT_EXPR,
2228 5064 : m_byte_size_sval, bits_per_byte_sval);
2229 : }
2230 :
2231 : /* class cast_region : public region. */
2232 :
2233 : /* Implementation of region::dump_to_pp vfunc for cast_region. */
2234 :
2235 : void
2236 1371 : cast_region::dump_to_pp (pretty_printer *pp, bool simple) const
2237 : {
2238 1371 : if (simple)
2239 : {
2240 1320 : pp_string (pp, "CAST_REG(");
2241 1320 : print_quoted_type (pp, get_type ());
2242 1320 : pp_string (pp, ", ");
2243 1320 : get_parent_region ()->dump_to_pp (pp, simple);
2244 1320 : pp_string (pp, ")");
2245 : }
2246 : else
2247 : {
2248 51 : pp_string (pp, "cast_region(");
2249 51 : get_parent_region ()->dump_to_pp (pp, simple);
2250 51 : pp_string (pp, ", ");
2251 51 : print_quoted_type (pp, get_type ());
2252 51 : pp_printf (pp, ")");
2253 : }
2254 1371 : }
2255 :
2256 : void
2257 0 : cast_region::print_dump_widget_label (pretty_printer *pp) const
2258 : {
2259 0 : pp_printf (pp, "cast_region");
2260 0 : }
2261 :
2262 : /* Implementation of region::get_relative_concrete_offset vfunc
2263 : for cast_region. */
2264 :
2265 : bool
2266 22 : cast_region::get_relative_concrete_offset (bit_offset_t *out) const
2267 : {
2268 22 : *out = (int) 0;
2269 22 : return true;
2270 : }
2271 :
2272 : /* class heap_allocated_region : public region. */
2273 :
2274 : /* Implementation of region::dump_to_pp vfunc for heap_allocated_region. */
2275 :
2276 : void
2277 2104 : heap_allocated_region::dump_to_pp (pretty_printer *pp, bool simple) const
2278 : {
2279 2104 : if (simple)
2280 2104 : pp_printf (pp, "HEAP_ALLOCATED_REGION(%i)", get_id ());
2281 : else
2282 0 : pp_printf (pp, "heap_allocated_region(%i)", get_id ());
2283 2104 : }
2284 :
2285 : void
2286 0 : heap_allocated_region::print_dump_widget_label (pretty_printer *pp) const
2287 : {
2288 0 : pp_printf (pp, "heap_allocated_region");
2289 0 : }
2290 :
2291 : /* class alloca_region : public region. */
2292 :
2293 : /* Implementation of region::dump_to_pp vfunc for alloca_region. */
2294 :
2295 : void
2296 0 : alloca_region::dump_to_pp (pretty_printer *pp, bool simple) const
2297 : {
2298 0 : if (simple)
2299 0 : pp_printf (pp, "ALLOCA_REGION(%i)", get_id ());
2300 : else
2301 0 : pp_printf (pp, "alloca_region(%i)", get_id ());
2302 0 : }
2303 :
2304 : void
2305 0 : alloca_region::print_dump_widget_label (pretty_printer *pp) const
2306 : {
2307 0 : pp_printf (pp, "alloca_region");
2308 0 : }
2309 :
2310 : /* class string_region : public region. */
2311 :
2312 : /* Implementation of region::dump_to_pp vfunc for string_region. */
2313 :
2314 : void
2315 0 : string_region::dump_to_pp (pretty_printer *pp, bool simple) const
2316 : {
2317 0 : if (simple)
2318 0 : dump_tree (pp, m_string_cst);
2319 : else
2320 : {
2321 0 : pp_string (pp, "string_region(");
2322 0 : dump_tree (pp, m_string_cst);
2323 0 : if (!flag_dump_noaddr)
2324 : {
2325 0 : pp_string (pp, " (");
2326 0 : pp_pointer (pp, m_string_cst);
2327 0 : pp_string (pp, "))");
2328 : }
2329 : }
2330 0 : }
2331 :
2332 : void
2333 0 : string_region::print_dump_widget_label (pretty_printer *pp) const
2334 : {
2335 0 : pp_string (pp, "string_region(");
2336 0 : dump_tree (pp, m_string_cst);
2337 0 : pp_string (pp, ")");
2338 0 : }
2339 :
2340 : /* class bit_range_region : public region. */
2341 :
2342 : /* Implementation of region::dump_to_pp vfunc for bit_range_region. */
2343 :
2344 : void
2345 0 : bit_range_region::dump_to_pp (pretty_printer *pp, bool simple) const
2346 : {
2347 0 : if (simple)
2348 : {
2349 0 : pp_string (pp, "BIT_RANGE_REG(");
2350 0 : get_parent_region ()->dump_to_pp (pp, simple);
2351 0 : pp_string (pp, ", ");
2352 0 : m_bits.dump_to_pp (pp);
2353 0 : pp_string (pp, ")");
2354 : }
2355 : else
2356 : {
2357 0 : pp_string (pp, "bit_range_region(");
2358 0 : get_parent_region ()->dump_to_pp (pp, simple);
2359 0 : pp_string (pp, ", ");
2360 0 : m_bits.dump_to_pp (pp);
2361 0 : pp_printf (pp, ")");
2362 : }
2363 0 : }
2364 :
2365 : void
2366 0 : bit_range_region::print_dump_widget_label (pretty_printer *pp) const
2367 : {
2368 0 : pp_printf (pp, "bit_range_region(m_bits: ");
2369 0 : m_bits.dump_to_pp (pp);
2370 0 : pp_string (pp, ")");
2371 0 : }
2372 :
2373 : /* Implementation of region::get_byte_size vfunc for bit_range_region. */
2374 :
2375 : bool
2376 0 : bit_range_region::get_byte_size (byte_size_t *out) const
2377 : {
2378 0 : if (m_bits.m_size_in_bits % BITS_PER_UNIT == 0)
2379 : {
2380 0 : *out = m_bits.m_size_in_bits / BITS_PER_UNIT;
2381 0 : return true;
2382 : }
2383 : return false;
2384 : }
2385 :
2386 : /* Implementation of region::get_bit_size vfunc for bit_range_region. */
2387 :
2388 : bool
2389 812 : bit_range_region::get_bit_size (bit_size_t *out) const
2390 : {
2391 812 : *out = m_bits.m_size_in_bits;
2392 812 : return true;
2393 : }
2394 :
2395 : /* Implementation of region::get_byte_size_sval vfunc for bit_range_region. */
2396 :
2397 : const svalue *
2398 48 : bit_range_region::get_byte_size_sval (region_model_manager *mgr) const
2399 : {
2400 48 : if (m_bits.m_size_in_bits % BITS_PER_UNIT != 0)
2401 0 : return mgr->get_or_create_unknown_svalue (size_type_node);
2402 :
2403 48 : HOST_WIDE_INT num_bytes = m_bits.m_size_in_bits.to_shwi () / BITS_PER_UNIT;
2404 48 : return mgr->get_or_create_int_cst (size_type_node, num_bytes);
2405 : }
2406 :
2407 : /* Implementation of region::get_bit_size_sval vfunc for bit_range_region. */
2408 :
2409 : const svalue *
2410 136 : bit_range_region::get_bit_size_sval (region_model_manager *mgr) const
2411 : {
2412 272 : return mgr->get_or_create_int_cst (size_type_node,
2413 136 : m_bits.m_size_in_bits);
2414 : }
2415 :
2416 : /* Implementation of region::get_relative_concrete_offset vfunc for
2417 : bit_range_region. */
2418 :
2419 : bool
2420 155 : bit_range_region::get_relative_concrete_offset (bit_offset_t *out) const
2421 : {
2422 155 : *out = m_bits.get_start_bit_offset ();
2423 155 : return true;
2424 : }
2425 :
2426 : /* Implementation of region::get_relative_symbolic_offset vfunc for
2427 : bit_range_region.
2428 : The returned svalue is equal to the offset converted to bytes and
2429 : rounded off. */
2430 :
2431 : const svalue *
2432 0 : bit_range_region::get_relative_symbolic_offset (region_model_manager *mgr)
2433 : const
2434 : {
2435 0 : byte_offset_t start_byte = m_bits.get_start_bit_offset () / BITS_PER_UNIT;
2436 0 : tree start_bit_tree = wide_int_to_tree (ptrdiff_type_node, start_byte);
2437 0 : return mgr->get_or_create_constant_svalue (start_bit_tree);
2438 : }
2439 :
2440 : /* class var_arg_region : public region. */
2441 :
2442 : void
2443 0 : var_arg_region::dump_to_pp (pretty_printer *pp, bool simple) const
2444 : {
2445 0 : if (simple)
2446 : {
2447 0 : pp_string (pp, "VAR_ARG_REG(");
2448 0 : get_parent_region ()->dump_to_pp (pp, simple);
2449 0 : pp_printf (pp, ", arg_idx: %d)", m_idx);
2450 : }
2451 : else
2452 : {
2453 0 : pp_string (pp, "var_arg_region(");
2454 0 : get_parent_region ()->dump_to_pp (pp, simple);
2455 0 : pp_printf (pp, ", arg_idx: %d)", m_idx);
2456 : }
2457 0 : }
2458 :
2459 : void
2460 0 : var_arg_region::print_dump_widget_label (pretty_printer *pp) const
2461 : {
2462 0 : pp_printf (pp, "var_arg_region(arg_idx: %i)", m_idx);
2463 0 : }
2464 :
2465 : /* Get the frame_region for this var_arg_region. */
2466 :
2467 : const frame_region *
2468 608 : var_arg_region::get_frame_region () const
2469 : {
2470 608 : gcc_assert (get_parent_region ());
2471 608 : return as_a <const frame_region *> (get_parent_region ());
2472 : }
2473 :
2474 : /* class errno_region : public region. */
2475 :
2476 : void
2477 0 : errno_region::dump_to_pp (pretty_printer *pp, bool simple) const
2478 : {
2479 0 : if (simple)
2480 0 : pp_string (pp, "errno_region");
2481 : else
2482 0 : pp_string (pp, "errno_region()");
2483 0 : }
2484 :
2485 : void
2486 0 : errno_region::print_dump_widget_label (pretty_printer *pp) const
2487 : {
2488 0 : pp_printf (pp, "errno_region");
2489 0 : }
2490 :
2491 : /* class private_region : public region. */
2492 :
2493 : void
2494 0 : private_region::dump_to_pp (pretty_printer *pp, bool simple) const
2495 : {
2496 0 : if (simple)
2497 0 : pp_printf (pp, "PRIVATE_REG(%qs)", m_desc);
2498 : else
2499 0 : pp_printf (pp, "private_region(%qs)", m_desc);
2500 0 : }
2501 :
2502 : void
2503 0 : private_region::print_dump_widget_label (pretty_printer *pp) const
2504 : {
2505 0 : pp_printf (pp, "private_region(%qs)", m_desc);
2506 0 : }
2507 :
2508 : /* class unknown_region : public region. */
2509 :
2510 : /* Implementation of region::dump_to_pp vfunc for unknown_region. */
2511 :
2512 : void
2513 35 : unknown_region::dump_to_pp (pretty_printer *pp, bool /*simple*/) const
2514 : {
2515 35 : pp_string (pp, "UNKNOWN_REGION");
2516 35 : }
2517 :
2518 : void
2519 0 : unknown_region::print_dump_widget_label (pretty_printer *pp) const
2520 : {
2521 0 : pp_printf (pp, "unknown_region");
2522 0 : }
2523 :
2524 : } // namespace ana
2525 :
2526 : #endif /* #if ENABLE_ANALYZER */
|