i386: Fix up spaceship expanders for -mtune=i[45]86 [PR117053]
[official-gcc.git] / gcc / analyzer / svalue.cc
blob663119613fb525e183c338f7a32717903f34c795
1 /* Symbolic values.
2 Copyright (C) 2019-2024 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 #define INCLUDE_VECTOR
24 #include "system.h"
25 #include "coretypes.h"
26 #include "tree.h"
27 #include "diagnostic-core.h"
28 #include "gimple-pretty-print.h"
29 #include "function.h"
30 #include "basic-block.h"
31 #include "gimple.h"
32 #include "gimple-iterator.h"
33 #include "diagnostic-core.h"
34 #include "graphviz.h"
35 #include "options.h"
36 #include "cgraph.h"
37 #include "tree-dfa.h"
38 #include "stringpool.h"
39 #include "convert.h"
40 #include "target.h"
41 #include "fold-const.h"
42 #include "tree-pretty-print.h"
43 #include "bitmap.h"
44 #include "analyzer/analyzer.h"
45 #include "analyzer/analyzer-logging.h"
46 #include "analyzer/call-string.h"
47 #include "analyzer/program-point.h"
48 #include "analyzer/store.h"
49 #include "analyzer/svalue.h"
50 #include "analyzer/region-model.h"
51 #include "diagnostic.h"
52 #include "tree-diagnostic.h"
53 #include "make-unique.h"
54 #include "text-art/dump.h"
56 #if ENABLE_ANALYZER
58 namespace ana {
60 static int cmp_csts_and_types (const_tree cst1, const_tree cst2);
62 /* class svalue and its various subclasses. */
64 /* class svalue. */
66 /* Dump a tree-like representation of this svalue and its constituent symbols
67 to stderr, using global_dc's colorization and theming options.
69 For example:
70 . (gdb) call index_sval->dump()
71 . (27): ‘int’: initial_svalue
72 . ╰─ m_reg: (26): ‘int’: decl_region(‘x_10(D)’)
73 . ╰─ parent: (9): frame_region(‘test_bitmask_2’, index: 0, depth: 1)
74 . ╰─ parent: (1): stack region
75 . ╰─ parent: (0): root region
78 DEBUG_FUNCTION void
79 svalue::dump () const
81 text_art::dump (*this);
84 /* Dump a representation of this svalue to stderr. */
86 DEBUG_FUNCTION void
87 svalue::dump (bool simple) const
89 tree_dump_pretty_printer pp (stderr);
90 dump_to_pp (&pp, simple);
91 pp_newline (&pp);
94 /* Generate a textual representation of this svalue for debugging purposes. */
96 label_text
97 svalue::get_desc (bool simple) const
99 pretty_printer pp;
100 pp_format_decoder (&pp) = default_tree_printer;
101 dump_to_pp (&pp, simple);
102 return label_text::take (xstrdup (pp_formatted_text (&pp)));
105 /* Return a new json::string describing the svalue. */
107 json::value *
108 svalue::to_json () const
110 label_text desc = get_desc (true);
111 json::value *sval_js = new json::string (desc.get ());
112 return sval_js;
115 /* Class for optionally adding open/close paren pairs within
116 svalue::maybe_print_for_user. */
118 class auto_add_parens
120 public:
121 auto_add_parens (pretty_printer *pp,
122 const svalue *outer_sval,
123 const svalue &inner_sval)
124 : m_pp (pp),
125 m_needs_parens (needs_parens_p (outer_sval, inner_sval))
127 if (m_needs_parens)
128 pp_string (m_pp, "(");
130 ~auto_add_parens ()
132 if (m_needs_parens)
133 pp_string (m_pp, ")");
136 private:
137 static bool needs_parens_p (const svalue *outer_sval,
138 const svalue &inner_sval)
140 if (!outer_sval)
141 return false;
142 if (inner_sval.get_kind () == SK_BINOP)
143 return true;
144 return false;
147 pretty_printer *m_pp;
148 bool m_needs_parens;
151 /* Attempt to print a user-facing description of this svalue to PP,
152 using MODEL for extracting representative tree values if necessary.
153 Use OUTER_SVAL (which can be null) to determine if we need to wrap
154 this value in parentheses. */
156 bool
157 svalue::maybe_print_for_user (pretty_printer *pp,
158 const region_model &model,
159 const svalue *outer_sval) const
161 auto_add_parens p (pp, outer_sval, *this);
163 switch (get_kind ())
165 default:
166 break;
167 case SK_CONSTANT:
169 const constant_svalue *sval = (const constant_svalue *)this;
170 pp_printf (pp, "%E", sval->get_constant ());
171 return true;
173 case SK_INITIAL:
175 const initial_svalue *sval = (const initial_svalue *)this;
176 return sval->get_region ()->maybe_print_for_user (pp, model);
178 case SK_UNARYOP:
180 const unaryop_svalue *sval = (const unaryop_svalue *)this;
181 if (sval->get_op () == NOP_EXPR)
183 if (!sval->get_arg ()->maybe_print_for_user (pp, model, outer_sval))
184 return false;
185 return true;
188 break;
189 case SK_BINOP:
191 const binop_svalue *sval = (const binop_svalue *)this;
192 switch (sval->get_op ())
194 default:
195 break;
197 case PLUS_EXPR:
198 case MINUS_EXPR:
199 case MULT_EXPR:
201 if (!sval->get_arg0 ()->maybe_print_for_user (pp, model, this))
202 return false;
203 pp_printf (pp, " %s ", op_symbol_code (sval->get_op ()));
204 if (!sval->get_arg1 ()->maybe_print_for_user (pp, model, this))
205 return false;
206 return true;
210 break;
213 if (tree expr = model.get_representative_tree (this))
215 expr = remove_ssa_names (expr);
216 print_expr_for_user (pp, expr);
217 return true;
220 return false;
223 /* Use DWI to create a text_art::widget describing this svalue in
224 a tree-like form, using PREFIX as a prefix (e.g. for field names).
225 We do this via two vfuncs:
226 (a) print_dump_widget_label, to populate the text of a tree_widget, and
227 (b) add_dump_widget_children, to add children to the tree_widget. */
229 std::unique_ptr<text_art::tree_widget>
230 svalue::make_dump_widget (const text_art::dump_widget_info &dwi,
231 const char *prefix) const
233 pretty_printer pp;
234 pp_format_decoder (&pp) = default_tree_printer;
235 pp_show_color (&pp) = true;
237 if (prefix)
238 pp_printf (&pp, "%s: ", prefix);
240 pp_printf (&pp, "(%i): ", get_id ());
241 if (get_type ())
242 pp_printf (&pp, "%qT: ", get_type ());
244 print_dump_widget_label (&pp);
246 std::unique_ptr<text_art::tree_widget> w
247 (text_art::tree_widget::make (dwi, &pp));
249 add_dump_widget_children (*w, dwi);
251 return w;
254 /* If this svalue is a constant_svalue, return the underlying tree constant.
255 Otherwise return NULL_TREE. */
257 tree
258 svalue::maybe_get_constant () const
260 const svalue *sval = unwrap_any_unmergeable ();
261 if (const constant_svalue *cst_sval = sval->dyn_cast_constant_svalue ())
262 return cst_sval->get_constant ();
263 else
264 return NULL_TREE;
267 /* If this svalue is a region_svalue, return the region it points to.
268 Otherwise return NULL. */
270 const region *
271 svalue::maybe_get_region () const
273 if (const region_svalue *region_sval = dyn_cast_region_svalue ())
274 return region_sval->get_pointee ();
275 else
276 return NULL;
279 /* If this svalue is a cast (i.e a unaryop NOP_EXPR or VIEW_CONVERT_EXPR),
280 return the underlying svalue.
281 Otherwise return NULL. */
283 const svalue *
284 svalue::maybe_undo_cast () const
286 if (const unaryop_svalue *unaryop_sval = dyn_cast_unaryop_svalue ())
288 enum tree_code op = unaryop_sval->get_op ();
289 if (op == NOP_EXPR || op == VIEW_CONVERT_EXPR)
290 return unaryop_sval->get_arg ();
292 return NULL;
295 /* If this svalue is an unmergeable decorator around another svalue, return
296 the underlying svalue.
297 Otherwise return this svalue. */
299 const svalue *
300 svalue::unwrap_any_unmergeable () const
302 if (const unmergeable_svalue *unmergeable = dyn_cast_unmergeable_svalue ())
303 return unmergeable->get_arg ();
304 return this;
307 /* Attempt to merge THIS with OTHER, returning the merged svalue.
308 Return NULL if not mergeable. */
310 const svalue *
311 svalue::can_merge_p (const svalue *other,
312 region_model_manager *mgr,
313 model_merger *merger) const
315 if (!(get_type () && other->get_type ()))
316 return NULL;
318 if (!types_compatible_p (get_type (), other->get_type ()))
319 return NULL;
321 /* Reject attempts to merge unmergeable svalues. */
322 if ((get_kind () == SK_UNMERGEABLE)
323 || (other->get_kind () == SK_UNMERGEABLE))
324 return NULL;
326 /* Reject attempts to merge poisoned svalues with other svalues
327 (either non-poisoned, or other kinds of poison), so that e.g.
328 we identify paths in which a variable is conditionally uninitialized. */
329 if (get_kind () == SK_POISONED
330 || other->get_kind () == SK_POISONED)
331 return NULL;
333 /* Reject attempts to merge NULL pointers with not-NULL-pointers. */
334 if (POINTER_TYPE_P (get_type ()))
336 bool null0 = false;
337 bool null1 = false;
338 if (tree cst0 = maybe_get_constant ())
339 if (zerop (cst0))
340 null0 = true;
341 if (tree cst1 = other->maybe_get_constant ())
342 if (zerop (cst1))
343 null1 = true;
344 if (null0 != null1)
345 return NULL;
348 /* Reject merging svalues that have non-purgable sm-state,
349 to avoid falsely reporting memory leaks by merging them
350 with something else. */
351 if (!merger->mergeable_svalue_p (this))
352 return NULL;
353 if (!merger->mergeable_svalue_p (other))
354 return NULL;
356 /* Widening. */
357 /* Merge: (new_cst, existing_cst) -> widen (existing, new). */
358 if (maybe_get_constant () && other->maybe_get_constant ())
360 return mgr->get_or_create_widening_svalue (other->get_type (),
361 merger->get_function_point (),
362 other, this);
365 /* Merger of:
366 this: BINOP (X, OP, CST)
367 other: X, where X is non-widening
368 to: WIDENING (other, this). */
369 if (const binop_svalue *binop_sval = dyn_cast_binop_svalue ())
370 if (binop_sval->get_arg0 () == other
371 && binop_sval->get_arg1 ()->get_kind () == SK_CONSTANT
372 && other->get_kind () != SK_WIDENING)
373 return mgr->get_or_create_widening_svalue (other->get_type (),
374 merger->get_function_point (),
375 other, this);
377 /* Merge: (Widen(existing_val, V), existing_val) -> Widen (existing_val, V)
378 and thus get a fixed point. */
379 if (const widening_svalue *widen_sval = dyn_cast_widening_svalue ())
381 if (other == widen_sval->get_base_svalue ())
382 return this;
383 if (other == widen_sval->get_iter_svalue ())
384 return this;
387 if (const binop_svalue *binop_sval = dyn_cast_binop_svalue ())
388 if (const widening_svalue *widen_arg0
389 = binop_sval->get_arg0 ()->dyn_cast_widening_svalue ())
391 if (other == binop_sval->get_arg1 ())
393 /* Merger of: (Widen(..., OTHER) BINOP X)
394 and : OTHER
395 to : (Widen(..., OTHER) BINOP X)
396 e.g. merge of Widen(0, 1) + 1 with 1 to the Widen(0, 1) + 1. */
397 return this;
400 /* Merger of : (Widen() BINOP X)
401 and : Widen()
402 to : Widen()
403 e.g. merge of Widen(0, 1) + 1 and Widen(0, 1) to Widen(0, 1).
404 However, we want to update constraints for this case, since we're
405 considering another iteration.
406 Presumably we also want to ensure that it converges; we don't want
407 a descending chain of constraints. */
408 if (other == widen_arg0)
410 merger->on_widening_reuse (widen_arg0);
411 return widen_arg0;
414 /* Merger of:
415 this: BINOP(WIDENING(BASE, BINOP(BASE, X)), X)
416 other: BINOP(BASE, X)
417 to: WIDENING(BASE, BINOP(BASE, X)). */
418 if (widen_arg0->get_iter_svalue () == other)
419 if (const binop_svalue *other_binop_sval
420 = other->dyn_cast_binop_svalue ())
421 if (other_binop_sval->get_arg0 () == widen_arg0->get_base_svalue ()
422 && other_binop_sval->get_arg1 () == binop_sval->get_arg1 ())
423 return widen_arg0;
426 return mgr->get_or_create_unknown_svalue (get_type ());
429 /* Determine if this svalue is either within LIVE_SVALUES, or is implicitly
430 live with respect to LIVE_SVALUES and MODEL.
431 LIVE_SVALUES can be NULL, in which case determine if this svalue is
432 intrinsically live. */
434 bool
435 svalue::live_p (const svalue_set *live_svalues,
436 const region_model *model) const
438 /* Determine if SVAL is explicitly live. */
439 if (live_svalues)
440 if (const_cast<svalue_set *> (live_svalues)->contains (this))
441 return true;
443 /* Otherwise, determine if SVAL is implicitly live due to being made of
444 other live svalues. */
445 return implicitly_live_p (live_svalues, model);
448 /* Base implementation of svalue::implicitly_live_p. */
450 bool
451 svalue::implicitly_live_p (const svalue_set *, const region_model *) const
453 return false;
456 /* Comparator for imposing a deterministic order on constants that are
457 of the same type. */
459 static int
460 cmp_csts_same_type (const_tree cst1, const_tree cst2)
462 gcc_assert (TREE_TYPE (cst1) == TREE_TYPE (cst2));
463 gcc_assert (TREE_CODE (cst1) == TREE_CODE (cst2));
464 switch (TREE_CODE (cst1))
466 default:
467 gcc_unreachable ();
468 case INTEGER_CST:
469 return tree_int_cst_compare (cst1, cst2);
470 case STRING_CST:
471 return strcmp (TREE_STRING_POINTER (cst1),
472 TREE_STRING_POINTER (cst2));
473 case REAL_CST:
474 /* Impose an arbitrary but deterministic order. */
475 return memcmp (TREE_REAL_CST_PTR (cst1),
476 TREE_REAL_CST_PTR (cst2),
477 sizeof (real_value));
478 case COMPLEX_CST:
479 if (int cmp_real = cmp_csts_and_types (TREE_REALPART (cst1),
480 TREE_REALPART (cst2)))
481 return cmp_real;
482 return cmp_csts_and_types (TREE_IMAGPART (cst1), TREE_IMAGPART (cst2));
483 case VECTOR_CST:
484 if (int cmp_log2_npatterns
485 = ((int)VECTOR_CST_LOG2_NPATTERNS (cst1)
486 - (int)VECTOR_CST_LOG2_NPATTERNS (cst2)))
487 return cmp_log2_npatterns;
488 if (int cmp_nelts_per_pattern
489 = ((int)VECTOR_CST_NELTS_PER_PATTERN (cst1)
490 - (int)VECTOR_CST_NELTS_PER_PATTERN (cst2)))
491 return cmp_nelts_per_pattern;
492 unsigned encoded_nelts = vector_cst_encoded_nelts (cst1);
493 for (unsigned i = 0; i < encoded_nelts; i++)
495 const_tree elt1 = VECTOR_CST_ENCODED_ELT (cst1, i);
496 const_tree elt2 = VECTOR_CST_ENCODED_ELT (cst2, i);
497 if (int el_cmp = cmp_csts_and_types (elt1, elt2))
498 return el_cmp;
500 return 0;
504 /* Comparator for imposing a deterministic order on constants that might
505 not be of the same type. */
507 static int
508 cmp_csts_and_types (const_tree cst1, const_tree cst2)
510 int t1 = TYPE_UID (TREE_TYPE (cst1));
511 int t2 = TYPE_UID (TREE_TYPE (cst2));
512 if (int cmp_type = t1 - t2)
513 return cmp_type;
514 return cmp_csts_same_type (cst1, cst2);
517 /* Comparator for imposing a deterministic order on svalues. */
520 svalue::cmp_ptr (const svalue *sval1, const svalue *sval2)
522 if (sval1 == sval2)
523 return 0;
524 if (int cmp_kind = sval1->get_kind () - sval2->get_kind ())
525 return cmp_kind;
526 int t1 = sval1->get_type () ? TYPE_UID (sval1->get_type ()) : -1;
527 int t2 = sval2->get_type () ? TYPE_UID (sval2->get_type ()) : -1;
528 if (int cmp_type = t1 - t2)
529 return cmp_type;
530 switch (sval1->get_kind ())
532 default:
533 gcc_unreachable ();
534 case SK_REGION:
536 const region_svalue *region_sval1 = (const region_svalue *)sval1;
537 const region_svalue *region_sval2 = (const region_svalue *)sval2;
538 return region::cmp_ids (region_sval1->get_pointee (),
539 region_sval2->get_pointee ());
541 break;
542 case SK_CONSTANT:
544 const constant_svalue *constant_sval1 = (const constant_svalue *)sval1;
545 const constant_svalue *constant_sval2 = (const constant_svalue *)sval2;
546 const_tree cst1 = constant_sval1->get_constant ();
547 const_tree cst2 = constant_sval2->get_constant ();
548 /* The svalues have the same type, but the underlying trees
549 might not (for the case where both svalues are typeless). */
550 return cmp_csts_and_types (cst1, cst2);
552 break;
553 case SK_UNKNOWN:
555 gcc_assert (sval1 == sval2);
556 return 0;
558 break;
559 case SK_POISONED:
561 const poisoned_svalue *poisoned_sval1 = (const poisoned_svalue *)sval1;
562 const poisoned_svalue *poisoned_sval2 = (const poisoned_svalue *)sval2;
563 return (poisoned_sval1->get_poison_kind ()
564 - poisoned_sval2->get_poison_kind ());
566 break;
567 case SK_SETJMP:
569 const setjmp_svalue *setjmp_sval1 = (const setjmp_svalue *)sval1;
570 const setjmp_svalue *setjmp_sval2 = (const setjmp_svalue *)sval2;
571 const setjmp_record &rec1 = setjmp_sval1->get_setjmp_record ();
572 const setjmp_record &rec2 = setjmp_sval2->get_setjmp_record ();
573 return setjmp_record::cmp (rec1, rec2);
575 break;
576 case SK_INITIAL:
578 const initial_svalue *initial_sval1 = (const initial_svalue *)sval1;
579 const initial_svalue *initial_sval2 = (const initial_svalue *)sval2;
580 return region::cmp_ids (initial_sval1->get_region (),
581 initial_sval2->get_region ());
583 break;
584 case SK_UNARYOP:
586 const unaryop_svalue *unaryop_sval1 = (const unaryop_svalue *)sval1;
587 const unaryop_svalue *unaryop_sval2 = (const unaryop_svalue *)sval2;
588 if (int op_cmp = unaryop_sval1->get_op () - unaryop_sval2->get_op ())
589 return op_cmp;
590 return svalue::cmp_ptr (unaryop_sval1->get_arg (),
591 unaryop_sval2->get_arg ());
593 break;
594 case SK_BINOP:
596 const binop_svalue *binop_sval1 = (const binop_svalue *)sval1;
597 const binop_svalue *binop_sval2 = (const binop_svalue *)sval2;
598 if (int op_cmp = binop_sval1->get_op () - binop_sval2->get_op ())
599 return op_cmp;
600 if (int arg0_cmp = svalue::cmp_ptr (binop_sval1->get_arg0 (),
601 binop_sval2->get_arg0 ()))
602 return arg0_cmp;
603 return svalue::cmp_ptr (binop_sval1->get_arg1 (),
604 binop_sval2->get_arg1 ());
606 break;
607 case SK_SUB:
609 const sub_svalue *sub_sval1 = (const sub_svalue *)sval1;
610 const sub_svalue *sub_sval2 = (const sub_svalue *)sval2;
611 if (int parent_cmp = svalue::cmp_ptr (sub_sval1->get_parent (),
612 sub_sval2->get_parent ()))
613 return parent_cmp;
614 return region::cmp_ids (sub_sval1->get_subregion (),
615 sub_sval2->get_subregion ());
617 break;
618 case SK_REPEATED:
620 const repeated_svalue *repeated_sval1 = (const repeated_svalue *)sval1;
621 const repeated_svalue *repeated_sval2 = (const repeated_svalue *)sval2;
622 return svalue::cmp_ptr (repeated_sval1->get_inner_svalue (),
623 repeated_sval2->get_inner_svalue ());
625 break;
626 case SK_BITS_WITHIN:
628 const bits_within_svalue *bits_within_sval1
629 = (const bits_within_svalue *)sval1;
630 const bits_within_svalue *bits_within_sval2
631 = (const bits_within_svalue *)sval2;
632 if (int cmp = bit_range::cmp (bits_within_sval1->get_bits (),
633 bits_within_sval2->get_bits ()))
634 return cmp;
635 return svalue::cmp_ptr (bits_within_sval1->get_inner_svalue (),
636 bits_within_sval2->get_inner_svalue ());
638 break;
639 case SK_UNMERGEABLE:
641 const unmergeable_svalue *unmergeable_sval1
642 = (const unmergeable_svalue *)sval1;
643 const unmergeable_svalue *unmergeable_sval2
644 = (const unmergeable_svalue *)sval2;
645 return svalue::cmp_ptr (unmergeable_sval1->get_arg (),
646 unmergeable_sval2->get_arg ());
648 break;
649 case SK_PLACEHOLDER:
651 const placeholder_svalue *placeholder_sval1
652 = (const placeholder_svalue *)sval1;
653 const placeholder_svalue *placeholder_sval2
654 = (const placeholder_svalue *)sval2;
655 return strcmp (placeholder_sval1->get_name (),
656 placeholder_sval2->get_name ());
658 break;
659 case SK_WIDENING:
661 const widening_svalue *widening_sval1 = (const widening_svalue *)sval1;
662 const widening_svalue *widening_sval2 = (const widening_svalue *)sval2;
663 if (int point_cmp = function_point::cmp (widening_sval1->get_point (),
664 widening_sval2->get_point ()))
665 return point_cmp;
666 if (int base_cmp = svalue::cmp_ptr (widening_sval1->get_base_svalue (),
667 widening_sval2->get_base_svalue ()))
668 return base_cmp;
669 return svalue::cmp_ptr (widening_sval1->get_iter_svalue (),
670 widening_sval2->get_iter_svalue ());
672 break;
673 case SK_COMPOUND:
675 const compound_svalue *compound_sval1 = (const compound_svalue *)sval1;
676 const compound_svalue *compound_sval2 = (const compound_svalue *)sval2;
677 return binding_map::cmp (compound_sval1->get_map (),
678 compound_sval2->get_map ());
680 break;
681 case SK_CONJURED:
683 const conjured_svalue *conjured_sval1 = (const conjured_svalue *)sval1;
684 const conjured_svalue *conjured_sval2 = (const conjured_svalue *)sval2;
685 if (int stmt_cmp = (conjured_sval1->get_stmt ()->uid
686 - conjured_sval2->get_stmt ()->uid))
687 return stmt_cmp;
688 return region::cmp_ids (conjured_sval1->get_id_region (),
689 conjured_sval2->get_id_region ());
691 break;
692 case SK_ASM_OUTPUT:
694 const asm_output_svalue *asm_output_sval1
695 = (const asm_output_svalue *)sval1;
696 const asm_output_svalue *asm_output_sval2
697 = (const asm_output_svalue *)sval2;
698 if (int asm_string_cmp = strcmp (asm_output_sval1->get_asm_string (),
699 asm_output_sval2->get_asm_string ()))
700 return asm_string_cmp;
701 if (int output_idx_cmp = ((int)asm_output_sval1->get_output_idx ()
702 - (int)asm_output_sval2->get_output_idx ()))
703 return output_idx_cmp;
704 if (int cmp = ((int)asm_output_sval1->get_num_inputs ()
705 - (int)asm_output_sval2->get_num_inputs ()))
706 return cmp;
707 for (unsigned i = 0; i < asm_output_sval1->get_num_inputs (); i++)
708 if (int input_cmp
709 = svalue::cmp_ptr (asm_output_sval1->get_input (i),
710 asm_output_sval2->get_input (i)))
711 return input_cmp;
712 return 0;
714 break;
715 case SK_CONST_FN_RESULT:
717 const const_fn_result_svalue *const_fn_result_sval1
718 = (const const_fn_result_svalue *)sval1;
719 const const_fn_result_svalue *const_fn_result_sval2
720 = (const const_fn_result_svalue *)sval2;
721 int d1 = DECL_UID (const_fn_result_sval1->get_fndecl ());
722 int d2 = DECL_UID (const_fn_result_sval2->get_fndecl ());
723 if (int cmp_fndecl = d1 - d2)
724 return cmp_fndecl;
725 if (int cmp = ((int)const_fn_result_sval1->get_num_inputs ()
726 - (int)const_fn_result_sval2->get_num_inputs ()))
727 return cmp;
728 for (unsigned i = 0; i < const_fn_result_sval1->get_num_inputs (); i++)
729 if (int input_cmp
730 = svalue::cmp_ptr (const_fn_result_sval1->get_input (i),
731 const_fn_result_sval2->get_input (i)))
732 return input_cmp;
733 return 0;
738 /* Comparator for use by vec<const svalue *>::qsort. */
741 svalue::cmp_ptr_ptr (const void *p1, const void *p2)
743 const svalue *sval1 = *(const svalue * const *)p1;
744 const svalue *sval2 = *(const svalue * const *)p2;
745 return cmp_ptr (sval1, sval2);
748 /* Subclass of visitor for use in implementing svalue::involves_p. */
750 class involvement_visitor : public visitor
752 public:
753 involvement_visitor (const svalue *needle)
754 : m_needle (needle), m_found (false) {}
756 void visit_initial_svalue (const initial_svalue *candidate) final override
758 if (candidate == m_needle)
759 m_found = true;
762 void visit_conjured_svalue (const conjured_svalue *candidate) final override
764 if (candidate == m_needle)
765 m_found = true;
768 void visit_widening_svalue (const widening_svalue *candidate) final override
770 if (candidate == m_needle)
771 m_found = true;
774 bool found_p () const { return m_found; }
776 private:
777 const svalue *m_needle;
778 bool m_found;
781 /* Return true iff this svalue is defined in terms of OTHER. */
783 bool
784 svalue::involves_p (const svalue *other) const
786 /* Currently only implemented for these kinds. */
787 gcc_assert (other->get_kind () == SK_INITIAL
788 || other->get_kind () == SK_CONJURED
789 || other->get_kind () == SK_WIDENING);
791 involvement_visitor v (other);
792 accept (&v);
793 return v.found_p ();
796 /* Extract SUBRANGE from this value, of type TYPE. */
798 const svalue *
799 svalue::extract_bit_range (tree type,
800 const bit_range &subrange,
801 region_model_manager *mgr) const
803 return mgr->get_or_create_bits_within (type, subrange, this);
806 /* Base implementation of svalue::maybe_fold_bits_within vfunc. */
808 const svalue *
809 svalue::maybe_fold_bits_within (tree,
810 const bit_range &,
811 region_model_manager *) const
813 /* By default, don't fold. */
814 return NULL;
817 /* Base implementation of svalue::all_zeroes_p.
818 Return true if this value is known to be all zeroes. */
820 bool
821 svalue::all_zeroes_p () const
823 return false;
826 /* If this svalue is a pointer, attempt to determine the base region it points
827 to. Return NULL on any problems. */
829 const region *
830 svalue::maybe_get_deref_base_region () const
832 const svalue *iter = this;
833 while (1)
835 switch (iter->get_kind ())
837 default:
838 return NULL;
840 case SK_REGION:
842 const region_svalue *region_sval
843 = as_a <const region_svalue *> (iter);
844 return region_sval->get_pointee ()->get_base_region ();
847 case SK_BINOP:
849 const binop_svalue *binop_sval
850 = as_a <const binop_svalue *> (iter);
851 switch (binop_sval->get_op ())
853 case POINTER_PLUS_EXPR:
854 /* If we have a symbolic value expressing pointer arithmetic,
855 use the LHS. */
856 iter = binop_sval->get_arg0 ();
857 continue;
859 default:
860 return NULL;
862 return NULL;
868 /* class region_svalue : public svalue. */
870 /* Implementation of svalue::dump_to_pp vfunc for region_svalue. */
872 void
873 region_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
875 if (simple)
877 pp_string (pp, "&");
878 m_reg->dump_to_pp (pp, simple);
880 else
882 pp_string (pp, "region_svalue(");
883 if (get_type ())
885 print_quoted_type (pp, get_type ());
886 pp_string (pp, ", ");
888 m_reg->dump_to_pp (pp, simple);
889 pp_string (pp, ")");
893 /* Implementation of svalue::print_dump_widget_label vfunc for
894 region_svalue. */
896 void
897 region_svalue::print_dump_widget_label (pretty_printer *pp) const
899 pp_printf (pp, "region_svalue: %qs", "&");
902 /* Implementation of svalue::add_dump_widget_children vfunc for
903 region_svalue. */
905 void
906 region_svalue::
907 add_dump_widget_children (text_art::tree_widget &w,
908 const text_art::dump_widget_info &dwi) const
910 w.add_child (m_reg->make_dump_widget (dwi));
913 /* Implementation of svalue::accept vfunc for region_svalue. */
915 void
916 region_svalue::accept (visitor *v) const
918 m_reg->accept (v);
919 v->visit_region_svalue (this);
922 /* Implementation of svalue::implicitly_live_p vfunc for region_svalue. */
924 bool
925 region_svalue::implicitly_live_p (const svalue_set *,
926 const region_model *model) const
928 /* Pointers into clusters that have escaped should be treated as live. */
929 const region *base_reg = get_pointee ()->get_base_region ();
930 const store *store = model->get_store ();
931 if (const binding_cluster *c = store->get_cluster (base_reg))
932 if (c->escaped_p ())
933 return true;
935 return false;
938 /* Evaluate the condition LHS OP RHS.
939 Subroutine of region_model::eval_condition for when we have a pair of
940 pointers. */
942 tristate
943 region_svalue::eval_condition (const region_svalue *lhs,
944 enum tree_code op,
945 const region_svalue *rhs)
947 /* See if they point to the same region. */
948 const region *lhs_reg = lhs->get_pointee ();
949 const region *rhs_reg = rhs->get_pointee ();
950 bool ptr_equality = lhs_reg == rhs_reg;
951 switch (op)
953 default:
954 gcc_unreachable ();
956 case EQ_EXPR:
957 if (ptr_equality)
958 return tristate::TS_TRUE;
959 else
960 return tristate::TS_FALSE;
961 break;
963 case NE_EXPR:
964 if (ptr_equality)
965 return tristate::TS_FALSE;
966 else
967 return tristate::TS_TRUE;
968 break;
970 case GE_EXPR:
971 case LE_EXPR:
972 if (ptr_equality)
973 return tristate::TS_TRUE;
974 break;
976 case GT_EXPR:
977 case LT_EXPR:
978 if (ptr_equality)
979 return tristate::TS_FALSE;
980 break;
983 return tristate::TS_UNKNOWN;
986 /* class constant_svalue : public svalue. */
988 /* Implementation of svalue::dump_to_pp vfunc for constant_svalue. */
990 void
991 constant_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
993 if (simple)
995 pp_string (pp, "(");
996 dump_tree (pp, get_type ());
997 pp_string (pp, ")");
998 dump_tree (pp, m_cst_expr);
1000 else
1002 pp_string (pp, "constant_svalue(");
1003 if (get_type ())
1005 print_quoted_type (pp, get_type ());
1006 pp_string (pp, ", ");
1008 dump_tree (pp, m_cst_expr);
1009 pp_string (pp, ")");
1013 /* Implementation of svalue::print_dump_widget_label vfunc for
1014 constant_svalue. */
1016 void
1017 constant_svalue::print_dump_widget_label (pretty_printer *pp) const
1019 pp_printf (pp, "constant_svalue (%qE)", m_cst_expr);
1022 /* Implementation of svalue::add_dump_widget_children vfunc for
1023 constant_svalue. */
1025 void
1026 constant_svalue::
1027 add_dump_widget_children (text_art::tree_widget &,
1028 const text_art::dump_widget_info &) const
1030 /* No children. */
1033 /* Implementation of svalue::accept vfunc for constant_svalue. */
1035 void
1036 constant_svalue::accept (visitor *v) const
1038 v->visit_constant_svalue (this);
1041 /* Implementation of svalue::implicitly_live_p vfunc for constant_svalue.
1042 Constants are implicitly live. */
1044 bool
1045 constant_svalue::implicitly_live_p (const svalue_set *,
1046 const region_model *) const
1048 return true;
1051 /* Given EXPR, a non-NULL expression of boolean type, convert to
1052 a tristate based on whether this is known to be true, false,
1053 or is not known. */
1055 static tristate
1056 tristate_from_boolean_tree_node (tree expr)
1058 gcc_assert (TREE_TYPE (expr) == boolean_type_node);
1060 if (expr == boolean_true_node)
1061 return tristate (tristate::TS_TRUE);
1062 else if (expr == boolean_false_node)
1063 return tristate (tristate::TS_FALSE);
1064 else
1065 return tristate (tristate::TS_UNKNOWN);
1068 /* Evaluate the condition LHS OP RHS.
1069 Subroutine of region_model::eval_condition for when we have a pair of
1070 constants. */
1072 tristate
1073 constant_svalue::eval_condition (const constant_svalue *lhs,
1074 enum tree_code op,
1075 const constant_svalue *rhs)
1077 tree lhs_const = lhs->get_constant ();
1078 tree rhs_const = rhs->get_constant ();
1080 gcc_assert (CONSTANT_CLASS_P (lhs_const));
1081 gcc_assert (CONSTANT_CLASS_P (rhs_const));
1083 if ((lhs->get_type () == NULL_TREE || rhs->get_type () == NULL_TREE)
1084 && TREE_CODE (lhs_const) == INTEGER_CST
1085 && TREE_CODE (rhs_const) == INTEGER_CST
1088 if (tree tree_cmp = const_binop (op, boolean_type_node,
1089 lhs_const, rhs_const))
1091 tristate ts = tristate_from_boolean_tree_node (tree_cmp);
1092 if (ts.is_known ())
1093 return ts;
1097 /* Check for comparable types. */
1098 if (types_compatible_p (TREE_TYPE (lhs_const), TREE_TYPE (rhs_const)))
1100 tree tree_cmp
1101 = fold_binary (op, boolean_type_node, lhs_const, rhs_const);
1102 tristate ts = tristate_from_boolean_tree_node (tree_cmp);
1103 if (ts.is_known ())
1104 return ts;
1106 return tristate::TS_UNKNOWN;
1109 /* Implementation of svalue::maybe_fold_bits_within vfunc
1110 for constant_svalue. */
1112 const svalue *
1113 constant_svalue::maybe_fold_bits_within (tree type,
1114 const bit_range &bits,
1115 region_model_manager *mgr) const
1117 /* Bits within an all-zero value are also all zero. */
1118 if (zerop (m_cst_expr))
1120 if (type)
1121 return mgr->get_or_create_cast (type, this);
1122 else
1123 return this;
1126 /* Handle the case of extracting a single bit. */
1127 if (bits.m_size_in_bits == 1
1128 && TREE_CODE (m_cst_expr) == INTEGER_CST
1129 && type
1130 && INTEGRAL_TYPE_P (type)
1131 && tree_fits_uhwi_p (m_cst_expr))
1133 unsigned HOST_WIDE_INT bit = bits.m_start_bit_offset.to_uhwi ();
1134 unsigned HOST_WIDE_INT mask = (1 << bit);
1135 unsigned HOST_WIDE_INT val_as_hwi = tree_to_uhwi (m_cst_expr);
1136 unsigned HOST_WIDE_INT masked_val = val_as_hwi & mask;
1137 int result = masked_val ? 1 : 0;
1138 return mgr->get_or_create_int_cst (type, result);
1141 /* Otherwise, don't fold. */
1142 return NULL;
1145 /* Implementation of svalue::all_zeroes_p for constant_svalue. */
1147 bool
1148 constant_svalue::all_zeroes_p () const
1150 return zerop (m_cst_expr);
1153 /* class unknown_svalue : public svalue. */
1155 /* Implementation of svalue::dump_to_pp vfunc for unknown_svalue. */
1157 void
1158 unknown_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
1160 if (simple)
1162 pp_string (pp, "UNKNOWN(");
1163 if (get_type ())
1164 dump_tree (pp, get_type ());
1165 pp_character (pp, ')');
1167 else
1169 pp_string (pp, "unknown_svalue(");
1170 if (get_type ())
1171 dump_tree (pp, get_type ());
1172 pp_character (pp, ')');
1176 /* Implementation of svalue::print_dump_widget_label vfunc for
1177 unknown_svalue. */
1179 void
1180 unknown_svalue::print_dump_widget_label (pretty_printer *pp) const
1182 pp_printf (pp, "unknown_svalue");
1185 /* Implementation of svalue::add_dump_widget_children vfunc for
1186 unknown_svalue. */
1188 void
1189 unknown_svalue::
1190 add_dump_widget_children (text_art::tree_widget &,
1191 const text_art::dump_widget_info &) const
1193 /* No children. */
1196 /* Implementation of svalue::accept vfunc for unknown_svalue. */
1198 void
1199 unknown_svalue::accept (visitor *v) const
1201 v->visit_unknown_svalue (this);
1204 /* Implementation of svalue::maybe_fold_bits_within vfunc
1205 for unknown_svalue. */
1207 const svalue *
1208 unknown_svalue::maybe_fold_bits_within (tree type,
1209 const bit_range &,
1210 region_model_manager *mgr) const
1212 /* Bits within an unknown_svalue are themselves unknown. */
1213 return mgr->get_or_create_unknown_svalue (type);
1216 /* Get a string for KIND for use in debug dumps. */
1218 const char *
1219 poison_kind_to_str (enum poison_kind kind)
1221 switch (kind)
1223 default:
1224 gcc_unreachable ();
1225 case POISON_KIND_UNINIT:
1226 return "uninit";
1227 case POISON_KIND_FREED:
1228 return "freed";
1229 case POISON_KIND_DELETED:
1230 return "deleted";
1231 case POISON_KIND_POPPED_STACK:
1232 return "popped stack";
1236 /* class poisoned_svalue : public svalue. */
1238 /* Implementation of svalue::dump_to_pp vfunc for poisoned_svalue. */
1240 void
1241 poisoned_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
1243 if (simple)
1245 pp_string (pp, "POISONED(");
1246 print_quoted_type (pp, get_type ());
1247 pp_printf (pp, ", %s)", poison_kind_to_str (m_kind));
1249 else
1251 pp_string (pp, "poisoned_svalue(");
1252 print_quoted_type (pp, get_type ());
1253 pp_printf (pp, ", %s)", poison_kind_to_str (m_kind));
1257 /* Implementation of svalue::print_dump_widget_label vfunc for
1258 poisoned_svalue. */
1260 void
1261 poisoned_svalue::print_dump_widget_label (pretty_printer *pp) const
1263 pp_printf (pp, "poisoned_svalue(%s)", poison_kind_to_str (m_kind));
1266 /* Implementation of svalue::add_dump_widget_children vfunc for
1267 poisoned_svalue. */
1269 void
1270 poisoned_svalue::
1271 add_dump_widget_children (text_art::tree_widget &,
1272 const text_art::dump_widget_info &) const
1274 /* No children. */
1277 /* Implementation of svalue::accept vfunc for poisoned_svalue. */
1279 void
1280 poisoned_svalue::accept (visitor *v) const
1282 v->visit_poisoned_svalue (this);
1285 /* Implementation of svalue::maybe_fold_bits_within vfunc
1286 for poisoned_svalue. */
1288 const svalue *
1289 poisoned_svalue::maybe_fold_bits_within (tree type,
1290 const bit_range &,
1291 region_model_manager *mgr) const
1293 /* Bits within a poisoned value are also poisoned. */
1294 return mgr->get_or_create_poisoned_svalue (m_kind, type);
1297 /* class setjmp_svalue's implementation is in engine.cc, so that it can use
1298 the declaration of exploded_node. */
1300 /* class initial_svalue : public svalue. */
1302 /* Implementation of svalue::dump_to_pp vfunc for initial_svalue. */
1304 void
1305 initial_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
1307 if (simple)
1309 pp_string (pp, "INIT_VAL(");
1310 m_reg->dump_to_pp (pp, simple);
1311 pp_string (pp, ")");
1313 else
1315 pp_string (pp, "initial_svalue(");
1316 if (get_type ())
1318 print_quoted_type (pp, get_type ());
1319 pp_string (pp, ", ");
1321 m_reg->dump_to_pp (pp, simple);
1322 pp_string (pp, ")");
1326 /* Implementation of svalue::print_dump_widget_label vfunc for
1327 initial_svalue. */
1329 void
1330 initial_svalue::print_dump_widget_label (pretty_printer *pp) const
1332 pp_printf (pp, "initial_svalue");
1335 /* Implementation of svalue::add_dump_widget_children vfunc for
1336 initial_svalue. */
1338 void
1339 initial_svalue::
1340 add_dump_widget_children (text_art::tree_widget &w,
1341 const text_art::dump_widget_info &dwi) const
1343 w.add_child (m_reg->make_dump_widget (dwi, "m_reg"));
1346 /* Implementation of svalue::accept vfunc for initial_svalue. */
1348 void
1349 initial_svalue::accept (visitor *v) const
1351 m_reg->accept (v);
1352 v->visit_initial_svalue (this);
1355 /* Implementation of svalue::implicitly_live_p vfunc for initial_svalue. */
1357 bool
1358 initial_svalue::implicitly_live_p (const svalue_set *,
1359 const region_model *model) const
1361 /* This svalue may be implicitly live if the region still implicitly
1362 has its initial value and is reachable. */
1364 /* It must be a region that exists; we don't want to consider
1365 INIT_VAL(R) as still being implicitly reachable if R is in
1366 a popped stack frame. */
1367 if (model->region_exists_p (m_reg))
1369 const svalue *reg_sval = model->get_store_value (m_reg, NULL);
1370 if (reg_sval == this)
1371 return true;
1374 /* Assume that the initial values of params for the top level frame
1375 are still live, because (presumably) they're still
1376 live in the external caller. */
1377 if (initial_value_of_param_p ())
1378 if (const frame_region *frame_reg = m_reg->maybe_get_frame_region ())
1379 if (frame_reg->get_calling_frame () == NULL)
1380 return true;
1382 return false;
1385 /* Return true if this is the initial value of a function parameter. */
1387 bool
1388 initial_svalue::initial_value_of_param_p () const
1390 if (tree reg_decl = m_reg->maybe_get_decl ())
1391 if (TREE_CODE (reg_decl) == SSA_NAME)
1393 tree ssa_name = reg_decl;
1394 if (SSA_NAME_IS_DEFAULT_DEF (ssa_name)
1395 && SSA_NAME_VAR (ssa_name)
1396 && TREE_CODE (SSA_NAME_VAR (ssa_name)) == PARM_DECL)
1397 return true;
1399 return false;
1402 /* class unaryop_svalue : public svalue. */
1404 /* Implementation of svalue::dump_to_pp vfunc for unaryop_svalue. */
1406 void
1407 unaryop_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
1409 if (simple)
1411 if (m_op == VIEW_CONVERT_EXPR || m_op == NOP_EXPR)
1413 pp_string (pp, "CAST(");
1414 dump_tree (pp, get_type ());
1415 pp_string (pp, ", ");
1416 m_arg->dump_to_pp (pp, simple);
1417 pp_character (pp, ')');
1419 else
1421 pp_character (pp, '(');
1422 pp_string (pp, get_tree_code_name (m_op));
1423 //pp_string (pp, op_symbol_code (m_op));
1424 m_arg->dump_to_pp (pp, simple);
1425 pp_character (pp, ')');
1428 else
1430 pp_string (pp, "unaryop_svalue (");
1431 pp_string (pp, get_tree_code_name (m_op));
1432 pp_string (pp, ", ");
1433 m_arg->dump_to_pp (pp, simple);
1434 pp_character (pp, ')');
1438 /* Implementation of svalue::print_dump_widget_label vfunc for
1439 unaryop_svalue. */
1441 void
1442 unaryop_svalue::print_dump_widget_label (pretty_printer *pp) const
1444 pp_printf (pp,
1445 "unaryop_svalue(%s)",
1446 get_tree_code_name (m_op));
1449 /* Implementation of svalue::add_dump_widget_children vfunc for
1450 unaryop_svalue. */
1452 void
1453 unaryop_svalue::
1454 add_dump_widget_children (text_art::tree_widget &w,
1455 const text_art::dump_widget_info &dwi) const
1457 w.add_child (m_arg->make_dump_widget (dwi));
1460 /* Implementation of svalue::accept vfunc for unaryop_svalue. */
1462 void
1463 unaryop_svalue::accept (visitor *v) const
1465 m_arg->accept (v);
1466 v->visit_unaryop_svalue (this);
1469 /* Implementation of svalue::implicitly_live_p vfunc for unaryop_svalue. */
1471 bool
1472 unaryop_svalue::implicitly_live_p (const svalue_set *live_svalues,
1473 const region_model *model) const
1475 return get_arg ()->live_p (live_svalues, model);
1478 /* Implementation of svalue::maybe_fold_bits_within vfunc
1479 for unaryop_svalue. */
1481 const svalue *
1482 unaryop_svalue::maybe_fold_bits_within (tree type,
1483 const bit_range &,
1484 region_model_manager *mgr) const
1486 switch (m_op)
1488 default:
1489 break;
1490 case NOP_EXPR:
1491 /* A cast of zero is zero. */
1492 if (tree cst = m_arg->maybe_get_constant ())
1493 if (zerop (cst))
1495 if (type)
1496 return mgr->get_or_create_cast (type, this);
1497 else
1498 return this;
1500 break;
1502 /* Otherwise, don't fold. */
1503 return NULL;
1506 /* class binop_svalue : public svalue. */
1508 /* Return whether OP be printed as an infix operator. */
1510 static bool
1511 infix_p (enum tree_code op)
1513 switch (op)
1515 default:
1516 return true;
1517 case MAX_EXPR:
1518 case MIN_EXPR:
1519 return false;
1523 /* Implementation of svalue::dump_to_pp vfunc for binop_svalue. */
1525 void
1526 binop_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
1528 if (simple)
1530 if (infix_p (m_op))
1532 /* Print "(A OP B)". */
1533 pp_character (pp, '(');
1534 m_arg0->dump_to_pp (pp, simple);
1535 pp_string (pp, op_symbol_code (m_op));
1536 m_arg1->dump_to_pp (pp, simple);
1537 pp_character (pp, ')');
1539 else
1541 /* Print "OP(A, B)". */
1542 pp_string (pp, op_symbol_code (m_op));
1543 pp_character (pp, '(');
1544 m_arg0->dump_to_pp (pp, simple);
1545 pp_string (pp, ", ");
1546 m_arg1->dump_to_pp (pp, simple);
1547 pp_character (pp, ')');
1550 else
1552 pp_string (pp, "binop_svalue (");
1553 pp_string (pp, get_tree_code_name (m_op));
1554 pp_string (pp, ", ");
1555 m_arg0->dump_to_pp (pp, simple);
1556 pp_string (pp, ", ");
1557 m_arg1->dump_to_pp (pp, simple);
1558 pp_character (pp, ')');
1562 /* Implementation of svalue::print_dump_widget_label vfunc for
1563 binop_svalue. */
1565 void
1566 binop_svalue::print_dump_widget_label (pretty_printer *pp) const
1568 pp_printf (pp,
1569 "binop_svalue(%s: %qs)",
1570 get_tree_code_name (m_op),
1571 op_symbol_code (m_op));
1574 /* Implementation of svalue::add_dump_widget_children vfunc for
1575 binop_svalue. */
1577 void
1578 binop_svalue::
1579 add_dump_widget_children (text_art::tree_widget &w,
1580 const text_art::dump_widget_info &dwi) const
1582 w.add_child (m_arg0->make_dump_widget (dwi));
1583 w.add_child (m_arg1->make_dump_widget (dwi));
1586 /* Implementation of svalue::accept vfunc for binop_svalue. */
1588 void
1589 binop_svalue::accept (visitor *v) const
1591 m_arg0->accept (v);
1592 m_arg1->accept (v);
1593 v->visit_binop_svalue (this);
1596 /* Implementation of svalue::implicitly_live_p vfunc for binop_svalue. */
1598 bool
1599 binop_svalue::implicitly_live_p (const svalue_set *live_svalues,
1600 const region_model *model) const
1602 return (get_arg0 ()->live_p (live_svalues, model)
1603 && get_arg1 ()->live_p (live_svalues, model));
1606 /* class sub_svalue : public svalue. */
1608 /* sub_svalue'c ctor. */
1610 sub_svalue::sub_svalue (symbol::id_t id,
1611 tree type, const svalue *parent_svalue,
1612 const region *subregion)
1613 : svalue (complexity::from_pair (parent_svalue->get_complexity (),
1614 subregion->get_complexity ()),
1616 type),
1617 m_parent_svalue (parent_svalue), m_subregion (subregion)
1619 gcc_assert (parent_svalue->can_have_associated_state_p ());
1622 /* Implementation of svalue::dump_to_pp vfunc for sub_svalue. */
1624 void
1625 sub_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
1627 if (simple)
1629 pp_string (pp, "SUB(");
1630 m_parent_svalue->dump_to_pp (pp, simple);
1631 pp_string (pp, ", ");
1632 m_subregion->dump_to_pp (pp, simple);
1633 pp_character (pp, ')');
1635 else
1637 pp_string (pp, "sub_svalue (");
1638 pp_string (pp, ", ");
1639 m_parent_svalue->dump_to_pp (pp, simple);
1640 pp_string (pp, ", ");
1641 m_subregion->dump_to_pp (pp, simple);
1642 pp_character (pp, ')');
1646 /* Implementation of svalue::print_dump_widget_label vfunc for
1647 sub_svalue. */
1649 void
1650 sub_svalue::print_dump_widget_label (pretty_printer *pp) const
1652 pp_printf (pp, "sub_svalue");
1655 /* Implementation of svalue::add_dump_widget_children vfunc for
1656 sub_svalue. */
1658 void
1659 sub_svalue::
1660 add_dump_widget_children (text_art::tree_widget &w,
1661 const text_art::dump_widget_info &dwi) const
1663 w.add_child (m_parent_svalue->make_dump_widget (dwi, "m_parent_svalue"));
1664 w.add_child (m_subregion->make_dump_widget (dwi, "m_subregion"));
1667 /* Implementation of svalue::accept vfunc for sub_svalue. */
1669 void
1670 sub_svalue::accept (visitor *v) const
1672 m_parent_svalue->accept (v);
1673 m_subregion->accept (v);
1674 v->visit_sub_svalue (this);
1677 /* Implementation of svalue::implicitly_live_p vfunc for sub_svalue. */
1679 bool
1680 sub_svalue::implicitly_live_p (const svalue_set *live_svalues,
1681 const region_model *model) const
1683 return get_parent ()->live_p (live_svalues, model);
1686 /* class repeated_svalue : public svalue. */
1688 /* repeated_svalue'c ctor. */
1690 repeated_svalue::repeated_svalue (symbol::id_t id,
1691 tree type,
1692 const svalue *outer_size,
1693 const svalue *inner_svalue)
1694 : svalue (complexity::from_pair (outer_size, inner_svalue), id, type),
1695 m_outer_size (outer_size),
1696 m_inner_svalue (inner_svalue)
1698 gcc_assert (outer_size->can_have_associated_state_p ());
1699 gcc_assert (inner_svalue->can_have_associated_state_p ());
1702 /* Implementation of svalue::dump_to_pp vfunc for repeated_svalue. */
1704 void
1705 repeated_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
1707 if (simple)
1709 pp_string (pp, "REPEATED(");
1710 if (get_type ())
1712 print_quoted_type (pp, get_type ());
1713 pp_string (pp, ", ");
1715 pp_string (pp, "outer_size: ");
1716 m_outer_size->dump_to_pp (pp, simple);
1717 pp_string (pp, ", inner_val: ");
1718 m_inner_svalue->dump_to_pp (pp, simple);
1719 pp_character (pp, ')');
1721 else
1723 pp_string (pp, "repeated_svalue (");
1724 if (get_type ())
1726 print_quoted_type (pp, get_type ());
1727 pp_string (pp, ", ");
1729 pp_string (pp, "outer_size: ");
1730 m_outer_size->dump_to_pp (pp, simple);
1731 pp_string (pp, ", inner_val: ");
1732 m_inner_svalue->dump_to_pp (pp, simple);
1733 pp_character (pp, ')');
1737 /* Implementation of svalue::print_dump_widget_label vfunc for
1738 repeated_svalue. */
1740 void
1741 repeated_svalue::print_dump_widget_label (pretty_printer *pp) const
1743 pp_printf (pp, "repeated_svalue");
1746 /* Implementation of svalue::add_dump_widget_children vfunc for
1747 repeated_svalue. */
1749 void
1750 repeated_svalue::
1751 add_dump_widget_children (text_art::tree_widget &w,
1752 const text_art::dump_widget_info &dwi) const
1754 w.add_child (m_outer_size->make_dump_widget (dwi, "m_outer_size"));
1755 w.add_child (m_inner_svalue->make_dump_widget (dwi, "m_inner_svalue"));
1758 /* Implementation of svalue::accept vfunc for repeated_svalue. */
1760 void
1761 repeated_svalue::accept (visitor *v) const
1763 m_inner_svalue->accept (v);
1764 v->visit_repeated_svalue (this);
1767 /* Implementation of svalue::all_zeroes_p for repeated_svalue. */
1769 bool
1770 repeated_svalue::all_zeroes_p () const
1772 return m_inner_svalue->all_zeroes_p ();
1775 /* Implementation of svalue::maybe_fold_bits_within vfunc
1776 for repeated_svalue. */
1778 const svalue *
1779 repeated_svalue::maybe_fold_bits_within (tree type,
1780 const bit_range &bits,
1781 region_model_manager *mgr) const
1783 const svalue *innermost_sval = m_inner_svalue;
1784 /* Fold
1785 BITS_WITHIN (range, REPEATED_SVALUE (ZERO))
1787 REPEATED_SVALUE (ZERO). */
1788 if (all_zeroes_p ())
1790 byte_range bytes (0,0);
1791 if (bits.as_byte_range (&bytes))
1793 const svalue *byte_size
1794 = mgr->get_or_create_int_cst (size_type_node,
1795 bytes.m_size_in_bytes.to_uhwi ());
1796 return mgr->get_or_create_repeated_svalue (type, byte_size,
1797 innermost_sval);
1801 /* Fold:
1802 BITS_WITHIN (range, REPEATED_SVALUE (INNERMOST_SVALUE))
1804 BITS_WITHIN (range - offset, INNERMOST_SVALUE)
1805 if range is fully within one instance of INNERMOST_SVALUE. */
1806 if (tree innermost_type = innermost_sval->get_type ())
1808 bit_size_t element_bit_size;
1809 if (int_size_in_bits (innermost_type, &element_bit_size)
1810 && element_bit_size > 0)
1812 HOST_WIDE_INT start_idx
1813 = (bits.get_start_bit_offset ()
1814 / element_bit_size).to_shwi ();
1815 HOST_WIDE_INT last_idx
1816 = (bits.get_last_bit_offset ()
1817 / element_bit_size).to_shwi ();
1818 if (start_idx == last_idx)
1820 bit_offset_t start_of_element
1821 = start_idx * element_bit_size;
1822 bit_range range_within_element
1823 (bits.m_start_bit_offset - start_of_element,
1824 bits.m_size_in_bits);
1825 return mgr->get_or_create_bits_within (type,
1826 range_within_element,
1827 innermost_sval);
1832 return NULL;
1835 /* class bits_within_svalue : public svalue. */
1837 /* bits_within_svalue'c ctor. */
1839 bits_within_svalue::bits_within_svalue (symbol::id_t id,
1840 tree type,
1841 const bit_range &bits,
1842 const svalue *inner_svalue)
1843 : svalue (complexity (inner_svalue), id, type),
1844 m_bits (bits),
1845 m_inner_svalue (inner_svalue)
1847 gcc_assert (inner_svalue->can_have_associated_state_p ());
1850 /* Implementation of svalue::dump_to_pp vfunc for bits_within_svalue. */
1852 void
1853 bits_within_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
1855 if (simple)
1857 pp_string (pp, "BITS_WITHIN(");
1858 if (get_type ())
1860 print_quoted_type (pp, get_type ());
1861 pp_string (pp, ", ");
1863 m_bits.dump_to_pp (pp);
1864 pp_string (pp, ", inner_val: ");
1865 m_inner_svalue->dump_to_pp (pp, simple);
1866 pp_character (pp, ')');
1868 else
1870 pp_string (pp, "bits_within_svalue (");
1871 if (get_type ())
1873 print_quoted_type (pp, get_type ());
1874 pp_string (pp, ", ");
1876 m_bits.dump_to_pp (pp);
1877 pp_string (pp, ", inner_val: ");
1878 m_inner_svalue->dump_to_pp (pp, simple);
1879 pp_character (pp, ')');
1883 /* Implementation of svalue::print_dump_widget_label vfunc for
1884 bits_within_svalue. */
1886 void
1887 bits_within_svalue::print_dump_widget_label (pretty_printer *pp) const
1889 pp_printf (pp, "bits_within_svalue: ");
1890 m_bits.dump_to_pp (pp);
1893 /* Implementation of svalue::add_dump_widget_children vfunc for
1894 bits_within_svalue. */
1896 void
1897 bits_within_svalue::
1898 add_dump_widget_children (text_art::tree_widget &w,
1899 const text_art::dump_widget_info &dwi) const
1901 w.add_child (m_inner_svalue->make_dump_widget (dwi, "m_inner_svalue"));
1904 /* Implementation of svalue::maybe_fold_bits_within vfunc
1905 for bits_within_svalue. */
1907 const svalue *
1908 bits_within_svalue::maybe_fold_bits_within (tree type,
1909 const bit_range &bits,
1910 region_model_manager *mgr) const
1912 /* Fold:
1913 BITS_WITHIN (range1, BITS_WITHIN (range2, VAL))
1915 BITS_WITHIN (range1 in range 2, VAL). */
1916 bit_range offset_bits (m_bits.get_start_bit_offset ()
1917 + bits.m_start_bit_offset,
1918 bits.m_size_in_bits);
1919 return mgr->get_or_create_bits_within (type, offset_bits, m_inner_svalue);
1922 /* Implementation of svalue::accept vfunc for bits_within_svalue. */
1924 void
1925 bits_within_svalue::accept (visitor *v) const
1927 m_inner_svalue->accept (v);
1928 v->visit_bits_within_svalue (this);
1931 /* Implementation of svalue::implicitly_live_p vfunc for bits_within_svalue. */
1933 bool
1934 bits_within_svalue::implicitly_live_p (const svalue_set *live_svalues,
1935 const region_model *model) const
1937 return m_inner_svalue->live_p (live_svalues, model);
1940 /* class widening_svalue : public svalue. */
1942 /* Implementation of svalue::dump_to_pp vfunc for widening_svalue. */
1944 void
1945 widening_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
1947 if (simple)
1949 pp_string (pp, "WIDENING(");
1950 pp_character (pp, '{');
1951 m_point.print (pp, format (false));
1952 pp_string (pp, "}, ");
1953 m_base_sval->dump_to_pp (pp, simple);
1954 pp_string (pp, ", ");
1955 m_iter_sval->dump_to_pp (pp, simple);
1956 pp_character (pp, ')');
1958 else
1960 pp_string (pp, "widening_svalue (");
1961 pp_string (pp, ", ");
1962 pp_character (pp, '{');
1963 m_point.print (pp, format (false));
1964 pp_string (pp, "}, ");
1965 m_base_sval->dump_to_pp (pp, simple);
1966 pp_string (pp, ", ");
1967 m_iter_sval->dump_to_pp (pp, simple);
1968 pp_character (pp, ')');
1972 /* Implementation of svalue::print_dump_widget_label vfunc for
1973 widening_svalue. */
1975 void
1976 widening_svalue::print_dump_widget_label (pretty_printer *pp) const
1978 pp_printf (pp, "widening_svalue at ");
1979 m_point.print (pp, format (false));
1982 /* Implementation of svalue::add_dump_widget_children vfunc for
1983 widening_svalue. */
1985 void
1986 widening_svalue::
1987 add_dump_widget_children (text_art::tree_widget &w,
1988 const text_art::dump_widget_info &dwi) const
1990 w.add_child (m_base_sval->make_dump_widget (dwi, "m_base_sval"));
1991 w.add_child (m_iter_sval->make_dump_widget (dwi, "m_iter_sval"));
1994 /* Implementation of svalue::accept vfunc for widening_svalue. */
1996 void
1997 widening_svalue::accept (visitor *v) const
1999 m_base_sval->accept (v);
2000 m_iter_sval->accept (v);
2001 v->visit_widening_svalue (this);
2004 /* Attempt to determine in which direction this value is changing
2005 w.r.t. the initial value. */
2007 enum widening_svalue::direction_t
2008 widening_svalue::get_direction () const
2010 tree base_cst = m_base_sval->maybe_get_constant ();
2011 if (base_cst == NULL_TREE)
2012 return DIR_UNKNOWN;
2013 tree iter_cst = m_iter_sval->maybe_get_constant ();
2014 if (iter_cst == NULL_TREE)
2015 return DIR_UNKNOWN;
2017 tree iter_gt_base = fold_binary (GT_EXPR, boolean_type_node,
2018 iter_cst, base_cst);
2019 if (iter_gt_base == boolean_true_node)
2020 return DIR_ASCENDING;
2022 tree iter_lt_base = fold_binary (LT_EXPR, boolean_type_node,
2023 iter_cst, base_cst);
2024 if (iter_lt_base == boolean_true_node)
2025 return DIR_DESCENDING;
2027 return DIR_UNKNOWN;
2030 /* Compare this value against constant RHS_CST. */
2032 tristate
2033 widening_svalue::eval_condition_without_cm (enum tree_code op,
2034 tree rhs_cst) const
2036 tree base_cst = m_base_sval->maybe_get_constant ();
2037 if (base_cst == NULL_TREE)
2038 return tristate::TS_UNKNOWN;
2039 tree iter_cst = m_iter_sval->maybe_get_constant ();
2040 if (iter_cst == NULL_TREE)
2041 return tristate::TS_UNKNOWN;
2043 switch (get_direction ())
2045 default:
2046 gcc_unreachable ();
2047 case DIR_ASCENDING:
2048 /* LHS is in [base_cst, +ve infinity), assuming no overflow. */
2049 switch (op)
2051 case LE_EXPR:
2052 case LT_EXPR:
2054 /* [BASE, +INF) OP RHS:
2055 This is either true or false at +ve ininity,
2056 It can be true for points X where X OP RHS, so we have either
2057 "false", or "unknown". */
2058 tree base_op_rhs = fold_binary (op, boolean_type_node,
2059 base_cst, rhs_cst);
2060 if (base_op_rhs == boolean_true_node)
2061 return tristate::TS_UNKNOWN;
2062 else
2063 return tristate::TS_FALSE;
2066 case GE_EXPR:
2067 case GT_EXPR:
2069 /* [BASE, +INF) OP RHS:
2070 This is true at +ve infinity. It will be true everywhere
2071 in the range if BASE >= RHS. */
2072 tree base_op_rhs = fold_binary (op, boolean_type_node,
2073 base_cst, rhs_cst);
2074 if (base_op_rhs == boolean_true_node)
2075 return tristate::TS_TRUE;
2076 else
2077 return tristate::TS_UNKNOWN;
2080 case EQ_EXPR:
2082 /* [BASE, +INF) == RHS:
2083 Could this be true at any point in the range? If so we
2084 have "unknown", otherwise we have "false". */
2085 tree base_le_rhs = fold_binary (LE_EXPR, boolean_type_node,
2086 base_cst, rhs_cst);
2087 if (base_le_rhs == boolean_true_node)
2088 return tristate::TS_UNKNOWN;
2089 else
2090 return tristate::TS_FALSE;
2093 case NE_EXPR:
2095 /* [BASE, +INF) != RHS:
2096 Could we have equality at any point in the range? If so we
2097 have "unknown", otherwise we have "true". */
2098 tree base_le_rhs = fold_binary (LE_EXPR, boolean_type_node,
2099 base_cst, rhs_cst);
2100 if (base_le_rhs == boolean_true_node)
2101 return tristate::TS_UNKNOWN;
2102 else
2103 return tristate::TS_TRUE;
2106 default:
2107 return tristate::TS_UNKNOWN;
2110 case DIR_DESCENDING:
2111 /* LHS is in (-ve infinity, base_cst], assuming no overflow. */
2112 return tristate::TS_UNKNOWN;
2114 case DIR_UNKNOWN:
2115 return tristate::TS_UNKNOWN;
2119 /* class placeholder_svalue : public svalue. */
2121 /* Implementation of svalue::dump_to_pp vfunc for placeholder_svalue. */
2123 void
2124 placeholder_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
2126 if (simple)
2127 pp_printf (pp, "PLACEHOLDER(%qs)", m_name);
2128 else
2129 pp_printf (pp, "placeholder_svalue (%qs)", m_name);
2132 /* Implementation of svalue::print_dump_widget_label vfunc for
2133 placeholder_svalue. */
2135 void
2136 placeholder_svalue::print_dump_widget_label (pretty_printer *pp) const
2138 pp_printf (pp, "placeholder_svalue: %qs", m_name);
2141 /* Implementation of svalue::add_dump_widget_children vfunc for
2142 placeholder_svalue. */
2144 void
2145 placeholder_svalue::
2146 add_dump_widget_children (text_art::tree_widget &,
2147 const text_art::dump_widget_info &) const
2149 /* No children. */
2152 /* Implementation of svalue::accept vfunc for placeholder_svalue. */
2154 void
2155 placeholder_svalue::accept (visitor *v) const
2157 v->visit_placeholder_svalue (this);
2160 /* class unmergeable_svalue : public svalue. */
2162 /* Implementation of svalue::dump_to_pp vfunc for unmergeable_svalue. */
2164 void
2165 unmergeable_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
2167 if (simple)
2169 pp_string (pp, "UNMERGEABLE(");
2170 m_arg->dump_to_pp (pp, simple);
2171 pp_character (pp, ')');
2173 else
2175 pp_string (pp, "unmergeable_svalue (");
2176 m_arg->dump_to_pp (pp, simple);
2177 pp_character (pp, ')');
2181 /* Implementation of svalue::print_dump_widget_label vfunc for
2182 unmergeable_svalue. */
2184 void
2185 unmergeable_svalue::print_dump_widget_label (pretty_printer *pp) const
2187 pp_printf (pp, "unmergeable_svalue");
2190 /* Implementation of svalue::add_dump_widget_children vfunc for
2191 unmergeable_svalue. */
2193 void
2194 unmergeable_svalue::
2195 add_dump_widget_children (text_art::tree_widget &w,
2196 const text_art::dump_widget_info &dwi) const
2198 w.add_child (m_arg->make_dump_widget (dwi));
2201 /* Implementation of svalue::accept vfunc for unmergeable_svalue. */
2203 void
2204 unmergeable_svalue::accept (visitor *v) const
2206 m_arg->accept (v);
2207 v->visit_unmergeable_svalue (this);
2210 /* Implementation of svalue::implicitly_live_p vfunc for unmergeable_svalue. */
2212 bool
2213 unmergeable_svalue::implicitly_live_p (const svalue_set *live_svalues,
2214 const region_model *model) const
2216 return get_arg ()->live_p (live_svalues, model);
2219 /* class compound_svalue : public svalue. */
2221 compound_svalue::compound_svalue (symbol::id_t id,
2222 tree type,
2223 const binding_map &map)
2224 : svalue (calc_complexity (map), id, type), m_map (map)
2226 #if CHECKING_P
2227 for (iterator_t iter = begin (); iter != end (); ++iter)
2229 /* All keys within the underlying binding_map are required to be concrete,
2230 not symbolic. */
2231 const binding_key *key = (*iter).first;
2232 gcc_assert (key->concrete_p ());
2234 /* We don't nest compound svalues. */
2235 const svalue *sval = (*iter).second;
2236 gcc_assert (sval->get_kind () != SK_COMPOUND);
2238 #endif
2241 /* Implementation of svalue::dump_to_pp vfunc for compound_svalue. */
2243 void
2244 compound_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
2246 if (simple)
2248 pp_string (pp, "COMPOUND(");
2249 if (get_type ())
2251 print_quoted_type (pp, get_type ());
2252 pp_string (pp, ", ");
2254 pp_character (pp, '{');
2255 m_map.dump_to_pp (pp, simple, false);
2256 pp_string (pp, "})");
2258 else
2260 pp_string (pp, "compound_svalue (");
2261 if (get_type ())
2263 print_quoted_type (pp, get_type ());
2264 pp_string (pp, ", ");
2266 pp_character (pp, '{');
2267 m_map.dump_to_pp (pp, simple, false);
2268 pp_string (pp, "})");
2272 /* Implementation of svalue::print_dump_widget_label vfunc for
2273 compound_svalue. */
2275 void
2276 compound_svalue::print_dump_widget_label (pretty_printer *pp) const
2278 pp_printf (pp, "compound_svalue");
2281 /* Implementation of svalue::add_dump_widget_children vfunc for
2282 compound_svalue. */
2284 void
2285 compound_svalue::
2286 add_dump_widget_children (text_art::tree_widget &w,
2287 const text_art::dump_widget_info &dwi) const
2289 m_map.add_to_tree_widget (w, dwi);
2292 /* Implementation of svalue::accept vfunc for compound_svalue. */
2294 void
2295 compound_svalue::accept (visitor *v) const
2297 for (binding_map::iterator_t iter = m_map.begin ();
2298 iter != m_map.end (); ++iter)
2300 //(*iter).first.accept (v);
2301 (*iter).second->accept (v);
2303 v->visit_compound_svalue (this);
2306 /* Calculate what the complexity of a compound_svalue instance for MAP
2307 will be, based on the svalues bound within MAP. */
2309 complexity
2310 compound_svalue::calc_complexity (const binding_map &map)
2312 unsigned num_child_nodes = 0;
2313 unsigned max_child_depth = 0;
2314 for (binding_map::iterator_t iter = map.begin ();
2315 iter != map.end (); ++iter)
2317 const complexity &sval_c = (*iter).second->get_complexity ();
2318 num_child_nodes += sval_c.m_num_nodes;
2319 max_child_depth = MAX (max_child_depth, sval_c.m_max_depth);
2321 return complexity (num_child_nodes + 1, max_child_depth + 1);
2324 /* Implementation of svalue::maybe_fold_bits_within vfunc
2325 for compound_svalue. */
2327 const svalue *
2328 compound_svalue::maybe_fold_bits_within (tree type,
2329 const bit_range &bits,
2330 region_model_manager *mgr) const
2332 binding_map result_map;
2333 for (auto iter : m_map)
2335 const binding_key *key = iter.first;
2336 if (const concrete_binding *conc_key
2337 = key->dyn_cast_concrete_binding ())
2339 /* Ignore concrete bindings outside BITS. */
2340 if (!conc_key->get_bit_range ().intersects_p (bits))
2341 continue;
2343 const svalue *sval = iter.second;
2344 /* Get the position of conc_key relative to BITS. */
2345 bit_range result_location (conc_key->get_start_bit_offset ()
2346 - bits.get_start_bit_offset (),
2347 conc_key->get_size_in_bits ());
2348 /* If conc_key starts after BITS, trim off leading bits
2349 from the svalue and adjust binding location. */
2350 if (result_location.m_start_bit_offset < 0)
2352 bit_size_t leading_bits_to_drop
2353 = -result_location.m_start_bit_offset;
2354 result_location = bit_range
2355 (0, result_location.m_size_in_bits - leading_bits_to_drop);
2356 bit_range bits_within_sval (leading_bits_to_drop,
2357 result_location.m_size_in_bits);
2358 /* Trim off leading bits from iter_sval. */
2359 sval = mgr->get_or_create_bits_within (NULL_TREE,
2360 bits_within_sval,
2361 sval);
2363 /* If conc_key finishes after BITS, trim off trailing bits
2364 from the svalue and adjust binding location. */
2365 if (conc_key->get_next_bit_offset ()
2366 > bits.get_next_bit_offset ())
2368 bit_size_t trailing_bits_to_drop
2369 = (conc_key->get_next_bit_offset ()
2370 - bits.get_next_bit_offset ());
2371 result_location = bit_range
2372 (result_location.m_start_bit_offset,
2373 result_location.m_size_in_bits - trailing_bits_to_drop);
2374 bit_range bits_within_sval (0,
2375 result_location.m_size_in_bits);
2376 /* Trim off leading bits from iter_sval. */
2377 sval = mgr->get_or_create_bits_within (NULL_TREE,
2378 bits_within_sval,
2379 sval);
2381 const concrete_binding *offset_conc_key
2382 = mgr->get_store_manager ()->get_concrete_binding
2383 (result_location);
2384 result_map.put (offset_conc_key, sval);
2386 else
2387 /* If we have any symbolic keys we can't get it as bits. */
2388 return NULL;
2390 return mgr->get_or_create_compound_svalue (type, result_map);
2393 /* class conjured_svalue : public svalue. */
2395 /* Implementation of svalue::dump_to_pp vfunc for conjured_svalue. */
2397 void
2398 conjured_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
2400 if (simple)
2402 pp_string (pp, "CONJURED(");
2403 pp_gimple_stmt_1 (pp, m_stmt, 0, (dump_flags_t)0);
2404 pp_string (pp, ", ");
2405 m_id_reg->dump_to_pp (pp, simple);
2406 pp_character (pp, ')');
2408 else
2410 pp_string (pp, "conjured_svalue (");
2411 if (get_type ())
2413 print_quoted_type (pp, get_type ());
2414 pp_string (pp, ", ");
2416 pp_gimple_stmt_1 (pp, m_stmt, 0, (dump_flags_t)0);
2417 pp_string (pp, ", ");
2418 m_id_reg->dump_to_pp (pp, simple);
2419 pp_character (pp, ')');
2423 /* Implementation of svalue::print_dump_widget_label vfunc for
2424 conjured_svalue. */
2426 void
2427 conjured_svalue::print_dump_widget_label (pretty_printer *pp) const
2429 pp_printf (pp, "conjured_svalue (");
2430 pp_gimple_stmt_1 (pp, m_stmt, 0, (dump_flags_t)0);
2431 if (m_idx != 0)
2432 pp_printf (pp, ", %i", m_idx);
2433 pp_character (pp, ')');
2436 /* Implementation of svalue::add_dump_widget_children vfunc for
2437 conjured_svalue. */
2439 void
2440 conjured_svalue::
2441 add_dump_widget_children (text_art::tree_widget &w,
2442 const text_art::dump_widget_info &dwi) const
2444 w.add_child (m_id_reg->make_dump_widget (dwi));
2447 /* Implementation of svalue::accept vfunc for conjured_svalue. */
2449 void
2450 conjured_svalue::accept (visitor *v) const
2452 m_id_reg->accept (v);
2453 v->visit_conjured_svalue (this);
2456 /* Return true iff this conjured_svalue is for the LHS of the
2457 stmt that conjured it. */
2459 bool
2460 conjured_svalue::lhs_value_p () const
2462 if (tree decl = m_id_reg->maybe_get_decl ())
2463 return decl == gimple_get_lhs (m_stmt);
2464 return false;
2467 /* class asm_output_svalue : public svalue. */
2469 /* Implementation of svalue::dump_to_pp vfunc for asm_output_svalue. */
2471 void
2472 asm_output_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
2474 if (simple)
2476 pp_printf (pp, "ASM_OUTPUT(%qs, %%%i, {",
2477 get_asm_string (),
2478 get_output_idx ());
2479 for (unsigned i = 0; i < m_num_inputs; i++)
2481 if (i > 0)
2482 pp_string (pp, ", ");
2483 dump_input (pp, 0, m_input_arr[i], simple);
2485 pp_string (pp, "})");
2487 else
2489 pp_printf (pp, "asm_output_svalue (%qs, %%%i, {",
2490 get_asm_string (),
2491 get_output_idx ());
2492 for (unsigned i = 0; i < m_num_inputs; i++)
2494 if (i > 0)
2495 pp_string (pp, ", ");
2496 dump_input (pp, 0, m_input_arr[i], simple);
2498 pp_string (pp, "})");
2502 /* Implementation of svalue::print_dump_widget_label vfunc for
2503 asm_output_svalue. */
2505 void
2506 asm_output_svalue::print_dump_widget_label (pretty_printer *pp) const
2508 pp_printf (pp, "asm_output_svalue(%qs, %%%i)",
2509 get_asm_string (),
2510 get_output_idx ());
2513 /* Implementation of svalue::add_dump_widget_children vfunc for
2514 asm_output_svalue. */
2516 void
2517 asm_output_svalue::
2518 add_dump_widget_children (text_art::tree_widget &w,
2519 const text_art::dump_widget_info &dwi) const
2521 for (unsigned i = 0; i < m_num_inputs; i++)
2523 pretty_printer pp;
2524 pp_printf (&pp, "arg %i", i);
2525 w.add_child (m_input_arr[i]->make_dump_widget (dwi,
2526 pp_formatted_text (&pp)));
2530 /* Subroutine of asm_output_svalue::dump_to_pp. */
2532 void
2533 asm_output_svalue::dump_input (pretty_printer *pp,
2534 unsigned input_idx,
2535 const svalue *sval,
2536 bool simple) const
2538 pp_printf (pp, "%%%i: ", input_idx_to_asm_idx (input_idx));
2539 sval->dump_to_pp (pp, simple);
2542 /* Convert INPUT_IDX from an index into the array of inputs
2543 into the index of all operands for the asm stmt. */
2545 unsigned
2546 asm_output_svalue::input_idx_to_asm_idx (unsigned input_idx) const
2548 return input_idx + m_num_outputs;
2551 /* Implementation of svalue::accept vfunc for asm_output_svalue. */
2553 void
2554 asm_output_svalue::accept (visitor *v) const
2556 for (unsigned i = 0; i < m_num_inputs; i++)
2557 m_input_arr[i]->accept (v);
2558 v->visit_asm_output_svalue (this);
2561 /* class const_fn_result_svalue : public svalue. */
2563 /* Implementation of svalue::dump_to_pp vfunc for const_fn_result_svalue. */
2565 void
2566 const_fn_result_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
2568 if (simple)
2570 pp_printf (pp, "CONST_FN_RESULT(%qD, {", m_fndecl);
2571 for (unsigned i = 0; i < m_num_inputs; i++)
2573 if (i > 0)
2574 pp_string (pp, ", ");
2575 dump_input (pp, i, m_input_arr[i], simple);
2577 pp_string (pp, "})");
2579 else
2581 pp_printf (pp, "CONST_FN_RESULT(%qD, {", m_fndecl);
2582 for (unsigned i = 0; i < m_num_inputs; i++)
2584 if (i > 0)
2585 pp_string (pp, ", ");
2586 dump_input (pp, i, m_input_arr[i], simple);
2588 pp_string (pp, "})");
2592 /* Implementation of svalue::print_dump_widget_label vfunc for
2593 const_fn_result_svalue. */
2595 void
2596 const_fn_result_svalue::print_dump_widget_label (pretty_printer *pp) const
2598 pp_printf (pp, "const_fn_result_svalue: %qD", m_fndecl);
2601 /* Implementation of svalue::add_dump_widget_children vfunc for
2602 const_fn_result_svalue. */
2604 void
2605 const_fn_result_svalue::
2606 add_dump_widget_children (text_art::tree_widget &w,
2607 const text_art::dump_widget_info &dwi) const
2609 for (unsigned i = 0; i < m_num_inputs; i++)
2611 pretty_printer pp;
2612 pp_printf (&pp, "arg %i", i);
2613 w.add_child (m_input_arr[i]->make_dump_widget (dwi,
2614 pp_formatted_text (&pp)));
2618 /* Subroutine of const_fn_result_svalue::dump_to_pp. */
2620 void
2621 const_fn_result_svalue::dump_input (pretty_printer *pp,
2622 unsigned input_idx,
2623 const svalue *sval,
2624 bool simple) const
2626 pp_printf (pp, "arg%i: ", input_idx);
2627 sval->dump_to_pp (pp, simple);
2630 /* Implementation of svalue::accept vfunc for const_fn_result_svalue. */
2632 void
2633 const_fn_result_svalue::accept (visitor *v) const
2635 for (unsigned i = 0; i < m_num_inputs; i++)
2636 m_input_arr[i]->accept (v);
2637 v->visit_const_fn_result_svalue (this);
2640 } // namespace ana
2642 #endif /* #if ENABLE_ANALYZER */