c++: decltype of (by-value captured reference) [PR79620]
[official-gcc.git] / gcc / analyzer / svalue.cc
blob35eb8307b203817f314749bef39019b62eb5dff8
1 /* Symbolic values.
2 Copyright (C) 2019-2023 Free Software Foundation, Inc.
3 Contributed by David Malcolm <dmalcolm@redhat.com>.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
10 any later version.
12 GCC is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
21 #include "config.h"
22 #define INCLUDE_MEMORY
23 #include "system.h"
24 #include "coretypes.h"
25 #include "tree.h"
26 #include "diagnostic-core.h"
27 #include "gimple-pretty-print.h"
28 #include "function.h"
29 #include "basic-block.h"
30 #include "gimple.h"
31 #include "gimple-iterator.h"
32 #include "diagnostic-core.h"
33 #include "graphviz.h"
34 #include "options.h"
35 #include "cgraph.h"
36 #include "tree-dfa.h"
37 #include "stringpool.h"
38 #include "convert.h"
39 #include "target.h"
40 #include "fold-const.h"
41 #include "tree-pretty-print.h"
42 #include "bitmap.h"
43 #include "analyzer/analyzer.h"
44 #include "analyzer/analyzer-logging.h"
45 #include "analyzer/call-string.h"
46 #include "analyzer/program-point.h"
47 #include "analyzer/store.h"
48 #include "analyzer/svalue.h"
49 #include "analyzer/region-model.h"
50 #include "diagnostic.h"
51 #include "tree-diagnostic.h"
53 #if ENABLE_ANALYZER
55 namespace ana {
57 static int cmp_csts_and_types (const_tree cst1, const_tree cst2);
59 /* class svalue and its various subclasses. */
61 /* class svalue. */
63 /* Dump a representation of this svalue to stderr. */
65 DEBUG_FUNCTION void
66 svalue::dump (bool simple) const
68 pretty_printer pp;
69 pp_format_decoder (&pp) = default_tree_printer;
70 pp_show_color (&pp) = pp_show_color (global_dc->printer);
71 pp.buffer->stream = stderr;
72 dump_to_pp (&pp, simple);
73 pp_newline (&pp);
74 pp_flush (&pp);
77 /* Generate a textual representation of this svalue for debugging purposes. */
79 label_text
80 svalue::get_desc (bool simple) const
82 pretty_printer pp;
83 pp_format_decoder (&pp) = default_tree_printer;
84 dump_to_pp (&pp, simple);
85 return label_text::take (xstrdup (pp_formatted_text (&pp)));
88 /* Return a new json::string describing the svalue. */
90 json::value *
91 svalue::to_json () const
93 label_text desc = get_desc (true);
94 json::value *sval_js = new json::string (desc.get ());
95 return sval_js;
98 /* If this svalue is a constant_svalue, return the underlying tree constant.
99 Otherwise return NULL_TREE. */
101 tree
102 svalue::maybe_get_constant () const
104 const svalue *sval = unwrap_any_unmergeable ();
105 if (const constant_svalue *cst_sval = sval->dyn_cast_constant_svalue ())
106 return cst_sval->get_constant ();
107 else
108 return NULL_TREE;
111 /* If this svalue is a region_svalue, return the region it points to.
112 Otherwise return NULL. */
114 const region *
115 svalue::maybe_get_region () const
117 if (const region_svalue *region_sval = dyn_cast_region_svalue ())
118 return region_sval->get_pointee ();
119 else
120 return NULL;
123 /* If this svalue is a cast (i.e a unaryop NOP_EXPR or VIEW_CONVERT_EXPR),
124 return the underlying svalue.
125 Otherwise return NULL. */
127 const svalue *
128 svalue::maybe_undo_cast () const
130 if (const unaryop_svalue *unaryop_sval = dyn_cast_unaryop_svalue ())
132 enum tree_code op = unaryop_sval->get_op ();
133 if (op == NOP_EXPR || op == VIEW_CONVERT_EXPR)
134 return unaryop_sval->get_arg ();
136 return NULL;
139 /* If this svalue is an unmergeable decorator around another svalue, return
140 the underlying svalue.
141 Otherwise return this svalue. */
143 const svalue *
144 svalue::unwrap_any_unmergeable () const
146 if (const unmergeable_svalue *unmergeable = dyn_cast_unmergeable_svalue ())
147 return unmergeable->get_arg ();
148 return this;
151 /* Attempt to merge THIS with OTHER, returning the merged svalue.
152 Return NULL if not mergeable. */
154 const svalue *
155 svalue::can_merge_p (const svalue *other,
156 region_model_manager *mgr,
157 model_merger *merger) const
159 if (!(get_type () && other->get_type ()))
160 return NULL;
162 if (!types_compatible_p (get_type (), other->get_type ()))
163 return NULL;
165 /* Reject attempts to merge unmergeable svalues. */
166 if ((get_kind () == SK_UNMERGEABLE)
167 || (other->get_kind () == SK_UNMERGEABLE))
168 return NULL;
170 /* Reject attempts to merge poisoned svalues with other svalues
171 (either non-poisoned, or other kinds of poison), so that e.g.
172 we identify paths in which a variable is conditionally uninitialized. */
173 if (get_kind () == SK_POISONED
174 || other->get_kind () == SK_POISONED)
175 return NULL;
177 /* Reject attempts to merge NULL pointers with not-NULL-pointers. */
178 if (POINTER_TYPE_P (get_type ()))
180 bool null0 = false;
181 bool null1 = false;
182 if (tree cst0 = maybe_get_constant ())
183 if (zerop (cst0))
184 null0 = true;
185 if (tree cst1 = other->maybe_get_constant ())
186 if (zerop (cst1))
187 null1 = true;
188 if (null0 != null1)
189 return NULL;
192 /* Reject merging svalues that have non-purgable sm-state,
193 to avoid falsely reporting memory leaks by merging them
194 with something else. */
195 if (!merger->mergeable_svalue_p (this))
196 return NULL;
197 if (!merger->mergeable_svalue_p (other))
198 return NULL;
200 /* Widening. */
201 /* Merge: (new_cst, existing_cst) -> widen (existing, new). */
202 if (maybe_get_constant () && other->maybe_get_constant ())
204 return mgr->get_or_create_widening_svalue (other->get_type (),
205 merger->get_function_point (),
206 other, this);
209 /* Merger of:
210 this: BINOP (X, OP, CST)
211 other: X, where X is non-widening
212 to: WIDENING (other, this). */
213 if (const binop_svalue *binop_sval = dyn_cast_binop_svalue ())
214 if (binop_sval->get_arg0 () == other
215 && binop_sval->get_arg1 ()->get_kind () == SK_CONSTANT
216 && other->get_kind () != SK_WIDENING)
217 return mgr->get_or_create_widening_svalue (other->get_type (),
218 merger->get_function_point (),
219 other, this);
221 /* Merge: (Widen(existing_val, V), existing_val) -> Widen (existing_val, V)
222 and thus get a fixed point. */
223 if (const widening_svalue *widen_sval = dyn_cast_widening_svalue ())
225 if (other == widen_sval->get_base_svalue ())
226 return this;
227 if (other == widen_sval->get_iter_svalue ())
228 return this;
231 if (const binop_svalue *binop_sval = dyn_cast_binop_svalue ())
232 if (const widening_svalue *widen_arg0
233 = binop_sval->get_arg0 ()->dyn_cast_widening_svalue ())
235 if (other == binop_sval->get_arg1 ())
237 /* Merger of: (Widen(..., OTHER) BINOP X)
238 and : OTHER
239 to : (Widen(..., OTHER) BINOP X)
240 e.g. merge of Widen(0, 1) + 1 with 1 to the Widen(0, 1) + 1. */
241 return this;
244 /* Merger of : (Widen() BINOP X)
245 and : Widen()
246 to : Widen()
247 e.g. merge of Widen(0, 1) + 1 and Widen(0, 1) to Widen(0, 1).
248 However, we want to update constraints for this case, since we're
249 considering another iteration.
250 Presumably we also want to ensure that it converges; we don't want
251 a descending chain of constraints. */
252 if (other == widen_arg0)
254 return widen_arg0;
257 /* Merger of:
258 this: BINOP(WIDENING(BASE, BINOP(BASE, X)), X)
259 other: BINOP(BASE, X)
260 to: WIDENING(BASE, BINOP(BASE, X)). */
261 if (widen_arg0->get_iter_svalue () == other)
262 if (const binop_svalue *other_binop_sval
263 = other->dyn_cast_binop_svalue ())
264 if (other_binop_sval->get_arg0 () == widen_arg0->get_base_svalue ()
265 && other_binop_sval->get_arg1 () == binop_sval->get_arg1 ())
266 return widen_arg0;
269 return mgr->get_or_create_unknown_svalue (get_type ());
272 /* Determine if this svalue is either within LIVE_SVALUES, or is implicitly
273 live with respect to LIVE_SVALUES and MODEL.
274 LIVE_SVALUES can be NULL, in which case determine if this svalue is
275 intrinsically live. */
277 bool
278 svalue::live_p (const svalue_set *live_svalues,
279 const region_model *model) const
281 /* Determine if SVAL is explicitly live. */
282 if (live_svalues)
283 if (const_cast<svalue_set *> (live_svalues)->contains (this))
284 return true;
286 /* Otherwise, determine if SVAL is implicitly live due to being made of
287 other live svalues. */
288 return implicitly_live_p (live_svalues, model);
291 /* Base implementation of svalue::implicitly_live_p. */
293 bool
294 svalue::implicitly_live_p (const svalue_set *, const region_model *) const
296 return false;
299 /* Comparator for imposing a deterministic order on constants that are
300 of the same type. */
302 static int
303 cmp_csts_same_type (const_tree cst1, const_tree cst2)
305 gcc_assert (TREE_TYPE (cst1) == TREE_TYPE (cst2));
306 gcc_assert (TREE_CODE (cst1) == TREE_CODE (cst2));
307 switch (TREE_CODE (cst1))
309 default:
310 gcc_unreachable ();
311 case INTEGER_CST:
312 return tree_int_cst_compare (cst1, cst2);
313 case STRING_CST:
314 return strcmp (TREE_STRING_POINTER (cst1),
315 TREE_STRING_POINTER (cst2));
316 case REAL_CST:
317 /* Impose an arbitrary but deterministic order. */
318 return memcmp (TREE_REAL_CST_PTR (cst1),
319 TREE_REAL_CST_PTR (cst2),
320 sizeof (real_value));
321 case COMPLEX_CST:
322 if (int cmp_real = cmp_csts_and_types (TREE_REALPART (cst1),
323 TREE_REALPART (cst2)))
324 return cmp_real;
325 return cmp_csts_and_types (TREE_IMAGPART (cst1), TREE_IMAGPART (cst2));
326 case VECTOR_CST:
327 if (int cmp_log2_npatterns
328 = ((int)VECTOR_CST_LOG2_NPATTERNS (cst1)
329 - (int)VECTOR_CST_LOG2_NPATTERNS (cst2)))
330 return cmp_log2_npatterns;
331 if (int cmp_nelts_per_pattern
332 = ((int)VECTOR_CST_NELTS_PER_PATTERN (cst1)
333 - (int)VECTOR_CST_NELTS_PER_PATTERN (cst2)))
334 return cmp_nelts_per_pattern;
335 unsigned encoded_nelts = vector_cst_encoded_nelts (cst1);
336 for (unsigned i = 0; i < encoded_nelts; i++)
338 const_tree elt1 = VECTOR_CST_ENCODED_ELT (cst1, i);
339 const_tree elt2 = VECTOR_CST_ENCODED_ELT (cst2, i);
340 if (int el_cmp = cmp_csts_and_types (elt1, elt2))
341 return el_cmp;
343 return 0;
347 /* Comparator for imposing a deterministic order on constants that might
348 not be of the same type. */
350 static int
351 cmp_csts_and_types (const_tree cst1, const_tree cst2)
353 int t1 = TYPE_UID (TREE_TYPE (cst1));
354 int t2 = TYPE_UID (TREE_TYPE (cst2));
355 if (int cmp_type = t1 - t2)
356 return cmp_type;
357 return cmp_csts_same_type (cst1, cst2);
360 /* Comparator for imposing a deterministic order on svalues. */
363 svalue::cmp_ptr (const svalue *sval1, const svalue *sval2)
365 if (sval1 == sval2)
366 return 0;
367 if (int cmp_kind = sval1->get_kind () - sval2->get_kind ())
368 return cmp_kind;
369 int t1 = sval1->get_type () ? TYPE_UID (sval1->get_type ()) : -1;
370 int t2 = sval2->get_type () ? TYPE_UID (sval2->get_type ()) : -1;
371 if (int cmp_type = t1 - t2)
372 return cmp_type;
373 switch (sval1->get_kind ())
375 default:
376 gcc_unreachable ();
377 case SK_REGION:
379 const region_svalue *region_sval1 = (const region_svalue *)sval1;
380 const region_svalue *region_sval2 = (const region_svalue *)sval2;
381 return region::cmp_ids (region_sval1->get_pointee (),
382 region_sval2->get_pointee ());
384 break;
385 case SK_CONSTANT:
387 const constant_svalue *constant_sval1 = (const constant_svalue *)sval1;
388 const constant_svalue *constant_sval2 = (const constant_svalue *)sval2;
389 const_tree cst1 = constant_sval1->get_constant ();
390 const_tree cst2 = constant_sval2->get_constant ();
391 return cmp_csts_same_type (cst1, cst2);
393 break;
394 case SK_UNKNOWN:
396 gcc_assert (sval1 == sval2);
397 return 0;
399 break;
400 case SK_POISONED:
402 const poisoned_svalue *poisoned_sval1 = (const poisoned_svalue *)sval1;
403 const poisoned_svalue *poisoned_sval2 = (const poisoned_svalue *)sval2;
404 return (poisoned_sval1->get_poison_kind ()
405 - poisoned_sval2->get_poison_kind ());
407 break;
408 case SK_SETJMP:
410 const setjmp_svalue *setjmp_sval1 = (const setjmp_svalue *)sval1;
411 const setjmp_svalue *setjmp_sval2 = (const setjmp_svalue *)sval2;
412 const setjmp_record &rec1 = setjmp_sval1->get_setjmp_record ();
413 const setjmp_record &rec2 = setjmp_sval2->get_setjmp_record ();
414 return setjmp_record::cmp (rec1, rec2);
416 break;
417 case SK_INITIAL:
419 const initial_svalue *initial_sval1 = (const initial_svalue *)sval1;
420 const initial_svalue *initial_sval2 = (const initial_svalue *)sval2;
421 return region::cmp_ids (initial_sval1->get_region (),
422 initial_sval2->get_region ());
424 break;
425 case SK_UNARYOP:
427 const unaryop_svalue *unaryop_sval1 = (const unaryop_svalue *)sval1;
428 const unaryop_svalue *unaryop_sval2 = (const unaryop_svalue *)sval2;
429 if (int op_cmp = unaryop_sval1->get_op () - unaryop_sval2->get_op ())
430 return op_cmp;
431 return svalue::cmp_ptr (unaryop_sval1->get_arg (),
432 unaryop_sval2->get_arg ());
434 break;
435 case SK_BINOP:
437 const binop_svalue *binop_sval1 = (const binop_svalue *)sval1;
438 const binop_svalue *binop_sval2 = (const binop_svalue *)sval2;
439 if (int op_cmp = binop_sval1->get_op () - binop_sval2->get_op ())
440 return op_cmp;
441 if (int arg0_cmp = svalue::cmp_ptr (binop_sval1->get_arg0 (),
442 binop_sval2->get_arg0 ()))
443 return arg0_cmp;
444 return svalue::cmp_ptr (binop_sval1->get_arg1 (),
445 binop_sval2->get_arg1 ());
447 break;
448 case SK_SUB:
450 const sub_svalue *sub_sval1 = (const sub_svalue *)sval1;
451 const sub_svalue *sub_sval2 = (const sub_svalue *)sval2;
452 if (int parent_cmp = svalue::cmp_ptr (sub_sval1->get_parent (),
453 sub_sval2->get_parent ()))
454 return parent_cmp;
455 return region::cmp_ids (sub_sval1->get_subregion (),
456 sub_sval2->get_subregion ());
458 break;
459 case SK_REPEATED:
461 const repeated_svalue *repeated_sval1 = (const repeated_svalue *)sval1;
462 const repeated_svalue *repeated_sval2 = (const repeated_svalue *)sval2;
463 return svalue::cmp_ptr (repeated_sval1->get_inner_svalue (),
464 repeated_sval2->get_inner_svalue ());
466 break;
467 case SK_BITS_WITHIN:
469 const bits_within_svalue *bits_within_sval1
470 = (const bits_within_svalue *)sval1;
471 const bits_within_svalue *bits_within_sval2
472 = (const bits_within_svalue *)sval2;
473 if (int cmp = bit_range::cmp (bits_within_sval1->get_bits (),
474 bits_within_sval2->get_bits ()))
475 return cmp;
476 return svalue::cmp_ptr (bits_within_sval1->get_inner_svalue (),
477 bits_within_sval2->get_inner_svalue ());
479 break;
480 case SK_UNMERGEABLE:
482 const unmergeable_svalue *unmergeable_sval1
483 = (const unmergeable_svalue *)sval1;
484 const unmergeable_svalue *unmergeable_sval2
485 = (const unmergeable_svalue *)sval2;
486 return svalue::cmp_ptr (unmergeable_sval1->get_arg (),
487 unmergeable_sval2->get_arg ());
489 break;
490 case SK_PLACEHOLDER:
492 const placeholder_svalue *placeholder_sval1
493 = (const placeholder_svalue *)sval1;
494 const placeholder_svalue *placeholder_sval2
495 = (const placeholder_svalue *)sval2;
496 return strcmp (placeholder_sval1->get_name (),
497 placeholder_sval2->get_name ());
499 break;
500 case SK_WIDENING:
502 const widening_svalue *widening_sval1 = (const widening_svalue *)sval1;
503 const widening_svalue *widening_sval2 = (const widening_svalue *)sval2;
504 if (int point_cmp = function_point::cmp (widening_sval1->get_point (),
505 widening_sval2->get_point ()))
506 return point_cmp;
507 if (int base_cmp = svalue::cmp_ptr (widening_sval1->get_base_svalue (),
508 widening_sval2->get_base_svalue ()))
509 return base_cmp;
510 return svalue::cmp_ptr (widening_sval1->get_iter_svalue (),
511 widening_sval2->get_iter_svalue ());
513 break;
514 case SK_COMPOUND:
516 const compound_svalue *compound_sval1 = (const compound_svalue *)sval1;
517 const compound_svalue *compound_sval2 = (const compound_svalue *)sval2;
518 return binding_map::cmp (compound_sval1->get_map (),
519 compound_sval2->get_map ());
521 break;
522 case SK_CONJURED:
524 const conjured_svalue *conjured_sval1 = (const conjured_svalue *)sval1;
525 const conjured_svalue *conjured_sval2 = (const conjured_svalue *)sval2;
526 if (int stmt_cmp = (conjured_sval1->get_stmt ()->uid
527 - conjured_sval2->get_stmt ()->uid))
528 return stmt_cmp;
529 return region::cmp_ids (conjured_sval1->get_id_region (),
530 conjured_sval2->get_id_region ());
532 break;
533 case SK_ASM_OUTPUT:
535 const asm_output_svalue *asm_output_sval1
536 = (const asm_output_svalue *)sval1;
537 const asm_output_svalue *asm_output_sval2
538 = (const asm_output_svalue *)sval2;
539 if (int asm_string_cmp = strcmp (asm_output_sval1->get_asm_string (),
540 asm_output_sval2->get_asm_string ()))
541 return asm_string_cmp;
542 if (int output_idx_cmp = ((int)asm_output_sval1->get_output_idx ()
543 - (int)asm_output_sval2->get_output_idx ()))
544 return output_idx_cmp;
545 if (int cmp = ((int)asm_output_sval1->get_num_inputs ()
546 - (int)asm_output_sval2->get_num_inputs ()))
547 return cmp;
548 for (unsigned i = 0; i < asm_output_sval1->get_num_inputs (); i++)
549 if (int input_cmp
550 = svalue::cmp_ptr (asm_output_sval1->get_input (i),
551 asm_output_sval2->get_input (i)))
552 return input_cmp;
553 return 0;
555 break;
556 case SK_CONST_FN_RESULT:
558 const const_fn_result_svalue *const_fn_result_sval1
559 = (const const_fn_result_svalue *)sval1;
560 const const_fn_result_svalue *const_fn_result_sval2
561 = (const const_fn_result_svalue *)sval2;
562 int d1 = DECL_UID (const_fn_result_sval1->get_fndecl ());
563 int d2 = DECL_UID (const_fn_result_sval2->get_fndecl ());
564 if (int cmp_fndecl = d1 - d2)
565 return cmp_fndecl;
566 if (int cmp = ((int)const_fn_result_sval1->get_num_inputs ()
567 - (int)const_fn_result_sval2->get_num_inputs ()))
568 return cmp;
569 for (unsigned i = 0; i < const_fn_result_sval1->get_num_inputs (); i++)
570 if (int input_cmp
571 = svalue::cmp_ptr (const_fn_result_sval1->get_input (i),
572 const_fn_result_sval2->get_input (i)))
573 return input_cmp;
574 return 0;
579 /* Comparator for use by vec<const svalue *>::qsort. */
582 svalue::cmp_ptr_ptr (const void *p1, const void *p2)
584 const svalue *sval1 = *(const svalue * const *)p1;
585 const svalue *sval2 = *(const svalue * const *)p2;
586 return cmp_ptr (sval1, sval2);
589 /* Subclass of visitor for use in implementing svalue::involves_p. */
591 class involvement_visitor : public visitor
593 public:
594 involvement_visitor (const svalue *needle)
595 : m_needle (needle), m_found (false) {}
597 void visit_initial_svalue (const initial_svalue *candidate) final override
599 if (candidate == m_needle)
600 m_found = true;
603 void visit_conjured_svalue (const conjured_svalue *candidate) final override
605 if (candidate == m_needle)
606 m_found = true;
609 bool found_p () const { return m_found; }
611 private:
612 const svalue *m_needle;
613 bool m_found;
616 /* Return true iff this svalue is defined in terms of OTHER. */
618 bool
619 svalue::involves_p (const svalue *other) const
621 /* Currently only implemented for these kinds. */
622 gcc_assert (other->get_kind () == SK_INITIAL
623 || other->get_kind () == SK_CONJURED);
625 involvement_visitor v (other);
626 accept (&v);
627 return v.found_p ();
630 /* Extract SUBRANGE from this value, of type TYPE. */
632 const svalue *
633 svalue::extract_bit_range (tree type,
634 const bit_range &subrange,
635 region_model_manager *mgr) const
637 return mgr->get_or_create_bits_within (type, subrange, this);
640 /* Base implementation of svalue::maybe_fold_bits_within vfunc. */
642 const svalue *
643 svalue::maybe_fold_bits_within (tree,
644 const bit_range &,
645 region_model_manager *) const
647 /* By default, don't fold. */
648 return NULL;
651 /* Base implementation of svalue::all_zeroes_p.
652 Return true if this value is known to be all zeroes. */
654 bool
655 svalue::all_zeroes_p () const
657 return false;
660 /* If this svalue is a pointer, attempt to determine the base region it points
661 to. Return NULL on any problems. */
663 const region *
664 svalue::maybe_get_deref_base_region () const
666 const svalue *iter = this;
667 while (1)
669 switch (iter->get_kind ())
671 default:
672 return NULL;
674 case SK_REGION:
676 const region_svalue *region_sval
677 = as_a <const region_svalue *> (iter);
678 return region_sval->get_pointee ()->get_base_region ();
681 case SK_BINOP:
683 const binop_svalue *binop_sval
684 = as_a <const binop_svalue *> (iter);
685 switch (binop_sval->get_op ())
687 case POINTER_PLUS_EXPR:
688 /* If we have a symbolic value expressing pointer arithmetic,
689 use the LHS. */
690 iter = binop_sval->get_arg0 ();
691 continue;
693 default:
694 return NULL;
696 return NULL;
702 /* class region_svalue : public svalue. */
704 /* Implementation of svalue::dump_to_pp vfunc for region_svalue. */
706 void
707 region_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
709 if (simple)
711 pp_string (pp, "&");
712 m_reg->dump_to_pp (pp, simple);
714 else
716 pp_string (pp, "region_svalue(");
717 if (get_type ())
719 print_quoted_type (pp, get_type ());
720 pp_string (pp, ", ");
722 m_reg->dump_to_pp (pp, simple);
723 pp_string (pp, ")");
727 /* Implementation of svalue::accept vfunc for region_svalue. */
729 void
730 region_svalue::accept (visitor *v) const
732 m_reg->accept (v);
733 v->visit_region_svalue (this);
736 /* Implementation of svalue::implicitly_live_p vfunc for region_svalue. */
738 bool
739 region_svalue::implicitly_live_p (const svalue_set *,
740 const region_model *model) const
742 /* Pointers into clusters that have escaped should be treated as live. */
743 const region *base_reg = get_pointee ()->get_base_region ();
744 const store *store = model->get_store ();
745 if (const binding_cluster *c = store->get_cluster (base_reg))
746 if (c->escaped_p ())
747 return true;
749 return false;
752 /* Evaluate the condition LHS OP RHS.
753 Subroutine of region_model::eval_condition for when we have a pair of
754 pointers. */
756 tristate
757 region_svalue::eval_condition (const region_svalue *lhs,
758 enum tree_code op,
759 const region_svalue *rhs)
761 /* See if they point to the same region. */
762 const region *lhs_reg = lhs->get_pointee ();
763 const region *rhs_reg = rhs->get_pointee ();
764 bool ptr_equality = lhs_reg == rhs_reg;
765 switch (op)
767 default:
768 gcc_unreachable ();
770 case EQ_EXPR:
771 if (ptr_equality)
772 return tristate::TS_TRUE;
773 else
774 return tristate::TS_FALSE;
775 break;
777 case NE_EXPR:
778 if (ptr_equality)
779 return tristate::TS_FALSE;
780 else
781 return tristate::TS_TRUE;
782 break;
784 case GE_EXPR:
785 case LE_EXPR:
786 if (ptr_equality)
787 return tristate::TS_TRUE;
788 break;
790 case GT_EXPR:
791 case LT_EXPR:
792 if (ptr_equality)
793 return tristate::TS_FALSE;
794 break;
797 return tristate::TS_UNKNOWN;
800 /* class constant_svalue : public svalue. */
802 /* Implementation of svalue::dump_to_pp vfunc for constant_svalue. */
804 void
805 constant_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
807 if (simple)
809 pp_string (pp, "(");
810 dump_tree (pp, get_type ());
811 pp_string (pp, ")");
812 dump_tree (pp, m_cst_expr);
814 else
816 pp_string (pp, "constant_svalue(");
817 if (get_type ())
819 print_quoted_type (pp, get_type ());
820 pp_string (pp, ", ");
822 dump_tree (pp, m_cst_expr);
823 pp_string (pp, ")");
827 /* Implementation of svalue::accept vfunc for constant_svalue. */
829 void
830 constant_svalue::accept (visitor *v) const
832 v->visit_constant_svalue (this);
835 /* Implementation of svalue::implicitly_live_p vfunc for constant_svalue.
836 Constants are implicitly live. */
838 bool
839 constant_svalue::implicitly_live_p (const svalue_set *,
840 const region_model *) const
842 return true;
845 /* Evaluate the condition LHS OP RHS.
846 Subroutine of region_model::eval_condition for when we have a pair of
847 constants. */
849 tristate
850 constant_svalue::eval_condition (const constant_svalue *lhs,
851 enum tree_code op,
852 const constant_svalue *rhs)
854 tree lhs_const = lhs->get_constant ();
855 tree rhs_const = rhs->get_constant ();
857 gcc_assert (CONSTANT_CLASS_P (lhs_const));
858 gcc_assert (CONSTANT_CLASS_P (rhs_const));
860 /* Check for comparable types. */
861 if (types_compatible_p (TREE_TYPE (lhs_const), TREE_TYPE (rhs_const)))
863 tree comparison
864 = fold_binary (op, boolean_type_node, lhs_const, rhs_const);
865 if (comparison == boolean_true_node)
866 return tristate (tristate::TS_TRUE);
867 if (comparison == boolean_false_node)
868 return tristate (tristate::TS_FALSE);
870 return tristate::TS_UNKNOWN;
873 /* Implementation of svalue::maybe_fold_bits_within vfunc
874 for constant_svalue. */
876 const svalue *
877 constant_svalue::maybe_fold_bits_within (tree type,
878 const bit_range &bits,
879 region_model_manager *mgr) const
881 /* Bits within an all-zero value are also all zero. */
882 if (zerop (m_cst_expr))
884 if (type)
885 return mgr->get_or_create_cast (type, this);
886 else
887 return this;
890 /* Handle the case of extracting a single bit. */
891 if (bits.m_size_in_bits == 1
892 && TREE_CODE (m_cst_expr) == INTEGER_CST
893 && type
894 && INTEGRAL_TYPE_P (type)
895 && tree_fits_uhwi_p (m_cst_expr))
897 unsigned HOST_WIDE_INT bit = bits.m_start_bit_offset.to_uhwi ();
898 unsigned HOST_WIDE_INT mask = (1 << bit);
899 unsigned HOST_WIDE_INT val_as_hwi = tree_to_uhwi (m_cst_expr);
900 unsigned HOST_WIDE_INT masked_val = val_as_hwi & mask;
901 int result = masked_val ? 1 : 0;
902 return mgr->get_or_create_int_cst (type, result);
905 /* Otherwise, don't fold. */
906 return NULL;
909 /* Implementation of svalue::all_zeroes_p for constant_svalue. */
911 bool
912 constant_svalue::all_zeroes_p () const
914 return zerop (m_cst_expr);
917 /* class unknown_svalue : public svalue. */
919 /* Implementation of svalue::dump_to_pp vfunc for unknown_svalue. */
921 void
922 unknown_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
924 if (simple)
926 pp_string (pp, "UNKNOWN(");
927 if (get_type ())
928 dump_tree (pp, get_type ());
929 pp_character (pp, ')');
931 else
933 pp_string (pp, "unknown_svalue(");
934 if (get_type ())
935 dump_tree (pp, get_type ());
936 pp_character (pp, ')');
940 /* Implementation of svalue::accept vfunc for unknown_svalue. */
942 void
943 unknown_svalue::accept (visitor *v) const
945 v->visit_unknown_svalue (this);
948 /* Implementation of svalue::maybe_fold_bits_within vfunc
949 for unknown_svalue. */
951 const svalue *
952 unknown_svalue::maybe_fold_bits_within (tree type,
953 const bit_range &,
954 region_model_manager *mgr) const
956 /* Bits within an unknown_svalue are themselves unknown. */
957 return mgr->get_or_create_unknown_svalue (type);
960 /* Get a string for KIND for use in debug dumps. */
962 const char *
963 poison_kind_to_str (enum poison_kind kind)
965 switch (kind)
967 default:
968 gcc_unreachable ();
969 case POISON_KIND_UNINIT:
970 return "uninit";
971 case POISON_KIND_FREED:
972 return "freed";
973 case POISON_KIND_DELETED:
974 return "deleted";
975 case POISON_KIND_POPPED_STACK:
976 return "popped stack";
980 /* class poisoned_svalue : public svalue. */
982 /* Implementation of svalue::dump_to_pp vfunc for poisoned_svalue. */
984 void
985 poisoned_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
987 if (simple)
989 pp_string (pp, "POISONED(");
990 print_quoted_type (pp, get_type ());
991 pp_printf (pp, ", %s)", poison_kind_to_str (m_kind));
993 else
995 pp_string (pp, "poisoned_svalue(");
996 print_quoted_type (pp, get_type ());
997 pp_printf (pp, ", %s)", poison_kind_to_str (m_kind));
1001 /* Implementation of svalue::accept vfunc for poisoned_svalue. */
1003 void
1004 poisoned_svalue::accept (visitor *v) const
1006 v->visit_poisoned_svalue (this);
1009 /* Implementation of svalue::maybe_fold_bits_within vfunc
1010 for poisoned_svalue. */
1012 const svalue *
1013 poisoned_svalue::maybe_fold_bits_within (tree type,
1014 const bit_range &,
1015 region_model_manager *mgr) const
1017 /* Bits within a poisoned value are also poisoned. */
1018 return mgr->get_or_create_poisoned_svalue (m_kind, type);
1021 /* class setjmp_svalue's implementation is in engine.cc, so that it can use
1022 the declaration of exploded_node. */
1024 /* class initial_svalue : public svalue. */
1026 /* Implementation of svalue::dump_to_pp vfunc for initial_svalue. */
1028 void
1029 initial_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
1031 if (simple)
1033 pp_string (pp, "INIT_VAL(");
1034 m_reg->dump_to_pp (pp, simple);
1035 pp_string (pp, ")");
1037 else
1039 pp_string (pp, "initial_svalue(");
1040 if (get_type ())
1042 print_quoted_type (pp, get_type ());
1043 pp_string (pp, ", ");
1045 m_reg->dump_to_pp (pp, simple);
1046 pp_string (pp, ")");
1050 /* Implementation of svalue::accept vfunc for initial_svalue. */
1052 void
1053 initial_svalue::accept (visitor *v) const
1055 m_reg->accept (v);
1056 v->visit_initial_svalue (this);
1059 /* Implementation of svalue::implicitly_live_p vfunc for initial_svalue. */
1061 bool
1062 initial_svalue::implicitly_live_p (const svalue_set *,
1063 const region_model *model) const
1065 /* This svalue may be implicitly live if the region still implicitly
1066 has its initial value and is reachable. */
1068 /* It must be a region that exists; we don't want to consider
1069 INIT_VAL(R) as still being implicitly reachable if R is in
1070 a popped stack frame. */
1071 if (model->region_exists_p (m_reg))
1073 const svalue *reg_sval = model->get_store_value (m_reg, NULL);
1074 if (reg_sval == this)
1075 return true;
1078 /* Assume that the initial values of params for the top level frame
1079 are still live, because (presumably) they're still
1080 live in the external caller. */
1081 if (initial_value_of_param_p ())
1082 if (const frame_region *frame_reg = m_reg->maybe_get_frame_region ())
1083 if (frame_reg->get_calling_frame () == NULL)
1084 return true;
1086 return false;
1089 /* Return true if this is the initial value of a function parameter. */
1091 bool
1092 initial_svalue::initial_value_of_param_p () const
1094 if (tree reg_decl = m_reg->maybe_get_decl ())
1095 if (TREE_CODE (reg_decl) == SSA_NAME)
1097 tree ssa_name = reg_decl;
1098 if (SSA_NAME_IS_DEFAULT_DEF (ssa_name)
1099 && SSA_NAME_VAR (ssa_name)
1100 && TREE_CODE (SSA_NAME_VAR (ssa_name)) == PARM_DECL)
1101 return true;
1103 return false;
1106 /* class unaryop_svalue : public svalue. */
1108 /* Implementation of svalue::dump_to_pp vfunc for unaryop_svalue. */
1110 void
1111 unaryop_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
1113 if (simple)
1115 if (m_op == VIEW_CONVERT_EXPR || m_op == NOP_EXPR)
1117 pp_string (pp, "CAST(");
1118 dump_tree (pp, get_type ());
1119 pp_string (pp, ", ");
1120 m_arg->dump_to_pp (pp, simple);
1121 pp_character (pp, ')');
1123 else
1125 pp_character (pp, '(');
1126 pp_string (pp, get_tree_code_name (m_op));
1127 //pp_string (pp, op_symbol_code (m_op));
1128 m_arg->dump_to_pp (pp, simple);
1129 pp_character (pp, ')');
1132 else
1134 pp_string (pp, "unaryop_svalue (");
1135 pp_string (pp, get_tree_code_name (m_op));
1136 pp_string (pp, ", ");
1137 m_arg->dump_to_pp (pp, simple);
1138 pp_character (pp, ')');
1142 /* Implementation of svalue::accept vfunc for unaryop_svalue. */
1144 void
1145 unaryop_svalue::accept (visitor *v) const
1147 m_arg->accept (v);
1148 v->visit_unaryop_svalue (this);
1151 /* Implementation of svalue::implicitly_live_p vfunc for unaryop_svalue. */
1153 bool
1154 unaryop_svalue::implicitly_live_p (const svalue_set *live_svalues,
1155 const region_model *model) const
1157 return get_arg ()->live_p (live_svalues, model);
1160 /* Implementation of svalue::maybe_fold_bits_within vfunc
1161 for unaryop_svalue. */
1163 const svalue *
1164 unaryop_svalue::maybe_fold_bits_within (tree type,
1165 const bit_range &,
1166 region_model_manager *mgr) const
1168 switch (m_op)
1170 default:
1171 break;
1172 case NOP_EXPR:
1173 /* A cast of zero is zero. */
1174 if (tree cst = m_arg->maybe_get_constant ())
1175 if (zerop (cst))
1177 if (type)
1178 return mgr->get_or_create_cast (type, this);
1179 else
1180 return this;
1182 break;
1184 /* Otherwise, don't fold. */
1185 return NULL;
1188 /* class binop_svalue : public svalue. */
1190 /* Return whether OP be printed as an infix operator. */
1192 static bool
1193 infix_p (enum tree_code op)
1195 switch (op)
1197 default:
1198 return true;
1199 case MAX_EXPR:
1200 case MIN_EXPR:
1201 return false;
1205 /* Implementation of svalue::dump_to_pp vfunc for binop_svalue. */
1207 void
1208 binop_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
1210 if (simple)
1212 if (infix_p (m_op))
1214 /* Print "(A OP B)". */
1215 pp_character (pp, '(');
1216 m_arg0->dump_to_pp (pp, simple);
1217 pp_string (pp, op_symbol_code (m_op));
1218 m_arg1->dump_to_pp (pp, simple);
1219 pp_character (pp, ')');
1221 else
1223 /* Print "OP(A, B)". */
1224 pp_string (pp, op_symbol_code (m_op));
1225 pp_character (pp, '(');
1226 m_arg0->dump_to_pp (pp, simple);
1227 pp_string (pp, ", ");
1228 m_arg1->dump_to_pp (pp, simple);
1229 pp_character (pp, ')');
1232 else
1234 pp_string (pp, "binop_svalue (");
1235 pp_string (pp, get_tree_code_name (m_op));
1236 pp_string (pp, ", ");
1237 m_arg0->dump_to_pp (pp, simple);
1238 pp_string (pp, ", ");
1239 m_arg1->dump_to_pp (pp, simple);
1240 pp_character (pp, ')');
1244 /* Implementation of svalue::accept vfunc for binop_svalue. */
1246 void
1247 binop_svalue::accept (visitor *v) const
1249 m_arg0->accept (v);
1250 m_arg1->accept (v);
1251 v->visit_binop_svalue (this);
1254 /* Implementation of svalue::implicitly_live_p vfunc for binop_svalue. */
1256 bool
1257 binop_svalue::implicitly_live_p (const svalue_set *live_svalues,
1258 const region_model *model) const
1260 return (get_arg0 ()->live_p (live_svalues, model)
1261 && get_arg1 ()->live_p (live_svalues, model));
1264 /* class sub_svalue : public svalue. */
1266 /* sub_svalue'c ctor. */
1268 sub_svalue::sub_svalue (symbol::id_t id,
1269 tree type, const svalue *parent_svalue,
1270 const region *subregion)
1271 : svalue (complexity::from_pair (parent_svalue->get_complexity (),
1272 subregion->get_complexity ()),
1274 type),
1275 m_parent_svalue (parent_svalue), m_subregion (subregion)
1277 gcc_assert (parent_svalue->can_have_associated_state_p ());
1280 /* Implementation of svalue::dump_to_pp vfunc for sub_svalue. */
1282 void
1283 sub_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
1285 if (simple)
1287 pp_string (pp, "SUB(");
1288 m_parent_svalue->dump_to_pp (pp, simple);
1289 pp_string (pp, ", ");
1290 m_subregion->dump_to_pp (pp, simple);
1291 pp_character (pp, ')');
1293 else
1295 pp_string (pp, "sub_svalue (");
1296 pp_string (pp, ", ");
1297 m_parent_svalue->dump_to_pp (pp, simple);
1298 pp_string (pp, ", ");
1299 m_subregion->dump_to_pp (pp, simple);
1300 pp_character (pp, ')');
1304 /* Implementation of svalue::accept vfunc for sub_svalue. */
1306 void
1307 sub_svalue::accept (visitor *v) const
1309 m_parent_svalue->accept (v);
1310 m_subregion->accept (v);
1311 v->visit_sub_svalue (this);
1314 /* Implementation of svalue::implicitly_live_p vfunc for sub_svalue. */
1316 bool
1317 sub_svalue::implicitly_live_p (const svalue_set *live_svalues,
1318 const region_model *model) const
1320 return get_parent ()->live_p (live_svalues, model);
1323 /* class repeated_svalue : public svalue. */
1325 /* repeated_svalue'c ctor. */
1327 repeated_svalue::repeated_svalue (symbol::id_t id,
1328 tree type,
1329 const svalue *outer_size,
1330 const svalue *inner_svalue)
1331 : svalue (complexity::from_pair (outer_size, inner_svalue), id, type),
1332 m_outer_size (outer_size),
1333 m_inner_svalue (inner_svalue)
1335 gcc_assert (outer_size->can_have_associated_state_p ());
1336 gcc_assert (inner_svalue->can_have_associated_state_p ());
1339 /* Implementation of svalue::dump_to_pp vfunc for repeated_svalue. */
1341 void
1342 repeated_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
1344 if (simple)
1346 pp_string (pp, "REPEATED(");
1347 if (get_type ())
1349 print_quoted_type (pp, get_type ());
1350 pp_string (pp, ", ");
1352 pp_string (pp, "outer_size: ");
1353 m_outer_size->dump_to_pp (pp, simple);
1354 pp_string (pp, ", inner_val: ");
1355 m_inner_svalue->dump_to_pp (pp, simple);
1356 pp_character (pp, ')');
1358 else
1360 pp_string (pp, "repeated_svalue (");
1361 if (get_type ())
1363 print_quoted_type (pp, get_type ());
1364 pp_string (pp, ", ");
1366 pp_string (pp, "outer_size: ");
1367 m_outer_size->dump_to_pp (pp, simple);
1368 pp_string (pp, ", inner_val: ");
1369 m_inner_svalue->dump_to_pp (pp, simple);
1370 pp_character (pp, ')');
1374 /* Implementation of svalue::accept vfunc for repeated_svalue. */
1376 void
1377 repeated_svalue::accept (visitor *v) const
1379 m_inner_svalue->accept (v);
1380 v->visit_repeated_svalue (this);
1383 /* Implementation of svalue::all_zeroes_p for repeated_svalue. */
1385 bool
1386 repeated_svalue::all_zeroes_p () const
1388 return m_inner_svalue->all_zeroes_p ();
1391 /* Implementation of svalue::maybe_fold_bits_within vfunc
1392 for repeated_svalue. */
1394 const svalue *
1395 repeated_svalue::maybe_fold_bits_within (tree type,
1396 const bit_range &bits,
1397 region_model_manager *mgr) const
1399 const svalue *innermost_sval = m_inner_svalue;
1400 /* Fold
1401 BITS_WITHIN (range, REPEATED_SVALUE (ZERO))
1403 REPEATED_SVALUE (ZERO). */
1404 if (all_zeroes_p ())
1406 byte_range bytes (0,0);
1407 if (bits.as_byte_range (&bytes))
1409 const svalue *byte_size
1410 = mgr->get_or_create_int_cst (size_type_node,
1411 bytes.m_size_in_bytes.to_uhwi ());
1412 return mgr->get_or_create_repeated_svalue (type, byte_size,
1413 innermost_sval);
1417 /* Fold:
1418 BITS_WITHIN (range, REPEATED_SVALUE (INNERMOST_SVALUE))
1420 BITS_WITHIN (range - offset, INNERMOST_SVALUE)
1421 if range is fully within one instance of INNERMOST_SVALUE. */
1422 if (tree innermost_type = innermost_sval->get_type ())
1424 bit_size_t element_bit_size;
1425 if (int_size_in_bits (innermost_type, &element_bit_size)
1426 && element_bit_size > 0)
1428 HOST_WIDE_INT start_idx
1429 = (bits.get_start_bit_offset ()
1430 / element_bit_size).to_shwi ();
1431 HOST_WIDE_INT last_idx
1432 = (bits.get_last_bit_offset ()
1433 / element_bit_size).to_shwi ();
1434 if (start_idx == last_idx)
1436 bit_offset_t start_of_element
1437 = start_idx * element_bit_size;
1438 bit_range range_within_element
1439 (bits.m_start_bit_offset - start_of_element,
1440 bits.m_size_in_bits);
1441 return mgr->get_or_create_bits_within (type,
1442 range_within_element,
1443 innermost_sval);
1448 return NULL;
1451 /* class bits_within_svalue : public svalue. */
1453 /* bits_within_svalue'c ctor. */
1455 bits_within_svalue::bits_within_svalue (symbol::id_t id,
1456 tree type,
1457 const bit_range &bits,
1458 const svalue *inner_svalue)
1459 : svalue (complexity (inner_svalue), id, type),
1460 m_bits (bits),
1461 m_inner_svalue (inner_svalue)
1463 gcc_assert (inner_svalue->can_have_associated_state_p ());
1466 /* Implementation of svalue::dump_to_pp vfunc for bits_within_svalue. */
1468 void
1469 bits_within_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
1471 if (simple)
1473 pp_string (pp, "BITS_WITHIN(");
1474 if (get_type ())
1476 print_quoted_type (pp, get_type ());
1477 pp_string (pp, ", ");
1479 m_bits.dump_to_pp (pp);
1480 pp_string (pp, ", inner_val: ");
1481 m_inner_svalue->dump_to_pp (pp, simple);
1482 pp_character (pp, ')');
1484 else
1486 pp_string (pp, "bits_within_svalue (");
1487 if (get_type ())
1489 print_quoted_type (pp, get_type ());
1490 pp_string (pp, ", ");
1492 m_bits.dump_to_pp (pp);
1493 pp_string (pp, ", inner_val: ");
1494 m_inner_svalue->dump_to_pp (pp, simple);
1495 pp_character (pp, ')');
1499 /* Implementation of svalue::maybe_fold_bits_within vfunc
1500 for bits_within_svalue. */
1502 const svalue *
1503 bits_within_svalue::maybe_fold_bits_within (tree type,
1504 const bit_range &bits,
1505 region_model_manager *mgr) const
1507 /* Fold:
1508 BITS_WITHIN (range1, BITS_WITHIN (range2, VAL))
1510 BITS_WITHIN (range1 in range 2, VAL). */
1511 bit_range offset_bits (m_bits.get_start_bit_offset ()
1512 + bits.m_start_bit_offset,
1513 bits.m_size_in_bits);
1514 return mgr->get_or_create_bits_within (type, offset_bits, m_inner_svalue);
1517 /* Implementation of svalue::accept vfunc for bits_within_svalue. */
1519 void
1520 bits_within_svalue::accept (visitor *v) const
1522 m_inner_svalue->accept (v);
1523 v->visit_bits_within_svalue (this);
1526 /* Implementation of svalue::implicitly_live_p vfunc for bits_within_svalue. */
1528 bool
1529 bits_within_svalue::implicitly_live_p (const svalue_set *live_svalues,
1530 const region_model *model) const
1532 return m_inner_svalue->live_p (live_svalues, model);
1535 /* class widening_svalue : public svalue. */
1537 /* Implementation of svalue::dump_to_pp vfunc for widening_svalue. */
1539 void
1540 widening_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
1542 if (simple)
1544 pp_string (pp, "WIDENING(");
1545 pp_character (pp, '{');
1546 m_point.print (pp, format (false));
1547 pp_string (pp, "}, ");
1548 m_base_sval->dump_to_pp (pp, simple);
1549 pp_string (pp, ", ");
1550 m_iter_sval->dump_to_pp (pp, simple);
1551 pp_character (pp, ')');
1553 else
1555 pp_string (pp, "widening_svalue (");
1556 pp_string (pp, ", ");
1557 pp_character (pp, '{');
1558 m_point.print (pp, format (false));
1559 pp_string (pp, "}, ");
1560 m_base_sval->dump_to_pp (pp, simple);
1561 pp_string (pp, ", ");
1562 m_iter_sval->dump_to_pp (pp, simple);
1563 pp_character (pp, ')');
1567 /* Implementation of svalue::accept vfunc for widening_svalue. */
1569 void
1570 widening_svalue::accept (visitor *v) const
1572 m_base_sval->accept (v);
1573 m_iter_sval->accept (v);
1574 v->visit_widening_svalue (this);
1577 /* Attempt to determine in which direction this value is changing
1578 w.r.t. the initial value. */
1580 enum widening_svalue::direction_t
1581 widening_svalue::get_direction () const
1583 tree base_cst = m_base_sval->maybe_get_constant ();
1584 if (base_cst == NULL_TREE)
1585 return DIR_UNKNOWN;
1586 tree iter_cst = m_iter_sval->maybe_get_constant ();
1587 if (iter_cst == NULL_TREE)
1588 return DIR_UNKNOWN;
1590 tree iter_gt_base = fold_binary (GT_EXPR, boolean_type_node,
1591 iter_cst, base_cst);
1592 if (iter_gt_base == boolean_true_node)
1593 return DIR_ASCENDING;
1595 tree iter_lt_base = fold_binary (LT_EXPR, boolean_type_node,
1596 iter_cst, base_cst);
1597 if (iter_lt_base == boolean_true_node)
1598 return DIR_DESCENDING;
1600 return DIR_UNKNOWN;
1603 /* Compare this value against constant RHS_CST. */
1605 tristate
1606 widening_svalue::eval_condition_without_cm (enum tree_code op,
1607 tree rhs_cst) const
1609 tree base_cst = m_base_sval->maybe_get_constant ();
1610 if (base_cst == NULL_TREE)
1611 return tristate::TS_UNKNOWN;
1612 tree iter_cst = m_iter_sval->maybe_get_constant ();
1613 if (iter_cst == NULL_TREE)
1614 return tristate::TS_UNKNOWN;
1616 switch (get_direction ())
1618 default:
1619 gcc_unreachable ();
1620 case DIR_ASCENDING:
1621 /* LHS is in [base_cst, +ve infinity), assuming no overflow. */
1622 switch (op)
1624 case LE_EXPR:
1625 case LT_EXPR:
1627 /* [BASE, +INF) OP RHS:
1628 This is either true or false at +ve ininity,
1629 It can be true for points X where X OP RHS, so we have either
1630 "false", or "unknown". */
1631 tree base_op_rhs = fold_binary (op, boolean_type_node,
1632 base_cst, rhs_cst);
1633 if (base_op_rhs == boolean_true_node)
1634 return tristate::TS_UNKNOWN;
1635 else
1636 return tristate::TS_FALSE;
1639 case GE_EXPR:
1640 case GT_EXPR:
1642 /* [BASE, +INF) OP RHS:
1643 This is true at +ve infinity. It will be true everywhere
1644 in the range if BASE >= RHS. */
1645 tree base_op_rhs = fold_binary (op, boolean_type_node,
1646 base_cst, rhs_cst);
1647 if (base_op_rhs == boolean_true_node)
1648 return tristate::TS_TRUE;
1649 else
1650 return tristate::TS_UNKNOWN;
1653 case EQ_EXPR:
1655 /* [BASE, +INF) == RHS:
1656 Could this be true at any point in the range? If so we
1657 have "unknown", otherwise we have "false". */
1658 tree base_le_rhs = fold_binary (LE_EXPR, boolean_type_node,
1659 base_cst, rhs_cst);
1660 if (base_le_rhs == boolean_true_node)
1661 return tristate::TS_UNKNOWN;
1662 else
1663 return tristate::TS_FALSE;
1666 case NE_EXPR:
1668 /* [BASE, +INF) != RHS:
1669 Could we have equality at any point in the range? If so we
1670 have "unknown", otherwise we have "true". */
1671 tree base_le_rhs = fold_binary (LE_EXPR, boolean_type_node,
1672 base_cst, rhs_cst);
1673 if (base_le_rhs == boolean_true_node)
1674 return tristate::TS_UNKNOWN;
1675 else
1676 return tristate::TS_TRUE;
1679 default:
1680 return tristate::TS_UNKNOWN;
1683 case DIR_DESCENDING:
1684 /* LHS is in (-ve infinity, base_cst], assuming no overflow. */
1685 return tristate::TS_UNKNOWN;
1687 case DIR_UNKNOWN:
1688 return tristate::TS_UNKNOWN;
1692 /* class placeholder_svalue : public svalue. */
1694 /* Implementation of svalue::dump_to_pp vfunc for placeholder_svalue. */
1696 void
1697 placeholder_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
1699 if (simple)
1700 pp_printf (pp, "PLACEHOLDER(%qs)", m_name);
1701 else
1702 pp_printf (pp, "placeholder_svalue (%qs)", m_name);
1705 /* Implementation of svalue::accept vfunc for placeholder_svalue. */
1707 void
1708 placeholder_svalue::accept (visitor *v) const
1710 v->visit_placeholder_svalue (this);
1713 /* class unmergeable_svalue : public svalue. */
1715 /* Implementation of svalue::dump_to_pp vfunc for unmergeable_svalue. */
1717 void
1718 unmergeable_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
1720 if (simple)
1722 pp_string (pp, "UNMERGEABLE(");
1723 m_arg->dump_to_pp (pp, simple);
1724 pp_character (pp, ')');
1726 else
1728 pp_string (pp, "unmergeable_svalue (");
1729 m_arg->dump_to_pp (pp, simple);
1730 pp_character (pp, ')');
1734 /* Implementation of svalue::accept vfunc for unmergeable_svalue. */
1736 void
1737 unmergeable_svalue::accept (visitor *v) const
1739 m_arg->accept (v);
1740 v->visit_unmergeable_svalue (this);
1743 /* Implementation of svalue::implicitly_live_p vfunc for unmergeable_svalue. */
1745 bool
1746 unmergeable_svalue::implicitly_live_p (const svalue_set *live_svalues,
1747 const region_model *model) const
1749 return get_arg ()->live_p (live_svalues, model);
1752 /* class compound_svalue : public svalue. */
1754 compound_svalue::compound_svalue (symbol::id_t id,
1755 tree type,
1756 const binding_map &map)
1757 : svalue (calc_complexity (map), id, type), m_map (map)
1759 #if CHECKING_P
1760 for (iterator_t iter = begin (); iter != end (); ++iter)
1762 /* All keys within the underlying binding_map are required to be concrete,
1763 not symbolic. */
1764 const binding_key *key = (*iter).first;
1765 gcc_assert (key->concrete_p ());
1767 /* We don't nest compound svalues. */
1768 const svalue *sval = (*iter).second;
1769 gcc_assert (sval->get_kind () != SK_COMPOUND);
1771 #endif
1774 /* Implementation of svalue::dump_to_pp vfunc for compound_svalue. */
1776 void
1777 compound_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
1779 if (simple)
1781 pp_string (pp, "COMPOUND(");
1782 if (get_type ())
1784 print_quoted_type (pp, get_type ());
1785 pp_string (pp, ", ");
1787 pp_character (pp, '{');
1788 m_map.dump_to_pp (pp, simple, false);
1789 pp_string (pp, "})");
1791 else
1793 pp_string (pp, "compound_svalue (");
1794 if (get_type ())
1796 print_quoted_type (pp, get_type ());
1797 pp_string (pp, ", ");
1799 pp_character (pp, '{');
1800 m_map.dump_to_pp (pp, simple, false);
1801 pp_string (pp, "})");
1805 /* Implementation of svalue::accept vfunc for compound_svalue. */
1807 void
1808 compound_svalue::accept (visitor *v) const
1810 for (binding_map::iterator_t iter = m_map.begin ();
1811 iter != m_map.end (); ++iter)
1813 //(*iter).first.accept (v);
1814 (*iter).second->accept (v);
1816 v->visit_compound_svalue (this);
1819 /* Calculate what the complexity of a compound_svalue instance for MAP
1820 will be, based on the svalues bound within MAP. */
1822 complexity
1823 compound_svalue::calc_complexity (const binding_map &map)
1825 unsigned num_child_nodes = 0;
1826 unsigned max_child_depth = 0;
1827 for (binding_map::iterator_t iter = map.begin ();
1828 iter != map.end (); ++iter)
1830 const complexity &sval_c = (*iter).second->get_complexity ();
1831 num_child_nodes += sval_c.m_num_nodes;
1832 max_child_depth = MAX (max_child_depth, sval_c.m_max_depth);
1834 return complexity (num_child_nodes + 1, max_child_depth + 1);
1837 /* Implementation of svalue::maybe_fold_bits_within vfunc
1838 for compound_svalue. */
1840 const svalue *
1841 compound_svalue::maybe_fold_bits_within (tree type,
1842 const bit_range &bits,
1843 region_model_manager *mgr) const
1845 binding_map result_map;
1846 for (auto iter : m_map)
1848 const binding_key *key = iter.first;
1849 if (const concrete_binding *conc_key
1850 = key->dyn_cast_concrete_binding ())
1852 /* Ignore concrete bindings outside BITS. */
1853 if (!conc_key->get_bit_range ().intersects_p (bits))
1854 continue;
1856 const svalue *sval = iter.second;
1857 /* Get the position of conc_key relative to BITS. */
1858 bit_range result_location (conc_key->get_start_bit_offset ()
1859 - bits.get_start_bit_offset (),
1860 conc_key->get_size_in_bits ());
1861 /* If conc_key starts after BITS, trim off leading bits
1862 from the svalue and adjust binding location. */
1863 if (result_location.m_start_bit_offset < 0)
1865 bit_size_t leading_bits_to_drop
1866 = -result_location.m_start_bit_offset;
1867 result_location = bit_range
1868 (0, result_location.m_size_in_bits - leading_bits_to_drop);
1869 bit_range bits_within_sval (leading_bits_to_drop,
1870 result_location.m_size_in_bits);
1871 /* Trim off leading bits from iter_sval. */
1872 sval = mgr->get_or_create_bits_within (NULL_TREE,
1873 bits_within_sval,
1874 sval);
1876 /* If conc_key finishes after BITS, trim off trailing bits
1877 from the svalue and adjust binding location. */
1878 if (conc_key->get_next_bit_offset ()
1879 > bits.get_next_bit_offset ())
1881 bit_size_t trailing_bits_to_drop
1882 = (conc_key->get_next_bit_offset ()
1883 - bits.get_next_bit_offset ());
1884 result_location = bit_range
1885 (result_location.m_start_bit_offset,
1886 result_location.m_size_in_bits - trailing_bits_to_drop);
1887 bit_range bits_within_sval (0,
1888 result_location.m_size_in_bits);
1889 /* Trim off leading bits from iter_sval. */
1890 sval = mgr->get_or_create_bits_within (NULL_TREE,
1891 bits_within_sval,
1892 sval);
1894 const concrete_binding *offset_conc_key
1895 = mgr->get_store_manager ()->get_concrete_binding
1896 (result_location);
1897 result_map.put (offset_conc_key, sval);
1899 else
1900 /* If we have any symbolic keys we can't get it as bits. */
1901 return NULL;
1903 return mgr->get_or_create_compound_svalue (type, result_map);
1906 /* class conjured_svalue : public svalue. */
1908 /* Implementation of svalue::dump_to_pp vfunc for conjured_svalue. */
1910 void
1911 conjured_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
1913 if (simple)
1915 pp_string (pp, "CONJURED(");
1916 pp_gimple_stmt_1 (pp, m_stmt, 0, (dump_flags_t)0);
1917 pp_string (pp, ", ");
1918 m_id_reg->dump_to_pp (pp, simple);
1919 pp_character (pp, ')');
1921 else
1923 pp_string (pp, "conjured_svalue (");
1924 if (get_type ())
1926 print_quoted_type (pp, get_type ());
1927 pp_string (pp, ", ");
1929 pp_gimple_stmt_1 (pp, m_stmt, 0, (dump_flags_t)0);
1930 pp_string (pp, ", ");
1931 m_id_reg->dump_to_pp (pp, simple);
1932 pp_character (pp, ')');
1936 /* Implementation of svalue::accept vfunc for conjured_svalue. */
1938 void
1939 conjured_svalue::accept (visitor *v) const
1941 m_id_reg->accept (v);
1942 v->visit_conjured_svalue (this);
1945 /* Return true iff this conjured_svalue is for the LHS of the
1946 stmt that conjured it. */
1948 bool
1949 conjured_svalue::lhs_value_p () const
1951 if (tree decl = m_id_reg->maybe_get_decl ())
1952 return decl == gimple_get_lhs (m_stmt);
1953 return false;
1956 /* class asm_output_svalue : public svalue. */
1958 /* Implementation of svalue::dump_to_pp vfunc for asm_output_svalue. */
1960 void
1961 asm_output_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
1963 if (simple)
1965 pp_printf (pp, "ASM_OUTPUT(%qs, %%%i, {",
1966 get_asm_string (),
1967 get_output_idx ());
1968 for (unsigned i = 0; i < m_num_inputs; i++)
1970 if (i > 0)
1971 pp_string (pp, ", ");
1972 dump_input (pp, 0, m_input_arr[i], simple);
1974 pp_string (pp, "})");
1976 else
1978 pp_printf (pp, "asm_output_svalue (%qs, %%%i, {",
1979 get_asm_string (),
1980 get_output_idx ());
1981 for (unsigned i = 0; i < m_num_inputs; i++)
1983 if (i > 0)
1984 pp_string (pp, ", ");
1985 dump_input (pp, 0, m_input_arr[i], simple);
1987 pp_string (pp, "})");
1991 /* Subroutine of asm_output_svalue::dump_to_pp. */
1993 void
1994 asm_output_svalue::dump_input (pretty_printer *pp,
1995 unsigned input_idx,
1996 const svalue *sval,
1997 bool simple) const
1999 pp_printf (pp, "%%%i: ", input_idx_to_asm_idx (input_idx));
2000 sval->dump_to_pp (pp, simple);
2003 /* Convert INPUT_IDX from an index into the array of inputs
2004 into the index of all operands for the asm stmt. */
2006 unsigned
2007 asm_output_svalue::input_idx_to_asm_idx (unsigned input_idx) const
2009 return input_idx + m_num_outputs;
2012 /* Implementation of svalue::accept vfunc for asm_output_svalue. */
2014 void
2015 asm_output_svalue::accept (visitor *v) const
2017 for (unsigned i = 0; i < m_num_inputs; i++)
2018 m_input_arr[i]->accept (v);
2019 v->visit_asm_output_svalue (this);
2022 /* class const_fn_result_svalue : public svalue. */
2024 /* Implementation of svalue::dump_to_pp vfunc for const_fn_result_svalue. */
2026 void
2027 const_fn_result_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
2029 if (simple)
2031 pp_printf (pp, "CONST_FN_RESULT(%qD, {", m_fndecl);
2032 for (unsigned i = 0; i < m_num_inputs; i++)
2034 if (i > 0)
2035 pp_string (pp, ", ");
2036 dump_input (pp, i, m_input_arr[i], simple);
2038 pp_string (pp, "})");
2040 else
2042 pp_printf (pp, "CONST_FN_RESULT(%qD, {", m_fndecl);
2043 for (unsigned i = 0; i < m_num_inputs; i++)
2045 if (i > 0)
2046 pp_string (pp, ", ");
2047 dump_input (pp, i, m_input_arr[i], simple);
2049 pp_string (pp, "})");
2053 /* Subroutine of const_fn_result_svalue::dump_to_pp. */
2055 void
2056 const_fn_result_svalue::dump_input (pretty_printer *pp,
2057 unsigned input_idx,
2058 const svalue *sval,
2059 bool simple) const
2061 pp_printf (pp, "arg%i: ", input_idx);
2062 sval->dump_to_pp (pp, simple);
2065 /* Implementation of svalue::accept vfunc for const_fn_result_svalue. */
2067 void
2068 const_fn_result_svalue::accept (visitor *v) const
2070 for (unsigned i = 0; i < m_num_inputs; i++)
2071 m_input_arr[i]->accept (v);
2072 v->visit_const_fn_result_svalue (this);
2075 } // namespace ana
2077 #endif /* #if ENABLE_ANALYZER */