Branch data Line data Source code
1 : : /* Regions of memory.
2 : : Copyright (C) 2019-2025 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 : 1314 : region_offset::make_byte_offset (const region *base_region,
49 : : const svalue *num_bytes_sval)
50 : : {
51 : 1314 : if (tree num_bytes_cst = num_bytes_sval->maybe_get_constant ())
52 : : {
53 : 982 : gcc_assert (TREE_CODE (num_bytes_cst) == INTEGER_CST);
54 : 982 : bit_offset_t num_bits = wi::to_offset (num_bytes_cst) * BITS_PER_UNIT;
55 : 982 : 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 NULL). */
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 : NULL);
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 : : NULL,
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 (NULL, NULL, NULL);
280 : 1743 : linear_op op_b (NULL, NULL, NULL);
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 (NULL, NULL, NULL);
322 : 125 : linear_op op_b (NULL, NULL, NULL);
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 : 5176 : strip_types (const region_offset &offset, region_model_manager &mgr)
366 : : {
367 : 5176 : 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 : 4299 : return offset;
374 : : }
375 : :
376 : : /* class region and its various subclasses. */
377 : :
378 : : /* class region. */
379 : :
380 : 200963 : region::~region ()
381 : : {
382 : 200963 : delete m_cached_offset;
383 : 200963 : }
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 : 44140705 : region::get_base_region () const
393 : : {
394 : 44140705 : const region *iter = this;
395 : 46389095 : while (iter)
396 : : {
397 : 46389095 : switch (iter->get_kind ())
398 : : {
399 : 2248390 : case RK_FIELD:
400 : 2248390 : case RK_ELEMENT:
401 : 2248390 : case RK_OFFSET:
402 : 2248390 : case RK_SIZED:
403 : 2248390 : case RK_BIT_RANGE:
404 : 2248390 : case RK_CAST:
405 : 2248390 : iter = iter->get_parent_region ();
406 : 2248390 : 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 : 274151 : region::base_region_p () const
418 : : {
419 : 274151 : 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 : 210213 : default:
431 : 210213 : return true;
432 : : }
433 : : }
434 : :
435 : : /* Return true if this region is ELDER or one of its descendents. */
436 : :
437 : : bool
438 : 225476 : region::descendent_of_p (const region *elder) const
439 : : {
440 : 225476 : const region *iter = this;
441 : 842892 : while (iter)
442 : : {
443 : 673949 : if (iter == elder)
444 : : return true;
445 : 617416 : 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 NULL. */
452 : :
453 : : const frame_region *
454 : 2412718 : region::maybe_get_frame_region () const
455 : : {
456 : 2412718 : const region *iter = this;
457 : 6413064 : while (iter)
458 : : {
459 : 5623901 : if (const frame_region *frame_reg = iter->dyn_cast_frame_region ())
460 : : return frame_reg;
461 : 4000346 : iter = iter->get_parent_region ();
462 : : }
463 : : return NULL;
464 : : }
465 : :
466 : : /* Get the memory space of this region. */
467 : :
468 : : enum memory_space
469 : 3433250 : region::get_memory_space () const
470 : : {
471 : 3433250 : const region *iter = this;
472 : 7273664 : while (iter)
473 : : {
474 : 6484202 : switch (iter->get_kind ())
475 : : {
476 : 3840414 : default:
477 : 3840414 : 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 : 3840414 : 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 : 2790441 : region::can_have_initial_svalue_p () const
508 : : {
509 : 2790441 : const region *base_reg = get_base_region ();
510 : :
511 : : /* Check for memory spaces that are uninitialized by default. */
512 : 2790441 : enum memory_space mem_space = base_reg->get_memory_space ();
513 : 2790441 : 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 : 1762403 : case MEMSPACE_STACK:
530 : 1762403 : 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 : 1754553 : 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 : 1644829 : case SSA_NAME:
549 : 1644829 : {
550 : : /* Some SSA names have an implicit default defined value. */
551 : 1644829 : tree ssa_name = decl;
552 : 1644829 : if (SSA_NAME_IS_DEFAULT_DEF (ssa_name))
553 : 1583710 : 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 : 7816 : region::get_initial_value_at_main (region_model_manager *mgr) const
571 : : {
572 : 7816 : if (!m_cached_init_sval_at_main)
573 : 443 : m_cached_init_sval_at_main = calc_initial_value_at_main (mgr);
574 : 7816 : return m_cached_init_sval_at_main;
575 : : }
576 : :
577 : : /* Implementation of region::get_initial_value_at_main. */
578 : :
579 : : const svalue *
580 : 443 : region::calc_initial_value_at_main (region_model_manager *mgr) const
581 : : {
582 : 443 : const decl_region *base_reg = get_base_region ()->dyn_cast_decl_region ();
583 : 443 : gcc_assert (base_reg);
584 : :
585 : : /* Attempt to get the initializer value for base_reg. */
586 : 886 : if (const svalue *base_reg_init
587 : 443 : = base_reg->get_svalue_for_initializer (mgr))
588 : : {
589 : 359 : if (this == base_reg)
590 : : return base_reg_init;
591 : : else
592 : : {
593 : : /* Get the value for REG within base_reg_init. */
594 : 176 : binding_cluster c (base_reg);
595 : 176 : c.bind (mgr->get_store_manager (), base_reg, base_reg_init);
596 : 176 : const svalue *sval
597 : 176 : = c.get_any_binding (mgr->get_store_manager (), this);
598 : 176 : if (sval)
599 : : {
600 : 175 : if (get_type ())
601 : 156 : sval = mgr->get_or_create_cast (get_type (), sval);
602 : 175 : return sval;
603 : : }
604 : 176 : }
605 : : }
606 : :
607 : : /* Otherwise, return INIT_VAL(REG). */
608 : 85 : 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. */
613 : :
614 : : tree
615 : 2855385 : region::maybe_get_decl () const
616 : : {
617 : 2855385 : if (const decl_region *decl_reg = dyn_cast_decl_region ())
618 : 2447602 : 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 : 4548021 : region::get_offset (region_model_manager *mgr) const
627 : : {
628 : 4548021 : if(!m_cached_offset)
629 : 138503 : m_cached_offset = new region_offset (calc_offset (mgr));
630 : 4548021 : return *m_cached_offset;
631 : : }
632 : :
633 : : /* Get the region_offset for immediately beyond this region. */
634 : :
635 : : region_offset
636 : 1044 : region::get_next_offset (region_model_manager *mgr) const
637 : : {
638 : 1044 : region_offset start = get_offset (mgr);
639 : :
640 : 1044 : bit_size_t bit_size;
641 : 1044 : if (get_bit_size (&bit_size))
642 : : {
643 : 1026 : if (start.concrete_p ())
644 : : {
645 : 838 : bit_offset_t next_bit_offset = start.get_bit_offset () + bit_size;
646 : 838 : 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 : 678 : region::get_byte_size (byte_size_t *out) const
669 : : {
670 : 678 : tree type = get_type ();
671 : :
672 : : /* Bail out e.g. for heap-allocated regions. */
673 : 678 : if (!type)
674 : : return false;
675 : :
676 : 514 : HOST_WIDE_INT bytes = int_size_in_bytes (type);
677 : 514 : if (bytes == -1)
678 : : return false;
679 : 514 : *out = bytes;
680 : 514 : return true;
681 : : }
682 : :
683 : : /* Base implementation of region::get_byte_size_sval vfunc. */
684 : :
685 : : const svalue *
686 : 57529 : region::get_byte_size_sval (region_model_manager *mgr) const
687 : : {
688 : 57529 : tree type = get_type ();
689 : :
690 : : /* Bail out e.g. for heap-allocated regions. */
691 : 57529 : if (!type)
692 : 12857 : return mgr->get_or_create_unknown_svalue (size_type_node);
693 : :
694 : 44672 : HOST_WIDE_INT bytes = int_size_in_bytes (type);
695 : 44672 : if (bytes == -1)
696 : 576 : return mgr->get_or_create_unknown_svalue (size_type_node);
697 : :
698 : 44096 : tree byte_size = size_in_bytes (type);
699 : 44096 : if (TREE_TYPE (byte_size) != size_type_node)
700 : 44096 : byte_size = fold_build1 (NOP_EXPR, size_type_node, byte_size);
701 : 44096 : 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 : 9059195 : int_size_in_bits (const_tree type, bit_size_t *out)
710 : : {
711 : 9059195 : if (INTEGRAL_TYPE_P (type))
712 : : {
713 : 3436663 : *out = TYPE_PRECISION (type);
714 : 3436663 : return true;
715 : : }
716 : :
717 : 5622532 : tree sz = TYPE_SIZE (type);
718 : 5622532 : if (sz
719 : 5603777 : && 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 : 11226122 : && !integer_zerop (sz))
723 : : {
724 : 5600975 : *out = TREE_INT_CST_LOW (sz);
725 : 5600975 : return true;
726 : : }
727 : : else
728 : 21557 : return false;
729 : : }
730 : :
731 : : /* Base implementation of region::get_bit_size_sval vfunc. */
732 : :
733 : : const svalue *
734 : 690836 : region::get_bit_size_sval (region_model_manager *mgr) const
735 : : {
736 : 690836 : tree type = get_type ();
737 : :
738 : : /* Bail out e.g. for heap-allocated regions. */
739 : 690836 : if (!type)
740 : 7595 : return mgr->get_or_create_unknown_svalue (size_type_node);
741 : :
742 : 683241 : bit_size_t bits;
743 : 683241 : if (!int_size_in_bits (type, &bits))
744 : 74 : return mgr->get_or_create_unknown_svalue (size_type_node);
745 : :
746 : 683167 : 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 : 10031192 : region::get_bit_size (bit_size_t *out) const
755 : : {
756 : 10031192 : tree type = get_type ();
757 : :
758 : : /* Bail out e.g. for heap-allocated regions. */
759 : 10031192 : if (!type)
760 : : return false;
761 : :
762 : 8371102 : return int_size_in_bits (type, out);
763 : : }
764 : :
765 : : /* Get the field within RECORD_TYPE at BIT_OFFSET. */
766 : :
767 : : tree
768 : 1502 : get_field_at_bit_offset (tree record_type, bit_offset_t bit_offset)
769 : : {
770 : 1502 : gcc_assert (TREE_CODE (record_type) == RECORD_TYPE);
771 : 1502 : if (bit_offset < 0)
772 : : return NULL;
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 : 1502 : tree last_field = NULL_TREE;
778 : 18634 : for (tree iter = TYPE_FIELDS (record_type); iter != NULL_TREE;
779 : 17132 : iter = DECL_CHAIN (iter))
780 : : {
781 : 17930 : if (TREE_CODE (iter) == FIELD_DECL)
782 : : {
783 : 3726 : int iter_field_offset = int_bit_position (iter);
784 : 3726 : if (bit_offset < iter_field_offset)
785 : 798 : return last_field;
786 : 2928 : 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 : 9666 : 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 : 9666 : if (get_type () == NULL_TREE || type == NULL_TREE)
803 : : return;
804 : 9372 : if (relative_bit_offset == 0
805 : 9372 : && types_compatible_p (get_type (), type))
806 : : {
807 : 8431 : out->safe_push (this);
808 : 8431 : return;
809 : : }
810 : 941 : switch (TREE_CODE (get_type ()))
811 : : {
812 : 115 : case ARRAY_TYPE:
813 : 115 : {
814 : 115 : tree element_type = TREE_TYPE (get_type ());
815 : 115 : HOST_WIDE_INT hwi_byte_size = int_size_in_bytes (element_type);
816 : 115 : if (hwi_byte_size > 0)
817 : : {
818 : 115 : HOST_WIDE_INT bits_per_element
819 : : = hwi_byte_size << LOG2_BITS_PER_UNIT;
820 : 115 : HOST_WIDE_INT element_index
821 : 115 : = (relative_bit_offset.to_shwi () / bits_per_element);
822 : 115 : tree element_index_cst
823 : 115 : = build_int_cst (integer_type_node, element_index);
824 : 115 : HOST_WIDE_INT inner_bit_offset
825 : 115 : = relative_bit_offset.to_shwi () % bits_per_element;
826 : 115 : const region *subregion = mgr->get_element_region
827 : 115 : (this, element_type,
828 : : mgr->get_or_create_constant_svalue (element_index_cst));
829 : 115 : subregion->get_subregions_for_binding (mgr, inner_bit_offset,
830 : : size_in_bits, type, out);
831 : : }
832 : : }
833 : : break;
834 : 686 : case RECORD_TYPE:
835 : 686 : {
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 : 686 : if (tree field = get_field_at_bit_offset (get_type (),
841 : : relative_bit_offset))
842 : : {
843 : 686 : int field_bit_offset = int_bit_position (field);
844 : 686 : const region *subregion = mgr->get_field_region (this, field);
845 : 686 : subregion->get_subregions_for_binding
846 : 686 : (mgr, relative_bit_offset - field_bit_offset,
847 : : size_in_bits, type, out);
848 : : }
849 : : }
850 : : break;
851 : 8 : case UNION_TYPE:
852 : 8 : {
853 : 24 : for (tree field = TYPE_FIELDS (get_type ()); field != NULL_TREE;
854 : 16 : field = DECL_CHAIN (field))
855 : : {
856 : 16 : if (TREE_CODE (field) != FIELD_DECL)
857 : 0 : continue;
858 : 16 : const region *subregion = mgr->get_field_region (this, field);
859 : 16 : 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 : 138503 : region::calc_offset (region_model_manager *mgr) const
879 : : {
880 : 138503 : const region *iter_region = this;
881 : 138503 : bit_offset_t accum_bit_offset = 0;
882 : 138503 : const svalue *accum_byte_sval = NULL;
883 : :
884 : 166210 : while (iter_region)
885 : : {
886 : 166210 : switch (iter_region->get_kind ())
887 : : {
888 : 20391 : case RK_FIELD:
889 : 20391 : case RK_ELEMENT:
890 : 20391 : case RK_OFFSET:
891 : 20391 : case RK_BIT_RANGE:
892 : 20391 : if (accum_byte_sval)
893 : : {
894 : 3123 : const svalue *sval
895 : 3123 : = iter_region->get_relative_symbolic_offset (mgr);
896 : 3123 : accum_byte_sval
897 : 3123 : = mgr->get_or_create_binop (ptrdiff_type_node, PLUS_EXPR,
898 : : accum_byte_sval, sval);
899 : 3123 : iter_region = iter_region->get_parent_region ();
900 : : }
901 : : else
902 : : {
903 : 17268 : bit_offset_t rel_bit_offset;
904 : 17268 : if (iter_region->get_relative_concrete_offset (&rel_bit_offset))
905 : : {
906 : 14527 : accum_bit_offset += rel_bit_offset;
907 : 14527 : 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 : 2741 : byte_offset_t byte_offset = accum_bit_offset / BITS_PER_UNIT;
915 : 2741 : tree offset_tree = wide_int_to_tree (ptrdiff_type_node,
916 : 2741 : byte_offset);
917 : 2741 : accum_byte_sval
918 : 2741 : = mgr->get_or_create_constant_svalue (offset_tree);
919 : : }
920 : : }
921 : 20391 : continue;
922 : 7316 : case RK_SIZED:
923 : 7316 : case RK_CAST:
924 : 7316 : iter_region = iter_region->get_parent_region ();
925 : 7316 : continue;
926 : :
927 : 138503 : default:
928 : 138503 : return accum_byte_sval
929 : 138503 : ? region_offset::make_symbolic (iter_region,
930 : : accum_byte_sval)
931 : 135762 : : region_offset::make_concrete (iter_region,
932 : : accum_bit_offset);
933 : 27707 : }
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 : 50 : region::get_relative_concrete_offset (bit_offset_t *) const
946 : : {
947 : 50 : 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 : 824 : region::get_relative_concrete_byte_range (byte_range *out) const
965 : : {
966 : : /* We must have a concrete offset relative to the parent. */
967 : 824 : bit_offset_t rel_bit_offset;
968 : 824 : if (!get_relative_concrete_offset (&rel_bit_offset))
969 : : return false;
970 : : /* ...which must be a whole number of bytes. */
971 : 678 : if (rel_bit_offset % BITS_PER_UNIT != 0)
972 : : return false;
973 : 678 : 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 : 678 : byte_size_t num_bytes;
978 : 678 : if (!get_byte_size (&num_bytes))
979 : : return false;
980 : :
981 : : /* Success. */
982 : 514 : *out = byte_range (start_byte_offset, num_bytes);
983 : 514 : 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 : 22703533 : region::accept (visitor *v) const
1099 : : {
1100 : 22703533 : v->visit_region (this);
1101 : 22703533 : if (m_parent)
1102 : 16212721 : m_parent->accept (v);
1103 : 22703533 : }
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 : 4677771 : region::symbolic_for_unknown_ptr_p () const
1112 : : {
1113 : 4677771 : if (const symbolic_region *sym_reg = dyn_cast_symbolic_region ())
1114 : 532708 : 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 : 696502 : region::symbolic_p () const
1123 : : {
1124 : 696502 : 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 : 6510767 : region::empty_p () const
1131 : : {
1132 : 6510767 : bit_size_t num_bits;
1133 : 6510767 : if (get_bit_size (&num_bits))
1134 : 6101735 : 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 : 201017 : region::region (complexity c, symbol::id_t id, const region *parent, tree type)
1156 : : : symbol (c, id),
1157 : 201017 : m_parent (parent), m_type (type),
1158 : 201017 : m_cached_offset (NULL), m_cached_init_sval_at_main (NULL)
1159 : : {
1160 : 201017 : gcc_assert (type == NULL_TREE || TYPE_P (type));
1161 : 201017 : }
1162 : :
1163 : : /* Comparator for use by vec<const region *>::qsort,
1164 : : using their IDs to order them. */
1165 : :
1166 : : int
1167 : 36682342 : region::cmp_ptr_ptr (const void *p1, const void *p2)
1168 : : {
1169 : 36682342 : const region * const *reg1 = (const region * const *)p1;
1170 : 36682342 : const region * const *reg2 = (const region * const *)p2;
1171 : :
1172 : 36682342 : 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 : 12918 : region::non_null_p () const
1189 : : {
1190 : 12918 : 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 : 692139 : region::involves_p (const svalue *sval) const
1207 : : {
1208 : 692139 : if (const symbolic_region *symbolic_reg = dyn_cast_symbolic_region ())
1209 : : {
1210 : 69348 : 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 : 28818 : frame_region::~frame_region ()
1325 : : {
1326 : 114402 : for (map_t::iterator iter = m_locals.begin ();
1327 : 114402 : iter != m_locals.end ();
1328 : 99993 : ++iter)
1329 : 99993 : delete (*iter).second;
1330 : 28818 : }
1331 : :
1332 : : void
1333 : 2896183 : frame_region::accept (visitor *v) const
1334 : : {
1335 : 4259682 : region::accept (v);
1336 : 4259682 : if (m_calling_frame)
1337 : : m_calling_frame->accept (v);
1338 : 2896183 : }
1339 : :
1340 : : /* Implementation of region::dump_to_pp vfunc for frame_region. */
1341 : :
1342 : : void
1343 : 4079 : frame_region::dump_to_pp (pretty_printer *pp, bool simple) const
1344 : : {
1345 : 4079 : if (simple)
1346 : 4078 : pp_printf (pp, "frame: %qs@%i", function_name (&m_fun), get_stack_depth ());
1347 : : else
1348 : 1 : pp_printf (pp, "frame_region(%qs, index: %i, depth: %i)",
1349 : 1 : function_name (&m_fun), m_index, get_stack_depth ());
1350 : 4079 : }
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 : 1301409 : frame_region::get_region_for_local (region_model_manager *mgr,
1361 : : tree expr,
1362 : : const region_model_context *ctxt) const
1363 : : {
1364 : 1301409 : 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 : 1301409 : 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 : 1301409 : switch (TREE_CODE (expr))
1373 : : {
1374 : 0 : default:
1375 : 0 : gcc_unreachable ();
1376 : 77872 : case VAR_DECL:
1377 : 77872 : gcc_assert (!is_global_var (expr));
1378 : : /* Fall through. */
1379 : 108388 : case PARM_DECL:
1380 : 108388 : case RESULT_DECL:
1381 : 108388 : gcc_assert (DECL_CONTEXT (expr) == m_fun.decl);
1382 : : break;
1383 : 1193021 : case SSA_NAME:
1384 : 1193021 : {
1385 : 1193021 : if (tree var = SSA_NAME_VAR (expr))
1386 : : {
1387 : 568237 : if (DECL_P (var))
1388 : 568237 : gcc_assert (DECL_CONTEXT (var) == m_fun.decl);
1389 : : }
1390 : 624784 : else if (ctxt)
1391 : 325393 : if (const extrinsic_state *ext_state = ctxt->get_ext_state ())
1392 : 322689 : if (const supergraph *sg
1393 : 322689 : = ext_state->get_engine ()->get_supergraph ())
1394 : : {
1395 : 322689 : const gimple *def_stmt = SSA_NAME_DEF_STMT (expr);
1396 : 322689 : const supernode *snode
1397 : 322689 : = sg->get_supernode_for_stmt (def_stmt);
1398 : 322689 : gcc_assert (snode->get_function () == &m_fun);
1399 : : }
1400 : : }
1401 : : break;
1402 : : }
1403 : : }
1404 : :
1405 : : /* Ideally we'd use mutable here. */
1406 : 1301409 : map_t &mutable_locals = const_cast <map_t &> (m_locals);
1407 : :
1408 : 1301409 : if (decl_region **slot = mutable_locals.get (expr))
1409 : 1201416 : return *slot;
1410 : 99993 : decl_region *reg
1411 : 99993 : = new decl_region (mgr->alloc_symbol_id (), this, expr);
1412 : 99993 : mutable_locals.put (expr, reg);
1413 : 99993 : return reg;
1414 : : }
1415 : :
1416 : : /* class globals_region : public space_region. */
1417 : :
1418 : : /* Implementation of region::dump_to_pp vfunc for globals_region. */
1419 : :
1420 : : void
1421 : 2079 : globals_region::dump_to_pp (pretty_printer *pp, bool simple) const
1422 : : {
1423 : 2079 : if (simple)
1424 : 996 : pp_string (pp, "::");
1425 : : else
1426 : 1083 : pp_string (pp, "globals");
1427 : 2079 : }
1428 : :
1429 : : void
1430 : 0 : globals_region::print_dump_widget_label (pretty_printer *pp) const
1431 : : {
1432 : 0 : pp_string (pp, "globals");
1433 : 0 : }
1434 : :
1435 : : /* class code_region : public map_region. */
1436 : :
1437 : : /* Implementation of region::dump_to_pp vfunc for code_region. */
1438 : :
1439 : : void
1440 : 0 : code_region::dump_to_pp (pretty_printer *pp, bool simple) const
1441 : : {
1442 : 0 : if (simple)
1443 : 0 : pp_string (pp, "code region");
1444 : : else
1445 : 0 : pp_string (pp, "code_region()");
1446 : 0 : }
1447 : :
1448 : : void
1449 : 0 : code_region::print_dump_widget_label (pretty_printer *pp) const
1450 : : {
1451 : 0 : pp_string (pp, "code region");
1452 : 0 : }
1453 : :
1454 : : /* class function_region : public region. */
1455 : :
1456 : : /* Implementation of region::dump_to_pp vfunc for function_region. */
1457 : :
1458 : : void
1459 : 326 : function_region::dump_to_pp (pretty_printer *pp, bool simple) const
1460 : : {
1461 : 326 : if (simple)
1462 : : {
1463 : 326 : dump_quoted_tree (pp, m_fndecl);
1464 : : }
1465 : : else
1466 : : {
1467 : 0 : pp_string (pp, "function_region(");
1468 : 0 : dump_quoted_tree (pp, m_fndecl);
1469 : 0 : pp_string (pp, ")");
1470 : : }
1471 : 326 : }
1472 : :
1473 : : void
1474 : 0 : function_region::print_dump_widget_label (pretty_printer *pp) const
1475 : : {
1476 : 0 : pp_string (pp, "function_region(");
1477 : 0 : dump_quoted_tree (pp, m_fndecl);
1478 : 0 : pp_string (pp, ")");
1479 : 0 : }
1480 : :
1481 : : /* class label_region : public region. */
1482 : :
1483 : : /* Implementation of region::dump_to_pp vfunc for label_region. */
1484 : :
1485 : : void
1486 : 0 : label_region::dump_to_pp (pretty_printer *pp, bool simple) const
1487 : : {
1488 : 0 : if (simple)
1489 : : {
1490 : 0 : dump_quoted_tree (pp, m_label);
1491 : : }
1492 : : else
1493 : : {
1494 : 0 : pp_string (pp, "label_region(");
1495 : 0 : dump_quoted_tree (pp, m_label);
1496 : 0 : pp_string (pp, ")");
1497 : : }
1498 : 0 : }
1499 : :
1500 : : void
1501 : 0 : label_region::print_dump_widget_label (pretty_printer *pp) const
1502 : : {
1503 : 0 : pp_string (pp, "label_region(");
1504 : 0 : dump_quoted_tree (pp, m_label);
1505 : 0 : pp_string (pp, ")");
1506 : 0 : }
1507 : :
1508 : : /* class stack_region : public region. */
1509 : :
1510 : : /* Implementation of region::dump_to_pp vfunc for stack_region. */
1511 : :
1512 : : void
1513 : 0 : stack_region::dump_to_pp (pretty_printer *pp, bool simple) const
1514 : : {
1515 : 0 : if (simple)
1516 : 0 : pp_string (pp, "stack region");
1517 : : else
1518 : 0 : pp_string (pp, "stack_region()");
1519 : 0 : }
1520 : :
1521 : : void
1522 : 0 : stack_region::print_dump_widget_label (pretty_printer *pp) const
1523 : : {
1524 : 0 : pp_string (pp, "stack region");
1525 : 0 : }
1526 : :
1527 : : /* class heap_region : public region. */
1528 : :
1529 : : /* Implementation of region::dump_to_pp vfunc for heap_region. */
1530 : :
1531 : : void
1532 : 190 : heap_region::dump_to_pp (pretty_printer *pp, bool simple) const
1533 : : {
1534 : 190 : if (simple)
1535 : 190 : pp_string (pp, "heap region");
1536 : : else
1537 : 0 : pp_string (pp, "heap_region()");
1538 : 190 : }
1539 : :
1540 : : void
1541 : 0 : heap_region::print_dump_widget_label (pretty_printer *pp) const
1542 : : {
1543 : 0 : pp_string (pp, "heap_region");
1544 : 0 : }
1545 : :
1546 : : /* class root_region : public region. */
1547 : :
1548 : : /* root_region's ctor. */
1549 : :
1550 : 3901 : root_region::root_region (symbol::id_t id)
1551 : 3901 : : region (complexity (1, 1), id, NULL, NULL_TREE)
1552 : : {
1553 : 3901 : }
1554 : :
1555 : : /* Implementation of region::dump_to_pp vfunc for root_region. */
1556 : :
1557 : : void
1558 : 1393 : root_region::dump_to_pp (pretty_printer *pp, bool simple) const
1559 : : {
1560 : 1393 : if (simple)
1561 : 1273 : pp_string (pp, "root region");
1562 : : else
1563 : 120 : pp_string (pp, "root_region()");
1564 : 1393 : }
1565 : :
1566 : : void
1567 : 0 : root_region::print_dump_widget_label (pretty_printer *pp) const
1568 : : {
1569 : 0 : pp_string (pp, "root region");
1570 : 0 : }
1571 : :
1572 : : /* class thread_local_region : public space_region. */
1573 : :
1574 : : void
1575 : 0 : thread_local_region::dump_to_pp (pretty_printer *pp, bool simple) const
1576 : : {
1577 : 0 : if (simple)
1578 : 0 : pp_string (pp, "thread_local_region");
1579 : : else
1580 : 0 : pp_string (pp, "thread_local_region()");
1581 : 0 : }
1582 : :
1583 : : void
1584 : 0 : thread_local_region::print_dump_widget_label (pretty_printer *pp) const
1585 : : {
1586 : 0 : pp_string (pp, "thread_local_region");
1587 : 0 : }
1588 : :
1589 : : /* class symbolic_region : public map_region. */
1590 : :
1591 : : /* symbolic_region's ctor. */
1592 : :
1593 : 8440 : symbolic_region::symbolic_region (symbol::id_t id, region *parent,
1594 : 8440 : const svalue *sval_ptr)
1595 : 8440 : : region (complexity::from_pair (parent, sval_ptr), id, parent,
1596 : 8440 : (sval_ptr->get_type ()
1597 : 8359 : ? TREE_TYPE (sval_ptr->get_type ())
1598 : : : NULL_TREE)),
1599 : 25239 : m_sval_ptr (sval_ptr)
1600 : : {
1601 : 8440 : }
1602 : :
1603 : : /* Implementation of region::accept vfunc for symbolic_region. */
1604 : :
1605 : : void
1606 : 785654 : symbolic_region::accept (visitor *v) const
1607 : : {
1608 : 785654 : region::accept (v);
1609 : 785654 : m_sval_ptr->accept (v);
1610 : 785654 : }
1611 : :
1612 : : /* Implementation of region::dump_to_pp vfunc for symbolic_region. */
1613 : :
1614 : : void
1615 : 6783 : symbolic_region::dump_to_pp (pretty_printer *pp, bool simple) const
1616 : : {
1617 : 6783 : if (simple)
1618 : : {
1619 : 6663 : pp_string (pp, "(*");
1620 : 6663 : m_sval_ptr->dump_to_pp (pp, simple);
1621 : 6663 : pp_string (pp, ")");
1622 : : }
1623 : : else
1624 : : {
1625 : 120 : pp_string (pp, "symbolic_region(");
1626 : 120 : get_parent_region ()->dump_to_pp (pp, simple);
1627 : 120 : if (get_type ())
1628 : : {
1629 : 120 : pp_string (pp, ", ");
1630 : 120 : print_quoted_type (pp, get_type ());
1631 : : }
1632 : 120 : pp_string (pp, ", ");
1633 : 120 : m_sval_ptr->dump_to_pp (pp, simple);
1634 : 120 : pp_string (pp, ")");
1635 : : }
1636 : 6783 : }
1637 : :
1638 : : void
1639 : 0 : symbolic_region::print_dump_widget_label (pretty_printer *pp) const
1640 : : {
1641 : 0 : pp_string (pp, "symbolic_region: %<*%>");
1642 : 0 : }
1643 : :
1644 : : void
1645 : 0 : symbolic_region::
1646 : : add_dump_widget_children (text_art::tree_widget &w,
1647 : : const text_art::dump_widget_info &dwi) const
1648 : : {
1649 : 0 : w.add_child (m_sval_ptr->make_dump_widget (dwi, "m_sval_ptr"));
1650 : 0 : }
1651 : :
1652 : : /* class decl_region : public region. */
1653 : :
1654 : : /* Implementation of region::dump_to_pp vfunc for decl_region. */
1655 : :
1656 : : void
1657 : 21313 : decl_region::dump_to_pp (pretty_printer *pp, bool simple) const
1658 : : {
1659 : 21313 : if (simple)
1660 : 20229 : pp_printf (pp, "%E", m_decl);
1661 : : else
1662 : : {
1663 : 1084 : pp_string (pp, "decl_region(");
1664 : 1084 : get_parent_region ()->dump_to_pp (pp, simple);
1665 : 1084 : pp_string (pp, ", ");
1666 : 1084 : print_quoted_type (pp, get_type ());
1667 : 1084 : pp_printf (pp, ", %qE)", m_decl);
1668 : : }
1669 : 21313 : }
1670 : :
1671 : : void
1672 : 0 : decl_region::print_dump_widget_label (pretty_printer *pp) const
1673 : : {
1674 : 0 : pp_printf (pp, "decl_region(%qE)", m_decl);
1675 : 0 : }
1676 : :
1677 : : /* Get the stack depth for the frame containing this decl, or 0
1678 : : for a global. */
1679 : :
1680 : : int
1681 : 11266 : decl_region::get_stack_depth () const
1682 : : {
1683 : 11266 : if (get_parent_region () == NULL)
1684 : : return 0;
1685 : 22532 : if (const frame_region *frame_reg
1686 : 11266 : = get_parent_region ()->dyn_cast_frame_region ())
1687 : 10735 : return frame_reg->get_stack_depth ();
1688 : : return 0;
1689 : : }
1690 : :
1691 : : /* If the underlying decl is in the global constant pool,
1692 : : return an svalue representing the constant value.
1693 : : Otherwise return NULL. */
1694 : :
1695 : : const svalue *
1696 : 2989835 : decl_region::maybe_get_constant_value (region_model_manager *mgr) const
1697 : : {
1698 : 2989835 : if (VAR_P (m_decl)
1699 : 403759 : && DECL_IN_CONSTANT_POOL (m_decl)
1700 : 12 : && DECL_INITIAL (m_decl)
1701 : 2989847 : && TREE_CODE (DECL_INITIAL (m_decl)) == CONSTRUCTOR)
1702 : 12 : return get_svalue_for_constructor (DECL_INITIAL (m_decl), mgr);
1703 : : return NULL;
1704 : : }
1705 : :
1706 : : /* Implementation of decl_region::get_svalue_for_constructor
1707 : : for when the cached value hasn't yet been calculated. */
1708 : :
1709 : : const svalue *
1710 : 148 : decl_region::calc_svalue_for_constructor (tree ctor,
1711 : : region_model_manager *mgr) const
1712 : : {
1713 : : /* Create a binding map, applying ctor to it, using this
1714 : : decl_region as the base region when building child regions
1715 : : for offset calculations. */
1716 : 148 : binding_map map;
1717 : 148 : if (!map.apply_ctor_to_region (this, ctor, mgr))
1718 : 1 : return mgr->get_or_create_unknown_svalue (get_type ());
1719 : :
1720 : : /* Return a compound svalue for the map we built. */
1721 : 147 : return mgr->get_or_create_compound_svalue (get_type (), map);
1722 : 148 : }
1723 : :
1724 : : /* Get an svalue for CTOR, a CONSTRUCTOR for this region's decl. */
1725 : :
1726 : : const svalue *
1727 : 246 : decl_region::get_svalue_for_constructor (tree ctor,
1728 : : region_model_manager *mgr) const
1729 : : {
1730 : 246 : gcc_assert (!TREE_CLOBBER_P (ctor));
1731 : 246 : gcc_assert (ctor == DECL_INITIAL (m_decl));
1732 : :
1733 : 246 : if (!m_ctor_svalue)
1734 : 148 : m_ctor_svalue = calc_svalue_for_constructor (ctor, mgr);
1735 : :
1736 : 246 : return m_ctor_svalue;
1737 : : }
1738 : :
1739 : : /* For use on decl_regions for global variables.
1740 : :
1741 : : Get an svalue for the initial value of this region at entry to
1742 : : "main" (either based on DECL_INITIAL, or implicit initialization to
1743 : : zero.
1744 : :
1745 : : Return NULL if there is a problem. */
1746 : :
1747 : : const svalue *
1748 : 443 : decl_region::get_svalue_for_initializer (region_model_manager *mgr) const
1749 : : {
1750 : 443 : tree init = DECL_INITIAL (m_decl);
1751 : 443 : if (!init)
1752 : : {
1753 : : /* If we have an "extern" decl then there may be an initializer in
1754 : : another TU. */
1755 : 113 : if (DECL_EXTERNAL (m_decl))
1756 : : return NULL;
1757 : :
1758 : 33 : if (empty_p ())
1759 : : return NULL;
1760 : :
1761 : : /* Implicit initialization to zero; use a compound_svalue for it.
1762 : : Doing so requires that we have a concrete binding for this region,
1763 : : which can fail if we have a region with unknown size
1764 : : (e.g. "extern const char arr[];"). */
1765 : 33 : const binding_key *binding
1766 : 33 : = binding_key::make (mgr->get_store_manager (), this);
1767 : 33 : if (binding->symbolic_p ())
1768 : : return NULL;
1769 : :
1770 : : /* If we don't care about tracking the content of this region, then
1771 : : it's unused, and the value doesn't matter. */
1772 : 33 : if (!tracked_p ())
1773 : : return NULL;
1774 : :
1775 : 33 : binding_cluster c (this);
1776 : 33 : c.zero_fill_region (mgr->get_store_manager (), this);
1777 : 33 : return mgr->get_or_create_compound_svalue (TREE_TYPE (m_decl),
1778 : : c.get_map ());
1779 : 33 : }
1780 : :
1781 : : /* LTO can write out error_mark_node as the DECL_INITIAL for simple scalar
1782 : : values (to avoid writing out an extra section). */
1783 : 330 : if (init == error_mark_node)
1784 : : return NULL;
1785 : :
1786 : 326 : if (TREE_CODE (init) == CONSTRUCTOR)
1787 : 234 : return get_svalue_for_constructor (init, mgr);
1788 : :
1789 : : /* Reuse the get_rvalue logic from region_model. */
1790 : 92 : region_model m (mgr);
1791 : 92 : return m.get_rvalue (path_var (init, 0), NULL);
1792 : 92 : }
1793 : :
1794 : : /* Subroutine of symnode_requires_tracking_p; return true if REF
1795 : : might imply that we should be tracking the value of its decl. */
1796 : :
1797 : : static bool
1798 : 4163 : ipa_ref_requires_tracking (ipa_ref *ref)
1799 : : {
1800 : : /* If we have a load/store/alias of the symbol, then we'll track
1801 : : the decl's value. */
1802 : 4163 : if (ref->use != IPA_REF_ADDR)
1803 : : return true;
1804 : :
1805 : 4132 : if (ref->stmt == NULL)
1806 : : return true;
1807 : :
1808 : 4132 : switch (ref->stmt->code)
1809 : : {
1810 : : default:
1811 : : return true;
1812 : 4101 : case GIMPLE_CALL:
1813 : 4101 : {
1814 : 4148 : cgraph_node *caller_cnode = dyn_cast <cgraph_node *> (ref->referring);
1815 : 4101 : if (caller_cnode == NULL)
1816 : : return true;
1817 : 4101 : cgraph_edge *edge = caller_cnode->get_edge (ref->stmt);
1818 : 4101 : if (!edge)
1819 : : return true;
1820 : 4101 : if (edge->callee == NULL)
1821 : : return true; /* e.g. call through function ptr. */
1822 : 4100 : if (edge->callee->definition)
1823 : : return true;
1824 : : /* If we get here, then this ref is a pointer passed to
1825 : : a function we don't have the definition for. */
1826 : : return false;
1827 : : }
1828 : 17 : break;
1829 : 17 : case GIMPLE_ASM:
1830 : 17 : {
1831 : 17 : const gasm *asm_stmt = as_a <const gasm *> (ref->stmt);
1832 : 17 : if (gimple_asm_noutputs (asm_stmt) > 0)
1833 : : return true;
1834 : 17 : if (gimple_asm_nclobbers (asm_stmt) > 0)
1835 : : return true;
1836 : : /* If we get here, then this ref is the decl being passed
1837 : : by pointer to asm with no outputs. */
1838 : : return false;
1839 : : }
1840 : : break;
1841 : : }
1842 : : }
1843 : :
1844 : : /* Determine if the decl for SYMNODE should have binding_clusters
1845 : : in our state objects; return false to optimize away tracking
1846 : : certain decls in our state objects, as an optimization. */
1847 : :
1848 : : static bool
1849 : 5460 : symnode_requires_tracking_p (symtab_node *symnode)
1850 : : {
1851 : 5460 : gcc_assert (symnode);
1852 : 5460 : if (symnode->externally_visible)
1853 : : return true;
1854 : 4733 : tree context_fndecl = DECL_CONTEXT (symnode->decl);
1855 : 4733 : if (context_fndecl == NULL)
1856 : : return true;
1857 : 4719 : if (TREE_CODE (context_fndecl) != FUNCTION_DECL)
1858 : : return true;
1859 : 16476 : for (auto ref : symnode->ref_list.referring)
1860 : 4163 : if (ipa_ref_requires_tracking (ref))
1861 : : return true;
1862 : :
1863 : : /* If we get here, then we don't have uses of this decl that require
1864 : : tracking; we never read from it or write to it explicitly. */
1865 : : return false;
1866 : : }
1867 : :
1868 : : /* Subroutine of decl_region ctor: determine whether this decl_region
1869 : : can have binding_clusters; return false to optimize away tracking
1870 : : of certain decls in our state objects, as an optimization. */
1871 : :
1872 : : bool
1873 : 106377 : decl_region::calc_tracked_p (tree decl)
1874 : : {
1875 : : /* Precondition of symtab_node::get. */
1876 : 106377 : if (TREE_CODE (decl) == VAR_DECL
1877 : 106377 : && (TREE_STATIC (decl) || DECL_EXTERNAL (decl) || in_lto_p))
1878 : 6386 : if (symtab_node *symnode = symtab_node::get (decl))
1879 : 5460 : return symnode_requires_tracking_p (symnode);
1880 : : return true;
1881 : : }
1882 : :
1883 : : /* class field_region : public region. */
1884 : :
1885 : : /* Implementation of region::dump_to_pp vfunc for field_region. */
1886 : :
1887 : : void
1888 : 2720 : field_region::dump_to_pp (pretty_printer *pp, bool simple) const
1889 : : {
1890 : 2720 : if (simple)
1891 : : {
1892 : 2720 : get_parent_region ()->dump_to_pp (pp, simple);
1893 : 2720 : pp_string (pp, ".");
1894 : 2720 : pp_printf (pp, "%E", m_field);
1895 : : }
1896 : : else
1897 : : {
1898 : 0 : pp_string (pp, "field_region(");
1899 : 0 : get_parent_region ()->dump_to_pp (pp, simple);
1900 : 0 : pp_string (pp, ", ");
1901 : 0 : print_quoted_type (pp, get_type ());
1902 : 0 : pp_printf (pp, ", %qE)", m_field);
1903 : : }
1904 : 2720 : }
1905 : :
1906 : : void
1907 : 0 : field_region::print_dump_widget_label (pretty_printer *pp) const
1908 : : {
1909 : 0 : pp_printf (pp, "field_region(%qE)", m_field);
1910 : 0 : }
1911 : :
1912 : : /* Implementation of region::get_relative_concrete_offset vfunc
1913 : : for field_region. */
1914 : :
1915 : : bool
1916 : 9617 : field_region::get_relative_concrete_offset (bit_offset_t *out) const
1917 : : {
1918 : : /* Compare with e.g. gimple-fold.cc's
1919 : : fold_nonarray_ctor_reference. */
1920 : 9617 : tree byte_offset = DECL_FIELD_OFFSET (m_field);
1921 : 9617 : if (TREE_CODE (byte_offset) != INTEGER_CST)
1922 : : return false;
1923 : 9615 : tree field_offset = DECL_FIELD_BIT_OFFSET (m_field);
1924 : : /* Compute bit offset of the field. */
1925 : 9615 : offset_int bitoffset
1926 : 9615 : = (wi::to_offset (field_offset)
1927 : 9615 : + (wi::to_offset (byte_offset) << LOG2_BITS_PER_UNIT));
1928 : 9615 : *out = bitoffset;
1929 : 9615 : return true;
1930 : : }
1931 : :
1932 : :
1933 : : /* Implementation of region::get_relative_symbolic_offset vfunc
1934 : : for field_region.
1935 : : If known, the returned svalue is equal to the offset converted to bytes and
1936 : : rounded off. */
1937 : :
1938 : : const svalue *
1939 : 349 : field_region::get_relative_symbolic_offset (region_model_manager *mgr) const
1940 : : {
1941 : 349 : bit_offset_t out;
1942 : 349 : if (get_relative_concrete_offset (&out))
1943 : : {
1944 : 348 : tree cst_tree
1945 : 348 : = wide_int_to_tree (ptrdiff_type_node, out / BITS_PER_UNIT);
1946 : 348 : return mgr->get_or_create_constant_svalue (cst_tree);
1947 : : }
1948 : 1 : return mgr->get_or_create_unknown_svalue (ptrdiff_type_node);
1949 : : }
1950 : :
1951 : : /* class element_region : public region. */
1952 : :
1953 : : /* Implementation of region::accept vfunc for element_region. */
1954 : :
1955 : : void
1956 : 289246 : element_region::accept (visitor *v) const
1957 : : {
1958 : 289246 : region::accept (v);
1959 : 289246 : m_index->accept (v);
1960 : 289246 : }
1961 : :
1962 : : /* Implementation of region::dump_to_pp vfunc for element_region. */
1963 : :
1964 : : void
1965 : 206 : element_region::dump_to_pp (pretty_printer *pp, bool simple) const
1966 : : {
1967 : 206 : if (simple)
1968 : : {
1969 : : //pp_string (pp, "(");
1970 : 206 : get_parent_region ()->dump_to_pp (pp, simple);
1971 : 206 : pp_string (pp, "[");
1972 : 206 : m_index->dump_to_pp (pp, simple);
1973 : 206 : pp_string (pp, "]");
1974 : : //pp_string (pp, ")");
1975 : : }
1976 : : else
1977 : : {
1978 : 0 : pp_string (pp, "element_region(");
1979 : 0 : get_parent_region ()->dump_to_pp (pp, simple);
1980 : 0 : pp_string (pp, ", ");
1981 : 0 : print_quoted_type (pp, get_type ());
1982 : 0 : pp_string (pp, ", ");
1983 : 0 : m_index->dump_to_pp (pp, simple);
1984 : 0 : pp_printf (pp, ")");
1985 : : }
1986 : 206 : }
1987 : :
1988 : : void
1989 : 0 : element_region::print_dump_widget_label (pretty_printer *pp) const
1990 : : {
1991 : 0 : pp_printf (pp, "element_region: %<[]%>");
1992 : 0 : }
1993 : :
1994 : : void
1995 : 0 : element_region::
1996 : : add_dump_widget_children (text_art::tree_widget &w,
1997 : : const text_art::dump_widget_info &dwi) const
1998 : : {
1999 : 0 : w.add_child (m_index->make_dump_widget (dwi, "m_index"));
2000 : 0 : }
2001 : :
2002 : : /* Implementation of region::get_relative_concrete_offset vfunc
2003 : : for element_region. */
2004 : :
2005 : : bool
2006 : 4891 : element_region::get_relative_concrete_offset (bit_offset_t *out) const
2007 : : {
2008 : 4891 : if (tree idx_cst = m_index->maybe_get_constant ())
2009 : : {
2010 : 3597 : gcc_assert (TREE_CODE (idx_cst) == INTEGER_CST);
2011 : :
2012 : 3597 : tree elem_type = get_type ();
2013 : 3597 : offset_int element_idx = wi::to_offset (idx_cst);
2014 : :
2015 : : /* First, use int_size_in_bytes, to reject the case where we
2016 : : have an incomplete type, or a non-constant value. */
2017 : 3597 : HOST_WIDE_INT hwi_byte_size = int_size_in_bytes (elem_type);
2018 : 3597 : if (hwi_byte_size > 0)
2019 : : {
2020 : 3593 : offset_int element_bit_size
2021 : 3593 : = hwi_byte_size << LOG2_BITS_PER_UNIT;
2022 : 3593 : offset_int element_bit_offset
2023 : 3593 : = element_idx * element_bit_size;
2024 : 3593 : *out = element_bit_offset;
2025 : 3593 : return true;
2026 : : }
2027 : : }
2028 : : return false;
2029 : : }
2030 : :
2031 : : /* Implementation of region::get_relative_symbolic_offset vfunc
2032 : : for element_region. */
2033 : :
2034 : : const svalue *
2035 : 1232 : element_region::get_relative_symbolic_offset (region_model_manager *mgr) const
2036 : : {
2037 : 1232 : tree elem_type = get_type ();
2038 : :
2039 : : /* First, use int_size_in_bytes, to reject the case where we
2040 : : have an incomplete type, or a non-constant value. */
2041 : 1232 : HOST_WIDE_INT hwi_byte_size = int_size_in_bytes (elem_type);
2042 : 1232 : if (hwi_byte_size > 0)
2043 : : {
2044 : 1218 : tree byte_size_tree = wide_int_to_tree (ptrdiff_type_node,
2045 : 1218 : hwi_byte_size);
2046 : 1218 : const svalue *byte_size_sval
2047 : 1218 : = mgr->get_or_create_constant_svalue (byte_size_tree);
2048 : 1218 : return mgr->get_or_create_binop (NULL_TREE, MULT_EXPR,
2049 : 1218 : m_index, byte_size_sval);
2050 : : }
2051 : 14 : return mgr->get_or_create_unknown_svalue (ptrdiff_type_node);
2052 : : }
2053 : :
2054 : : /* class offset_region : public region. */
2055 : :
2056 : : /* Implementation of region::accept vfunc for offset_region. */
2057 : :
2058 : : void
2059 : 101980 : offset_region::accept (visitor *v) const
2060 : : {
2061 : 101980 : region::accept (v);
2062 : 101980 : m_byte_offset->accept (v);
2063 : 101980 : }
2064 : :
2065 : : /* Implementation of region::dump_to_pp vfunc for offset_region. */
2066 : :
2067 : : void
2068 : 2288 : offset_region::dump_to_pp (pretty_printer *pp, bool simple) const
2069 : : {
2070 : 2288 : if (simple)
2071 : : {
2072 : : //pp_string (pp, "(");
2073 : 2202 : get_parent_region ()->dump_to_pp (pp, simple);
2074 : 2202 : pp_string (pp, "+");
2075 : 2202 : m_byte_offset->dump_to_pp (pp, simple);
2076 : : //pp_string (pp, ")");
2077 : : }
2078 : : else
2079 : : {
2080 : 86 : pp_string (pp, "offset_region(");
2081 : 86 : get_parent_region ()->dump_to_pp (pp, simple);
2082 : 86 : pp_string (pp, ", ");
2083 : 86 : print_quoted_type (pp, get_type ());
2084 : 86 : pp_string (pp, ", ");
2085 : 86 : m_byte_offset->dump_to_pp (pp, simple);
2086 : 86 : pp_printf (pp, ")");
2087 : : }
2088 : 2288 : }
2089 : :
2090 : : void
2091 : 0 : offset_region::print_dump_widget_label (pretty_printer *pp) const
2092 : : {
2093 : 0 : pp_printf (pp, "offset_region");
2094 : 0 : }
2095 : :
2096 : : void
2097 : 0 : offset_region::
2098 : : add_dump_widget_children (text_art::tree_widget &w,
2099 : : const text_art::dump_widget_info &dwi) const
2100 : : {
2101 : 0 : w.add_child (m_byte_offset->make_dump_widget (dwi, "m_byte_offset"));
2102 : 0 : }
2103 : :
2104 : : const svalue *
2105 : 0 : offset_region::get_bit_offset (region_model_manager *mgr) const
2106 : : {
2107 : 0 : const svalue *bits_per_byte_sval
2108 : 0 : = mgr->get_or_create_int_cst (NULL_TREE, BITS_PER_UNIT);
2109 : 0 : return mgr->get_or_create_binop (NULL_TREE, MULT_EXPR,
2110 : 0 : m_byte_offset, bits_per_byte_sval);
2111 : : }
2112 : :
2113 : : /* Implementation of region::get_relative_concrete_offset vfunc
2114 : : for offset_region. */
2115 : :
2116 : : bool
2117 : 3708 : offset_region::get_relative_concrete_offset (bit_offset_t *out) const
2118 : : {
2119 : 3708 : if (tree byte_offset_cst = m_byte_offset->maybe_get_constant ())
2120 : : {
2121 : 2170 : gcc_assert (TREE_CODE (byte_offset_cst) == INTEGER_CST);
2122 : : /* Use a signed value for the byte offset, to handle
2123 : : negative offsets. */
2124 : 2170 : HOST_WIDE_INT byte_offset
2125 : 2170 : = wi::to_offset (byte_offset_cst).to_shwi ();
2126 : 2170 : HOST_WIDE_INT bit_offset = byte_offset * BITS_PER_UNIT;
2127 : 2170 : *out = bit_offset;
2128 : 2170 : return true;
2129 : : }
2130 : : return false;
2131 : : }
2132 : :
2133 : : /* Implementation of region::get_relative_symbolic_offset vfunc
2134 : : for offset_region. */
2135 : :
2136 : : const svalue *
2137 : 1542 : offset_region::get_relative_symbolic_offset (region_model_manager *mgr
2138 : : ATTRIBUTE_UNUSED) const
2139 : : {
2140 : 1542 : return get_byte_offset ();
2141 : : }
2142 : :
2143 : : /* class sized_region : public region. */
2144 : :
2145 : : /* Implementation of region::accept vfunc for sized_region. */
2146 : :
2147 : : void
2148 : 15242 : sized_region::accept (visitor *v) const
2149 : : {
2150 : 15242 : region::accept (v);
2151 : 15242 : m_byte_size_sval->accept (v);
2152 : 15242 : }
2153 : :
2154 : : /* Implementation of region::dump_to_pp vfunc for sized_region. */
2155 : :
2156 : : void
2157 : 70 : sized_region::dump_to_pp (pretty_printer *pp, bool simple) const
2158 : : {
2159 : 70 : if (simple)
2160 : : {
2161 : 70 : pp_string (pp, "SIZED_REG(");
2162 : 70 : get_parent_region ()->dump_to_pp (pp, simple);
2163 : 70 : pp_string (pp, ", ");
2164 : 70 : m_byte_size_sval->dump_to_pp (pp, simple);
2165 : 70 : pp_string (pp, ")");
2166 : : }
2167 : : else
2168 : : {
2169 : 0 : pp_string (pp, "sized_region(");
2170 : 0 : get_parent_region ()->dump_to_pp (pp, simple);
2171 : 0 : pp_string (pp, ", ");
2172 : 0 : m_byte_size_sval->dump_to_pp (pp, simple);
2173 : 0 : pp_printf (pp, ")");
2174 : : }
2175 : 70 : }
2176 : :
2177 : : void
2178 : 0 : sized_region::print_dump_widget_label (pretty_printer *pp) const
2179 : : {
2180 : 0 : pp_printf (pp, "sized_region");
2181 : 0 : }
2182 : :
2183 : : void
2184 : 0 : sized_region::
2185 : : add_dump_widget_children (text_art::tree_widget &w,
2186 : : const text_art::dump_widget_info &dwi) const
2187 : : {
2188 : 0 : w.add_child (m_byte_size_sval->make_dump_widget (dwi, "m_byte_size_sval"));
2189 : 0 : }
2190 : :
2191 : : /* Implementation of region::get_byte_size vfunc for sized_region. */
2192 : :
2193 : : bool
2194 : 29352 : sized_region::get_byte_size (byte_size_t *out) const
2195 : : {
2196 : 29352 : if (tree cst = m_byte_size_sval->maybe_get_constant ())
2197 : : {
2198 : 23379 : gcc_assert (TREE_CODE (cst) == INTEGER_CST);
2199 : 23379 : *out = tree_to_uhwi (cst);
2200 : 23379 : return true;
2201 : : }
2202 : : return false;
2203 : : }
2204 : :
2205 : : /* Implementation of region::get_bit_size vfunc for sized_region. */
2206 : :
2207 : : bool
2208 : 29352 : sized_region::get_bit_size (bit_size_t *out) const
2209 : : {
2210 : 29352 : byte_size_t byte_size;
2211 : 29352 : if (!get_byte_size (&byte_size))
2212 : : return false;
2213 : 23379 : *out = byte_size * BITS_PER_UNIT;
2214 : 23379 : return true;
2215 : : }
2216 : :
2217 : : /* Implementation of region::get_bit_size_sval vfunc for sized_region. */
2218 : :
2219 : : const svalue *
2220 : 5550 : sized_region::get_bit_size_sval (region_model_manager *mgr) const
2221 : : {
2222 : 5550 : const svalue *bits_per_byte_sval
2223 : 5550 : = mgr->get_or_create_int_cst (NULL_TREE, BITS_PER_UNIT);
2224 : 5550 : return mgr->get_or_create_binop (NULL_TREE, MULT_EXPR,
2225 : 5550 : m_byte_size_sval, bits_per_byte_sval);
2226 : : }
2227 : :
2228 : : /* class cast_region : public region. */
2229 : :
2230 : : /* Implementation of region::dump_to_pp vfunc for cast_region. */
2231 : :
2232 : : void
2233 : 1382 : cast_region::dump_to_pp (pretty_printer *pp, bool simple) const
2234 : : {
2235 : 1382 : if (simple)
2236 : : {
2237 : 1338 : pp_string (pp, "CAST_REG(");
2238 : 1338 : print_quoted_type (pp, get_type ());
2239 : 1338 : pp_string (pp, ", ");
2240 : 1338 : get_parent_region ()->dump_to_pp (pp, simple);
2241 : 1338 : pp_string (pp, ")");
2242 : : }
2243 : : else
2244 : : {
2245 : 44 : pp_string (pp, "cast_region(");
2246 : 44 : get_parent_region ()->dump_to_pp (pp, simple);
2247 : 44 : pp_string (pp, ", ");
2248 : 44 : print_quoted_type (pp, get_type ());
2249 : 44 : pp_printf (pp, ")");
2250 : : }
2251 : 1382 : }
2252 : :
2253 : : void
2254 : 0 : cast_region::print_dump_widget_label (pretty_printer *pp) const
2255 : : {
2256 : 0 : pp_printf (pp, "cast_region");
2257 : 0 : }
2258 : :
2259 : : /* Implementation of region::get_relative_concrete_offset vfunc
2260 : : for cast_region. */
2261 : :
2262 : : bool
2263 : 20 : cast_region::get_relative_concrete_offset (bit_offset_t *out) const
2264 : : {
2265 : 20 : *out = (int) 0;
2266 : 20 : return true;
2267 : : }
2268 : :
2269 : : /* class heap_allocated_region : public region. */
2270 : :
2271 : : /* Implementation of region::dump_to_pp vfunc for heap_allocated_region. */
2272 : :
2273 : : void
2274 : 2401 : heap_allocated_region::dump_to_pp (pretty_printer *pp, bool simple) const
2275 : : {
2276 : 2401 : if (simple)
2277 : 2401 : pp_printf (pp, "HEAP_ALLOCATED_REGION(%i)", get_id ());
2278 : : else
2279 : 0 : pp_printf (pp, "heap_allocated_region(%i)", get_id ());
2280 : 2401 : }
2281 : :
2282 : : void
2283 : 0 : heap_allocated_region::print_dump_widget_label (pretty_printer *pp) const
2284 : : {
2285 : 0 : pp_printf (pp, "heap_allocated_region");
2286 : 0 : }
2287 : :
2288 : : /* class alloca_region : public region. */
2289 : :
2290 : : /* Implementation of region::dump_to_pp vfunc for alloca_region. */
2291 : :
2292 : : void
2293 : 0 : alloca_region::dump_to_pp (pretty_printer *pp, bool simple) const
2294 : : {
2295 : 0 : if (simple)
2296 : 0 : pp_printf (pp, "ALLOCA_REGION(%i)", get_id ());
2297 : : else
2298 : 0 : pp_printf (pp, "alloca_region(%i)", get_id ());
2299 : 0 : }
2300 : :
2301 : : void
2302 : 0 : alloca_region::print_dump_widget_label (pretty_printer *pp) const
2303 : : {
2304 : 0 : pp_printf (pp, "alloca_region");
2305 : 0 : }
2306 : :
2307 : : /* class string_region : public region. */
2308 : :
2309 : : /* Implementation of region::dump_to_pp vfunc for string_region. */
2310 : :
2311 : : void
2312 : 0 : string_region::dump_to_pp (pretty_printer *pp, bool simple) const
2313 : : {
2314 : 0 : if (simple)
2315 : 0 : dump_tree (pp, m_string_cst);
2316 : : else
2317 : : {
2318 : 0 : pp_string (pp, "string_region(");
2319 : 0 : dump_tree (pp, m_string_cst);
2320 : 0 : if (!flag_dump_noaddr)
2321 : : {
2322 : 0 : pp_string (pp, " (");
2323 : 0 : pp_pointer (pp, m_string_cst);
2324 : 0 : pp_string (pp, "))");
2325 : : }
2326 : : }
2327 : 0 : }
2328 : :
2329 : : void
2330 : 0 : string_region::print_dump_widget_label (pretty_printer *pp) const
2331 : : {
2332 : 0 : pp_string (pp, "string_region(");
2333 : 0 : dump_tree (pp, m_string_cst);
2334 : 0 : pp_string (pp, ")");
2335 : 0 : }
2336 : :
2337 : : /* class bit_range_region : public region. */
2338 : :
2339 : : /* Implementation of region::dump_to_pp vfunc for bit_range_region. */
2340 : :
2341 : : void
2342 : 0 : bit_range_region::dump_to_pp (pretty_printer *pp, bool simple) const
2343 : : {
2344 : 0 : if (simple)
2345 : : {
2346 : 0 : pp_string (pp, "BIT_RANGE_REG(");
2347 : 0 : get_parent_region ()->dump_to_pp (pp, simple);
2348 : 0 : pp_string (pp, ", ");
2349 : 0 : m_bits.dump_to_pp (pp);
2350 : 0 : pp_string (pp, ")");
2351 : : }
2352 : : else
2353 : : {
2354 : 0 : pp_string (pp, "bit_range_region(");
2355 : 0 : get_parent_region ()->dump_to_pp (pp, simple);
2356 : 0 : pp_string (pp, ", ");
2357 : 0 : m_bits.dump_to_pp (pp);
2358 : 0 : pp_printf (pp, ")");
2359 : : }
2360 : 0 : }
2361 : :
2362 : : void
2363 : 0 : bit_range_region::print_dump_widget_label (pretty_printer *pp) const
2364 : : {
2365 : 0 : pp_printf (pp, "bit_range_region(m_bits: ");
2366 : 0 : m_bits.dump_to_pp (pp);
2367 : 0 : pp_string (pp, ")");
2368 : 0 : }
2369 : :
2370 : : /* Implementation of region::get_byte_size vfunc for bit_range_region. */
2371 : :
2372 : : bool
2373 : 0 : bit_range_region::get_byte_size (byte_size_t *out) const
2374 : : {
2375 : 0 : if (m_bits.m_size_in_bits % BITS_PER_UNIT == 0)
2376 : : {
2377 : 0 : *out = m_bits.m_size_in_bits / BITS_PER_UNIT;
2378 : 0 : return true;
2379 : : }
2380 : : return false;
2381 : : }
2382 : :
2383 : : /* Implementation of region::get_bit_size vfunc for bit_range_region. */
2384 : :
2385 : : bool
2386 : 802 : bit_range_region::get_bit_size (bit_size_t *out) const
2387 : : {
2388 : 802 : *out = m_bits.m_size_in_bits;
2389 : 802 : return true;
2390 : : }
2391 : :
2392 : : /* Implementation of region::get_byte_size_sval vfunc for bit_range_region. */
2393 : :
2394 : : const svalue *
2395 : 48 : bit_range_region::get_byte_size_sval (region_model_manager *mgr) const
2396 : : {
2397 : 48 : if (m_bits.m_size_in_bits % BITS_PER_UNIT != 0)
2398 : 0 : return mgr->get_or_create_unknown_svalue (size_type_node);
2399 : :
2400 : 48 : HOST_WIDE_INT num_bytes = m_bits.m_size_in_bits.to_shwi () / BITS_PER_UNIT;
2401 : 48 : return mgr->get_or_create_int_cst (size_type_node, num_bytes);
2402 : : }
2403 : :
2404 : : /* Implementation of region::get_bit_size_sval vfunc for bit_range_region. */
2405 : :
2406 : : const svalue *
2407 : 136 : bit_range_region::get_bit_size_sval (region_model_manager *mgr) const
2408 : : {
2409 : 272 : return mgr->get_or_create_int_cst (size_type_node,
2410 : 136 : m_bits.m_size_in_bits);
2411 : : }
2412 : :
2413 : : /* Implementation of region::get_relative_concrete_offset vfunc for
2414 : : bit_range_region. */
2415 : :
2416 : : bool
2417 : 155 : bit_range_region::get_relative_concrete_offset (bit_offset_t *out) const
2418 : : {
2419 : 155 : *out = m_bits.get_start_bit_offset ();
2420 : 155 : return true;
2421 : : }
2422 : :
2423 : : /* Implementation of region::get_relative_symbolic_offset vfunc for
2424 : : bit_range_region.
2425 : : The returned svalue is equal to the offset converted to bytes and
2426 : : rounded off. */
2427 : :
2428 : : const svalue *
2429 : 0 : bit_range_region::get_relative_symbolic_offset (region_model_manager *mgr)
2430 : : const
2431 : : {
2432 : 0 : byte_offset_t start_byte = m_bits.get_start_bit_offset () / BITS_PER_UNIT;
2433 : 0 : tree start_bit_tree = wide_int_to_tree (ptrdiff_type_node, start_byte);
2434 : 0 : return mgr->get_or_create_constant_svalue (start_bit_tree);
2435 : : }
2436 : :
2437 : : /* class var_arg_region : public region. */
2438 : :
2439 : : void
2440 : 0 : var_arg_region::dump_to_pp (pretty_printer *pp, bool simple) const
2441 : : {
2442 : 0 : if (simple)
2443 : : {
2444 : 0 : pp_string (pp, "VAR_ARG_REG(");
2445 : 0 : get_parent_region ()->dump_to_pp (pp, simple);
2446 : 0 : pp_printf (pp, ", arg_idx: %d)", m_idx);
2447 : : }
2448 : : else
2449 : : {
2450 : 0 : pp_string (pp, "var_arg_region(");
2451 : 0 : get_parent_region ()->dump_to_pp (pp, simple);
2452 : 0 : pp_printf (pp, ", arg_idx: %d)", m_idx);
2453 : : }
2454 : 0 : }
2455 : :
2456 : : void
2457 : 0 : var_arg_region::print_dump_widget_label (pretty_printer *pp) const
2458 : : {
2459 : 0 : pp_printf (pp, "var_arg_region(arg_idx: %i)", m_idx);
2460 : 0 : }
2461 : :
2462 : : /* Get the frame_region for this var_arg_region. */
2463 : :
2464 : : const frame_region *
2465 : 523 : var_arg_region::get_frame_region () const
2466 : : {
2467 : 523 : gcc_assert (get_parent_region ());
2468 : 523 : return as_a <const frame_region *> (get_parent_region ());
2469 : : }
2470 : :
2471 : : /* class errno_region : public region. */
2472 : :
2473 : : void
2474 : 0 : errno_region::dump_to_pp (pretty_printer *pp, bool simple) const
2475 : : {
2476 : 0 : if (simple)
2477 : 0 : pp_string (pp, "errno_region");
2478 : : else
2479 : 0 : pp_string (pp, "errno_region()");
2480 : 0 : }
2481 : :
2482 : : void
2483 : 0 : errno_region::print_dump_widget_label (pretty_printer *pp) const
2484 : : {
2485 : 0 : pp_printf (pp, "errno_region");
2486 : 0 : }
2487 : :
2488 : : /* class private_region : public region. */
2489 : :
2490 : : void
2491 : 0 : private_region::dump_to_pp (pretty_printer *pp, bool simple) const
2492 : : {
2493 : 0 : if (simple)
2494 : 0 : pp_printf (pp, "PRIVATE_REG(%qs)", m_desc);
2495 : : else
2496 : 0 : pp_printf (pp, "private_region(%qs)", m_desc);
2497 : 0 : }
2498 : :
2499 : : void
2500 : 0 : private_region::print_dump_widget_label (pretty_printer *pp) const
2501 : : {
2502 : 0 : pp_printf (pp, "private_region(%qs)", m_desc);
2503 : 0 : }
2504 : :
2505 : : /* class unknown_region : public region. */
2506 : :
2507 : : /* Implementation of region::dump_to_pp vfunc for unknown_region. */
2508 : :
2509 : : void
2510 : 0 : unknown_region::dump_to_pp (pretty_printer *pp, bool /*simple*/) const
2511 : : {
2512 : 0 : pp_string (pp, "UNKNOWN_REGION");
2513 : 0 : }
2514 : :
2515 : : void
2516 : 0 : unknown_region::print_dump_widget_label (pretty_printer *pp) const
2517 : : {
2518 : 0 : pp_printf (pp, "unknown_region");
2519 : 0 : }
2520 : :
2521 : : } // namespace ana
2522 : :
2523 : : #endif /* #if ENABLE_ANALYZER */
|