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)
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/>. */
22 #define INCLUDE_MEMORY
24 #include "coretypes.h"
26 #include "diagnostic-core.h"
27 #include "gimple-pretty-print.h"
29 #include "basic-block.h"
31 #include "gimple-iterator.h"
32 #include "diagnostic-core.h"
37 #include "stringpool.h"
40 #include "fold-const.h"
41 #include "tree-pretty-print.h"
43 #include "analyzer/analyzer.h"
44 #include "analyzer/analyzer-logging.h"
45 #include "analyzer/call-string.h"
46 #include "analyzer/program-point.h"
47 #include "analyzer/store.h"
48 #include "analyzer/svalue.h"
49 #include "analyzer/region-model.h"
50 #include "diagnostic.h"
51 #include "tree-diagnostic.h"
57 static int cmp_csts_and_types (const_tree cst1
, const_tree cst2
);
59 /* class svalue and its various subclasses. */
63 /* Dump a representation of this svalue to stderr. */
66 svalue::dump (bool simple
) const
69 pp_format_decoder (&pp
) = default_tree_printer
;
70 pp_show_color (&pp
) = pp_show_color (global_dc
->printer
);
71 pp
.buffer
->stream
= stderr
;
72 dump_to_pp (&pp
, simple
);
77 /* Generate a textual representation of this svalue for debugging purposes. */
80 svalue::get_desc (bool simple
) const
83 pp_format_decoder (&pp
) = default_tree_printer
;
84 dump_to_pp (&pp
, simple
);
85 return label_text::take (xstrdup (pp_formatted_text (&pp
)));
88 /* Return a new json::string describing the svalue. */
91 svalue::to_json () const
93 label_text desc
= get_desc (true);
94 json::value
*sval_js
= new json::string (desc
.get ());
98 /* If this svalue is a constant_svalue, return the underlying tree constant.
99 Otherwise return NULL_TREE. */
102 svalue::maybe_get_constant () const
104 const svalue
*sval
= unwrap_any_unmergeable ();
105 if (const constant_svalue
*cst_sval
= sval
->dyn_cast_constant_svalue ())
106 return cst_sval
->get_constant ();
111 /* If this svalue is a region_svalue, return the region it points to.
112 Otherwise return NULL. */
115 svalue::maybe_get_region () const
117 if (const region_svalue
*region_sval
= dyn_cast_region_svalue ())
118 return region_sval
->get_pointee ();
123 /* If this svalue is a cast (i.e a unaryop NOP_EXPR or VIEW_CONVERT_EXPR),
124 return the underlying svalue.
125 Otherwise return NULL. */
128 svalue::maybe_undo_cast () const
130 if (const unaryop_svalue
*unaryop_sval
= dyn_cast_unaryop_svalue ())
132 enum tree_code op
= unaryop_sval
->get_op ();
133 if (op
== NOP_EXPR
|| op
== VIEW_CONVERT_EXPR
)
134 return unaryop_sval
->get_arg ();
139 /* If this svalue is an unmergeable decorator around another svalue, return
140 the underlying svalue.
141 Otherwise return this svalue. */
144 svalue::unwrap_any_unmergeable () const
146 if (const unmergeable_svalue
*unmergeable
= dyn_cast_unmergeable_svalue ())
147 return unmergeable
->get_arg ();
151 /* Attempt to merge THIS with OTHER, returning the merged svalue.
152 Return NULL if not mergeable. */
155 svalue::can_merge_p (const svalue
*other
,
156 region_model_manager
*mgr
,
157 model_merger
*merger
) const
159 if (!(get_type () && other
->get_type ()))
162 if (!types_compatible_p (get_type (), other
->get_type ()))
165 /* Reject attempts to merge unmergeable svalues. */
166 if ((get_kind () == SK_UNMERGEABLE
)
167 || (other
->get_kind () == SK_UNMERGEABLE
))
170 /* Reject attempts to merge poisoned svalues with other svalues
171 (either non-poisoned, or other kinds of poison), so that e.g.
172 we identify paths in which a variable is conditionally uninitialized. */
173 if (get_kind () == SK_POISONED
174 || other
->get_kind () == SK_POISONED
)
177 /* Reject attempts to merge NULL pointers with not-NULL-pointers. */
178 if (POINTER_TYPE_P (get_type ()))
182 if (tree cst0
= maybe_get_constant ())
185 if (tree cst1
= other
->maybe_get_constant ())
192 /* Reject merging svalues that have non-purgable sm-state,
193 to avoid falsely reporting memory leaks by merging them
194 with something else. */
195 if (!merger
->mergeable_svalue_p (this))
197 if (!merger
->mergeable_svalue_p (other
))
201 /* Merge: (new_cst, existing_cst) -> widen (existing, new). */
202 if (maybe_get_constant () && other
->maybe_get_constant ())
204 return mgr
->get_or_create_widening_svalue (other
->get_type (),
205 merger
->get_function_point (),
210 this: BINOP (X, OP, CST)
211 other: X, where X is non-widening
212 to: WIDENING (other, this). */
213 if (const binop_svalue
*binop_sval
= dyn_cast_binop_svalue ())
214 if (binop_sval
->get_arg0 () == other
215 && binop_sval
->get_arg1 ()->get_kind () == SK_CONSTANT
216 && other
->get_kind () != SK_WIDENING
)
217 return mgr
->get_or_create_widening_svalue (other
->get_type (),
218 merger
->get_function_point (),
221 /* Merge: (Widen(existing_val, V), existing_val) -> Widen (existing_val, V)
222 and thus get a fixed point. */
223 if (const widening_svalue
*widen_sval
= dyn_cast_widening_svalue ())
225 if (other
== widen_sval
->get_base_svalue ())
227 if (other
== widen_sval
->get_iter_svalue ())
231 if (const binop_svalue
*binop_sval
= dyn_cast_binop_svalue ())
232 if (const widening_svalue
*widen_arg0
233 = binop_sval
->get_arg0 ()->dyn_cast_widening_svalue ())
235 if (other
== binop_sval
->get_arg1 ())
237 /* Merger of: (Widen(..., OTHER) BINOP X)
239 to : (Widen(..., OTHER) BINOP X)
240 e.g. merge of Widen(0, 1) + 1 with 1 to the Widen(0, 1) + 1. */
244 /* Merger of : (Widen() BINOP X)
247 e.g. merge of Widen(0, 1) + 1 and Widen(0, 1) to Widen(0, 1).
248 However, we want to update constraints for this case, since we're
249 considering another iteration.
250 Presumably we also want to ensure that it converges; we don't want
251 a descending chain of constraints. */
252 if (other
== widen_arg0
)
254 merger
->on_widening_reuse (widen_arg0
);
259 this: BINOP(WIDENING(BASE, BINOP(BASE, X)), X)
260 other: BINOP(BASE, X)
261 to: WIDENING(BASE, BINOP(BASE, X)). */
262 if (widen_arg0
->get_iter_svalue () == other
)
263 if (const binop_svalue
*other_binop_sval
264 = other
->dyn_cast_binop_svalue ())
265 if (other_binop_sval
->get_arg0 () == widen_arg0
->get_base_svalue ()
266 && other_binop_sval
->get_arg1 () == binop_sval
->get_arg1 ())
270 return mgr
->get_or_create_unknown_svalue (get_type ());
273 /* Determine if this svalue is either within LIVE_SVALUES, or is implicitly
274 live with respect to LIVE_SVALUES and MODEL.
275 LIVE_SVALUES can be NULL, in which case determine if this svalue is
276 intrinsically live. */
279 svalue::live_p (const svalue_set
*live_svalues
,
280 const region_model
*model
) const
282 /* Determine if SVAL is explicitly live. */
284 if (const_cast<svalue_set
*> (live_svalues
)->contains (this))
287 /* Otherwise, determine if SVAL is implicitly live due to being made of
288 other live svalues. */
289 return implicitly_live_p (live_svalues
, model
);
292 /* Base implementation of svalue::implicitly_live_p. */
295 svalue::implicitly_live_p (const svalue_set
*, const region_model
*) const
300 /* Comparator for imposing a deterministic order on constants that are
304 cmp_csts_same_type (const_tree cst1
, const_tree cst2
)
306 gcc_assert (TREE_TYPE (cst1
) == TREE_TYPE (cst2
));
307 gcc_assert (TREE_CODE (cst1
) == TREE_CODE (cst2
));
308 switch (TREE_CODE (cst1
))
313 return tree_int_cst_compare (cst1
, cst2
);
315 return strcmp (TREE_STRING_POINTER (cst1
),
316 TREE_STRING_POINTER (cst2
));
318 /* Impose an arbitrary but deterministic order. */
319 return memcmp (TREE_REAL_CST_PTR (cst1
),
320 TREE_REAL_CST_PTR (cst2
),
321 sizeof (real_value
));
323 if (int cmp_real
= cmp_csts_and_types (TREE_REALPART (cst1
),
324 TREE_REALPART (cst2
)))
326 return cmp_csts_and_types (TREE_IMAGPART (cst1
), TREE_IMAGPART (cst2
));
328 if (int cmp_log2_npatterns
329 = ((int)VECTOR_CST_LOG2_NPATTERNS (cst1
)
330 - (int)VECTOR_CST_LOG2_NPATTERNS (cst2
)))
331 return cmp_log2_npatterns
;
332 if (int cmp_nelts_per_pattern
333 = ((int)VECTOR_CST_NELTS_PER_PATTERN (cst1
)
334 - (int)VECTOR_CST_NELTS_PER_PATTERN (cst2
)))
335 return cmp_nelts_per_pattern
;
336 unsigned encoded_nelts
= vector_cst_encoded_nelts (cst1
);
337 for (unsigned i
= 0; i
< encoded_nelts
; i
++)
339 const_tree elt1
= VECTOR_CST_ENCODED_ELT (cst1
, i
);
340 const_tree elt2
= VECTOR_CST_ENCODED_ELT (cst2
, i
);
341 if (int el_cmp
= cmp_csts_and_types (elt1
, elt2
))
348 /* Comparator for imposing a deterministic order on constants that might
349 not be of the same type. */
352 cmp_csts_and_types (const_tree cst1
, const_tree cst2
)
354 int t1
= TYPE_UID (TREE_TYPE (cst1
));
355 int t2
= TYPE_UID (TREE_TYPE (cst2
));
356 if (int cmp_type
= t1
- t2
)
358 return cmp_csts_same_type (cst1
, cst2
);
361 /* Comparator for imposing a deterministic order on svalues. */
364 svalue::cmp_ptr (const svalue
*sval1
, const svalue
*sval2
)
368 if (int cmp_kind
= sval1
->get_kind () - sval2
->get_kind ())
370 int t1
= sval1
->get_type () ? TYPE_UID (sval1
->get_type ()) : -1;
371 int t2
= sval2
->get_type () ? TYPE_UID (sval2
->get_type ()) : -1;
372 if (int cmp_type
= t1
- t2
)
374 switch (sval1
->get_kind ())
380 const region_svalue
*region_sval1
= (const region_svalue
*)sval1
;
381 const region_svalue
*region_sval2
= (const region_svalue
*)sval2
;
382 return region::cmp_ids (region_sval1
->get_pointee (),
383 region_sval2
->get_pointee ());
388 const constant_svalue
*constant_sval1
= (const constant_svalue
*)sval1
;
389 const constant_svalue
*constant_sval2
= (const constant_svalue
*)sval2
;
390 const_tree cst1
= constant_sval1
->get_constant ();
391 const_tree cst2
= constant_sval2
->get_constant ();
392 return cmp_csts_same_type (cst1
, cst2
);
397 gcc_assert (sval1
== sval2
);
403 const poisoned_svalue
*poisoned_sval1
= (const poisoned_svalue
*)sval1
;
404 const poisoned_svalue
*poisoned_sval2
= (const poisoned_svalue
*)sval2
;
405 return (poisoned_sval1
->get_poison_kind ()
406 - poisoned_sval2
->get_poison_kind ());
411 const setjmp_svalue
*setjmp_sval1
= (const setjmp_svalue
*)sval1
;
412 const setjmp_svalue
*setjmp_sval2
= (const setjmp_svalue
*)sval2
;
413 const setjmp_record
&rec1
= setjmp_sval1
->get_setjmp_record ();
414 const setjmp_record
&rec2
= setjmp_sval2
->get_setjmp_record ();
415 return setjmp_record::cmp (rec1
, rec2
);
420 const initial_svalue
*initial_sval1
= (const initial_svalue
*)sval1
;
421 const initial_svalue
*initial_sval2
= (const initial_svalue
*)sval2
;
422 return region::cmp_ids (initial_sval1
->get_region (),
423 initial_sval2
->get_region ());
428 const unaryop_svalue
*unaryop_sval1
= (const unaryop_svalue
*)sval1
;
429 const unaryop_svalue
*unaryop_sval2
= (const unaryop_svalue
*)sval2
;
430 if (int op_cmp
= unaryop_sval1
->get_op () - unaryop_sval2
->get_op ())
432 return svalue::cmp_ptr (unaryop_sval1
->get_arg (),
433 unaryop_sval2
->get_arg ());
438 const binop_svalue
*binop_sval1
= (const binop_svalue
*)sval1
;
439 const binop_svalue
*binop_sval2
= (const binop_svalue
*)sval2
;
440 if (int op_cmp
= binop_sval1
->get_op () - binop_sval2
->get_op ())
442 if (int arg0_cmp
= svalue::cmp_ptr (binop_sval1
->get_arg0 (),
443 binop_sval2
->get_arg0 ()))
445 return svalue::cmp_ptr (binop_sval1
->get_arg1 (),
446 binop_sval2
->get_arg1 ());
451 const sub_svalue
*sub_sval1
= (const sub_svalue
*)sval1
;
452 const sub_svalue
*sub_sval2
= (const sub_svalue
*)sval2
;
453 if (int parent_cmp
= svalue::cmp_ptr (sub_sval1
->get_parent (),
454 sub_sval2
->get_parent ()))
456 return region::cmp_ids (sub_sval1
->get_subregion (),
457 sub_sval2
->get_subregion ());
462 const repeated_svalue
*repeated_sval1
= (const repeated_svalue
*)sval1
;
463 const repeated_svalue
*repeated_sval2
= (const repeated_svalue
*)sval2
;
464 return svalue::cmp_ptr (repeated_sval1
->get_inner_svalue (),
465 repeated_sval2
->get_inner_svalue ());
470 const bits_within_svalue
*bits_within_sval1
471 = (const bits_within_svalue
*)sval1
;
472 const bits_within_svalue
*bits_within_sval2
473 = (const bits_within_svalue
*)sval2
;
474 if (int cmp
= bit_range::cmp (bits_within_sval1
->get_bits (),
475 bits_within_sval2
->get_bits ()))
477 return svalue::cmp_ptr (bits_within_sval1
->get_inner_svalue (),
478 bits_within_sval2
->get_inner_svalue ());
483 const unmergeable_svalue
*unmergeable_sval1
484 = (const unmergeable_svalue
*)sval1
;
485 const unmergeable_svalue
*unmergeable_sval2
486 = (const unmergeable_svalue
*)sval2
;
487 return svalue::cmp_ptr (unmergeable_sval1
->get_arg (),
488 unmergeable_sval2
->get_arg ());
493 const placeholder_svalue
*placeholder_sval1
494 = (const placeholder_svalue
*)sval1
;
495 const placeholder_svalue
*placeholder_sval2
496 = (const placeholder_svalue
*)sval2
;
497 return strcmp (placeholder_sval1
->get_name (),
498 placeholder_sval2
->get_name ());
503 const widening_svalue
*widening_sval1
= (const widening_svalue
*)sval1
;
504 const widening_svalue
*widening_sval2
= (const widening_svalue
*)sval2
;
505 if (int point_cmp
= function_point::cmp (widening_sval1
->get_point (),
506 widening_sval2
->get_point ()))
508 if (int base_cmp
= svalue::cmp_ptr (widening_sval1
->get_base_svalue (),
509 widening_sval2
->get_base_svalue ()))
511 return svalue::cmp_ptr (widening_sval1
->get_iter_svalue (),
512 widening_sval2
->get_iter_svalue ());
517 const compound_svalue
*compound_sval1
= (const compound_svalue
*)sval1
;
518 const compound_svalue
*compound_sval2
= (const compound_svalue
*)sval2
;
519 return binding_map::cmp (compound_sval1
->get_map (),
520 compound_sval2
->get_map ());
525 const conjured_svalue
*conjured_sval1
= (const conjured_svalue
*)sval1
;
526 const conjured_svalue
*conjured_sval2
= (const conjured_svalue
*)sval2
;
527 if (int stmt_cmp
= (conjured_sval1
->get_stmt ()->uid
528 - conjured_sval2
->get_stmt ()->uid
))
530 return region::cmp_ids (conjured_sval1
->get_id_region (),
531 conjured_sval2
->get_id_region ());
536 const asm_output_svalue
*asm_output_sval1
537 = (const asm_output_svalue
*)sval1
;
538 const asm_output_svalue
*asm_output_sval2
539 = (const asm_output_svalue
*)sval2
;
540 if (int asm_string_cmp
= strcmp (asm_output_sval1
->get_asm_string (),
541 asm_output_sval2
->get_asm_string ()))
542 return asm_string_cmp
;
543 if (int output_idx_cmp
= ((int)asm_output_sval1
->get_output_idx ()
544 - (int)asm_output_sval2
->get_output_idx ()))
545 return output_idx_cmp
;
546 if (int cmp
= ((int)asm_output_sval1
->get_num_inputs ()
547 - (int)asm_output_sval2
->get_num_inputs ()))
549 for (unsigned i
= 0; i
< asm_output_sval1
->get_num_inputs (); i
++)
551 = svalue::cmp_ptr (asm_output_sval1
->get_input (i
),
552 asm_output_sval2
->get_input (i
)))
557 case SK_CONST_FN_RESULT
:
559 const const_fn_result_svalue
*const_fn_result_sval1
560 = (const const_fn_result_svalue
*)sval1
;
561 const const_fn_result_svalue
*const_fn_result_sval2
562 = (const const_fn_result_svalue
*)sval2
;
563 int d1
= DECL_UID (const_fn_result_sval1
->get_fndecl ());
564 int d2
= DECL_UID (const_fn_result_sval2
->get_fndecl ());
565 if (int cmp_fndecl
= d1
- d2
)
567 if (int cmp
= ((int)const_fn_result_sval1
->get_num_inputs ()
568 - (int)const_fn_result_sval2
->get_num_inputs ()))
570 for (unsigned i
= 0; i
< const_fn_result_sval1
->get_num_inputs (); i
++)
572 = svalue::cmp_ptr (const_fn_result_sval1
->get_input (i
),
573 const_fn_result_sval2
->get_input (i
)))
580 /* Comparator for use by vec<const svalue *>::qsort. */
583 svalue::cmp_ptr_ptr (const void *p1
, const void *p2
)
585 const svalue
*sval1
= *(const svalue
* const *)p1
;
586 const svalue
*sval2
= *(const svalue
* const *)p2
;
587 return cmp_ptr (sval1
, sval2
);
590 /* Subclass of visitor for use in implementing svalue::involves_p. */
592 class involvement_visitor
: public visitor
595 involvement_visitor (const svalue
*needle
)
596 : m_needle (needle
), m_found (false) {}
598 void visit_initial_svalue (const initial_svalue
*candidate
) final override
600 if (candidate
== m_needle
)
604 void visit_conjured_svalue (const conjured_svalue
*candidate
) final override
606 if (candidate
== m_needle
)
610 void visit_widening_svalue (const widening_svalue
*candidate
) final override
612 if (candidate
== m_needle
)
616 bool found_p () const { return m_found
; }
619 const svalue
*m_needle
;
623 /* Return true iff this svalue is defined in terms of OTHER. */
626 svalue::involves_p (const svalue
*other
) const
628 /* Currently only implemented for these kinds. */
629 gcc_assert (other
->get_kind () == SK_INITIAL
630 || other
->get_kind () == SK_CONJURED
631 || other
->get_kind () == SK_WIDENING
);
633 involvement_visitor
v (other
);
638 /* Extract SUBRANGE from this value, of type TYPE. */
641 svalue::extract_bit_range (tree type
,
642 const bit_range
&subrange
,
643 region_model_manager
*mgr
) const
645 return mgr
->get_or_create_bits_within (type
, subrange
, this);
648 /* Base implementation of svalue::maybe_fold_bits_within vfunc. */
651 svalue::maybe_fold_bits_within (tree
,
653 region_model_manager
*) const
655 /* By default, don't fold. */
659 /* Base implementation of svalue::all_zeroes_p.
660 Return true if this value is known to be all zeroes. */
663 svalue::all_zeroes_p () const
668 /* If this svalue is a pointer, attempt to determine the base region it points
669 to. Return NULL on any problems. */
672 svalue::maybe_get_deref_base_region () const
674 const svalue
*iter
= this;
677 switch (iter
->get_kind ())
684 const region_svalue
*region_sval
685 = as_a
<const region_svalue
*> (iter
);
686 return region_sval
->get_pointee ()->get_base_region ();
691 const binop_svalue
*binop_sval
692 = as_a
<const binop_svalue
*> (iter
);
693 switch (binop_sval
->get_op ())
695 case POINTER_PLUS_EXPR
:
696 /* If we have a symbolic value expressing pointer arithmetic,
698 iter
= binop_sval
->get_arg0 ();
710 /* class region_svalue : public svalue. */
712 /* Implementation of svalue::dump_to_pp vfunc for region_svalue. */
715 region_svalue::dump_to_pp (pretty_printer
*pp
, bool simple
) const
720 m_reg
->dump_to_pp (pp
, simple
);
724 pp_string (pp
, "region_svalue(");
727 print_quoted_type (pp
, get_type ());
728 pp_string (pp
, ", ");
730 m_reg
->dump_to_pp (pp
, simple
);
735 /* Implementation of svalue::accept vfunc for region_svalue. */
738 region_svalue::accept (visitor
*v
) const
741 v
->visit_region_svalue (this);
744 /* Implementation of svalue::implicitly_live_p vfunc for region_svalue. */
747 region_svalue::implicitly_live_p (const svalue_set
*,
748 const region_model
*model
) const
750 /* Pointers into clusters that have escaped should be treated as live. */
751 const region
*base_reg
= get_pointee ()->get_base_region ();
752 const store
*store
= model
->get_store ();
753 if (const binding_cluster
*c
= store
->get_cluster (base_reg
))
760 /* Evaluate the condition LHS OP RHS.
761 Subroutine of region_model::eval_condition for when we have a pair of
765 region_svalue::eval_condition (const region_svalue
*lhs
,
767 const region_svalue
*rhs
)
769 /* See if they point to the same region. */
770 const region
*lhs_reg
= lhs
->get_pointee ();
771 const region
*rhs_reg
= rhs
->get_pointee ();
772 bool ptr_equality
= lhs_reg
== rhs_reg
;
780 return tristate::TS_TRUE
;
782 return tristate::TS_FALSE
;
787 return tristate::TS_FALSE
;
789 return tristate::TS_TRUE
;
795 return tristate::TS_TRUE
;
801 return tristate::TS_FALSE
;
805 return tristate::TS_UNKNOWN
;
808 /* class constant_svalue : public svalue. */
810 /* Implementation of svalue::dump_to_pp vfunc for constant_svalue. */
813 constant_svalue::dump_to_pp (pretty_printer
*pp
, bool simple
) const
818 dump_tree (pp
, get_type ());
820 dump_tree (pp
, m_cst_expr
);
824 pp_string (pp
, "constant_svalue(");
827 print_quoted_type (pp
, get_type ());
828 pp_string (pp
, ", ");
830 dump_tree (pp
, m_cst_expr
);
835 /* Implementation of svalue::accept vfunc for constant_svalue. */
838 constant_svalue::accept (visitor
*v
) const
840 v
->visit_constant_svalue (this);
843 /* Implementation of svalue::implicitly_live_p vfunc for constant_svalue.
844 Constants are implicitly live. */
847 constant_svalue::implicitly_live_p (const svalue_set
*,
848 const region_model
*) const
853 /* Evaluate the condition LHS OP RHS.
854 Subroutine of region_model::eval_condition for when we have a pair of
858 constant_svalue::eval_condition (const constant_svalue
*lhs
,
860 const constant_svalue
*rhs
)
862 tree lhs_const
= lhs
->get_constant ();
863 tree rhs_const
= rhs
->get_constant ();
865 gcc_assert (CONSTANT_CLASS_P (lhs_const
));
866 gcc_assert (CONSTANT_CLASS_P (rhs_const
));
868 /* Check for comparable types. */
869 if (types_compatible_p (TREE_TYPE (lhs_const
), TREE_TYPE (rhs_const
)))
872 = fold_binary (op
, boolean_type_node
, lhs_const
, rhs_const
);
873 if (comparison
== boolean_true_node
)
874 return tristate (tristate::TS_TRUE
);
875 if (comparison
== boolean_false_node
)
876 return tristate (tristate::TS_FALSE
);
878 return tristate::TS_UNKNOWN
;
881 /* Implementation of svalue::maybe_fold_bits_within vfunc
882 for constant_svalue. */
885 constant_svalue::maybe_fold_bits_within (tree type
,
886 const bit_range
&bits
,
887 region_model_manager
*mgr
) const
889 /* Bits within an all-zero value are also all zero. */
890 if (zerop (m_cst_expr
))
893 return mgr
->get_or_create_cast (type
, this);
898 /* Handle the case of extracting a single bit. */
899 if (bits
.m_size_in_bits
== 1
900 && TREE_CODE (m_cst_expr
) == INTEGER_CST
902 && INTEGRAL_TYPE_P (type
)
903 && tree_fits_uhwi_p (m_cst_expr
))
905 unsigned HOST_WIDE_INT bit
= bits
.m_start_bit_offset
.to_uhwi ();
906 unsigned HOST_WIDE_INT mask
= (1 << bit
);
907 unsigned HOST_WIDE_INT val_as_hwi
= tree_to_uhwi (m_cst_expr
);
908 unsigned HOST_WIDE_INT masked_val
= val_as_hwi
& mask
;
909 int result
= masked_val
? 1 : 0;
910 return mgr
->get_or_create_int_cst (type
, result
);
913 /* Otherwise, don't fold. */
917 /* Implementation of svalue::all_zeroes_p for constant_svalue. */
920 constant_svalue::all_zeroes_p () const
922 return zerop (m_cst_expr
);
925 /* class unknown_svalue : public svalue. */
927 /* Implementation of svalue::dump_to_pp vfunc for unknown_svalue. */
930 unknown_svalue::dump_to_pp (pretty_printer
*pp
, bool simple
) const
934 pp_string (pp
, "UNKNOWN(");
936 dump_tree (pp
, get_type ());
937 pp_character (pp
, ')');
941 pp_string (pp
, "unknown_svalue(");
943 dump_tree (pp
, get_type ());
944 pp_character (pp
, ')');
948 /* Implementation of svalue::accept vfunc for unknown_svalue. */
951 unknown_svalue::accept (visitor
*v
) const
953 v
->visit_unknown_svalue (this);
956 /* Implementation of svalue::maybe_fold_bits_within vfunc
957 for unknown_svalue. */
960 unknown_svalue::maybe_fold_bits_within (tree type
,
962 region_model_manager
*mgr
) const
964 /* Bits within an unknown_svalue are themselves unknown. */
965 return mgr
->get_or_create_unknown_svalue (type
);
968 /* Get a string for KIND for use in debug dumps. */
971 poison_kind_to_str (enum poison_kind kind
)
977 case POISON_KIND_UNINIT
:
979 case POISON_KIND_FREED
:
981 case POISON_KIND_DELETED
:
983 case POISON_KIND_POPPED_STACK
:
984 return "popped stack";
988 /* class poisoned_svalue : public svalue. */
990 /* Implementation of svalue::dump_to_pp vfunc for poisoned_svalue. */
993 poisoned_svalue::dump_to_pp (pretty_printer
*pp
, bool simple
) const
997 pp_string (pp
, "POISONED(");
998 print_quoted_type (pp
, get_type ());
999 pp_printf (pp
, ", %s)", poison_kind_to_str (m_kind
));
1003 pp_string (pp
, "poisoned_svalue(");
1004 print_quoted_type (pp
, get_type ());
1005 pp_printf (pp
, ", %s)", poison_kind_to_str (m_kind
));
1009 /* Implementation of svalue::accept vfunc for poisoned_svalue. */
1012 poisoned_svalue::accept (visitor
*v
) const
1014 v
->visit_poisoned_svalue (this);
1017 /* Implementation of svalue::maybe_fold_bits_within vfunc
1018 for poisoned_svalue. */
1021 poisoned_svalue::maybe_fold_bits_within (tree type
,
1023 region_model_manager
*mgr
) const
1025 /* Bits within a poisoned value are also poisoned. */
1026 return mgr
->get_or_create_poisoned_svalue (m_kind
, type
);
1029 /* class setjmp_svalue's implementation is in engine.cc, so that it can use
1030 the declaration of exploded_node. */
1032 /* class initial_svalue : public svalue. */
1034 /* Implementation of svalue::dump_to_pp vfunc for initial_svalue. */
1037 initial_svalue::dump_to_pp (pretty_printer
*pp
, bool simple
) const
1041 pp_string (pp
, "INIT_VAL(");
1042 m_reg
->dump_to_pp (pp
, simple
);
1043 pp_string (pp
, ")");
1047 pp_string (pp
, "initial_svalue(");
1050 print_quoted_type (pp
, get_type ());
1051 pp_string (pp
, ", ");
1053 m_reg
->dump_to_pp (pp
, simple
);
1054 pp_string (pp
, ")");
1058 /* Implementation of svalue::accept vfunc for initial_svalue. */
1061 initial_svalue::accept (visitor
*v
) const
1064 v
->visit_initial_svalue (this);
1067 /* Implementation of svalue::implicitly_live_p vfunc for initial_svalue. */
1070 initial_svalue::implicitly_live_p (const svalue_set
*,
1071 const region_model
*model
) const
1073 /* This svalue may be implicitly live if the region still implicitly
1074 has its initial value and is reachable. */
1076 /* It must be a region that exists; we don't want to consider
1077 INIT_VAL(R) as still being implicitly reachable if R is in
1078 a popped stack frame. */
1079 if (model
->region_exists_p (m_reg
))
1081 const svalue
*reg_sval
= model
->get_store_value (m_reg
, NULL
);
1082 if (reg_sval
== this)
1086 /* Assume that the initial values of params for the top level frame
1087 are still live, because (presumably) they're still
1088 live in the external caller. */
1089 if (initial_value_of_param_p ())
1090 if (const frame_region
*frame_reg
= m_reg
->maybe_get_frame_region ())
1091 if (frame_reg
->get_calling_frame () == NULL
)
1097 /* Return true if this is the initial value of a function parameter. */
1100 initial_svalue::initial_value_of_param_p () const
1102 if (tree reg_decl
= m_reg
->maybe_get_decl ())
1103 if (TREE_CODE (reg_decl
) == SSA_NAME
)
1105 tree ssa_name
= reg_decl
;
1106 if (SSA_NAME_IS_DEFAULT_DEF (ssa_name
)
1107 && SSA_NAME_VAR (ssa_name
)
1108 && TREE_CODE (SSA_NAME_VAR (ssa_name
)) == PARM_DECL
)
1114 /* class unaryop_svalue : public svalue. */
1116 /* Implementation of svalue::dump_to_pp vfunc for unaryop_svalue. */
1119 unaryop_svalue::dump_to_pp (pretty_printer
*pp
, bool simple
) const
1123 if (m_op
== VIEW_CONVERT_EXPR
|| m_op
== NOP_EXPR
)
1125 pp_string (pp
, "CAST(");
1126 dump_tree (pp
, get_type ());
1127 pp_string (pp
, ", ");
1128 m_arg
->dump_to_pp (pp
, simple
);
1129 pp_character (pp
, ')');
1133 pp_character (pp
, '(');
1134 pp_string (pp
, get_tree_code_name (m_op
));
1135 //pp_string (pp, op_symbol_code (m_op));
1136 m_arg
->dump_to_pp (pp
, simple
);
1137 pp_character (pp
, ')');
1142 pp_string (pp
, "unaryop_svalue (");
1143 pp_string (pp
, get_tree_code_name (m_op
));
1144 pp_string (pp
, ", ");
1145 m_arg
->dump_to_pp (pp
, simple
);
1146 pp_character (pp
, ')');
1150 /* Implementation of svalue::accept vfunc for unaryop_svalue. */
1153 unaryop_svalue::accept (visitor
*v
) const
1156 v
->visit_unaryop_svalue (this);
1159 /* Implementation of svalue::implicitly_live_p vfunc for unaryop_svalue. */
1162 unaryop_svalue::implicitly_live_p (const svalue_set
*live_svalues
,
1163 const region_model
*model
) const
1165 return get_arg ()->live_p (live_svalues
, model
);
1168 /* Implementation of svalue::maybe_fold_bits_within vfunc
1169 for unaryop_svalue. */
1172 unaryop_svalue::maybe_fold_bits_within (tree type
,
1174 region_model_manager
*mgr
) const
1181 /* A cast of zero is zero. */
1182 if (tree cst
= m_arg
->maybe_get_constant ())
1186 return mgr
->get_or_create_cast (type
, this);
1192 /* Otherwise, don't fold. */
1196 /* class binop_svalue : public svalue. */
1198 /* Return whether OP be printed as an infix operator. */
1201 infix_p (enum tree_code op
)
1213 /* Implementation of svalue::dump_to_pp vfunc for binop_svalue. */
1216 binop_svalue::dump_to_pp (pretty_printer
*pp
, bool simple
) const
1222 /* Print "(A OP B)". */
1223 pp_character (pp
, '(');
1224 m_arg0
->dump_to_pp (pp
, simple
);
1225 pp_string (pp
, op_symbol_code (m_op
));
1226 m_arg1
->dump_to_pp (pp
, simple
);
1227 pp_character (pp
, ')');
1231 /* Print "OP(A, B)". */
1232 pp_string (pp
, op_symbol_code (m_op
));
1233 pp_character (pp
, '(');
1234 m_arg0
->dump_to_pp (pp
, simple
);
1235 pp_string (pp
, ", ");
1236 m_arg1
->dump_to_pp (pp
, simple
);
1237 pp_character (pp
, ')');
1242 pp_string (pp
, "binop_svalue (");
1243 pp_string (pp
, get_tree_code_name (m_op
));
1244 pp_string (pp
, ", ");
1245 m_arg0
->dump_to_pp (pp
, simple
);
1246 pp_string (pp
, ", ");
1247 m_arg1
->dump_to_pp (pp
, simple
);
1248 pp_character (pp
, ')');
1252 /* Implementation of svalue::accept vfunc for binop_svalue. */
1255 binop_svalue::accept (visitor
*v
) const
1259 v
->visit_binop_svalue (this);
1262 /* Implementation of svalue::implicitly_live_p vfunc for binop_svalue. */
1265 binop_svalue::implicitly_live_p (const svalue_set
*live_svalues
,
1266 const region_model
*model
) const
1268 return (get_arg0 ()->live_p (live_svalues
, model
)
1269 && get_arg1 ()->live_p (live_svalues
, model
));
1272 /* class sub_svalue : public svalue. */
1274 /* sub_svalue'c ctor. */
1276 sub_svalue::sub_svalue (symbol::id_t id
,
1277 tree type
, const svalue
*parent_svalue
,
1278 const region
*subregion
)
1279 : svalue (complexity::from_pair (parent_svalue
->get_complexity (),
1280 subregion
->get_complexity ()),
1283 m_parent_svalue (parent_svalue
), m_subregion (subregion
)
1285 gcc_assert (parent_svalue
->can_have_associated_state_p ());
1288 /* Implementation of svalue::dump_to_pp vfunc for sub_svalue. */
1291 sub_svalue::dump_to_pp (pretty_printer
*pp
, bool simple
) const
1295 pp_string (pp
, "SUB(");
1296 m_parent_svalue
->dump_to_pp (pp
, simple
);
1297 pp_string (pp
, ", ");
1298 m_subregion
->dump_to_pp (pp
, simple
);
1299 pp_character (pp
, ')');
1303 pp_string (pp
, "sub_svalue (");
1304 pp_string (pp
, ", ");
1305 m_parent_svalue
->dump_to_pp (pp
, simple
);
1306 pp_string (pp
, ", ");
1307 m_subregion
->dump_to_pp (pp
, simple
);
1308 pp_character (pp
, ')');
1312 /* Implementation of svalue::accept vfunc for sub_svalue. */
1315 sub_svalue::accept (visitor
*v
) const
1317 m_parent_svalue
->accept (v
);
1318 m_subregion
->accept (v
);
1319 v
->visit_sub_svalue (this);
1322 /* Implementation of svalue::implicitly_live_p vfunc for sub_svalue. */
1325 sub_svalue::implicitly_live_p (const svalue_set
*live_svalues
,
1326 const region_model
*model
) const
1328 return get_parent ()->live_p (live_svalues
, model
);
1331 /* class repeated_svalue : public svalue. */
1333 /* repeated_svalue'c ctor. */
1335 repeated_svalue::repeated_svalue (symbol::id_t id
,
1337 const svalue
*outer_size
,
1338 const svalue
*inner_svalue
)
1339 : svalue (complexity::from_pair (outer_size
, inner_svalue
), id
, type
),
1340 m_outer_size (outer_size
),
1341 m_inner_svalue (inner_svalue
)
1343 gcc_assert (outer_size
->can_have_associated_state_p ());
1344 gcc_assert (inner_svalue
->can_have_associated_state_p ());
1347 /* Implementation of svalue::dump_to_pp vfunc for repeated_svalue. */
1350 repeated_svalue::dump_to_pp (pretty_printer
*pp
, bool simple
) const
1354 pp_string (pp
, "REPEATED(");
1357 print_quoted_type (pp
, get_type ());
1358 pp_string (pp
, ", ");
1360 pp_string (pp
, "outer_size: ");
1361 m_outer_size
->dump_to_pp (pp
, simple
);
1362 pp_string (pp
, ", inner_val: ");
1363 m_inner_svalue
->dump_to_pp (pp
, simple
);
1364 pp_character (pp
, ')');
1368 pp_string (pp
, "repeated_svalue (");
1371 print_quoted_type (pp
, get_type ());
1372 pp_string (pp
, ", ");
1374 pp_string (pp
, "outer_size: ");
1375 m_outer_size
->dump_to_pp (pp
, simple
);
1376 pp_string (pp
, ", inner_val: ");
1377 m_inner_svalue
->dump_to_pp (pp
, simple
);
1378 pp_character (pp
, ')');
1382 /* Implementation of svalue::accept vfunc for repeated_svalue. */
1385 repeated_svalue::accept (visitor
*v
) const
1387 m_inner_svalue
->accept (v
);
1388 v
->visit_repeated_svalue (this);
1391 /* Implementation of svalue::all_zeroes_p for repeated_svalue. */
1394 repeated_svalue::all_zeroes_p () const
1396 return m_inner_svalue
->all_zeroes_p ();
1399 /* Implementation of svalue::maybe_fold_bits_within vfunc
1400 for repeated_svalue. */
1403 repeated_svalue::maybe_fold_bits_within (tree type
,
1404 const bit_range
&bits
,
1405 region_model_manager
*mgr
) const
1407 const svalue
*innermost_sval
= m_inner_svalue
;
1409 BITS_WITHIN (range, REPEATED_SVALUE (ZERO))
1411 REPEATED_SVALUE (ZERO). */
1412 if (all_zeroes_p ())
1414 byte_range
bytes (0,0);
1415 if (bits
.as_byte_range (&bytes
))
1417 const svalue
*byte_size
1418 = mgr
->get_or_create_int_cst (size_type_node
,
1419 bytes
.m_size_in_bytes
.to_uhwi ());
1420 return mgr
->get_or_create_repeated_svalue (type
, byte_size
,
1426 BITS_WITHIN (range, REPEATED_SVALUE (INNERMOST_SVALUE))
1428 BITS_WITHIN (range - offset, INNERMOST_SVALUE)
1429 if range is fully within one instance of INNERMOST_SVALUE. */
1430 if (tree innermost_type
= innermost_sval
->get_type ())
1432 bit_size_t element_bit_size
;
1433 if (int_size_in_bits (innermost_type
, &element_bit_size
)
1434 && element_bit_size
> 0)
1436 HOST_WIDE_INT start_idx
1437 = (bits
.get_start_bit_offset ()
1438 / element_bit_size
).to_shwi ();
1439 HOST_WIDE_INT last_idx
1440 = (bits
.get_last_bit_offset ()
1441 / element_bit_size
).to_shwi ();
1442 if (start_idx
== last_idx
)
1444 bit_offset_t start_of_element
1445 = start_idx
* element_bit_size
;
1446 bit_range range_within_element
1447 (bits
.m_start_bit_offset
- start_of_element
,
1448 bits
.m_size_in_bits
);
1449 return mgr
->get_or_create_bits_within (type
,
1450 range_within_element
,
1459 /* class bits_within_svalue : public svalue. */
1461 /* bits_within_svalue'c ctor. */
1463 bits_within_svalue::bits_within_svalue (symbol::id_t id
,
1465 const bit_range
&bits
,
1466 const svalue
*inner_svalue
)
1467 : svalue (complexity (inner_svalue
), id
, type
),
1469 m_inner_svalue (inner_svalue
)
1471 gcc_assert (inner_svalue
->can_have_associated_state_p ());
1474 /* Implementation of svalue::dump_to_pp vfunc for bits_within_svalue. */
1477 bits_within_svalue::dump_to_pp (pretty_printer
*pp
, bool simple
) const
1481 pp_string (pp
, "BITS_WITHIN(");
1484 print_quoted_type (pp
, get_type ());
1485 pp_string (pp
, ", ");
1487 m_bits
.dump_to_pp (pp
);
1488 pp_string (pp
, ", inner_val: ");
1489 m_inner_svalue
->dump_to_pp (pp
, simple
);
1490 pp_character (pp
, ')');
1494 pp_string (pp
, "bits_within_svalue (");
1497 print_quoted_type (pp
, get_type ());
1498 pp_string (pp
, ", ");
1500 m_bits
.dump_to_pp (pp
);
1501 pp_string (pp
, ", inner_val: ");
1502 m_inner_svalue
->dump_to_pp (pp
, simple
);
1503 pp_character (pp
, ')');
1507 /* Implementation of svalue::maybe_fold_bits_within vfunc
1508 for bits_within_svalue. */
1511 bits_within_svalue::maybe_fold_bits_within (tree type
,
1512 const bit_range
&bits
,
1513 region_model_manager
*mgr
) const
1516 BITS_WITHIN (range1, BITS_WITHIN (range2, VAL))
1518 BITS_WITHIN (range1 in range 2, VAL). */
1519 bit_range
offset_bits (m_bits
.get_start_bit_offset ()
1520 + bits
.m_start_bit_offset
,
1521 bits
.m_size_in_bits
);
1522 return mgr
->get_or_create_bits_within (type
, offset_bits
, m_inner_svalue
);
1525 /* Implementation of svalue::accept vfunc for bits_within_svalue. */
1528 bits_within_svalue::accept (visitor
*v
) const
1530 m_inner_svalue
->accept (v
);
1531 v
->visit_bits_within_svalue (this);
1534 /* Implementation of svalue::implicitly_live_p vfunc for bits_within_svalue. */
1537 bits_within_svalue::implicitly_live_p (const svalue_set
*live_svalues
,
1538 const region_model
*model
) const
1540 return m_inner_svalue
->live_p (live_svalues
, model
);
1543 /* class widening_svalue : public svalue. */
1545 /* Implementation of svalue::dump_to_pp vfunc for widening_svalue. */
1548 widening_svalue::dump_to_pp (pretty_printer
*pp
, bool simple
) const
1552 pp_string (pp
, "WIDENING(");
1553 pp_character (pp
, '{');
1554 m_point
.print (pp
, format (false));
1555 pp_string (pp
, "}, ");
1556 m_base_sval
->dump_to_pp (pp
, simple
);
1557 pp_string (pp
, ", ");
1558 m_iter_sval
->dump_to_pp (pp
, simple
);
1559 pp_character (pp
, ')');
1563 pp_string (pp
, "widening_svalue (");
1564 pp_string (pp
, ", ");
1565 pp_character (pp
, '{');
1566 m_point
.print (pp
, format (false));
1567 pp_string (pp
, "}, ");
1568 m_base_sval
->dump_to_pp (pp
, simple
);
1569 pp_string (pp
, ", ");
1570 m_iter_sval
->dump_to_pp (pp
, simple
);
1571 pp_character (pp
, ')');
1575 /* Implementation of svalue::accept vfunc for widening_svalue. */
1578 widening_svalue::accept (visitor
*v
) const
1580 m_base_sval
->accept (v
);
1581 m_iter_sval
->accept (v
);
1582 v
->visit_widening_svalue (this);
1585 /* Attempt to determine in which direction this value is changing
1586 w.r.t. the initial value. */
1588 enum widening_svalue::direction_t
1589 widening_svalue::get_direction () const
1591 tree base_cst
= m_base_sval
->maybe_get_constant ();
1592 if (base_cst
== NULL_TREE
)
1594 tree iter_cst
= m_iter_sval
->maybe_get_constant ();
1595 if (iter_cst
== NULL_TREE
)
1598 tree iter_gt_base
= fold_binary (GT_EXPR
, boolean_type_node
,
1599 iter_cst
, base_cst
);
1600 if (iter_gt_base
== boolean_true_node
)
1601 return DIR_ASCENDING
;
1603 tree iter_lt_base
= fold_binary (LT_EXPR
, boolean_type_node
,
1604 iter_cst
, base_cst
);
1605 if (iter_lt_base
== boolean_true_node
)
1606 return DIR_DESCENDING
;
1611 /* Compare this value against constant RHS_CST. */
1614 widening_svalue::eval_condition_without_cm (enum tree_code op
,
1617 tree base_cst
= m_base_sval
->maybe_get_constant ();
1618 if (base_cst
== NULL_TREE
)
1619 return tristate::TS_UNKNOWN
;
1620 tree iter_cst
= m_iter_sval
->maybe_get_constant ();
1621 if (iter_cst
== NULL_TREE
)
1622 return tristate::TS_UNKNOWN
;
1624 switch (get_direction ())
1629 /* LHS is in [base_cst, +ve infinity), assuming no overflow. */
1635 /* [BASE, +INF) OP RHS:
1636 This is either true or false at +ve ininity,
1637 It can be true for points X where X OP RHS, so we have either
1638 "false", or "unknown". */
1639 tree base_op_rhs
= fold_binary (op
, boolean_type_node
,
1641 if (base_op_rhs
== boolean_true_node
)
1642 return tristate::TS_UNKNOWN
;
1644 return tristate::TS_FALSE
;
1650 /* [BASE, +INF) OP RHS:
1651 This is true at +ve infinity. It will be true everywhere
1652 in the range if BASE >= RHS. */
1653 tree base_op_rhs
= fold_binary (op
, boolean_type_node
,
1655 if (base_op_rhs
== boolean_true_node
)
1656 return tristate::TS_TRUE
;
1658 return tristate::TS_UNKNOWN
;
1663 /* [BASE, +INF) == RHS:
1664 Could this be true at any point in the range? If so we
1665 have "unknown", otherwise we have "false". */
1666 tree base_le_rhs
= fold_binary (LE_EXPR
, boolean_type_node
,
1668 if (base_le_rhs
== boolean_true_node
)
1669 return tristate::TS_UNKNOWN
;
1671 return tristate::TS_FALSE
;
1676 /* [BASE, +INF) != RHS:
1677 Could we have equality at any point in the range? If so we
1678 have "unknown", otherwise we have "true". */
1679 tree base_le_rhs
= fold_binary (LE_EXPR
, boolean_type_node
,
1681 if (base_le_rhs
== boolean_true_node
)
1682 return tristate::TS_UNKNOWN
;
1684 return tristate::TS_TRUE
;
1688 return tristate::TS_UNKNOWN
;
1691 case DIR_DESCENDING
:
1692 /* LHS is in (-ve infinity, base_cst], assuming no overflow. */
1693 return tristate::TS_UNKNOWN
;
1696 return tristate::TS_UNKNOWN
;
1700 /* class placeholder_svalue : public svalue. */
1702 /* Implementation of svalue::dump_to_pp vfunc for placeholder_svalue. */
1705 placeholder_svalue::dump_to_pp (pretty_printer
*pp
, bool simple
) const
1708 pp_printf (pp
, "PLACEHOLDER(%qs)", m_name
);
1710 pp_printf (pp
, "placeholder_svalue (%qs)", m_name
);
1713 /* Implementation of svalue::accept vfunc for placeholder_svalue. */
1716 placeholder_svalue::accept (visitor
*v
) const
1718 v
->visit_placeholder_svalue (this);
1721 /* class unmergeable_svalue : public svalue. */
1723 /* Implementation of svalue::dump_to_pp vfunc for unmergeable_svalue. */
1726 unmergeable_svalue::dump_to_pp (pretty_printer
*pp
, bool simple
) const
1730 pp_string (pp
, "UNMERGEABLE(");
1731 m_arg
->dump_to_pp (pp
, simple
);
1732 pp_character (pp
, ')');
1736 pp_string (pp
, "unmergeable_svalue (");
1737 m_arg
->dump_to_pp (pp
, simple
);
1738 pp_character (pp
, ')');
1742 /* Implementation of svalue::accept vfunc for unmergeable_svalue. */
1745 unmergeable_svalue::accept (visitor
*v
) const
1748 v
->visit_unmergeable_svalue (this);
1751 /* Implementation of svalue::implicitly_live_p vfunc for unmergeable_svalue. */
1754 unmergeable_svalue::implicitly_live_p (const svalue_set
*live_svalues
,
1755 const region_model
*model
) const
1757 return get_arg ()->live_p (live_svalues
, model
);
1760 /* class compound_svalue : public svalue. */
1762 compound_svalue::compound_svalue (symbol::id_t id
,
1764 const binding_map
&map
)
1765 : svalue (calc_complexity (map
), id
, type
), m_map (map
)
1768 for (iterator_t iter
= begin (); iter
!= end (); ++iter
)
1770 /* All keys within the underlying binding_map are required to be concrete,
1772 const binding_key
*key
= (*iter
).first
;
1773 gcc_assert (key
->concrete_p ());
1775 /* We don't nest compound svalues. */
1776 const svalue
*sval
= (*iter
).second
;
1777 gcc_assert (sval
->get_kind () != SK_COMPOUND
);
1782 /* Implementation of svalue::dump_to_pp vfunc for compound_svalue. */
1785 compound_svalue::dump_to_pp (pretty_printer
*pp
, bool simple
) const
1789 pp_string (pp
, "COMPOUND(");
1792 print_quoted_type (pp
, get_type ());
1793 pp_string (pp
, ", ");
1795 pp_character (pp
, '{');
1796 m_map
.dump_to_pp (pp
, simple
, false);
1797 pp_string (pp
, "})");
1801 pp_string (pp
, "compound_svalue (");
1804 print_quoted_type (pp
, get_type ());
1805 pp_string (pp
, ", ");
1807 pp_character (pp
, '{');
1808 m_map
.dump_to_pp (pp
, simple
, false);
1809 pp_string (pp
, "})");
1813 /* Implementation of svalue::accept vfunc for compound_svalue. */
1816 compound_svalue::accept (visitor
*v
) const
1818 for (binding_map::iterator_t iter
= m_map
.begin ();
1819 iter
!= m_map
.end (); ++iter
)
1821 //(*iter).first.accept (v);
1822 (*iter
).second
->accept (v
);
1824 v
->visit_compound_svalue (this);
1827 /* Calculate what the complexity of a compound_svalue instance for MAP
1828 will be, based on the svalues bound within MAP. */
1831 compound_svalue::calc_complexity (const binding_map
&map
)
1833 unsigned num_child_nodes
= 0;
1834 unsigned max_child_depth
= 0;
1835 for (binding_map::iterator_t iter
= map
.begin ();
1836 iter
!= map
.end (); ++iter
)
1838 const complexity
&sval_c
= (*iter
).second
->get_complexity ();
1839 num_child_nodes
+= sval_c
.m_num_nodes
;
1840 max_child_depth
= MAX (max_child_depth
, sval_c
.m_max_depth
);
1842 return complexity (num_child_nodes
+ 1, max_child_depth
+ 1);
1845 /* Implementation of svalue::maybe_fold_bits_within vfunc
1846 for compound_svalue. */
1849 compound_svalue::maybe_fold_bits_within (tree type
,
1850 const bit_range
&bits
,
1851 region_model_manager
*mgr
) const
1853 binding_map result_map
;
1854 for (auto iter
: m_map
)
1856 const binding_key
*key
= iter
.first
;
1857 if (const concrete_binding
*conc_key
1858 = key
->dyn_cast_concrete_binding ())
1860 /* Ignore concrete bindings outside BITS. */
1861 if (!conc_key
->get_bit_range ().intersects_p (bits
))
1864 const svalue
*sval
= iter
.second
;
1865 /* Get the position of conc_key relative to BITS. */
1866 bit_range
result_location (conc_key
->get_start_bit_offset ()
1867 - bits
.get_start_bit_offset (),
1868 conc_key
->get_size_in_bits ());
1869 /* If conc_key starts after BITS, trim off leading bits
1870 from the svalue and adjust binding location. */
1871 if (result_location
.m_start_bit_offset
< 0)
1873 bit_size_t leading_bits_to_drop
1874 = -result_location
.m_start_bit_offset
;
1875 result_location
= bit_range
1876 (0, result_location
.m_size_in_bits
- leading_bits_to_drop
);
1877 bit_range
bits_within_sval (leading_bits_to_drop
,
1878 result_location
.m_size_in_bits
);
1879 /* Trim off leading bits from iter_sval. */
1880 sval
= mgr
->get_or_create_bits_within (NULL_TREE
,
1884 /* If conc_key finishes after BITS, trim off trailing bits
1885 from the svalue and adjust binding location. */
1886 if (conc_key
->get_next_bit_offset ()
1887 > bits
.get_next_bit_offset ())
1889 bit_size_t trailing_bits_to_drop
1890 = (conc_key
->get_next_bit_offset ()
1891 - bits
.get_next_bit_offset ());
1892 result_location
= bit_range
1893 (result_location
.m_start_bit_offset
,
1894 result_location
.m_size_in_bits
- trailing_bits_to_drop
);
1895 bit_range
bits_within_sval (0,
1896 result_location
.m_size_in_bits
);
1897 /* Trim off leading bits from iter_sval. */
1898 sval
= mgr
->get_or_create_bits_within (NULL_TREE
,
1902 const concrete_binding
*offset_conc_key
1903 = mgr
->get_store_manager ()->get_concrete_binding
1905 result_map
.put (offset_conc_key
, sval
);
1908 /* If we have any symbolic keys we can't get it as bits. */
1911 return mgr
->get_or_create_compound_svalue (type
, result_map
);
1914 /* class conjured_svalue : public svalue. */
1916 /* Implementation of svalue::dump_to_pp vfunc for conjured_svalue. */
1919 conjured_svalue::dump_to_pp (pretty_printer
*pp
, bool simple
) const
1923 pp_string (pp
, "CONJURED(");
1924 pp_gimple_stmt_1 (pp
, m_stmt
, 0, (dump_flags_t
)0);
1925 pp_string (pp
, ", ");
1926 m_id_reg
->dump_to_pp (pp
, simple
);
1927 pp_character (pp
, ')');
1931 pp_string (pp
, "conjured_svalue (");
1934 print_quoted_type (pp
, get_type ());
1935 pp_string (pp
, ", ");
1937 pp_gimple_stmt_1 (pp
, m_stmt
, 0, (dump_flags_t
)0);
1938 pp_string (pp
, ", ");
1939 m_id_reg
->dump_to_pp (pp
, simple
);
1940 pp_character (pp
, ')');
1944 /* Implementation of svalue::accept vfunc for conjured_svalue. */
1947 conjured_svalue::accept (visitor
*v
) const
1949 m_id_reg
->accept (v
);
1950 v
->visit_conjured_svalue (this);
1953 /* Return true iff this conjured_svalue is for the LHS of the
1954 stmt that conjured it. */
1957 conjured_svalue::lhs_value_p () const
1959 if (tree decl
= m_id_reg
->maybe_get_decl ())
1960 return decl
== gimple_get_lhs (m_stmt
);
1964 /* class asm_output_svalue : public svalue. */
1966 /* Implementation of svalue::dump_to_pp vfunc for asm_output_svalue. */
1969 asm_output_svalue::dump_to_pp (pretty_printer
*pp
, bool simple
) const
1973 pp_printf (pp
, "ASM_OUTPUT(%qs, %%%i, {",
1976 for (unsigned i
= 0; i
< m_num_inputs
; i
++)
1979 pp_string (pp
, ", ");
1980 dump_input (pp
, 0, m_input_arr
[i
], simple
);
1982 pp_string (pp
, "})");
1986 pp_printf (pp
, "asm_output_svalue (%qs, %%%i, {",
1989 for (unsigned i
= 0; i
< m_num_inputs
; i
++)
1992 pp_string (pp
, ", ");
1993 dump_input (pp
, 0, m_input_arr
[i
], simple
);
1995 pp_string (pp
, "})");
1999 /* Subroutine of asm_output_svalue::dump_to_pp. */
2002 asm_output_svalue::dump_input (pretty_printer
*pp
,
2007 pp_printf (pp
, "%%%i: ", input_idx_to_asm_idx (input_idx
));
2008 sval
->dump_to_pp (pp
, simple
);
2011 /* Convert INPUT_IDX from an index into the array of inputs
2012 into the index of all operands for the asm stmt. */
2015 asm_output_svalue::input_idx_to_asm_idx (unsigned input_idx
) const
2017 return input_idx
+ m_num_outputs
;
2020 /* Implementation of svalue::accept vfunc for asm_output_svalue. */
2023 asm_output_svalue::accept (visitor
*v
) const
2025 for (unsigned i
= 0; i
< m_num_inputs
; i
++)
2026 m_input_arr
[i
]->accept (v
);
2027 v
->visit_asm_output_svalue (this);
2030 /* class const_fn_result_svalue : public svalue. */
2032 /* Implementation of svalue::dump_to_pp vfunc for const_fn_result_svalue. */
2035 const_fn_result_svalue::dump_to_pp (pretty_printer
*pp
, bool simple
) const
2039 pp_printf (pp
, "CONST_FN_RESULT(%qD, {", m_fndecl
);
2040 for (unsigned i
= 0; i
< m_num_inputs
; i
++)
2043 pp_string (pp
, ", ");
2044 dump_input (pp
, i
, m_input_arr
[i
], simple
);
2046 pp_string (pp
, "})");
2050 pp_printf (pp
, "CONST_FN_RESULT(%qD, {", m_fndecl
);
2051 for (unsigned i
= 0; i
< m_num_inputs
; i
++)
2054 pp_string (pp
, ", ");
2055 dump_input (pp
, i
, m_input_arr
[i
], simple
);
2057 pp_string (pp
, "})");
2061 /* Subroutine of const_fn_result_svalue::dump_to_pp. */
2064 const_fn_result_svalue::dump_input (pretty_printer
*pp
,
2069 pp_printf (pp
, "arg%i: ", input_idx
);
2070 sval
->dump_to_pp (pp
, simple
);
2073 /* Implementation of svalue::accept vfunc for const_fn_result_svalue. */
2076 const_fn_result_svalue::accept (visitor
*v
) const
2078 for (unsigned i
= 0; i
< m_num_inputs
; i
++)
2079 m_input_arr
[i
]->accept (v
);
2080 v
->visit_const_fn_result_svalue (this);
2085 #endif /* #if ENABLE_ANALYZER */