[RS6000] dg-do !compile and scan-assembler
[official-gcc.git] / gcc / analyzer / svalue.cc
blob8eece134e109c98e140711c8634c13484bd967d4
1 /* Symbolic values.
2 Copyright (C) 2019-2020 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 #include "system.h"
23 #include "coretypes.h"
24 #include "tree.h"
25 #include "diagnostic-core.h"
26 #include "gimple-pretty-print.h"
27 #include "function.h"
28 #include "basic-block.h"
29 #include "gimple.h"
30 #include "gimple-iterator.h"
31 #include "diagnostic-core.h"
32 #include "graphviz.h"
33 #include "options.h"
34 #include "cgraph.h"
35 #include "tree-dfa.h"
36 #include "stringpool.h"
37 #include "convert.h"
38 #include "target.h"
39 #include "fold-const.h"
40 #include "tree-pretty-print.h"
41 #include "tristate.h"
42 #include "bitmap.h"
43 #include "selftest.h"
44 #include "function.h"
45 #include "json.h"
46 #include "analyzer/analyzer.h"
47 #include "analyzer/analyzer-logging.h"
48 #include "options.h"
49 #include "cgraph.h"
50 #include "cfg.h"
51 #include "digraph.h"
52 #include "analyzer/call-string.h"
53 #include "analyzer/program-point.h"
54 #include "analyzer/store.h"
55 #include "analyzer/region-model.h"
57 #if ENABLE_ANALYZER
59 namespace ana {
61 /* struct complexity. */
63 /* Get complexity for a new node that references REG
64 (the complexity of REG, plus one for the new node). */
66 complexity::complexity (const region *reg)
67 : m_num_nodes (reg->get_complexity ().m_num_nodes + 1),
68 m_max_depth (reg->get_complexity ().m_max_depth + 1)
72 /* Get complexity for a new node that references SVAL.
73 (the complexity of SVAL, plus one for the new node). */
75 complexity::complexity (const svalue *sval)
76 : m_num_nodes (sval->get_complexity ().m_num_nodes + 1),
77 m_max_depth (sval->get_complexity ().m_max_depth + 1)
81 /* Get complexity for a new node that references nodes with complexity
82 C1 and C2. */
84 complexity
85 complexity::from_pair (const complexity &c1, const complexity &c2)
87 return complexity (c1.m_num_nodes + c2.m_num_nodes + 1,
88 MAX (c1.m_max_depth, c2.m_max_depth) + 1);
91 /* class svalue and its various subclasses. */
93 /* class svalue. */
95 /* Dump a representation of this svalue to stderr. */
97 DEBUG_FUNCTION void
98 svalue::dump (bool simple) const
100 pretty_printer pp;
101 pp_format_decoder (&pp) = default_tree_printer;
102 pp_show_color (&pp) = pp_show_color (global_dc->printer);
103 pp.buffer->stream = stderr;
104 dump_to_pp (&pp, simple);
105 pp_newline (&pp);
106 pp_flush (&pp);
109 /* Generate a textual representation of this svalue for debugging purposes. */
111 label_text
112 svalue::get_desc (bool simple) const
114 pretty_printer pp;
115 pp_format_decoder (&pp) = default_tree_printer;
116 dump_to_pp (&pp, simple);
117 return label_text::take (xstrdup (pp_formatted_text (&pp)));
120 /* Return a new json::string describing the svalue. */
122 json::value *
123 svalue::to_json () const
125 label_text desc = get_desc (true);
126 json::value *sval_js = new json::string (desc.m_buffer);
127 desc.maybe_free ();
128 return sval_js;
131 /* If this svalue is a constant_svalue, return the underlying tree constant.
132 Otherwise return NULL_TREE. */
134 tree
135 svalue::maybe_get_constant () const
137 if (const constant_svalue *cst_sval = dyn_cast_constant_svalue ())
138 return cst_sval->get_constant ();
139 else
140 return NULL_TREE;
143 /* If this svalue is a cast (i.e a unaryop NOP_EXPR or VIEW_CONVERT_EXPR),
144 return the underlying svalue.
145 Otherwise return NULL. */
147 const svalue *
148 svalue::maybe_undo_cast () const
150 if (const unaryop_svalue *unaryop_sval = dyn_cast_unaryop_svalue ())
152 enum tree_code op = unaryop_sval->get_op ();
153 if (op == NOP_EXPR || op == VIEW_CONVERT_EXPR)
154 return unaryop_sval->get_arg ();
156 return NULL;
159 /* If this svalue is an unmergeable decorator around another svalue, return
160 the underlying svalue.
161 Otherwise return this svalue. */
163 const svalue *
164 svalue::unwrap_any_unmergeable () const
166 if (const unmergeable_svalue *unmergeable = dyn_cast_unmergeable_svalue ())
167 return unmergeable->get_arg ();
168 return this;
171 /* Attempt to merge THIS with OTHER, returning the merged svalue.
172 Return NULL if not mergeable. */
174 const svalue *
175 svalue::can_merge_p (const svalue *other,
176 region_model_manager *mgr,
177 model_merger *merger) const
179 if (!(get_type () && other->get_type ()))
180 return NULL;
182 if (!types_compatible_p (get_type (), other->get_type ()))
183 return NULL;
185 /* Reject attempts to merge unmergeable svalues. */
186 if ((get_kind () == SK_UNMERGEABLE)
187 || (other->get_kind () == SK_UNMERGEABLE))
188 return NULL;
190 /* Reject attempts to merge NULL pointers with not-NULL-pointers. */
191 if (POINTER_TYPE_P (get_type ()))
193 bool null0 = false;
194 bool null1 = false;
195 if (tree cst0 = maybe_get_constant ())
196 if (zerop (cst0))
197 null0 = true;
198 if (tree cst1 = other->maybe_get_constant ())
199 if (zerop (cst1))
200 null1 = true;
201 if (null0 != null1)
202 return NULL;
205 /* Widening. */
206 /* Merge: (new_cst, existing_cst) -> widen (existing, new). */
207 if (maybe_get_constant () && other->maybe_get_constant ())
209 return mgr->get_or_create_widening_svalue (other->get_type (),
210 merger->m_point,
211 other, this);
214 /* Merger of:
215 this: BINOP (X, OP, CST)
216 other: X, where X is non-widening
217 to: WIDENING (other, this). */
218 if (const binop_svalue *binop_sval = dyn_cast_binop_svalue ())
219 if (binop_sval->get_arg0 () == other
220 && binop_sval->get_arg1 ()->get_kind () == SK_CONSTANT
221 && other->get_kind () != SK_WIDENING)
222 return mgr->get_or_create_widening_svalue (other->get_type (),
223 merger->m_point,
224 other, this);
226 /* Merge: (Widen(existing_val, V), existing_val) -> Widen (existing_val, V)
227 and thus get a fixed point. */
228 if (const widening_svalue *widen_sval = dyn_cast_widening_svalue ())
230 if (other == widen_sval->get_base_svalue ())
231 return this;
232 if (other == widen_sval->get_iter_svalue ())
233 return this;
236 if (const binop_svalue *binop_sval = dyn_cast_binop_svalue ())
237 if (const widening_svalue *widen_arg0
238 = binop_sval->get_arg0 ()->dyn_cast_widening_svalue ())
240 if (other == binop_sval->get_arg1 ())
242 /* Merger of: (Widen(..., OTHER) BINOP X)
243 and : OTHER
244 to : (Widen(..., OTHER) BINOP X)
245 e.g. merge of Widen(0, 1) + 1 with 1 to the Widen(0, 1) + 1. */
246 return this;
249 /* Merger of : (Widen() BINOP X)
250 and : Widen()
251 to : Widen()
252 e.g. merge of Widen(0, 1) + 1 and Widen(0, 1) to Widen(0, 1).
253 However, we want to update constraints for this case, since we're
254 considering another iteration.
255 Presumably we also want to ensure that it converges; we don't want
256 a descending chain of constraints. */
257 if (other == widen_arg0)
259 return widen_arg0;
262 /* Merger of:
263 this: BINOP(WIDENING(BASE, BINOP(BASE, X)), X)
264 other: BINOP(BASE, X)
265 to: WIDENING(BASE, BINOP(BASE, X)). */
266 if (widen_arg0->get_iter_svalue () == other)
267 if (const binop_svalue *other_binop_sval
268 = other->dyn_cast_binop_svalue ())
269 if (other_binop_sval->get_arg0 () == widen_arg0->get_base_svalue ()
270 && other_binop_sval->get_arg1 () == binop_sval->get_arg1 ())
271 return widen_arg0;
274 return mgr->get_or_create_unknown_svalue (get_type ());
277 /* Determine if this svalue is either within LIVE_SVALUES, or is implicitly
278 live with respect to LIVE_SVALUES and MODEL. */
280 bool
281 svalue::live_p (const svalue_set &live_svalues,
282 const region_model *model) const
284 /* Determine if SVAL is explicitly live. */
285 if (const_cast<svalue_set &> (live_svalues).contains (this))
286 return true;
288 /* Otherwise, determine if SVAL is implicitly live due to being made of
289 other live svalues. */
290 return implicitly_live_p (live_svalues, model);
293 /* Base implementation of svalue::implicitly_live_p. */
295 bool
296 svalue::implicitly_live_p (const svalue_set &, const region_model *) const
298 return false;
301 /* Comparator for imposing a deterministic order on constants that are
302 of the same type. */
304 static int
305 cmp_cst (const_tree cst1, const_tree cst2)
307 gcc_assert (TREE_TYPE (cst1) == TREE_TYPE (cst2));
308 gcc_assert (TREE_CODE (cst1) == TREE_CODE (cst2));
309 switch (TREE_CODE (cst1))
311 default:
312 gcc_unreachable ();
313 case INTEGER_CST:
314 return tree_int_cst_compare (cst1, cst2);
315 case STRING_CST:
316 return strcmp (TREE_STRING_POINTER (cst1),
317 TREE_STRING_POINTER (cst2));
318 case REAL_CST:
319 /* Impose an arbitrary but deterministic order. */
320 return memcmp (TREE_REAL_CST_PTR (cst1),
321 TREE_REAL_CST_PTR (cst2),
322 sizeof (real_value));
323 case VECTOR_CST:
324 if (int cmp_log2_npatterns
325 = ((int)VECTOR_CST_LOG2_NPATTERNS (cst1)
326 - (int)VECTOR_CST_LOG2_NPATTERNS (cst2)))
327 return cmp_log2_npatterns;
328 if (int cmp_nelts_per_pattern
329 = ((int)VECTOR_CST_NELTS_PER_PATTERN (cst1)
330 - (int)VECTOR_CST_NELTS_PER_PATTERN (cst2)))
331 return cmp_nelts_per_pattern;
332 unsigned encoded_nelts = vector_cst_encoded_nelts (cst1);
333 for (unsigned i = 0; i < encoded_nelts; i++)
334 if (int el_cmp = cmp_cst (VECTOR_CST_ENCODED_ELT (cst1, i),
335 VECTOR_CST_ENCODED_ELT (cst2, i)))
336 return el_cmp;
337 return 0;
341 /* Comparator for imposing a deterministic order on svalues. */
344 svalue::cmp_ptr (const svalue *sval1, const svalue *sval2)
346 if (sval1 == sval2)
347 return 0;
348 if (int cmp_kind = sval1->get_kind () - sval2->get_kind ())
349 return cmp_kind;
350 int t1 = sval1->get_type () ? TYPE_UID (sval1->get_type ()) : -1;
351 int t2 = sval2->get_type () ? TYPE_UID (sval2->get_type ()) : -1;
352 if (int cmp_type = t1 - t2)
353 return cmp_type;
354 switch (sval1->get_kind ())
356 default:
357 gcc_unreachable ();
358 case SK_REGION:
360 const region_svalue *region_sval1 = (const region_svalue *)sval1;
361 const region_svalue *region_sval2 = (const region_svalue *)sval2;
362 return region::cmp_ids (region_sval1->get_pointee (),
363 region_sval2->get_pointee ());
365 break;
366 case SK_CONSTANT:
368 const constant_svalue *constant_sval1 = (const constant_svalue *)sval1;
369 const constant_svalue *constant_sval2 = (const constant_svalue *)sval2;
370 const_tree cst1 = constant_sval1->get_constant ();
371 const_tree cst2 = constant_sval2->get_constant ();
372 return cmp_cst (cst1, cst2);
374 break;
375 case SK_UNKNOWN:
377 gcc_assert (sval1 == sval2);
378 return 0;
380 break;
381 case SK_POISONED:
383 const poisoned_svalue *poisoned_sval1 = (const poisoned_svalue *)sval1;
384 const poisoned_svalue *poisoned_sval2 = (const poisoned_svalue *)sval2;
385 return (poisoned_sval1->get_poison_kind ()
386 - poisoned_sval2->get_poison_kind ());
388 break;
389 case SK_SETJMP:
391 const setjmp_svalue *setjmp_sval1 = (const setjmp_svalue *)sval1;
392 const setjmp_svalue *setjmp_sval2 = (const setjmp_svalue *)sval2;
393 const setjmp_record &rec1 = setjmp_sval1->get_setjmp_record ();
394 const setjmp_record &rec2 = setjmp_sval2->get_setjmp_record ();
395 return setjmp_record::cmp (rec1, rec2);
397 break;
398 case SK_INITIAL:
400 const initial_svalue *initial_sval1 = (const initial_svalue *)sval1;
401 const initial_svalue *initial_sval2 = (const initial_svalue *)sval2;
402 return region::cmp_ids (initial_sval1->get_region (),
403 initial_sval2->get_region ());
405 break;
406 case SK_UNARYOP:
408 const unaryop_svalue *unaryop_sval1 = (const unaryop_svalue *)sval1;
409 const unaryop_svalue *unaryop_sval2 = (const unaryop_svalue *)sval2;
410 if (int op_cmp = unaryop_sval1->get_op () - unaryop_sval2->get_op ())
411 return op_cmp;
412 return svalue::cmp_ptr (unaryop_sval1->get_arg (),
413 unaryop_sval2->get_arg ());
415 break;
416 case SK_BINOP:
418 const binop_svalue *binop_sval1 = (const binop_svalue *)sval1;
419 const binop_svalue *binop_sval2 = (const binop_svalue *)sval2;
420 if (int op_cmp = binop_sval1->get_op () - binop_sval2->get_op ())
421 return op_cmp;
422 if (int arg0_cmp = svalue::cmp_ptr (binop_sval1->get_arg0 (),
423 binop_sval2->get_arg0 ()))
424 return arg0_cmp;
425 return svalue::cmp_ptr (binop_sval1->get_arg1 (),
426 binop_sval2->get_arg1 ());
428 break;
429 case SK_SUB:
431 const sub_svalue *sub_sval1 = (const sub_svalue *)sval1;
432 const sub_svalue *sub_sval2 = (const sub_svalue *)sval2;
433 if (int parent_cmp = svalue::cmp_ptr (sub_sval1->get_parent (),
434 sub_sval2->get_parent ()))
435 return parent_cmp;
436 return region::cmp_ids (sub_sval1->get_subregion (),
437 sub_sval2->get_subregion ());
439 break;
440 case SK_UNMERGEABLE:
442 const unmergeable_svalue *unmergeable_sval1
443 = (const unmergeable_svalue *)sval1;
444 const unmergeable_svalue *unmergeable_sval2
445 = (const unmergeable_svalue *)sval2;
446 return svalue::cmp_ptr (unmergeable_sval1->get_arg (),
447 unmergeable_sval2->get_arg ());
449 break;
450 case SK_PLACEHOLDER:
452 const placeholder_svalue *placeholder_sval1
453 = (const placeholder_svalue *)sval1;
454 const placeholder_svalue *placeholder_sval2
455 = (const placeholder_svalue *)sval2;
456 return strcmp (placeholder_sval1->get_name (),
457 placeholder_sval2->get_name ());
459 break;
460 case SK_WIDENING:
462 const widening_svalue *widening_sval1 = (const widening_svalue *)sval1;
463 const widening_svalue *widening_sval2 = (const widening_svalue *)sval2;
464 if (int point_cmp = function_point::cmp (widening_sval1->get_point (),
465 widening_sval2->get_point ()))
466 return point_cmp;
467 if (int base_cmp = svalue::cmp_ptr (widening_sval1->get_base_svalue (),
468 widening_sval2->get_base_svalue ()))
469 return base_cmp;
470 return svalue::cmp_ptr (widening_sval1->get_iter_svalue (),
471 widening_sval2->get_iter_svalue ());
473 break;
474 case SK_COMPOUND:
476 const compound_svalue *compound_sval1 = (const compound_svalue *)sval1;
477 const compound_svalue *compound_sval2 = (const compound_svalue *)sval2;
478 return binding_map::cmp (compound_sval1->get_map (),
479 compound_sval2->get_map ());
481 break;
482 case SK_CONJURED:
484 const conjured_svalue *conjured_sval1 = (const conjured_svalue *)sval1;
485 const conjured_svalue *conjured_sval2 = (const conjured_svalue *)sval2;
486 if (int stmt_cmp = (conjured_sval1->get_stmt ()->uid
487 - conjured_sval2->get_stmt ()->uid))
488 return stmt_cmp;
489 return region::cmp_ids (conjured_sval1->get_id_region (),
490 conjured_sval2->get_id_region ());
492 break;
496 /* Comparator for use by vec<const svalue *>::qsort. */
499 svalue::cmp_ptr_ptr (const void *p1, const void *p2)
501 const svalue *sval1 = *(const svalue * const *)p1;
502 const svalue *sval2 = *(const svalue * const *)p2;
503 return cmp_ptr (sval1, sval2);
506 /* class region_svalue : public svalue. */
508 /* Implementation of svalue::dump_to_pp vfunc for region_svalue. */
510 void
511 region_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
513 if (simple)
515 pp_string (pp, "&");
516 m_reg->dump_to_pp (pp, simple);
518 else
520 pp_string (pp, "region_svalue(");
521 print_quoted_type (pp, get_type ());
522 pp_string (pp, ", ");
523 m_reg->dump_to_pp (pp, simple);
524 pp_string (pp, ")");
528 /* Implementation of svalue::accept vfunc for region_svalue. */
530 void
531 region_svalue::accept (visitor *v) const
533 v->visit_region_svalue (this);
534 m_reg->accept (v);
537 /* Evaluate the condition LHS OP RHS.
538 Subroutine of region_model::eval_condition for when we have a pair of
539 pointers. */
541 tristate
542 region_svalue::eval_condition (const region_svalue *lhs,
543 enum tree_code op,
544 const region_svalue *rhs)
546 /* See if they point to the same region. */
547 const region *lhs_reg = lhs->get_pointee ();
548 const region *rhs_reg = rhs->get_pointee ();
549 bool ptr_equality = lhs_reg == rhs_reg;
550 switch (op)
552 default:
553 gcc_unreachable ();
555 case EQ_EXPR:
556 if (ptr_equality)
557 return tristate::TS_TRUE;
558 else
559 return tristate::TS_FALSE;
560 break;
562 case NE_EXPR:
563 if (ptr_equality)
564 return tristate::TS_FALSE;
565 else
566 return tristate::TS_TRUE;
567 break;
569 case GE_EXPR:
570 case LE_EXPR:
571 if (ptr_equality)
572 return tristate::TS_TRUE;
573 break;
575 case GT_EXPR:
576 case LT_EXPR:
577 if (ptr_equality)
578 return tristate::TS_FALSE;
579 break;
582 return tristate::TS_UNKNOWN;
585 /* class constant_svalue : public svalue. */
587 /* Implementation of svalue::dump_to_pp vfunc for constant_svalue. */
589 void
590 constant_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
592 if (simple)
594 pp_string (pp, "(");
595 dump_tree (pp, get_type ());
596 pp_string (pp, ")");
597 dump_tree (pp, m_cst_expr);
599 else
601 pp_string (pp, "constant_svalue(");
602 print_quoted_type (pp, get_type ());
603 pp_string (pp, ", ");
604 dump_tree (pp, m_cst_expr);
605 pp_string (pp, ")");
609 /* Implementation of svalue::accept vfunc for constant_svalue. */
611 void
612 constant_svalue::accept (visitor *v) const
614 v->visit_constant_svalue (this);
617 /* Implementation of svalue::implicitly_live_p vfunc for constant_svalue.
618 Constants are implicitly live. */
620 bool
621 constant_svalue::implicitly_live_p (const svalue_set &,
622 const region_model *) const
624 return true;
627 /* Evaluate the condition LHS OP RHS.
628 Subroutine of region_model::eval_condition for when we have a pair of
629 constants. */
631 tristate
632 constant_svalue::eval_condition (const constant_svalue *lhs,
633 enum tree_code op,
634 const constant_svalue *rhs)
636 tree lhs_const = lhs->get_constant ();
637 tree rhs_const = rhs->get_constant ();
639 gcc_assert (CONSTANT_CLASS_P (lhs_const));
640 gcc_assert (CONSTANT_CLASS_P (rhs_const));
642 /* Check for comparable types. */
643 if (types_compatible_p (TREE_TYPE (lhs_const), TREE_TYPE (rhs_const)))
645 tree comparison
646 = fold_binary (op, boolean_type_node, lhs_const, rhs_const);
647 if (comparison == boolean_true_node)
648 return tristate (tristate::TS_TRUE);
649 if (comparison == boolean_false_node)
650 return tristate (tristate::TS_FALSE);
652 return tristate::TS_UNKNOWN;
655 /* class unknown_svalue : public svalue. */
657 /* Implementation of svalue::dump_to_pp vfunc for unknown_svalue. */
659 void
660 unknown_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
662 if (simple)
664 pp_string (pp, "UNKNOWN(");
665 if (get_type ())
666 dump_tree (pp, get_type ());
667 pp_character (pp, ')');
669 else
671 pp_string (pp, "unknown_svalue(");
672 if (get_type ())
673 dump_tree (pp, get_type ());
674 pp_character (pp, ')');
678 /* Implementation of svalue::accept vfunc for unknown_svalue. */
680 void
681 unknown_svalue::accept (visitor *v) const
683 v->visit_unknown_svalue (this);
686 /* Get a string for KIND for use in debug dumps. */
688 const char *
689 poison_kind_to_str (enum poison_kind kind)
691 switch (kind)
693 default:
694 gcc_unreachable ();
695 case POISON_KIND_FREED:
696 return "freed";
697 case POISON_KIND_POPPED_STACK:
698 return "popped stack";
702 /* class poisoned_svalue : public svalue. */
704 /* Implementation of svalue::dump_to_pp vfunc for poisoned_svalue. */
706 void
707 poisoned_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
709 if (simple)
710 pp_printf (pp, "POISONED(%s)", poison_kind_to_str (m_kind));
711 else
712 pp_printf (pp, "poisoned_svalue(%s)", poison_kind_to_str (m_kind));
715 /* Implementation of svalue::accept vfunc for poisoned_svalue. */
717 void
718 poisoned_svalue::accept (visitor *v) const
720 v->visit_poisoned_svalue (this);
723 /* class setjmp_svalue's implementation is in engine.cc, so that it can use
724 the declaration of exploded_node. */
726 /* class initial_svalue : public svalue. */
728 /* Implementation of svalue::dump_to_pp vfunc for initial_svalue. */
730 void
731 initial_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
733 if (simple)
735 pp_string (pp, "INIT_VAL(");
736 m_reg->dump_to_pp (pp, simple);
737 pp_string (pp, ")");
739 else
741 pp_string (pp, "initial_svalue(");
742 print_quoted_type (pp, get_type ());
743 pp_string (pp, ", ");
744 m_reg->dump_to_pp (pp, simple);
745 pp_string (pp, ")");
749 /* Implementation of svalue::accept vfunc for initial_svalue. */
751 void
752 initial_svalue::accept (visitor *v) const
754 v->visit_initial_svalue (this);
755 m_reg->accept (v);
758 /* Implementation of svalue::implicitly_live_p vfunc for initial_svalue. */
760 bool
761 initial_svalue::implicitly_live_p (const svalue_set &,
762 const region_model *model) const
764 /* This svalue may be implicitly live if the region still implicitly
765 has its initial value and is reachable. */
767 /* It must be a region that exists; we don't want to consider
768 INIT_VAL(R) as still being implicitly reachable if R is in
769 a popped stack frame. */
770 if (model->region_exists_p (m_reg))
772 const svalue *reg_sval = model->get_store_value (m_reg);
773 if (reg_sval == this)
774 return true;
777 return false;
780 /* class unaryop_svalue : public svalue. */
782 /* Implementation of svalue::dump_to_pp vfunc for unaryop_svalue. */
784 void
785 unaryop_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
787 if (simple)
789 if (m_op == VIEW_CONVERT_EXPR || m_op == NOP_EXPR)
791 pp_string (pp, "CAST(");
792 dump_tree (pp, get_type ());
793 pp_string (pp, ", ");
794 m_arg->dump_to_pp (pp, simple);
795 pp_character (pp, ')');
797 else
799 pp_character (pp, '(');
800 pp_string (pp, get_tree_code_name (m_op));
801 //pp_string (pp, op_symbol_code (m_op));
802 m_arg->dump_to_pp (pp, simple);
803 pp_character (pp, ')');
806 else
808 pp_string (pp, "unaryop_svalue (");
809 pp_string (pp, get_tree_code_name (m_op));
810 pp_string (pp, ", ");
811 m_arg->dump_to_pp (pp, simple);
812 pp_character (pp, ')');
816 /* Implementation of svalue::accept vfunc for unaryop_svalue. */
818 void
819 unaryop_svalue::accept (visitor *v) const
821 v->visit_unaryop_svalue (this);
822 m_arg->accept (v);
825 /* Implementation of svalue::implicitly_live_p vfunc for unaryop_svalue. */
827 bool
828 unaryop_svalue::implicitly_live_p (const svalue_set &live_svalues,
829 const region_model *model) const
831 return get_arg ()->live_p (live_svalues, model);
834 /* class binop_svalue : public svalue. */
836 /* Implementation of svalue::dump_to_pp vfunc for binop_svalue. */
838 void
839 binop_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
841 if (simple)
843 pp_character (pp, '(');
844 m_arg0->dump_to_pp (pp, simple);
845 pp_string (pp, op_symbol_code (m_op));
846 m_arg1->dump_to_pp (pp, simple);
847 pp_character (pp, ')');
849 else
851 pp_string (pp, "binop_svalue (");
852 pp_string (pp, get_tree_code_name (m_op));
853 pp_string (pp, ", ");
854 m_arg0->dump_to_pp (pp, simple);
855 pp_string (pp, ", ");
856 m_arg1->dump_to_pp (pp, simple);
857 pp_character (pp, ')');
861 /* Implementation of svalue::accept vfunc for binop_svalue. */
863 void
864 binop_svalue::accept (visitor *v) const
866 v->visit_binop_svalue (this);
867 m_arg0->accept (v);
868 m_arg1->accept (v);
871 /* Implementation of svalue::implicitly_live_p vfunc for binop_svalue. */
873 bool
874 binop_svalue::implicitly_live_p (const svalue_set &live_svalues,
875 const region_model *model) const
877 return (get_arg0 ()->live_p (live_svalues, model)
878 && get_arg1 ()->live_p (live_svalues, model));
881 /* class sub_svalue : public svalue. */
883 /* sub_svalue'c ctor. */
885 sub_svalue::sub_svalue (tree type, const svalue *parent_svalue,
886 const region *subregion)
887 : svalue (complexity::from_pair (parent_svalue->get_complexity (),
888 subregion->get_complexity ()),
889 type),
890 m_parent_svalue (parent_svalue), m_subregion (subregion)
894 /* Implementation of svalue::dump_to_pp vfunc for sub_svalue. */
896 void
897 sub_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
899 if (simple)
901 pp_string (pp, "SUB(");
902 m_parent_svalue->dump_to_pp (pp, simple);
903 pp_string (pp, ", ");
904 m_subregion->dump_to_pp (pp, simple);
905 pp_character (pp, ')');
907 else
909 pp_string (pp, "sub_svalue (");
910 pp_string (pp, ", ");
911 m_parent_svalue->dump_to_pp (pp, simple);
912 pp_string (pp, ", ");
913 m_subregion->dump_to_pp (pp, simple);
914 pp_character (pp, ')');
918 /* Implementation of svalue::accept vfunc for sub_svalue. */
920 void
921 sub_svalue::accept (visitor *v) const
923 v->visit_sub_svalue (this);
924 m_parent_svalue->accept (v);
925 m_subregion->accept (v);
928 /* Implementation of svalue::implicitly_live_p vfunc for sub_svalue. */
930 bool
931 sub_svalue::implicitly_live_p (const svalue_set &live_svalues,
932 const region_model *model) const
934 return get_parent ()->live_p (live_svalues, model);
937 /* class widening_svalue : public svalue. */
939 /* Implementation of svalue::dump_to_pp vfunc for widening_svalue. */
941 void
942 widening_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
944 if (simple)
946 pp_string (pp, "WIDENING(");
947 pp_character (pp, '{');
948 m_point.print (pp, format (false));
949 pp_string (pp, "}, ");
950 m_base_sval->dump_to_pp (pp, simple);
951 pp_string (pp, ", ");
952 m_iter_sval->dump_to_pp (pp, simple);
953 pp_character (pp, ')');
955 else
957 pp_string (pp, "widening_svalue (");
958 pp_string (pp, ", ");
959 pp_character (pp, '{');
960 m_point.print (pp, format (false));
961 pp_string (pp, "}, ");
962 m_base_sval->dump_to_pp (pp, simple);
963 pp_string (pp, ", ");
964 m_iter_sval->dump_to_pp (pp, simple);
965 pp_character (pp, ')');
969 /* Implementation of svalue::accept vfunc for widening_svalue. */
971 void
972 widening_svalue::accept (visitor *v) const
974 v->visit_widening_svalue (this);
975 m_base_sval->accept (v);
976 m_iter_sval->accept (v);
979 /* Attempt to determine in which direction this value is changing
980 w.r.t. the initial value. */
982 enum widening_svalue::direction_t
983 widening_svalue::get_direction () const
985 tree base_cst = m_base_sval->maybe_get_constant ();
986 if (base_cst == NULL_TREE)
987 return DIR_UNKNOWN;
988 tree iter_cst = m_iter_sval->maybe_get_constant ();
989 if (iter_cst == NULL_TREE)
990 return DIR_UNKNOWN;
992 tree iter_gt_base = fold_binary (GT_EXPR, boolean_type_node,
993 iter_cst, base_cst);
994 if (iter_gt_base == boolean_true_node)
995 return DIR_ASCENDING;
997 tree iter_lt_base = fold_binary (LT_EXPR, boolean_type_node,
998 iter_cst, base_cst);
999 if (iter_lt_base == boolean_true_node)
1000 return DIR_DESCENDING;
1002 return DIR_UNKNOWN;
1005 /* Compare this value against constant RHS_CST. */
1007 tristate
1008 widening_svalue::eval_condition_without_cm (enum tree_code op,
1009 tree rhs_cst) const
1011 tree base_cst = m_base_sval->maybe_get_constant ();
1012 if (base_cst == NULL_TREE)
1013 return tristate::TS_UNKNOWN;
1014 tree iter_cst = m_iter_sval->maybe_get_constant ();
1015 if (iter_cst == NULL_TREE)
1016 return tristate::TS_UNKNOWN;
1018 switch (get_direction ())
1020 default:
1021 gcc_unreachable ();
1022 case DIR_ASCENDING:
1023 /* LHS is in [base_cst, +ve infinity), assuming no overflow. */
1024 switch (op)
1026 case LE_EXPR:
1027 case LT_EXPR:
1029 /* [BASE, +INF) OP RHS:
1030 This is either true or false at +ve ininity,
1031 It can be true for points X where X OP RHS, so we have either
1032 "false", or "unknown". */
1033 tree base_op_rhs = fold_binary (op, boolean_type_node,
1034 base_cst, rhs_cst);
1035 if (base_op_rhs == boolean_true_node)
1036 return tristate::TS_UNKNOWN;
1037 else
1038 return tristate::TS_FALSE;
1041 case GE_EXPR:
1042 case GT_EXPR:
1044 /* [BASE, +INF) OP RHS:
1045 This is true at +ve infinity. It will be true everywhere
1046 in the range if BASE >= RHS. */
1047 tree base_op_rhs = fold_binary (op, boolean_type_node,
1048 base_cst, rhs_cst);
1049 if (base_op_rhs == boolean_true_node)
1050 return tristate::TS_TRUE;
1051 else
1052 return tristate::TS_UNKNOWN;
1055 case EQ_EXPR:
1057 /* [BASE, +INF) == RHS:
1058 Could this be true at any point in the range? If so we
1059 have "unknown", otherwise we have "false". */
1060 tree base_le_rhs = fold_binary (LE_EXPR, boolean_type_node,
1061 base_cst, rhs_cst);
1062 if (base_le_rhs == boolean_true_node)
1063 return tristate::TS_UNKNOWN;
1064 else
1065 return tristate::TS_FALSE;
1068 case NE_EXPR:
1070 /* [BASE, +INF) != RHS:
1071 Could we have equality at any point in the range? If so we
1072 have "unknown", otherwise we have "true". */
1073 tree base_le_rhs = fold_binary (LE_EXPR, boolean_type_node,
1074 base_cst, rhs_cst);
1075 if (base_le_rhs == boolean_true_node)
1076 return tristate::TS_UNKNOWN;
1077 else
1078 return tristate::TS_TRUE;
1081 default:
1082 return tristate::TS_UNKNOWN;
1085 case DIR_DESCENDING:
1086 /* LHS is in (-ve infinity, base_cst], assuming no overflow. */
1087 return tristate::TS_UNKNOWN;
1089 case DIR_UNKNOWN:
1090 return tristate::TS_UNKNOWN;
1094 /* class placeholder_svalue : public svalue. */
1096 /* Implementation of svalue::dump_to_pp vfunc for placeholder_svalue. */
1098 void
1099 placeholder_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
1101 if (simple)
1102 pp_printf (pp, "PLACEHOLDER(%qs)", m_name);
1103 else
1104 pp_printf (pp, "placeholder_svalue (%qs)", m_name);
1107 /* Implementation of svalue::accept vfunc for placeholder_svalue. */
1109 void
1110 placeholder_svalue::accept (visitor *v) const
1112 v->visit_placeholder_svalue (this);
1115 /* class unmergeable_svalue : public svalue. */
1117 /* Implementation of svalue::dump_to_pp vfunc for unmergeable_svalue. */
1119 void
1120 unmergeable_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
1122 if (simple)
1124 pp_string (pp, "UNMERGEABLE(");
1125 m_arg->dump_to_pp (pp, simple);
1126 pp_character (pp, ')');
1128 else
1130 pp_string (pp, "unmergeable_svalue (");
1131 m_arg->dump_to_pp (pp, simple);
1132 pp_character (pp, ')');
1136 /* Implementation of svalue::accept vfunc for unmergeable_svalue. */
1138 void
1139 unmergeable_svalue::accept (visitor *v) const
1141 v->visit_unmergeable_svalue (this);
1142 m_arg->accept (v);
1145 /* Implementation of svalue::implicitly_live_p vfunc for unmergeable_svalue. */
1147 bool
1148 unmergeable_svalue::implicitly_live_p (const svalue_set &live_svalues,
1149 const region_model *model) const
1151 return get_arg ()->live_p (live_svalues, model);
1154 /* class compound_svalue : public svalue. */
1156 compound_svalue::compound_svalue (tree type, const binding_map &map)
1157 : svalue (calc_complexity (map), type), m_map (map)
1159 /* All keys within the underlying binding_map are required to be concrete,
1160 not symbolic. */
1161 #if CHECKING_P
1162 for (iterator_t iter = begin (); iter != end (); ++iter)
1164 const binding_key *key = (*iter).first;
1165 gcc_assert (key->concrete_p ());
1167 #endif
1170 /* Implementation of svalue::dump_to_pp vfunc for compound_svalue. */
1172 void
1173 compound_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
1175 if (simple)
1177 pp_string (pp, "COMPOUND(");
1178 m_map.dump_to_pp (pp, simple, false);
1179 pp_character (pp, ')');
1181 else
1183 pp_string (pp, "compound_svalue (");
1184 pp_string (pp, ", ");
1185 pp_character (pp, '{');
1186 m_map.dump_to_pp (pp, simple, false);
1187 pp_string (pp, "}, ");
1188 pp_character (pp, ')');
1192 /* Implementation of svalue::accept vfunc for compound_svalue. */
1194 void
1195 compound_svalue::accept (visitor *v) const
1197 v->visit_compound_svalue (this);
1198 for (binding_map::iterator_t iter = m_map.begin ();
1199 iter != m_map.end (); ++iter)
1201 //(*iter).first.accept (v);
1202 (*iter).second->accept (v);
1206 /* Calculate what the complexity of a compound_svalue instance for MAP
1207 will be, based on the svalues bound within MAP. */
1209 complexity
1210 compound_svalue::calc_complexity (const binding_map &map)
1212 unsigned num_child_nodes = 0;
1213 unsigned max_child_depth = 0;
1214 for (binding_map::iterator_t iter = map.begin ();
1215 iter != map.end (); ++iter)
1217 const complexity &sval_c = (*iter).second->get_complexity ();
1218 num_child_nodes += sval_c.m_num_nodes;
1219 max_child_depth = MAX (max_child_depth, sval_c.m_max_depth);
1221 return complexity (num_child_nodes + 1, max_child_depth + 1);
1224 /* class conjured_svalue : public svalue. */
1226 /* Implementation of svalue::dump_to_pp vfunc for conjured_svalue. */
1228 void
1229 conjured_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
1231 if (simple)
1233 pp_string (pp, "CONJURED(");
1234 pp_gimple_stmt_1 (pp, m_stmt, 0, (dump_flags_t)0);
1235 pp_string (pp, ", ");
1236 m_id_reg->dump_to_pp (pp, simple);
1237 pp_character (pp, ')');
1239 else
1241 pp_string (pp, "conjured_svalue (");
1242 pp_string (pp, ", ");
1243 pp_gimple_stmt_1 (pp, m_stmt, 0, (dump_flags_t)0);
1244 pp_string (pp, ", ");
1245 m_id_reg->dump_to_pp (pp, simple);
1246 pp_character (pp, ')');
1250 /* Implementation of svalue::accept vfunc for conjured_svalue. */
1252 void
1253 conjured_svalue::accept (visitor *v) const
1255 v->visit_conjured_svalue (this);
1256 m_id_reg->accept (v);
1259 } // namespace ana
1261 #endif /* #if ENABLE_ANALYZER */