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 /* class region_svalue : public svalue. */
303 /* Implementation of svalue::dump_to_pp vfunc for region_svalue. */
306 region_svalue::dump_to_pp (pretty_printer
*pp
, bool simple
) const
311 m_reg
->dump_to_pp (pp
, simple
);
315 pp_string (pp
, "region_svalue(");
316 print_quoted_type (pp
, get_type ());
317 pp_string (pp
, ", ");
318 m_reg
->dump_to_pp (pp
, simple
);
323 /* Implementation of svalue::accept vfunc for region_svalue. */
326 region_svalue::accept (visitor
*v
) const
328 v
->visit_region_svalue (this);
332 /* Evaluate the condition LHS OP RHS.
333 Subroutine of region_model::eval_condition for when we have a pair of
337 region_svalue::eval_condition (const region_svalue
*lhs
,
339 const region_svalue
*rhs
)
341 /* See if they point to the same region. */
342 const region
*lhs_reg
= lhs
->get_pointee ();
343 const region
*rhs_reg
= rhs
->get_pointee ();
344 bool ptr_equality
= lhs_reg
== rhs_reg
;
352 return tristate::TS_TRUE
;
354 return tristate::TS_FALSE
;
359 return tristate::TS_FALSE
;
361 return tristate::TS_TRUE
;
367 return tristate::TS_TRUE
;
373 return tristate::TS_FALSE
;
377 return tristate::TS_UNKNOWN
;
380 /* class constant_svalue : public svalue. */
382 /* Implementation of svalue::dump_to_pp vfunc for constant_svalue. */
385 constant_svalue::dump_to_pp (pretty_printer
*pp
, bool simple
) const
390 dump_tree (pp
, get_type ());
392 dump_tree (pp
, m_cst_expr
);
396 pp_string (pp
, "constant_svalue(");
397 print_quoted_type (pp
, get_type ());
398 pp_string (pp
, ", ");
399 dump_tree (pp
, m_cst_expr
);
404 /* Implementation of svalue::accept vfunc for constant_svalue. */
407 constant_svalue::accept (visitor
*v
) const
409 v
->visit_constant_svalue (this);
412 /* Implementation of svalue::implicitly_live_p vfunc for constant_svalue.
413 Constants are implicitly live. */
416 constant_svalue::implicitly_live_p (const svalue_set
&,
417 const region_model
*) const
422 /* Evaluate the condition LHS OP RHS.
423 Subroutine of region_model::eval_condition for when we have a pair of
427 constant_svalue::eval_condition (const constant_svalue
*lhs
,
429 const constant_svalue
*rhs
)
431 tree lhs_const
= lhs
->get_constant ();
432 tree rhs_const
= rhs
->get_constant ();
434 gcc_assert (CONSTANT_CLASS_P (lhs_const
));
435 gcc_assert (CONSTANT_CLASS_P (rhs_const
));
437 /* Check for comparable types. */
438 if (types_compatible_p (TREE_TYPE (lhs_const
), TREE_TYPE (rhs_const
)))
441 = fold_binary (op
, boolean_type_node
, lhs_const
, rhs_const
);
442 if (comparison
== boolean_true_node
)
443 return tristate (tristate::TS_TRUE
);
444 if (comparison
== boolean_false_node
)
445 return tristate (tristate::TS_FALSE
);
447 return tristate::TS_UNKNOWN
;
450 /* class unknown_svalue : public svalue. */
452 /* Implementation of svalue::dump_to_pp vfunc for unknown_svalue. */
455 unknown_svalue::dump_to_pp (pretty_printer
*pp
, bool simple
) const
459 pp_string (pp
, "UNKNOWN(");
461 dump_tree (pp
, get_type ());
462 pp_character (pp
, ')');
466 pp_string (pp
, "unknown_svalue(");
468 dump_tree (pp
, get_type ());
469 pp_character (pp
, ')');
473 /* Implementation of svalue::accept vfunc for unknown_svalue. */
476 unknown_svalue::accept (visitor
*v
) const
478 v
->visit_unknown_svalue (this);
481 /* Get a string for KIND for use in debug dumps. */
484 poison_kind_to_str (enum poison_kind kind
)
490 case POISON_KIND_FREED
:
492 case POISON_KIND_POPPED_STACK
:
493 return "popped stack";
497 /* class poisoned_svalue : public svalue. */
499 /* Implementation of svalue::dump_to_pp vfunc for poisoned_svalue. */
502 poisoned_svalue::dump_to_pp (pretty_printer
*pp
, bool simple
) const
505 pp_printf (pp
, "POISONED(%s)", poison_kind_to_str (m_kind
));
507 pp_printf (pp
, "poisoned_svalue(%s)", poison_kind_to_str (m_kind
));
510 /* Implementation of svalue::accept vfunc for poisoned_svalue. */
513 poisoned_svalue::accept (visitor
*v
) const
515 v
->visit_poisoned_svalue (this);
518 /* class setjmp_svalue's implementation is in engine.cc, so that it can use
519 the declaration of exploded_node. */
521 /* class initial_svalue : public svalue. */
523 /* Implementation of svalue::dump_to_pp vfunc for initial_svalue. */
526 initial_svalue::dump_to_pp (pretty_printer
*pp
, bool simple
) const
530 pp_string (pp
, "INIT_VAL(");
531 m_reg
->dump_to_pp (pp
, simple
);
536 pp_string (pp
, "initial_svalue(");
537 print_quoted_type (pp
, get_type ());
538 pp_string (pp
, ", ");
539 m_reg
->dump_to_pp (pp
, simple
);
544 /* Implementation of svalue::accept vfunc for initial_svalue. */
547 initial_svalue::accept (visitor
*v
) const
549 v
->visit_initial_svalue (this);
553 /* Implementation of svalue::implicitly_live_p vfunc for initial_svalue. */
556 initial_svalue::implicitly_live_p (const svalue_set
&,
557 const region_model
*model
) const
559 /* This svalue may be implicitly live if the region still implicitly
560 has its initial value and is reachable. */
562 /* It must be a region that exists; we don't want to consider
563 INIT_VAL(R) as still being implicitly reachable if R is in
564 a popped stack frame. */
565 if (model
->region_exists_p (m_reg
))
567 const svalue
*reg_sval
= model
->get_store_value (m_reg
);
568 if (reg_sval
== this)
575 /* class unaryop_svalue : public svalue. */
577 /* Implementation of svalue::dump_to_pp vfunc for unaryop_svalue. */
580 unaryop_svalue::dump_to_pp (pretty_printer
*pp
, bool simple
) const
584 if (m_op
== VIEW_CONVERT_EXPR
|| m_op
== NOP_EXPR
)
586 pp_string (pp
, "CAST(");
587 dump_tree (pp
, get_type ());
588 pp_string (pp
, ", ");
589 m_arg
->dump_to_pp (pp
, simple
);
590 pp_character (pp
, ')');
594 pp_character (pp
, '(');
595 pp_string (pp
, get_tree_code_name (m_op
));
596 //pp_string (pp, op_symbol_code (m_op));
597 m_arg
->dump_to_pp (pp
, simple
);
598 pp_character (pp
, ')');
603 pp_string (pp
, "unaryop_svalue (");
604 pp_string (pp
, get_tree_code_name (m_op
));
605 pp_string (pp
, ", ");
606 m_arg
->dump_to_pp (pp
, simple
);
607 pp_character (pp
, ')');
611 /* Implementation of svalue::accept vfunc for unaryop_svalue. */
614 unaryop_svalue::accept (visitor
*v
) const
616 v
->visit_unaryop_svalue (this);
620 /* Implementation of svalue::implicitly_live_p vfunc for unaryop_svalue. */
623 unaryop_svalue::implicitly_live_p (const svalue_set
&live_svalues
,
624 const region_model
*model
) const
626 return get_arg ()->live_p (live_svalues
, model
);
629 /* class binop_svalue : public svalue. */
631 /* Implementation of svalue::dump_to_pp vfunc for binop_svalue. */
634 binop_svalue::dump_to_pp (pretty_printer
*pp
, bool simple
) const
638 pp_character (pp
, '(');
639 m_arg0
->dump_to_pp (pp
, simple
);
640 pp_string (pp
, op_symbol_code (m_op
));
641 m_arg1
->dump_to_pp (pp
, simple
);
642 pp_character (pp
, ')');
646 pp_string (pp
, "binop_svalue (");
647 pp_string (pp
, get_tree_code_name (m_op
));
648 pp_string (pp
, ", ");
649 m_arg0
->dump_to_pp (pp
, simple
);
650 pp_string (pp
, ", ");
651 m_arg1
->dump_to_pp (pp
, simple
);
652 pp_character (pp
, ')');
656 /* Implementation of svalue::accept vfunc for binop_svalue. */
659 binop_svalue::accept (visitor
*v
) const
661 v
->visit_binop_svalue (this);
666 /* Implementation of svalue::implicitly_live_p vfunc for binop_svalue. */
669 binop_svalue::implicitly_live_p (const svalue_set
&live_svalues
,
670 const region_model
*model
) const
672 return (get_arg0 ()->live_p (live_svalues
, model
)
673 && get_arg1 ()->live_p (live_svalues
, model
));
676 /* class sub_svalue : public svalue. */
678 /* sub_svalue'c ctor. */
680 sub_svalue::sub_svalue (tree type
, const svalue
*parent_svalue
,
681 const region
*subregion
)
682 : svalue (complexity::from_pair (parent_svalue
->get_complexity (),
683 subregion
->get_complexity ()),
685 m_parent_svalue (parent_svalue
), m_subregion (subregion
)
689 /* Implementation of svalue::dump_to_pp vfunc for sub_svalue. */
692 sub_svalue::dump_to_pp (pretty_printer
*pp
, bool simple
) const
696 pp_string (pp
, "SUB(");
697 m_parent_svalue
->dump_to_pp (pp
, simple
);
698 pp_string (pp
, ", ");
699 m_subregion
->dump_to_pp (pp
, simple
);
700 pp_character (pp
, ')');
704 pp_string (pp
, "sub_svalue (");
705 pp_string (pp
, ", ");
706 m_parent_svalue
->dump_to_pp (pp
, simple
);
707 pp_string (pp
, ", ");
708 m_subregion
->dump_to_pp (pp
, simple
);
709 pp_character (pp
, ')');
713 /* Implementation of svalue::accept vfunc for sub_svalue. */
716 sub_svalue::accept (visitor
*v
) const
718 v
->visit_sub_svalue (this);
719 m_parent_svalue
->accept (v
);
720 m_subregion
->accept (v
);
723 /* Implementation of svalue::implicitly_live_p vfunc for sub_svalue. */
726 sub_svalue::implicitly_live_p (const svalue_set
&live_svalues
,
727 const region_model
*model
) const
729 return get_parent ()->live_p (live_svalues
, model
);
732 /* class widening_svalue : public svalue. */
734 /* Implementation of svalue::dump_to_pp vfunc for widening_svalue. */
737 widening_svalue::dump_to_pp (pretty_printer
*pp
, bool simple
) const
741 pp_string (pp
, "WIDENING(");
742 pp_character (pp
, '{');
743 m_point
.print (pp
, format (false));
744 pp_string (pp
, "}, ");
745 m_base_sval
->dump_to_pp (pp
, simple
);
746 pp_string (pp
, ", ");
747 m_iter_sval
->dump_to_pp (pp
, simple
);
748 pp_character (pp
, ')');
752 pp_string (pp
, "widening_svalue (");
753 pp_string (pp
, ", ");
754 pp_character (pp
, '{');
755 m_point
.print (pp
, format (false));
756 pp_string (pp
, "}, ");
757 m_base_sval
->dump_to_pp (pp
, simple
);
758 pp_string (pp
, ", ");
759 m_iter_sval
->dump_to_pp (pp
, simple
);
760 pp_character (pp
, ')');
764 /* Implementation of svalue::accept vfunc for widening_svalue. */
767 widening_svalue::accept (visitor
*v
) const
769 v
->visit_widening_svalue (this);
770 m_base_sval
->accept (v
);
771 m_iter_sval
->accept (v
);
774 /* Attempt to determine in which direction this value is changing
775 w.r.t. the initial value. */
777 enum widening_svalue::direction_t
778 widening_svalue::get_direction () const
780 tree base_cst
= m_base_sval
->maybe_get_constant ();
781 if (base_cst
== NULL_TREE
)
783 tree iter_cst
= m_iter_sval
->maybe_get_constant ();
784 if (iter_cst
== NULL_TREE
)
787 tree iter_gt_base
= fold_binary (GT_EXPR
, boolean_type_node
,
789 if (iter_gt_base
== boolean_true_node
)
790 return DIR_ASCENDING
;
792 tree iter_lt_base
= fold_binary (LT_EXPR
, boolean_type_node
,
794 if (iter_lt_base
== boolean_true_node
)
795 return DIR_DESCENDING
;
800 /* Compare this value against constant RHS_CST. */
803 widening_svalue::eval_condition_without_cm (enum tree_code op
,
806 tree base_cst
= m_base_sval
->maybe_get_constant ();
807 if (base_cst
== NULL_TREE
)
808 return tristate::TS_UNKNOWN
;
809 tree iter_cst
= m_iter_sval
->maybe_get_constant ();
810 if (iter_cst
== NULL_TREE
)
811 return tristate::TS_UNKNOWN
;
813 switch (get_direction ())
818 /* LHS is in [base_cst, +ve infinity), assuming no overflow. */
824 /* [BASE, +INF) OP RHS:
825 This is either true or false at +ve ininity,
826 It can be true for points X where X OP RHS, so we have either
827 "false", or "unknown". */
828 tree base_op_rhs
= fold_binary (op
, boolean_type_node
,
830 if (base_op_rhs
== boolean_true_node
)
831 return tristate::TS_UNKNOWN
;
833 return tristate::TS_FALSE
;
839 /* [BASE, +INF) OP RHS:
840 This is true at +ve infinity. It will be true everywhere
841 in the range if BASE >= RHS. */
842 tree base_op_rhs
= fold_binary (op
, boolean_type_node
,
844 if (base_op_rhs
== boolean_true_node
)
845 return tristate::TS_TRUE
;
847 return tristate::TS_UNKNOWN
;
852 /* [BASE, +INF) == RHS:
853 Could this be true at any point in the range? If so we
854 have "unknown", otherwise we have "false". */
855 tree base_le_rhs
= fold_binary (LE_EXPR
, boolean_type_node
,
857 if (base_le_rhs
== boolean_true_node
)
858 return tristate::TS_UNKNOWN
;
860 return tristate::TS_FALSE
;
865 /* [BASE, +INF) != RHS:
866 Could we have equality at any point in the range? If so we
867 have "unknown", otherwise we have "true". */
868 tree base_le_rhs
= fold_binary (LE_EXPR
, boolean_type_node
,
870 if (base_le_rhs
== boolean_true_node
)
871 return tristate::TS_UNKNOWN
;
873 return tristate::TS_TRUE
;
877 return tristate::TS_UNKNOWN
;
881 /* LHS is in (-ve infinity, base_cst], assuming no overflow. */
882 return tristate::TS_UNKNOWN
;
885 return tristate::TS_UNKNOWN
;
889 /* class placeholder_svalue : public svalue. */
891 /* Implementation of svalue::dump_to_pp vfunc for placeholder_svalue. */
894 placeholder_svalue::dump_to_pp (pretty_printer
*pp
, bool simple
) const
897 pp_printf (pp
, "PLACEHOLDER(%qs)", m_name
);
899 pp_printf (pp
, "placeholder_svalue (%qs)", m_name
);
902 /* Implementation of svalue::accept vfunc for placeholder_svalue. */
905 placeholder_svalue::accept (visitor
*v
) const
907 v
->visit_placeholder_svalue (this);
910 /* class unmergeable_svalue : public svalue. */
912 /* Implementation of svalue::dump_to_pp vfunc for unmergeable_svalue. */
915 unmergeable_svalue::dump_to_pp (pretty_printer
*pp
, bool simple
) const
919 pp_string (pp
, "UNMERGEABLE(");
920 m_arg
->dump_to_pp (pp
, simple
);
921 pp_character (pp
, ')');
925 pp_string (pp
, "unmergeable_svalue (");
926 m_arg
->dump_to_pp (pp
, simple
);
927 pp_character (pp
, ')');
931 /* Implementation of svalue::accept vfunc for unmergeable_svalue. */
934 unmergeable_svalue::accept (visitor
*v
) const
936 v
->visit_unmergeable_svalue (this);
940 /* Implementation of svalue::implicitly_live_p vfunc for unmergeable_svalue. */
943 unmergeable_svalue::implicitly_live_p (const svalue_set
&live_svalues
,
944 const region_model
*model
) const
946 return get_arg ()->live_p (live_svalues
, model
);
949 /* class compound_svalue : public svalue. */
951 compound_svalue::compound_svalue (tree type
, const binding_map
&map
)
952 : svalue (calc_complexity (map
), type
), m_map (map
)
954 /* All keys within the underlying binding_map are required to be concrete,
957 for (iterator_t iter
= begin (); iter
!= end (); ++iter
)
959 const binding_key
*key
= (*iter
).first
;
960 gcc_assert (key
->concrete_p ());
965 /* Implementation of svalue::dump_to_pp vfunc for compound_svalue. */
968 compound_svalue::dump_to_pp (pretty_printer
*pp
, bool simple
) const
972 pp_string (pp
, "COMPOUND(");
973 m_map
.dump_to_pp (pp
, simple
, false);
974 pp_character (pp
, ')');
978 pp_string (pp
, "compound_svalue (");
979 pp_string (pp
, ", ");
980 pp_character (pp
, '{');
981 m_map
.dump_to_pp (pp
, simple
, false);
982 pp_string (pp
, "}, ");
983 pp_character (pp
, ')');
987 /* Implementation of svalue::accept vfunc for compound_svalue. */
990 compound_svalue::accept (visitor
*v
) const
992 v
->visit_compound_svalue (this);
993 for (binding_map::iterator_t iter
= m_map
.begin ();
994 iter
!= m_map
.end (); ++iter
)
996 //(*iter).first.accept (v);
997 (*iter
).second
->accept (v
);
1001 /* Calculate what the complexity of a compound_svalue instance for MAP
1002 will be, based on the svalues bound within MAP. */
1005 compound_svalue::calc_complexity (const binding_map
&map
)
1007 unsigned num_child_nodes
= 0;
1008 unsigned max_child_depth
= 0;
1009 for (binding_map::iterator_t iter
= map
.begin ();
1010 iter
!= map
.end (); ++iter
)
1012 const complexity
&sval_c
= (*iter
).second
->get_complexity ();
1013 num_child_nodes
+= sval_c
.m_num_nodes
;
1014 max_child_depth
= MAX (max_child_depth
, sval_c
.m_max_depth
);
1016 return complexity (num_child_nodes
+ 1, max_child_depth
+ 1);
1019 /* class conjured_svalue : public svalue. */
1021 /* Implementation of svalue::dump_to_pp vfunc for conjured_svalue. */
1024 conjured_svalue::dump_to_pp (pretty_printer
*pp
, bool simple
) const
1028 pp_string (pp
, "CONJURED(");
1029 pp_gimple_stmt_1 (pp
, m_stmt
, 0, (dump_flags_t
)0);
1030 pp_string (pp
, ", ");
1031 m_id_reg
->dump_to_pp (pp
, simple
);
1032 pp_character (pp
, ')');
1036 pp_string (pp
, "conjured_svalue (");
1037 pp_string (pp
, ", ");
1038 pp_gimple_stmt_1 (pp
, m_stmt
, 0, (dump_flags_t
)0);
1039 pp_string (pp
, ", ");
1040 m_id_reg
->dump_to_pp (pp
, simple
);
1041 pp_character (pp
, ')');
1045 /* Implementation of svalue::accept vfunc for conjured_svalue. */
1048 conjured_svalue::accept (visitor
*v
) const
1050 v
->visit_conjured_svalue (this);
1051 m_id_reg
->accept (v
);
1056 #endif /* #if ENABLE_ANALYZER */