]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/analyzer/region.cc
Update copyright years.
[thirdparty/gcc.git] / gcc / analyzer / region.cc
CommitLineData
808f4dfe 1/* Regions of memory.
7adcbafe 2 Copyright (C) 2019-2022 Free Software Foundation, Inc.
808f4dfe
DM
3 Contributed by David Malcolm <dmalcolm@redhat.com>.
4
5This file is part of GCC.
6
7GCC is free software; you can redistribute it and/or modify it
8under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 3, or (at your option)
10any later version.
11
12GCC is distributed in the hope that it will be useful, but
13WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with GCC; see the file COPYING3. If not see
19<http://www.gnu.org/licenses/>. */
20
21#include "config.h"
22#include "system.h"
23#include "coretypes.h"
24#include "tree.h"
25#include "diagnostic-core.h"
26#include "gimple-pretty-print.h"
27#include "function.h"
28#include "basic-block.h"
29#include "gimple.h"
30#include "gimple-iterator.h"
31#include "diagnostic-core.h"
32#include "graphviz.h"
33#include "options.h"
34#include "cgraph.h"
35#include "tree-dfa.h"
36#include "stringpool.h"
37#include "convert.h"
38#include "target.h"
39#include "fold-const.h"
40#include "tree-pretty-print.h"
41#include "diagnostic-color.h"
42#include "diagnostic-metadata.h"
43#include "tristate.h"
44#include "bitmap.h"
45#include "selftest.h"
46#include "function.h"
809192e7 47#include "json.h"
808f4dfe
DM
48#include "analyzer/analyzer.h"
49#include "analyzer/analyzer-logging.h"
50#include "ordered-hash-map.h"
51#include "options.h"
52#include "cgraph.h"
53#include "cfg.h"
54#include "digraph.h"
55#include "analyzer/supergraph.h"
56#include "sbitmap.h"
57#include "analyzer/call-string.h"
58#include "analyzer/program-point.h"
59#include "analyzer/store.h"
e9751143 60#include "analyzer/region.h"
808f4dfe
DM
61#include "analyzer/region-model.h"
62
63#if ENABLE_ANALYZER
64
65namespace ana {
66
67/* class region and its various subclasses. */
68
69/* class region. */
70
71region::~region ()
72{
73 delete m_cached_offset;
74}
75
76/* Compare REG1 and REG2 by id. */
77
78int
79region::cmp_ids (const region *reg1, const region *reg2)
80{
81 return (long)reg1->get_id () - (long)reg2->get_id ();
82}
83
84/* Determine the base region for this region: when considering bindings
85 for this region, the base region is the ancestor which identifies
86 which cluster they should be partitioned into.
87 Regions within the same struct/union/array are in the same cluster.
88 Different decls are in different clusters. */
89
90const region *
91region::get_base_region () const
92{
93 const region *iter = this;
94 while (iter)
95 {
96 switch (iter->get_kind ())
97 {
98 case RK_FIELD:
99 case RK_ELEMENT:
100 case RK_OFFSET:
e61ffa20 101 case RK_SIZED:
808f4dfe
DM
102 iter = iter->get_parent_region ();
103 continue;
104 case RK_CAST:
105 iter = iter->dyn_cast_cast_region ()->get_original_region ();
106 continue;
107 default:
108 return iter;
109 }
110 }
111 return iter;
112}
113
114/* Return true if get_base_region() == this for this region. */
115
116bool
117region::base_region_p () const
118{
119 switch (get_kind ())
120 {
121 /* Region kinds representing a descendent of a base region. */
122 case RK_FIELD:
123 case RK_ELEMENT:
124 case RK_OFFSET:
e61ffa20 125 case RK_SIZED:
808f4dfe
DM
126 case RK_CAST:
127 return false;
128
129 default:
130 return true;
131 }
132}
133
134/* Return true if this region is ELDER or one of its descendents. */
135
136bool
137region::descendent_of_p (const region *elder) const
138{
139 const region *iter = this;
140 while (iter)
141 {
142 if (iter == elder)
143 return true;
144 if (iter->get_kind () == RK_CAST)
145 iter = iter->dyn_cast_cast_region ()->get_original_region ();
146 else
147 iter = iter->get_parent_region ();
148 }
149 return false;
150}
151
152/* If this region is a frame_region, or a descendent of one, return it.
153 Otherwise return NULL. */
154
155const frame_region *
156region::maybe_get_frame_region () const
157{
158 const region *iter = this;
159 while (iter)
160 {
161 if (const frame_region *frame_reg = iter->dyn_cast_frame_region ())
162 return frame_reg;
163 if (iter->get_kind () == RK_CAST)
164 iter = iter->dyn_cast_cast_region ()->get_original_region ();
165 else
166 iter = iter->get_parent_region ();
167 }
168 return NULL;
169}
170
33255ad3
DM
171/* Get the memory space of this region. */
172
173enum memory_space
174region::get_memory_space () const
175{
176 const region *iter = this;
177 while (iter)
178 {
179 switch (iter->get_kind ())
180 {
181 default:
182 break;
183 case RK_GLOBALS:
184 return MEMSPACE_GLOBALS;
185 case RK_CODE:
186 case RK_FUNCTION:
187 case RK_LABEL:
188 return MEMSPACE_CODE;
189 case RK_FRAME:
190 case RK_STACK:
191 case RK_ALLOCA:
192 return MEMSPACE_STACK;
193 case RK_HEAP:
194 case RK_HEAP_ALLOCATED:
195 return MEMSPACE_HEAP;
196 case RK_STRING:
197 return MEMSPACE_READONLY_DATA;
198 }
199 if (iter->get_kind () == RK_CAST)
200 iter = iter->dyn_cast_cast_region ()->get_original_region ();
201 else
202 iter = iter->get_parent_region ();
203 }
204 return MEMSPACE_UNKNOWN;
205}
206
207/* Subroutine for use by region_model_manager::get_or_create_initial_value.
208 Return true if this region has an initial_svalue.
209 Return false if attempting to use INIT_VAL(this_region) should give
210 the "UNINITIALIZED" poison value. */
211
212bool
213region::can_have_initial_svalue_p () const
214{
215 const region *base_reg = get_base_region ();
216
217 /* Check for memory spaces that are uninitialized by default. */
218 enum memory_space mem_space = base_reg->get_memory_space ();
219 switch (mem_space)
220 {
221 default:
222 gcc_unreachable ();
223 case MEMSPACE_UNKNOWN:
224 case MEMSPACE_CODE:
225 case MEMSPACE_GLOBALS:
226 case MEMSPACE_READONLY_DATA:
227 /* Such regions have initial_svalues. */
228 return true;
229
230 case MEMSPACE_HEAP:
231 /* Heap allocations are uninitialized by default. */
232 return false;
233
234 case MEMSPACE_STACK:
235 if (tree decl = base_reg->maybe_get_decl ())
236 {
237 /* See the assertion in frame_region::get_region_for_local for the
238 tree codes we need to handle here. */
239 switch (TREE_CODE (decl))
240 {
241 default:
242 gcc_unreachable ();
243
244 case PARM_DECL:
245 /* Parameters have initial values. */
246 return true;
247
248 case VAR_DECL:
249 case RESULT_DECL:
250 /* Function locals don't have initial values. */
251 return false;
252
253 case SSA_NAME:
254 {
255 tree ssa_name = decl;
256 /* SSA names that are the default defn of a PARM_DECL
257 have initial_svalues; other SSA names don't. */
258 if (SSA_NAME_IS_DEFAULT_DEF (ssa_name)
259 && SSA_NAME_VAR (ssa_name)
260 && TREE_CODE (SSA_NAME_VAR (ssa_name)) == PARM_DECL)
261 return true;
262 else
263 return false;
264 }
265 }
266 }
267
268 /* If we have an on-stack region that isn't associated with a decl
269 or SSA name, then we have VLA/alloca, which is uninitialized. */
270 return false;
271 }
272}
273
808f4dfe
DM
274/* If this region is a decl_region, return the decl.
275 Otherwise return NULL. */
276
277tree
278region::maybe_get_decl () const
279{
280 if (const decl_region *decl_reg = dyn_cast_decl_region ())
281 return decl_reg->get_decl ();
282 return NULL_TREE;
283}
284
285/* Get the region_offset for this region (calculating it on the
286 first call and caching it internally). */
287
288region_offset
289region::get_offset () const
290{
291 if(!m_cached_offset)
292 m_cached_offset = new region_offset (calc_offset ());
293 return *m_cached_offset;
294}
295
e61ffa20
DM
296/* Base class implementation of region::get_byte_size vfunc.
297 If the size of this region (in bytes) is known statically, write it to *OUT
808f4dfe
DM
298 and return true.
299 Otherwise return false. */
300
301bool
302region::get_byte_size (byte_size_t *out) const
303{
304 tree type = get_type ();
305
306 /* Bail out e.g. for heap-allocated regions. */
307 if (!type)
308 return false;
309
310 HOST_WIDE_INT bytes = int_size_in_bytes (type);
311 if (bytes == -1)
312 return false;
313 *out = bytes;
314 return true;
315}
316
e61ffa20
DM
317/* Base implementation of region::get_byte_size_sval vfunc. */
318
319const svalue *
320region::get_byte_size_sval (region_model_manager *mgr) const
321{
322 tree type = get_type ();
323
324 /* Bail out e.g. for heap-allocated regions. */
325 if (!type)
326 return mgr->get_or_create_unknown_svalue (size_type_node);
327
328 HOST_WIDE_INT bytes = int_size_in_bytes (type);
329 if (bytes == -1)
330 return mgr->get_or_create_unknown_svalue (size_type_node);
331
332 tree byte_size = size_in_bytes (type);
333 if (TREE_TYPE (byte_size) != size_type_node)
334 byte_size = fold_build1 (NOP_EXPR, size_type_node, byte_size);
335 return mgr->get_or_create_constant_svalue (byte_size);
336}
337
338/* Attempt to get the size of TYPE in bits.
339 If successful, return true and write the size to *OUT.
c957d380
DM
340 Otherwise return false. */
341
342bool
343int_size_in_bits (const_tree type, bit_size_t *out)
344{
345 if (INTEGRAL_TYPE_P (type))
346 {
347 *out = TYPE_PRECISION (type);
348 return true;
349 }
350
351 tree sz = TYPE_SIZE (type);
352 if (sz && tree_fits_uhwi_p (sz))
353 {
354 *out = TREE_INT_CST_LOW (sz);
355 return true;
356 }
357 else
358 return false;
359}
360
808f4dfe
DM
361/* If the size of this region (in bits) is known statically, write it to *OUT
362 and return true.
363 Otherwise return false. */
364
365bool
366region::get_bit_size (bit_size_t *out) const
367{
c957d380
DM
368 tree type = get_type ();
369
370 /* Bail out e.g. for heap-allocated regions. */
371 if (!type)
808f4dfe 372 return false;
c957d380
DM
373
374 return int_size_in_bits (type, out);
808f4dfe
DM
375}
376
377/* Get the field within RECORD_TYPE at BIT_OFFSET. */
378
e61ffa20 379tree
808f4dfe
DM
380get_field_at_bit_offset (tree record_type, bit_offset_t bit_offset)
381{
382 gcc_assert (TREE_CODE (record_type) == RECORD_TYPE);
400abebf
DM
383 if (bit_offset < 0)
384 return NULL;
808f4dfe
DM
385
386 /* Find the first field that has an offset > BIT_OFFSET,
387 then return the one preceding it.
388 Skip other trees within the chain, such as FUNCTION_DECLs. */
389 tree last_field = NULL_TREE;
390 for (tree iter = TYPE_FIELDS (record_type); iter != NULL_TREE;
391 iter = DECL_CHAIN (iter))
392 {
393 if (TREE_CODE (iter) == FIELD_DECL)
394 {
395 int iter_field_offset = int_bit_position (iter);
396 if (bit_offset < iter_field_offset)
397 return last_field;
398 last_field = iter;
399 }
400 }
401 return last_field;
402}
403
404/* Populate *OUT with descendent regions of type TYPE that match
405 RELATIVE_BIT_OFFSET and SIZE_IN_BITS within this region. */
406
407void
408region::get_subregions_for_binding (region_model_manager *mgr,
409 bit_offset_t relative_bit_offset,
410 bit_size_t size_in_bits,
411 tree type,
412 auto_vec <const region *> *out) const
413{
42c5ae5d 414 if (get_type () == NULL_TREE || type == NULL_TREE)
808f4dfe
DM
415 return;
416 if (relative_bit_offset == 0
417 && types_compatible_p (get_type (), type))
418 {
419 out->safe_push (this);
420 return;
421 }
422 switch (TREE_CODE (get_type ()))
423 {
424 case ARRAY_TYPE:
425 {
426 tree element_type = TREE_TYPE (get_type ());
427 HOST_WIDE_INT hwi_byte_size = int_size_in_bytes (element_type);
428 if (hwi_byte_size > 0)
429 {
430 HOST_WIDE_INT bits_per_element
431 = hwi_byte_size << LOG2_BITS_PER_UNIT;
432 HOST_WIDE_INT element_index
433 = (relative_bit_offset.to_shwi () / bits_per_element);
434 tree element_index_cst
435 = build_int_cst (integer_type_node, element_index);
436 HOST_WIDE_INT inner_bit_offset
437 = relative_bit_offset.to_shwi () % bits_per_element;
438 const region *subregion = mgr->get_element_region
439 (this, element_type,
440 mgr->get_or_create_constant_svalue (element_index_cst));
441 subregion->get_subregions_for_binding (mgr, inner_bit_offset,
442 size_in_bits, type, out);
443 }
444 }
445 break;
446 case RECORD_TYPE:
447 {
448 /* The bit offset might be *within* one of the fields (such as
449 with nested structs).
450 So we want to find the enclosing field, adjust the offset,
451 and repeat. */
452 if (tree field = get_field_at_bit_offset (get_type (),
453 relative_bit_offset))
454 {
455 int field_bit_offset = int_bit_position (field);
456 const region *subregion = mgr->get_field_region (this, field);
457 subregion->get_subregions_for_binding
458 (mgr, relative_bit_offset - field_bit_offset,
459 size_in_bits, type, out);
460 }
461 }
462 break;
463 case UNION_TYPE:
464 {
465 for (tree field = TYPE_FIELDS (get_type ()); field != NULL_TREE;
466 field = DECL_CHAIN (field))
467 {
00cb0f58
DM
468 if (TREE_CODE (field) != FIELD_DECL)
469 continue;
808f4dfe
DM
470 const region *subregion = mgr->get_field_region (this, field);
471 subregion->get_subregions_for_binding (mgr,
472 relative_bit_offset,
473 size_in_bits,
474 type,
475 out);
476 }
477 }
478 break;
479 default:
480 /* Do nothing. */
481 break;
482 }
483}
484
485/* Walk from this region up to the base region within its cluster, calculating
486 the offset relative to the base region, either as an offset in bits,
487 or a symbolic offset. */
488
489region_offset
490region::calc_offset () const
491{
492 const region *iter_region = this;
493 bit_offset_t accum_bit_offset = 0;
494
495 while (iter_region)
496 {
497 switch (iter_region->get_kind ())
498 {
499 case RK_FIELD:
500 {
501 const field_region *field_reg
502 = (const field_region *)iter_region;
503 iter_region = iter_region->get_parent_region ();
504
e61ffa20
DM
505 bit_offset_t rel_bit_offset;
506 if (!field_reg->get_relative_concrete_offset (&rel_bit_offset))
808f4dfe 507 return region_offset::make_symbolic (iter_region);
e61ffa20 508 accum_bit_offset += rel_bit_offset;
808f4dfe
DM
509 }
510 continue;
511
512 case RK_ELEMENT:
513 {
514 const element_region *element_reg
515 = (const element_region *)iter_region;
516 iter_region = iter_region->get_parent_region ();
517
e61ffa20
DM
518 bit_offset_t rel_bit_offset;
519 if (!element_reg->get_relative_concrete_offset (&rel_bit_offset))
520 return region_offset::make_symbolic (iter_region);
521 accum_bit_offset += rel_bit_offset;
808f4dfe
DM
522 }
523 continue;
524
525 case RK_OFFSET:
526 {
527 const offset_region *offset_reg
528 = (const offset_region *)iter_region;
529 iter_region = iter_region->get_parent_region ();
530
e61ffa20
DM
531 bit_offset_t rel_bit_offset;
532 if (!offset_reg->get_relative_concrete_offset (&rel_bit_offset))
808f4dfe 533 return region_offset::make_symbolic (iter_region);
e61ffa20 534 accum_bit_offset += rel_bit_offset;
808f4dfe
DM
535 }
536 continue;
537
e61ffa20
DM
538 case RK_SIZED:
539 iter_region = iter_region->get_parent_region ();
540 continue;
541
808f4dfe
DM
542 case RK_CAST:
543 {
544 const cast_region *cast_reg
545 = as_a <const cast_region *> (iter_region);
546 iter_region = cast_reg->get_original_region ();
547 }
548 continue;
549
550 default:
551 return region_offset::make_concrete (iter_region, accum_bit_offset);
552 }
553 }
554 return region_offset::make_concrete (iter_region, accum_bit_offset);
555}
556
e61ffa20
DM
557/* Base implementation of region::get_relative_concrete_offset vfunc. */
558
559bool
560region::get_relative_concrete_offset (bit_offset_t *) const
561{
562 return false;
563}
564
808f4dfe
DM
565/* Copy from SRC_REG to DST_REG, using CTXT for any issues that occur. */
566
567void
568region_model::copy_region (const region *dst_reg, const region *src_reg,
569 region_model_context *ctxt)
570{
571 gcc_assert (dst_reg);
572 gcc_assert (src_reg);
573 if (dst_reg == src_reg)
574 return;
575
9faf8348 576 const svalue *sval = get_store_value (src_reg, ctxt);
808f4dfe
DM
577 set_value (dst_reg, sval, ctxt);
578}
579
580/* Dump a description of this region to stderr. */
581
582DEBUG_FUNCTION void
583region::dump (bool simple) const
584{
585 pretty_printer pp;
586 pp_format_decoder (&pp) = default_tree_printer;
587 pp_show_color (&pp) = pp_show_color (global_dc->printer);
588 pp.buffer->stream = stderr;
589 dump_to_pp (&pp, simple);
590 pp_newline (&pp);
591 pp_flush (&pp);
592}
593
809192e7
DM
594/* Return a new json::string describing the region. */
595
596json::value *
597region::to_json () const
598{
599 label_text desc = get_desc (true);
600 json::value *reg_js = new json::string (desc.m_buffer);
601 desc.maybe_free ();
602 return reg_js;
603}
604
808f4dfe
DM
605/* Generate a description of this region. */
606
607DEBUG_FUNCTION label_text
608region::get_desc (bool simple) const
609{
610 pretty_printer pp;
611 pp_format_decoder (&pp) = default_tree_printer;
612 dump_to_pp (&pp, simple);
613 return label_text::take (xstrdup (pp_formatted_text (&pp)));
614}
615
616/* Base implementation of region::accept vfunc.
617 Subclass implementations should chain up to this. */
618
619void
620region::accept (visitor *v) const
621{
622 v->visit_region (this);
623 if (m_parent)
624 m_parent->accept (v);
625}
626
627/* Return true if this is a symbolic region for deferencing an
628 unknown ptr.
629 We shouldn't attempt to bind values for this region (but
630 can unbind values for other regions). */
631
632bool
633region::symbolic_for_unknown_ptr_p () const
634{
635 if (const symbolic_region *sym_reg = dyn_cast_symbolic_region ())
636 if (sym_reg->get_pointer ()->get_kind () == SK_UNKNOWN)
637 return true;
638 return false;
639}
640
641/* region's ctor. */
642
643region::region (complexity c, unsigned id, const region *parent, tree type)
644: m_complexity (c), m_id (id), m_parent (parent), m_type (type),
645 m_cached_offset (NULL)
646{
647 gcc_assert (type == NULL_TREE || TYPE_P (type));
648}
649
b0702ac5
DM
650/* Comparator for use by vec<const region *>::qsort,
651 using their IDs to order them. */
808f4dfe
DM
652
653int
b0702ac5 654region::cmp_ptr_ptr (const void *p1, const void *p2)
808f4dfe
DM
655{
656 const region * const *reg1 = (const region * const *)p1;
657 const region * const *reg2 = (const region * const *)p2;
658
659 return cmp_ids (*reg1, *reg2);
660}
661
662/* Determine if a pointer to this region must be non-NULL.
663
664 Generally, pointers to regions must be non-NULL, but pointers
665 to symbolic_regions might, in fact, be NULL.
666
667 This allows us to simulate functions like malloc and calloc with:
668 - only one "outcome" from each statement,
669 - the idea that the pointer is on the heap if non-NULL
670 - the possibility that the pointer could be NULL
671 - the idea that successive values returned from malloc are non-equal
672 - to be able to zero-fill for calloc. */
673
674bool
675region::non_null_p () const
676{
677 switch (get_kind ())
678 {
679 default:
680 return true;
681 case RK_SYMBOLIC:
682 /* Are we within a symbolic_region? If so, it could be NULL, and we
683 have to fall back on the constraints. */
684 return false;
685 case RK_HEAP_ALLOCATED:
686 return false;
687 }
688}
689
33255ad3
DM
690/* Return true iff this region is defined in terms of SVAL. */
691
692bool
693region::involves_p (const svalue *sval) const
694{
695 if (const symbolic_region *symbolic_reg = dyn_cast_symbolic_region ())
696 {
697 if (symbolic_reg->get_pointer ()->involves_p (sval))
698 return true;
699 }
700
701 return false;
702}
703
808f4dfe
DM
704/* Comparator for trees to impose a deterministic ordering on
705 T1 and T2. */
706
707static int
708tree_cmp (const_tree t1, const_tree t2)
709{
710 gcc_assert (t1);
711 gcc_assert (t2);
712
713 /* Test tree codes first. */
714 if (TREE_CODE (t1) != TREE_CODE (t2))
715 return TREE_CODE (t1) - TREE_CODE (t2);
716
717 /* From this point on, we know T1 and T2 have the same tree code. */
718
719 if (DECL_P (t1))
720 {
721 if (DECL_NAME (t1) && DECL_NAME (t2))
722 return strcmp (IDENTIFIER_POINTER (DECL_NAME (t1)),
723 IDENTIFIER_POINTER (DECL_NAME (t2)));
724 else
725 {
726 if (DECL_NAME (t1))
727 return -1;
728 else if (DECL_NAME (t2))
729 return 1;
730 else
731 return DECL_UID (t1) - DECL_UID (t2);
732 }
733 }
734
735 switch (TREE_CODE (t1))
736 {
737 case SSA_NAME:
738 {
739 if (SSA_NAME_VAR (t1) && SSA_NAME_VAR (t2))
740 {
741 int var_cmp = tree_cmp (SSA_NAME_VAR (t1), SSA_NAME_VAR (t2));
742 if (var_cmp)
743 return var_cmp;
744 return SSA_NAME_VERSION (t1) - SSA_NAME_VERSION (t2);
745 }
746 else
747 {
748 if (SSA_NAME_VAR (t1))
749 return -1;
750 else if (SSA_NAME_VAR (t2))
751 return 1;
752 else
753 return SSA_NAME_VERSION (t1) - SSA_NAME_VERSION (t2);
754 }
755 }
756 break;
757
758 case INTEGER_CST:
759 return tree_int_cst_compare (t1, t2);
760
761 case REAL_CST:
762 {
763 const real_value *rv1 = TREE_REAL_CST_PTR (t1);
764 const real_value *rv2 = TREE_REAL_CST_PTR (t2);
765 if (real_compare (UNORDERED_EXPR, rv1, rv2))
766 {
767 /* Impose an arbitrary order on NaNs relative to other NaNs
768 and to non-NaNs. */
769 if (int cmp_isnan = real_isnan (rv1) - real_isnan (rv2))
770 return cmp_isnan;
771 if (int cmp_issignaling_nan
772 = real_issignaling_nan (rv1) - real_issignaling_nan (rv2))
773 return cmp_issignaling_nan;
774 return real_isneg (rv1) - real_isneg (rv2);
775 }
776 if (real_compare (LT_EXPR, rv1, rv2))
777 return -1;
778 if (real_compare (GT_EXPR, rv1, rv2))
779 return 1;
780 return 0;
781 }
782
783 case STRING_CST:
784 return strcmp (TREE_STRING_POINTER (t1),
785 TREE_STRING_POINTER (t2));
786
787 default:
788 gcc_unreachable ();
789 break;
790 }
791
792 gcc_unreachable ();
793
794 return 0;
795}
796
797/* qsort comparator for trees to impose a deterministic ordering on
798 P1 and P2. */
799
800int
801tree_cmp (const void *p1, const void *p2)
802{
803 const_tree t1 = *(const_tree const *)p1;
804 const_tree t2 = *(const_tree const *)p2;
805
806 return tree_cmp (t1, t2);
807}
808
809/* class frame_region : public space_region. */
810
811frame_region::~frame_region ()
812{
813 for (map_t::iterator iter = m_locals.begin ();
814 iter != m_locals.end ();
815 ++iter)
816 delete (*iter).second;
817}
818
819void
820frame_region::accept (visitor *v) const
821{
822 region::accept (v);
823 if (m_calling_frame)
824 m_calling_frame->accept (v);
825}
826
827/* Implementation of region::dump_to_pp vfunc for frame_region. */
828
829void
830frame_region::dump_to_pp (pretty_printer *pp, bool simple) const
831{
832 if (simple)
833 pp_printf (pp, "frame: %qs@%i", function_name (m_fun), get_stack_depth ());
834 else
835 pp_printf (pp, "frame_region(%qs, index: %i, depth: %i)",
836 function_name (m_fun), m_index, get_stack_depth ());
837}
838
839const decl_region *
840frame_region::get_region_for_local (region_model_manager *mgr,
841 tree expr) const
842{
843 // TODO: could also check that VAR_DECLs are locals
844 gcc_assert (TREE_CODE (expr) == PARM_DECL
845 || TREE_CODE (expr) == VAR_DECL
846 || TREE_CODE (expr) == SSA_NAME
847 || TREE_CODE (expr) == RESULT_DECL);
848
849 /* Ideally we'd use mutable here. */
850 map_t &mutable_locals = const_cast <map_t &> (m_locals);
851
852 if (decl_region **slot = mutable_locals.get (expr))
853 return *slot;
854 decl_region *reg
855 = new decl_region (mgr->alloc_region_id (), this, expr);
856 mutable_locals.put (expr, reg);
857 return reg;
858}
859
860/* class globals_region : public space_region. */
861
862/* Implementation of region::dump_to_pp vfunc for globals_region. */
863
864void
865globals_region::dump_to_pp (pretty_printer *pp, bool simple) const
866{
867 if (simple)
868 pp_string (pp, "::");
869 else
870 pp_string (pp, "globals");
871}
872
873/* class code_region : public map_region. */
874
875/* Implementation of region::dump_to_pp vfunc for code_region. */
876
877void
878code_region::dump_to_pp (pretty_printer *pp, bool simple) const
879{
880 if (simple)
881 pp_string (pp, "code region");
882 else
883 pp_string (pp, "code_region()");
884}
885
886/* class function_region : public region. */
887
888/* Implementation of region::dump_to_pp vfunc for function_region. */
889
890void
891function_region::dump_to_pp (pretty_printer *pp, bool simple) const
892{
893 if (simple)
894 {
895 dump_quoted_tree (pp, m_fndecl);
896 }
897 else
898 {
899 pp_string (pp, "function_region(");
900 dump_quoted_tree (pp, m_fndecl);
901 pp_string (pp, ")");
902 }
903}
904
905/* class label_region : public region. */
906
907/* Implementation of region::dump_to_pp vfunc for label_region. */
908
909void
910label_region::dump_to_pp (pretty_printer *pp, bool simple) const
911{
912 if (simple)
913 {
914 dump_quoted_tree (pp, m_label);
915 }
916 else
917 {
918 pp_string (pp, "label_region(");
919 dump_quoted_tree (pp, m_label);
920 pp_string (pp, ")");
921 }
922}
923
924/* class stack_region : public region. */
925
926/* Implementation of region::dump_to_pp vfunc for stack_region. */
927
928void
929stack_region::dump_to_pp (pretty_printer *pp, bool simple) const
930{
931 if (simple)
932 pp_string (pp, "stack region");
933 else
934 pp_string (pp, "stack_region()");
935}
936
937/* class heap_region : public region. */
938
939/* Implementation of region::dump_to_pp vfunc for heap_region. */
940
941void
942heap_region::dump_to_pp (pretty_printer *pp, bool simple) const
943{
944 if (simple)
945 pp_string (pp, "heap region");
946 else
947 pp_string (pp, "heap_region()");
948}
949
950/* class root_region : public region. */
951
952/* root_region's ctor. */
953
954root_region::root_region (unsigned id)
955: region (complexity (1, 1), id, NULL, NULL_TREE)
956{
957}
958
959/* Implementation of region::dump_to_pp vfunc for root_region. */
960
961void
962root_region::dump_to_pp (pretty_printer *pp, bool simple) const
963{
964 if (simple)
965 pp_string (pp, "root region");
966 else
967 pp_string (pp, "root_region()");
968}
969
970/* class symbolic_region : public map_region. */
971
e9751143
DM
972/* symbolic_region's ctor. */
973
974symbolic_region::symbolic_region (unsigned id, region *parent,
975 const svalue *sval_ptr)
976: region (complexity::from_pair (parent, sval_ptr), id, parent,
977 TREE_TYPE (sval_ptr->get_type ())),
978 m_sval_ptr (sval_ptr)
979{
980}
981
808f4dfe
DM
982/* Implementation of region::accept vfunc for symbolic_region. */
983
984void
985symbolic_region::accept (visitor *v) const
986{
987 region::accept (v);
988 m_sval_ptr->accept (v);
989}
990
991/* Implementation of region::dump_to_pp vfunc for symbolic_region. */
992
993void
994symbolic_region::dump_to_pp (pretty_printer *pp, bool simple) const
995{
996 if (simple)
997 {
998 pp_string (pp, "(*");
999 m_sval_ptr->dump_to_pp (pp, simple);
1000 pp_string (pp, ")");
1001 }
1002 else
1003 {
1004 pp_string (pp, "symbolic_region(");
1005 get_parent_region ()->dump_to_pp (pp, simple);
1006 pp_string (pp, ", ");
1007 print_quoted_type (pp, get_type ());
1008 pp_string (pp, ", ");
1009 m_sval_ptr->dump_to_pp (pp, simple);
1010 pp_string (pp, ")");
1011 }
1012}
1013
1014/* class decl_region : public region. */
1015
1016/* Implementation of region::dump_to_pp vfunc for decl_region. */
1017
1018void
1019decl_region::dump_to_pp (pretty_printer *pp, bool simple) const
1020{
1021 if (simple)
1022 pp_printf (pp, "%E", m_decl);
1023 else
1024 {
1025 pp_string (pp, "decl_region(");
1026 get_parent_region ()->dump_to_pp (pp, simple);
1027 pp_string (pp, ", ");
1028 print_quoted_type (pp, get_type ());
1029 pp_printf (pp, ", %qE)", m_decl);
1030 }
1031}
1032
1033/* Get the stack depth for the frame containing this decl, or 0
1034 for a global. */
1035
1036int
1037decl_region::get_stack_depth () const
1038{
1039 if (get_parent_region () == NULL)
1040 return 0;
1041 if (const frame_region *frame_reg
1042 = get_parent_region ()->dyn_cast_frame_region ())
1043 return frame_reg->get_stack_depth ();
1044 return 0;
1045}
1046
2867118d
DM
1047/* If the underlying decl is in the global constant pool,
1048 return an svalue representing the constant value.
1049 Otherwise return NULL. */
1050
1051const svalue *
1052decl_region::maybe_get_constant_value (region_model_manager *mgr) const
1053{
1054 if (TREE_CODE (m_decl) == VAR_DECL
1055 && DECL_IN_CONSTANT_POOL (m_decl)
1056 && DECL_INITIAL (m_decl)
1057 && TREE_CODE (DECL_INITIAL (m_decl)) == CONSTRUCTOR)
623bc027
DM
1058 return get_svalue_for_constructor (DECL_INITIAL (m_decl), mgr);
1059 return NULL;
1060}
2867118d 1061
623bc027 1062/* Get an svalue for CTOR, a CONSTRUCTOR for this region's decl. */
2867118d 1063
623bc027
DM
1064const svalue *
1065decl_region::get_svalue_for_constructor (tree ctor,
1066 region_model_manager *mgr) const
1067{
1068 gcc_assert (!TREE_CLOBBER_P (ctor));
1069
1070 /* Create a binding map, applying ctor to it, using this
1071 decl_region as the base region when building child regions
1072 for offset calculations. */
1073 binding_map map;
18056e45
DM
1074 if (!map.apply_ctor_to_region (this, ctor, mgr))
1075 return mgr->get_or_create_unknown_svalue (get_type ());
623bc027
DM
1076
1077 /* Return a compound svalue for the map we built. */
1078 return mgr->get_or_create_compound_svalue (get_type (), map);
1079}
1080
1081/* For use on decl_regions for global variables.
1082
1083 Get an svalue for the initial value of this region at entry to
1084 "main" (either based on DECL_INITIAL, or implicit initialization to
61a43de5
DM
1085 zero.
1086
1087 Return NULL if there is a problem. */
623bc027
DM
1088
1089const svalue *
1090decl_region::get_svalue_for_initializer (region_model_manager *mgr) const
1091{
1092 tree init = DECL_INITIAL (m_decl);
1093 if (!init)
1094 {
16ad9ae8
DM
1095 /* If we have an "extern" decl then there may be an initializer in
1096 another TU. */
1097 if (DECL_EXTERNAL (m_decl))
1098 return NULL;
1099
61a43de5
DM
1100 /* Implicit initialization to zero; use a compound_svalue for it.
1101 Doing so requires that we have a concrete binding for this region,
1102 which can fail if we have a region with unknown size
1103 (e.g. "extern const char arr[];"). */
1104 const binding_key *binding
e61ffa20 1105 = binding_key::make (mgr->get_store_manager (), this);
61a43de5
DM
1106 if (binding->symbolic_p ())
1107 return NULL;
1108
623bc027
DM
1109 binding_cluster c (this);
1110 c.zero_fill_region (mgr->get_store_manager (), this);
1111 return mgr->get_or_create_compound_svalue (TREE_TYPE (m_decl),
1112 c.get_map ());
61a43de5 1113 }
623bc027 1114
0677759f
DM
1115 /* LTO can write out error_mark_node as the DECL_INITIAL for simple scalar
1116 values (to avoid writing out an extra section). */
1117 if (init == error_mark_node)
1118 return NULL;
1119
623bc027
DM
1120 if (TREE_CODE (init) == CONSTRUCTOR)
1121 return get_svalue_for_constructor (init, mgr);
1122
1123 /* Reuse the get_rvalue logic from region_model. */
1124 region_model m (mgr);
1125 return m.get_rvalue (path_var (init, 0), NULL);
2867118d
DM
1126}
1127
808f4dfe
DM
1128/* class field_region : public region. */
1129
1130/* Implementation of region::dump_to_pp vfunc for field_region. */
1131
1132void
1133field_region::dump_to_pp (pretty_printer *pp, bool simple) const
1134{
1135 if (simple)
1136 {
1137 get_parent_region ()->dump_to_pp (pp, simple);
1138 pp_string (pp, ".");
1139 pp_printf (pp, "%E", m_field);
1140 }
1141 else
1142 {
1143 pp_string (pp, "field_region(");
1144 get_parent_region ()->dump_to_pp (pp, simple);
1145 pp_string (pp, ", ");
1146 print_quoted_type (pp, get_type ());
1147 pp_printf (pp, ", %qE)", m_field);
1148 }
1149}
1150
e61ffa20
DM
1151/* Implementation of region::get_relative_concrete_offset vfunc
1152 for field_region. */
1153
1154bool
1155field_region::get_relative_concrete_offset (bit_offset_t *out) const
1156{
1157 /* Compare with e.g. gimple-fold.c's
1158 fold_nonarray_ctor_reference. */
1159 tree byte_offset = DECL_FIELD_OFFSET (m_field);
1160 if (TREE_CODE (byte_offset) != INTEGER_CST)
1161 return false;
1162 tree field_offset = DECL_FIELD_BIT_OFFSET (m_field);
1163 /* Compute bit offset of the field. */
1164 offset_int bitoffset
1165 = (wi::to_offset (field_offset)
1166 + (wi::to_offset (byte_offset) << LOG2_BITS_PER_UNIT));
1167 *out = bitoffset;
1168 return true;
1169}
1170
808f4dfe
DM
1171/* class element_region : public region. */
1172
1173/* Implementation of region::accept vfunc for element_region. */
1174
1175void
1176element_region::accept (visitor *v) const
1177{
1178 region::accept (v);
1179 m_index->accept (v);
1180}
1181
1182/* Implementation of region::dump_to_pp vfunc for element_region. */
1183
1184void
1185element_region::dump_to_pp (pretty_printer *pp, bool simple) const
1186{
1187 if (simple)
1188 {
1189 //pp_string (pp, "(");
1190 get_parent_region ()->dump_to_pp (pp, simple);
1191 pp_string (pp, "[");
1192 m_index->dump_to_pp (pp, simple);
1193 pp_string (pp, "]");
1194 //pp_string (pp, ")");
1195 }
1196 else
1197 {
1198 pp_string (pp, "element_region(");
1199 get_parent_region ()->dump_to_pp (pp, simple);
1200 pp_string (pp, ", ");
1201 print_quoted_type (pp, get_type ());
1202 pp_string (pp, ", ");
1203 m_index->dump_to_pp (pp, simple);
1204 pp_printf (pp, ")");
1205 }
1206}
1207
e61ffa20
DM
1208/* Implementation of region::get_relative_concrete_offset vfunc
1209 for element_region. */
1210
1211bool
1212element_region::get_relative_concrete_offset (bit_offset_t *out) const
1213{
1214 if (tree idx_cst = m_index->maybe_get_constant ())
1215 {
1216 gcc_assert (TREE_CODE (idx_cst) == INTEGER_CST);
1217
1218 tree elem_type = get_type ();
1219 offset_int element_idx = wi::to_offset (idx_cst);
1220
1221 /* First, use int_size_in_bytes, to reject the case where we
1222 have an incomplete type, or a non-constant value. */
1223 HOST_WIDE_INT hwi_byte_size = int_size_in_bytes (elem_type);
1224 if (hwi_byte_size > 0)
1225 {
1226 offset_int element_bit_size
1227 = hwi_byte_size << LOG2_BITS_PER_UNIT;
1228 offset_int element_bit_offset
1229 = element_idx * element_bit_size;
1230 *out = element_bit_offset;
1231 return true;
1232 }
1233 }
1234 return false;
1235}
1236
808f4dfe
DM
1237/* class offset_region : public region. */
1238
1239/* Implementation of region::accept vfunc for offset_region. */
1240
1241void
1242offset_region::accept (visitor *v) const
1243{
1244 region::accept (v);
1245 m_byte_offset->accept (v);
1246}
1247
1248/* Implementation of region::dump_to_pp vfunc for offset_region. */
1249
1250void
1251offset_region::dump_to_pp (pretty_printer *pp, bool simple) const
1252{
1253 if (simple)
1254 {
1255 //pp_string (pp, "(");
1256 get_parent_region ()->dump_to_pp (pp, simple);
1257 pp_string (pp, "+");
1258 m_byte_offset->dump_to_pp (pp, simple);
1259 //pp_string (pp, ")");
1260 }
1261 else
1262 {
1263 pp_string (pp, "offset_region(");
1264 get_parent_region ()->dump_to_pp (pp, simple);
1265 pp_string (pp, ", ");
1266 print_quoted_type (pp, get_type ());
1267 pp_string (pp, ", ");
1268 m_byte_offset->dump_to_pp (pp, simple);
1269 pp_printf (pp, ")");
1270 }
1271}
1272
e61ffa20
DM
1273/* Implementation of region::get_relative_concrete_offset vfunc
1274 for offset_region. */
1275
1276bool
1277offset_region::get_relative_concrete_offset (bit_offset_t *out) const
1278{
1279 if (tree byte_offset_cst = m_byte_offset->maybe_get_constant ())
1280 {
1281 gcc_assert (TREE_CODE (byte_offset_cst) == INTEGER_CST);
1282 /* Use a signed value for the byte offset, to handle
1283 negative offsets. */
1284 HOST_WIDE_INT byte_offset
1285 = wi::to_offset (byte_offset_cst).to_shwi ();
1286 HOST_WIDE_INT bit_offset = byte_offset * BITS_PER_UNIT;
1287 *out = bit_offset;
1288 return true;
1289 }
1290 return false;
1291}
1292
1293/* class sized_region : public region. */
1294
1295/* Implementation of region::accept vfunc for sized_region. */
1296
1297void
1298sized_region::accept (visitor *v) const
1299{
1300 region::accept (v);
1301 m_byte_size_sval->accept (v);
1302}
1303
1304/* Implementation of region::dump_to_pp vfunc for sized_region. */
1305
1306void
1307sized_region::dump_to_pp (pretty_printer *pp, bool simple) const
1308{
1309 if (simple)
1310 {
1311 pp_string (pp, "SIZED_REG(");
1312 get_parent_region ()->dump_to_pp (pp, simple);
1313 pp_string (pp, ", ");
1314 m_byte_size_sval->dump_to_pp (pp, simple);
1315 pp_string (pp, ")");
1316 }
1317 else
1318 {
1319 pp_string (pp, "sized_region(");
1320 get_parent_region ()->dump_to_pp (pp, simple);
1321 pp_string (pp, ", ");
1322 m_byte_size_sval->dump_to_pp (pp, simple);
1323 pp_printf (pp, ")");
1324 }
1325}
1326
1327/* Implementation of region::get_byte_size vfunc for sized_region. */
1328
1329bool
1330sized_region::get_byte_size (byte_size_t *out) const
1331{
1332 if (tree cst = m_byte_size_sval->maybe_get_constant ())
1333 {
1334 gcc_assert (TREE_CODE (cst) == INTEGER_CST);
1335 *out = tree_to_uhwi (cst);
1336 return true;
1337 }
1338 return false;
1339}
1340
1341/* Implementation of region::get_bit_size vfunc for sized_region. */
1342
1343bool
1344sized_region::get_bit_size (bit_size_t *out) const
1345{
1346 byte_size_t byte_size;
1347 if (!get_byte_size (&byte_size))
1348 return false;
1349 *out = byte_size * BITS_PER_UNIT;
1350 return true;
1351}
1352
808f4dfe
DM
1353/* class cast_region : public region. */
1354
1355/* Implementation of region::accept vfunc for cast_region. */
1356
1357void
1358cast_region::accept (visitor *v) const
1359{
1360 region::accept (v);
1361 m_original_region->accept (v);
1362}
1363
1364/* Implementation of region::dump_to_pp vfunc for cast_region. */
1365
1366void
1367cast_region::dump_to_pp (pretty_printer *pp, bool simple) const
1368{
1369 if (simple)
1370 {
1371 pp_string (pp, "CAST_REG(");
1372 print_quoted_type (pp, get_type ());
1373 pp_string (pp, ", ");
1374 m_original_region->dump_to_pp (pp, simple);
1375 pp_string (pp, ")");
1376 }
1377 else
1378 {
1379 pp_string (pp, "cast_region(");
1380 m_original_region->dump_to_pp (pp, simple);
1381 pp_string (pp, ", ");
1382 print_quoted_type (pp, get_type ());
1383 pp_printf (pp, ")");
1384 }
1385}
1386
1387/* class heap_allocated_region : public region. */
1388
1389/* Implementation of region::dump_to_pp vfunc for heap_allocated_region. */
1390
1391void
1392heap_allocated_region::dump_to_pp (pretty_printer *pp, bool simple) const
1393{
1394 if (simple)
1395 pp_printf (pp, "HEAP_ALLOCATED_REGION(%i)", get_id ());
1396 else
1397 pp_printf (pp, "heap_allocated_region(%i)", get_id ());
1398}
1399
1400/* class alloca_region : public region. */
1401
1402/* Implementation of region::dump_to_pp vfunc for alloca_region. */
1403
1404void
1405alloca_region::dump_to_pp (pretty_printer *pp, bool simple) const
1406{
1407 if (simple)
1408 pp_string (pp, "ALLOCA_REGION");
1409 else
1410 pp_string (pp, "alloca_region()");
1411}
1412
1413/* class string_region : public region. */
1414
1415/* Implementation of region::dump_to_pp vfunc for string_region. */
1416
1417void
1418string_region::dump_to_pp (pretty_printer *pp, bool simple) const
1419{
1420 if (simple)
1421 dump_tree (pp, m_string_cst);
1422 else
1423 {
1424 pp_string (pp, "string_region(");
1425 dump_tree (pp, m_string_cst);
0a36f5f2
DM
1426 if (!flag_dump_noaddr)
1427 {
1428 pp_string (pp, " (");
1429 pp_pointer (pp, m_string_cst);
1430 pp_string (pp, "))");
1431 }
808f4dfe
DM
1432 }
1433}
1434
1435/* class unknown_region : public region. */
1436
1437/* Implementation of region::dump_to_pp vfunc for unknown_region. */
1438
1439void
1440unknown_region::dump_to_pp (pretty_printer *pp, bool /*simple*/) const
1441{
1442 pp_string (pp, "UNKNOWN_REGION");
1443}
1444
1445} // namespace ana
1446
1447#endif /* #if ENABLE_ANALYZER */