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)
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/>. */
23 #include "coretypes.h"
25 #include "diagnostic-core.h"
26 #include "gimple-pretty-print.h"
28 #include "basic-block.h"
30 #include "gimple-iterator.h"
31 #include "diagnostic-core.h"
36 #include "stringpool.h"
39 #include "fold-const.h"
40 #include "tree-pretty-print.h"
46 #include "analyzer/analyzer.h"
47 #include "analyzer/analyzer-logging.h"
52 #include "analyzer/call-string.h"
53 #include "analyzer/program-point.h"
54 #include "analyzer/store.h"
55 #include "analyzer/region-model.h"
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
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. */
95 /* Dump a representation of this svalue to stderr. */
98 svalue::dump (bool simple
) const
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
);
109 /* Generate a textual representation of this svalue for debugging purposes. */
112 svalue::get_desc (bool simple
) const
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. */
123 svalue::to_json () const
125 label_text desc
= get_desc (true);
126 json::value
*sval_js
= new json::string (desc
.m_buffer
);
131 /* If this svalue is a constant_svalue, return the underlying tree constant.
132 Otherwise return NULL_TREE. */
135 svalue::maybe_get_constant () const
137 if (const constant_svalue
*cst_sval
= dyn_cast_constant_svalue ())
138 return cst_sval
->get_constant ();
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. */
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 ();
159 /* If this svalue is an unmergeable decorator around another svalue, return
160 the underlying svalue.
161 Otherwise return this svalue. */
164 svalue::unwrap_any_unmergeable () const
166 if (const unmergeable_svalue
*unmergeable
= dyn_cast_unmergeable_svalue ())
167 return unmergeable
->get_arg ();
171 /* Attempt to merge THIS with OTHER, returning the merged svalue.
172 Return NULL if not mergeable. */
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 ()))
182 if (!types_compatible_p (get_type (), other
->get_type ()))
185 /* Reject attempts to merge unmergeable svalues. */
186 if ((get_kind () == SK_UNMERGEABLE
)
187 || (other
->get_kind () == SK_UNMERGEABLE
))
190 /* Reject attempts to merge NULL pointers with not-NULL-pointers. */
191 if (POINTER_TYPE_P (get_type ()))
195 if (tree cst0
= maybe_get_constant ())
198 if (tree cst1
= other
->maybe_get_constant ())
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 (),
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 (),
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 ())
232 if (other
== widen_sval
->get_iter_svalue ())
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)
244 to : (Widen(..., OTHER) BINOP X)
245 e.g. merge of Widen(0, 1) + 1 with 1 to the Widen(0, 1) + 1. */
249 /* Merger of : (Widen() BINOP X)
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
)
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 ())
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. */
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))
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. */
296 svalue::implicitly_live_p (const svalue_set
&, const region_model
*) const
301 /* Comparator for imposing a deterministic order on constants that are
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
))
314 return tree_int_cst_compare (cst1
, cst2
);
316 return strcmp (TREE_STRING_POINTER (cst1
),
317 TREE_STRING_POINTER (cst2
));
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
));
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
)))
341 /* Comparator for imposing a deterministic order on svalues. */
344 svalue::cmp_ptr (const svalue
*sval1
, const svalue
*sval2
)
348 if (int cmp_kind
= sval1
->get_kind () - sval2
->get_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
)
354 switch (sval1
->get_kind ())
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 ());
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
);
377 gcc_assert (sval1
== sval2
);
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 ());
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
);
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 ());
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 ())
412 return svalue::cmp_ptr (unaryop_sval1
->get_arg (),
413 unaryop_sval2
->get_arg ());
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 ())
422 if (int arg0_cmp
= svalue::cmp_ptr (binop_sval1
->get_arg0 (),
423 binop_sval2
->get_arg0 ()))
425 return svalue::cmp_ptr (binop_sval1
->get_arg1 (),
426 binop_sval2
->get_arg1 ());
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 ()))
436 return region::cmp_ids (sub_sval1
->get_subregion (),
437 sub_sval2
->get_subregion ());
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 ());
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 ());
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 ()))
467 if (int base_cmp
= svalue::cmp_ptr (widening_sval1
->get_base_svalue (),
468 widening_sval2
->get_base_svalue ()))
470 return svalue::cmp_ptr (widening_sval1
->get_iter_svalue (),
471 widening_sval2
->get_iter_svalue ());
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 ());
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
))
489 return region::cmp_ids (conjured_sval1
->get_id_region (),
490 conjured_sval2
->get_id_region ());
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. */
511 region_svalue::dump_to_pp (pretty_printer
*pp
, bool simple
) const
516 m_reg
->dump_to_pp (pp
, simple
);
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
);
528 /* Implementation of svalue::accept vfunc for region_svalue. */
531 region_svalue::accept (visitor
*v
) const
533 v
->visit_region_svalue (this);
537 /* Evaluate the condition LHS OP RHS.
538 Subroutine of region_model::eval_condition for when we have a pair of
542 region_svalue::eval_condition (const region_svalue
*lhs
,
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
;
557 return tristate::TS_TRUE
;
559 return tristate::TS_FALSE
;
564 return tristate::TS_FALSE
;
566 return tristate::TS_TRUE
;
572 return tristate::TS_TRUE
;
578 return tristate::TS_FALSE
;
582 return tristate::TS_UNKNOWN
;
585 /* class constant_svalue : public svalue. */
587 /* Implementation of svalue::dump_to_pp vfunc for constant_svalue. */
590 constant_svalue::dump_to_pp (pretty_printer
*pp
, bool simple
) const
595 dump_tree (pp
, get_type ());
597 dump_tree (pp
, m_cst_expr
);
601 pp_string (pp
, "constant_svalue(");
602 print_quoted_type (pp
, get_type ());
603 pp_string (pp
, ", ");
604 dump_tree (pp
, m_cst_expr
);
609 /* Implementation of svalue::accept vfunc for constant_svalue. */
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. */
621 constant_svalue::implicitly_live_p (const svalue_set
&,
622 const region_model
*) const
627 /* Evaluate the condition LHS OP RHS.
628 Subroutine of region_model::eval_condition for when we have a pair of
632 constant_svalue::eval_condition (const constant_svalue
*lhs
,
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
)))
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. */
660 unknown_svalue::dump_to_pp (pretty_printer
*pp
, bool simple
) const
664 pp_string (pp
, "UNKNOWN(");
666 dump_tree (pp
, get_type ());
667 pp_character (pp
, ')');
671 pp_string (pp
, "unknown_svalue(");
673 dump_tree (pp
, get_type ());
674 pp_character (pp
, ')');
678 /* Implementation of svalue::accept vfunc for unknown_svalue. */
681 unknown_svalue::accept (visitor
*v
) const
683 v
->visit_unknown_svalue (this);
686 /* Get a string for KIND for use in debug dumps. */
689 poison_kind_to_str (enum poison_kind kind
)
695 case POISON_KIND_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. */
707 poisoned_svalue::dump_to_pp (pretty_printer
*pp
, bool simple
) const
710 pp_printf (pp
, "POISONED(%s)", poison_kind_to_str (m_kind
));
712 pp_printf (pp
, "poisoned_svalue(%s)", poison_kind_to_str (m_kind
));
715 /* Implementation of svalue::accept vfunc for poisoned_svalue. */
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. */
731 initial_svalue::dump_to_pp (pretty_printer
*pp
, bool simple
) const
735 pp_string (pp
, "INIT_VAL(");
736 m_reg
->dump_to_pp (pp
, simple
);
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
);
749 /* Implementation of svalue::accept vfunc for initial_svalue. */
752 initial_svalue::accept (visitor
*v
) const
754 v
->visit_initial_svalue (this);
758 /* Implementation of svalue::implicitly_live_p vfunc for initial_svalue. */
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)
780 /* class unaryop_svalue : public svalue. */
782 /* Implementation of svalue::dump_to_pp vfunc for unaryop_svalue. */
785 unaryop_svalue::dump_to_pp (pretty_printer
*pp
, bool simple
) const
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
, ')');
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
, ')');
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. */
819 unaryop_svalue::accept (visitor
*v
) const
821 v
->visit_unaryop_svalue (this);
825 /* Implementation of svalue::implicitly_live_p vfunc for unaryop_svalue. */
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. */
839 binop_svalue::dump_to_pp (pretty_printer
*pp
, bool simple
) const
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
, ')');
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. */
864 binop_svalue::accept (visitor
*v
) const
866 v
->visit_binop_svalue (this);
871 /* Implementation of svalue::implicitly_live_p vfunc for binop_svalue. */
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 ()),
890 m_parent_svalue (parent_svalue
), m_subregion (subregion
)
894 /* Implementation of svalue::dump_to_pp vfunc for sub_svalue. */
897 sub_svalue::dump_to_pp (pretty_printer
*pp
, bool simple
) const
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
, ')');
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. */
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. */
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. */
942 widening_svalue::dump_to_pp (pretty_printer
*pp
, bool simple
) const
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
, ')');
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. */
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
)
988 tree iter_cst
= m_iter_sval
->maybe_get_constant ();
989 if (iter_cst
== NULL_TREE
)
992 tree iter_gt_base
= fold_binary (GT_EXPR
, boolean_type_node
,
994 if (iter_gt_base
== boolean_true_node
)
995 return DIR_ASCENDING
;
997 tree iter_lt_base
= fold_binary (LT_EXPR
, boolean_type_node
,
999 if (iter_lt_base
== boolean_true_node
)
1000 return DIR_DESCENDING
;
1005 /* Compare this value against constant RHS_CST. */
1008 widening_svalue::eval_condition_without_cm (enum tree_code op
,
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 ())
1023 /* LHS is in [base_cst, +ve infinity), assuming no overflow. */
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
,
1035 if (base_op_rhs
== boolean_true_node
)
1036 return tristate::TS_UNKNOWN
;
1038 return tristate::TS_FALSE
;
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
,
1049 if (base_op_rhs
== boolean_true_node
)
1050 return tristate::TS_TRUE
;
1052 return tristate::TS_UNKNOWN
;
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
,
1062 if (base_le_rhs
== boolean_true_node
)
1063 return tristate::TS_UNKNOWN
;
1065 return tristate::TS_FALSE
;
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
,
1075 if (base_le_rhs
== boolean_true_node
)
1076 return tristate::TS_UNKNOWN
;
1078 return tristate::TS_TRUE
;
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
;
1090 return tristate::TS_UNKNOWN
;
1094 /* class placeholder_svalue : public svalue. */
1096 /* Implementation of svalue::dump_to_pp vfunc for placeholder_svalue. */
1099 placeholder_svalue::dump_to_pp (pretty_printer
*pp
, bool simple
) const
1102 pp_printf (pp
, "PLACEHOLDER(%qs)", m_name
);
1104 pp_printf (pp
, "placeholder_svalue (%qs)", m_name
);
1107 /* Implementation of svalue::accept vfunc for placeholder_svalue. */
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. */
1120 unmergeable_svalue::dump_to_pp (pretty_printer
*pp
, bool simple
) const
1124 pp_string (pp
, "UNMERGEABLE(");
1125 m_arg
->dump_to_pp (pp
, simple
);
1126 pp_character (pp
, ')');
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. */
1139 unmergeable_svalue::accept (visitor
*v
) const
1141 v
->visit_unmergeable_svalue (this);
1145 /* Implementation of svalue::implicitly_live_p vfunc for unmergeable_svalue. */
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,
1162 for (iterator_t iter
= begin (); iter
!= end (); ++iter
)
1164 const binding_key
*key
= (*iter
).first
;
1165 gcc_assert (key
->concrete_p ());
1170 /* Implementation of svalue::dump_to_pp vfunc for compound_svalue. */
1173 compound_svalue::dump_to_pp (pretty_printer
*pp
, bool simple
) const
1177 pp_string (pp
, "COMPOUND(");
1178 m_map
.dump_to_pp (pp
, simple
, false);
1179 pp_character (pp
, ')');
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. */
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. */
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. */
1229 conjured_svalue::dump_to_pp (pretty_printer
*pp
, bool simple
) const
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
, ')');
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. */
1253 conjured_svalue::accept (visitor
*v
) const
1255 v
->visit_conjured_svalue (this);
1256 m_id_reg
->accept (v
);
1261 #endif /* #if ENABLE_ANALYZER */