2 Copyright (C) 2019-2023 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
)
258 this: BINOP(WIDENING(BASE, BINOP(BASE, X)), X)
259 other: BINOP(BASE, X)
260 to: WIDENING(BASE, BINOP(BASE, X)). */
261 if (widen_arg0
->get_iter_svalue () == other
)
262 if (const binop_svalue
*other_binop_sval
263 = other
->dyn_cast_binop_svalue ())
264 if (other_binop_sval
->get_arg0 () == widen_arg0
->get_base_svalue ()
265 && other_binop_sval
->get_arg1 () == binop_sval
->get_arg1 ())
269 return mgr
->get_or_create_unknown_svalue (get_type ());
272 /* Determine if this svalue is either within LIVE_SVALUES, or is implicitly
273 live with respect to LIVE_SVALUES and MODEL.
274 LIVE_SVALUES can be NULL, in which case determine if this svalue is
275 intrinsically live. */
278 svalue::live_p (const svalue_set
*live_svalues
,
279 const region_model
*model
) const
281 /* Determine if SVAL is explicitly live. */
283 if (const_cast<svalue_set
*> (live_svalues
)->contains (this))
286 /* Otherwise, determine if SVAL is implicitly live due to being made of
287 other live svalues. */
288 return implicitly_live_p (live_svalues
, model
);
291 /* Base implementation of svalue::implicitly_live_p. */
294 svalue::implicitly_live_p (const svalue_set
*, const region_model
*) const
299 /* Comparator for imposing a deterministic order on constants that are
303 cmp_csts_same_type (const_tree cst1
, const_tree cst2
)
305 gcc_assert (TREE_TYPE (cst1
) == TREE_TYPE (cst2
));
306 gcc_assert (TREE_CODE (cst1
) == TREE_CODE (cst2
));
307 switch (TREE_CODE (cst1
))
312 return tree_int_cst_compare (cst1
, cst2
);
314 return strcmp (TREE_STRING_POINTER (cst1
),
315 TREE_STRING_POINTER (cst2
));
317 /* Impose an arbitrary but deterministic order. */
318 return memcmp (TREE_REAL_CST_PTR (cst1
),
319 TREE_REAL_CST_PTR (cst2
),
320 sizeof (real_value
));
322 if (int cmp_real
= cmp_csts_and_types (TREE_REALPART (cst1
),
323 TREE_REALPART (cst2
)))
325 return cmp_csts_and_types (TREE_IMAGPART (cst1
), TREE_IMAGPART (cst2
));
327 if (int cmp_log2_npatterns
328 = ((int)VECTOR_CST_LOG2_NPATTERNS (cst1
)
329 - (int)VECTOR_CST_LOG2_NPATTERNS (cst2
)))
330 return cmp_log2_npatterns
;
331 if (int cmp_nelts_per_pattern
332 = ((int)VECTOR_CST_NELTS_PER_PATTERN (cst1
)
333 - (int)VECTOR_CST_NELTS_PER_PATTERN (cst2
)))
334 return cmp_nelts_per_pattern
;
335 unsigned encoded_nelts
= vector_cst_encoded_nelts (cst1
);
336 for (unsigned i
= 0; i
< encoded_nelts
; i
++)
338 const_tree elt1
= VECTOR_CST_ENCODED_ELT (cst1
, i
);
339 const_tree elt2
= VECTOR_CST_ENCODED_ELT (cst2
, i
);
340 if (int el_cmp
= cmp_csts_and_types (elt1
, elt2
))
347 /* Comparator for imposing a deterministic order on constants that might
348 not be of the same type. */
351 cmp_csts_and_types (const_tree cst1
, const_tree cst2
)
353 int t1
= TYPE_UID (TREE_TYPE (cst1
));
354 int t2
= TYPE_UID (TREE_TYPE (cst2
));
355 if (int cmp_type
= t1
- t2
)
357 return cmp_csts_same_type (cst1
, cst2
);
360 /* Comparator for imposing a deterministic order on svalues. */
363 svalue::cmp_ptr (const svalue
*sval1
, const svalue
*sval2
)
367 if (int cmp_kind
= sval1
->get_kind () - sval2
->get_kind ())
369 int t1
= sval1
->get_type () ? TYPE_UID (sval1
->get_type ()) : -1;
370 int t2
= sval2
->get_type () ? TYPE_UID (sval2
->get_type ()) : -1;
371 if (int cmp_type
= t1
- t2
)
373 switch (sval1
->get_kind ())
379 const region_svalue
*region_sval1
= (const region_svalue
*)sval1
;
380 const region_svalue
*region_sval2
= (const region_svalue
*)sval2
;
381 return region::cmp_ids (region_sval1
->get_pointee (),
382 region_sval2
->get_pointee ());
387 const constant_svalue
*constant_sval1
= (const constant_svalue
*)sval1
;
388 const constant_svalue
*constant_sval2
= (const constant_svalue
*)sval2
;
389 const_tree cst1
= constant_sval1
->get_constant ();
390 const_tree cst2
= constant_sval2
->get_constant ();
391 return cmp_csts_same_type (cst1
, cst2
);
396 gcc_assert (sval1
== sval2
);
402 const poisoned_svalue
*poisoned_sval1
= (const poisoned_svalue
*)sval1
;
403 const poisoned_svalue
*poisoned_sval2
= (const poisoned_svalue
*)sval2
;
404 return (poisoned_sval1
->get_poison_kind ()
405 - poisoned_sval2
->get_poison_kind ());
410 const setjmp_svalue
*setjmp_sval1
= (const setjmp_svalue
*)sval1
;
411 const setjmp_svalue
*setjmp_sval2
= (const setjmp_svalue
*)sval2
;
412 const setjmp_record
&rec1
= setjmp_sval1
->get_setjmp_record ();
413 const setjmp_record
&rec2
= setjmp_sval2
->get_setjmp_record ();
414 return setjmp_record::cmp (rec1
, rec2
);
419 const initial_svalue
*initial_sval1
= (const initial_svalue
*)sval1
;
420 const initial_svalue
*initial_sval2
= (const initial_svalue
*)sval2
;
421 return region::cmp_ids (initial_sval1
->get_region (),
422 initial_sval2
->get_region ());
427 const unaryop_svalue
*unaryop_sval1
= (const unaryop_svalue
*)sval1
;
428 const unaryop_svalue
*unaryop_sval2
= (const unaryop_svalue
*)sval2
;
429 if (int op_cmp
= unaryop_sval1
->get_op () - unaryop_sval2
->get_op ())
431 return svalue::cmp_ptr (unaryop_sval1
->get_arg (),
432 unaryop_sval2
->get_arg ());
437 const binop_svalue
*binop_sval1
= (const binop_svalue
*)sval1
;
438 const binop_svalue
*binop_sval2
= (const binop_svalue
*)sval2
;
439 if (int op_cmp
= binop_sval1
->get_op () - binop_sval2
->get_op ())
441 if (int arg0_cmp
= svalue::cmp_ptr (binop_sval1
->get_arg0 (),
442 binop_sval2
->get_arg0 ()))
444 return svalue::cmp_ptr (binop_sval1
->get_arg1 (),
445 binop_sval2
->get_arg1 ());
450 const sub_svalue
*sub_sval1
= (const sub_svalue
*)sval1
;
451 const sub_svalue
*sub_sval2
= (const sub_svalue
*)sval2
;
452 if (int parent_cmp
= svalue::cmp_ptr (sub_sval1
->get_parent (),
453 sub_sval2
->get_parent ()))
455 return region::cmp_ids (sub_sval1
->get_subregion (),
456 sub_sval2
->get_subregion ());
461 const repeated_svalue
*repeated_sval1
= (const repeated_svalue
*)sval1
;
462 const repeated_svalue
*repeated_sval2
= (const repeated_svalue
*)sval2
;
463 return svalue::cmp_ptr (repeated_sval1
->get_inner_svalue (),
464 repeated_sval2
->get_inner_svalue ());
469 const bits_within_svalue
*bits_within_sval1
470 = (const bits_within_svalue
*)sval1
;
471 const bits_within_svalue
*bits_within_sval2
472 = (const bits_within_svalue
*)sval2
;
473 if (int cmp
= bit_range::cmp (bits_within_sval1
->get_bits (),
474 bits_within_sval2
->get_bits ()))
476 return svalue::cmp_ptr (bits_within_sval1
->get_inner_svalue (),
477 bits_within_sval2
->get_inner_svalue ());
482 const unmergeable_svalue
*unmergeable_sval1
483 = (const unmergeable_svalue
*)sval1
;
484 const unmergeable_svalue
*unmergeable_sval2
485 = (const unmergeable_svalue
*)sval2
;
486 return svalue::cmp_ptr (unmergeable_sval1
->get_arg (),
487 unmergeable_sval2
->get_arg ());
492 const placeholder_svalue
*placeholder_sval1
493 = (const placeholder_svalue
*)sval1
;
494 const placeholder_svalue
*placeholder_sval2
495 = (const placeholder_svalue
*)sval2
;
496 return strcmp (placeholder_sval1
->get_name (),
497 placeholder_sval2
->get_name ());
502 const widening_svalue
*widening_sval1
= (const widening_svalue
*)sval1
;
503 const widening_svalue
*widening_sval2
= (const widening_svalue
*)sval2
;
504 if (int point_cmp
= function_point::cmp (widening_sval1
->get_point (),
505 widening_sval2
->get_point ()))
507 if (int base_cmp
= svalue::cmp_ptr (widening_sval1
->get_base_svalue (),
508 widening_sval2
->get_base_svalue ()))
510 return svalue::cmp_ptr (widening_sval1
->get_iter_svalue (),
511 widening_sval2
->get_iter_svalue ());
516 const compound_svalue
*compound_sval1
= (const compound_svalue
*)sval1
;
517 const compound_svalue
*compound_sval2
= (const compound_svalue
*)sval2
;
518 return binding_map::cmp (compound_sval1
->get_map (),
519 compound_sval2
->get_map ());
524 const conjured_svalue
*conjured_sval1
= (const conjured_svalue
*)sval1
;
525 const conjured_svalue
*conjured_sval2
= (const conjured_svalue
*)sval2
;
526 if (int stmt_cmp
= (conjured_sval1
->get_stmt ()->uid
527 - conjured_sval2
->get_stmt ()->uid
))
529 return region::cmp_ids (conjured_sval1
->get_id_region (),
530 conjured_sval2
->get_id_region ());
535 const asm_output_svalue
*asm_output_sval1
536 = (const asm_output_svalue
*)sval1
;
537 const asm_output_svalue
*asm_output_sval2
538 = (const asm_output_svalue
*)sval2
;
539 if (int asm_string_cmp
= strcmp (asm_output_sval1
->get_asm_string (),
540 asm_output_sval2
->get_asm_string ()))
541 return asm_string_cmp
;
542 if (int output_idx_cmp
= ((int)asm_output_sval1
->get_output_idx ()
543 - (int)asm_output_sval2
->get_output_idx ()))
544 return output_idx_cmp
;
545 if (int cmp
= ((int)asm_output_sval1
->get_num_inputs ()
546 - (int)asm_output_sval2
->get_num_inputs ()))
548 for (unsigned i
= 0; i
< asm_output_sval1
->get_num_inputs (); i
++)
550 = svalue::cmp_ptr (asm_output_sval1
->get_input (i
),
551 asm_output_sval2
->get_input (i
)))
556 case SK_CONST_FN_RESULT
:
558 const const_fn_result_svalue
*const_fn_result_sval1
559 = (const const_fn_result_svalue
*)sval1
;
560 const const_fn_result_svalue
*const_fn_result_sval2
561 = (const const_fn_result_svalue
*)sval2
;
562 int d1
= DECL_UID (const_fn_result_sval1
->get_fndecl ());
563 int d2
= DECL_UID (const_fn_result_sval2
->get_fndecl ());
564 if (int cmp_fndecl
= d1
- d2
)
566 if (int cmp
= ((int)const_fn_result_sval1
->get_num_inputs ()
567 - (int)const_fn_result_sval2
->get_num_inputs ()))
569 for (unsigned i
= 0; i
< const_fn_result_sval1
->get_num_inputs (); i
++)
571 = svalue::cmp_ptr (const_fn_result_sval1
->get_input (i
),
572 const_fn_result_sval2
->get_input (i
)))
579 /* Comparator for use by vec<const svalue *>::qsort. */
582 svalue::cmp_ptr_ptr (const void *p1
, const void *p2
)
584 const svalue
*sval1
= *(const svalue
* const *)p1
;
585 const svalue
*sval2
= *(const svalue
* const *)p2
;
586 return cmp_ptr (sval1
, sval2
);
589 /* Subclass of visitor for use in implementing svalue::involves_p. */
591 class involvement_visitor
: public visitor
594 involvement_visitor (const svalue
*needle
)
595 : m_needle (needle
), m_found (false) {}
597 void visit_initial_svalue (const initial_svalue
*candidate
) final override
599 if (candidate
== m_needle
)
603 void visit_conjured_svalue (const conjured_svalue
*candidate
) final override
605 if (candidate
== m_needle
)
609 bool found_p () const { return m_found
; }
612 const svalue
*m_needle
;
616 /* Return true iff this svalue is defined in terms of OTHER. */
619 svalue::involves_p (const svalue
*other
) const
621 /* Currently only implemented for these kinds. */
622 gcc_assert (other
->get_kind () == SK_INITIAL
623 || other
->get_kind () == SK_CONJURED
);
625 involvement_visitor
v (other
);
630 /* Extract SUBRANGE from this value, of type TYPE. */
633 svalue::extract_bit_range (tree type
,
634 const bit_range
&subrange
,
635 region_model_manager
*mgr
) const
637 return mgr
->get_or_create_bits_within (type
, subrange
, this);
640 /* Base implementation of svalue::maybe_fold_bits_within vfunc. */
643 svalue::maybe_fold_bits_within (tree
,
645 region_model_manager
*) const
647 /* By default, don't fold. */
651 /* Base implementation of svalue::all_zeroes_p.
652 Return true if this value is known to be all zeroes. */
655 svalue::all_zeroes_p () const
660 /* If this svalue is a pointer, attempt to determine the base region it points
661 to. Return NULL on any problems. */
664 svalue::maybe_get_deref_base_region () const
666 const svalue
*iter
= this;
669 switch (iter
->get_kind ())
676 const region_svalue
*region_sval
677 = as_a
<const region_svalue
*> (iter
);
678 return region_sval
->get_pointee ()->get_base_region ();
683 const binop_svalue
*binop_sval
684 = as_a
<const binop_svalue
*> (iter
);
685 switch (binop_sval
->get_op ())
687 case POINTER_PLUS_EXPR
:
688 /* If we have a symbolic value expressing pointer arithmetic,
690 iter
= binop_sval
->get_arg0 ();
702 /* class region_svalue : public svalue. */
704 /* Implementation of svalue::dump_to_pp vfunc for region_svalue. */
707 region_svalue::dump_to_pp (pretty_printer
*pp
, bool simple
) const
712 m_reg
->dump_to_pp (pp
, simple
);
716 pp_string (pp
, "region_svalue(");
717 print_quoted_type (pp
, get_type ());
718 pp_string (pp
, ", ");
719 m_reg
->dump_to_pp (pp
, simple
);
724 /* Implementation of svalue::accept vfunc for region_svalue. */
727 region_svalue::accept (visitor
*v
) const
730 v
->visit_region_svalue (this);
733 /* Implementation of svalue::implicitly_live_p vfunc for region_svalue. */
736 region_svalue::implicitly_live_p (const svalue_set
*,
737 const region_model
*model
) const
739 /* Pointers into clusters that have escaped should be treated as live. */
740 const region
*base_reg
= get_pointee ()->get_base_region ();
741 const store
*store
= model
->get_store ();
742 if (const binding_cluster
*c
= store
->get_cluster (base_reg
))
749 /* Evaluate the condition LHS OP RHS.
750 Subroutine of region_model::eval_condition for when we have a pair of
754 region_svalue::eval_condition (const region_svalue
*lhs
,
756 const region_svalue
*rhs
)
758 /* See if they point to the same region. */
759 const region
*lhs_reg
= lhs
->get_pointee ();
760 const region
*rhs_reg
= rhs
->get_pointee ();
761 bool ptr_equality
= lhs_reg
== rhs_reg
;
769 return tristate::TS_TRUE
;
771 return tristate::TS_FALSE
;
776 return tristate::TS_FALSE
;
778 return tristate::TS_TRUE
;
784 return tristate::TS_TRUE
;
790 return tristate::TS_FALSE
;
794 return tristate::TS_UNKNOWN
;
797 /* class constant_svalue : public svalue. */
799 /* Implementation of svalue::dump_to_pp vfunc for constant_svalue. */
802 constant_svalue::dump_to_pp (pretty_printer
*pp
, bool simple
) const
807 dump_tree (pp
, get_type ());
809 dump_tree (pp
, m_cst_expr
);
813 pp_string (pp
, "constant_svalue(");
814 print_quoted_type (pp
, get_type ());
815 pp_string (pp
, ", ");
816 dump_tree (pp
, m_cst_expr
);
821 /* Implementation of svalue::accept vfunc for constant_svalue. */
824 constant_svalue::accept (visitor
*v
) const
826 v
->visit_constant_svalue (this);
829 /* Implementation of svalue::implicitly_live_p vfunc for constant_svalue.
830 Constants are implicitly live. */
833 constant_svalue::implicitly_live_p (const svalue_set
*,
834 const region_model
*) const
839 /* Evaluate the condition LHS OP RHS.
840 Subroutine of region_model::eval_condition for when we have a pair of
844 constant_svalue::eval_condition (const constant_svalue
*lhs
,
846 const constant_svalue
*rhs
)
848 tree lhs_const
= lhs
->get_constant ();
849 tree rhs_const
= rhs
->get_constant ();
851 gcc_assert (CONSTANT_CLASS_P (lhs_const
));
852 gcc_assert (CONSTANT_CLASS_P (rhs_const
));
854 /* Check for comparable types. */
855 if (types_compatible_p (TREE_TYPE (lhs_const
), TREE_TYPE (rhs_const
)))
858 = fold_binary (op
, boolean_type_node
, lhs_const
, rhs_const
);
859 if (comparison
== boolean_true_node
)
860 return tristate (tristate::TS_TRUE
);
861 if (comparison
== boolean_false_node
)
862 return tristate (tristate::TS_FALSE
);
864 return tristate::TS_UNKNOWN
;
867 /* Implementation of svalue::maybe_fold_bits_within vfunc
868 for constant_svalue. */
871 constant_svalue::maybe_fold_bits_within (tree type
,
872 const bit_range
&bits
,
873 region_model_manager
*mgr
) const
875 /* Bits within an all-zero value are also all zero. */
876 if (zerop (m_cst_expr
))
879 return mgr
->get_or_create_cast (type
, this);
884 /* Handle the case of extracting a single bit. */
885 if (bits
.m_size_in_bits
== 1
886 && TREE_CODE (m_cst_expr
) == INTEGER_CST
888 && INTEGRAL_TYPE_P (type
)
889 && tree_fits_uhwi_p (m_cst_expr
))
891 unsigned HOST_WIDE_INT bit
= bits
.m_start_bit_offset
.to_uhwi ();
892 unsigned HOST_WIDE_INT mask
= (1 << bit
);
893 unsigned HOST_WIDE_INT val_as_hwi
= tree_to_uhwi (m_cst_expr
);
894 unsigned HOST_WIDE_INT masked_val
= val_as_hwi
& mask
;
895 int result
= masked_val
? 1 : 0;
896 return mgr
->get_or_create_int_cst (type
, result
);
899 /* Otherwise, don't fold. */
903 /* Implementation of svalue::all_zeroes_p for constant_svalue. */
906 constant_svalue::all_zeroes_p () const
908 return zerop (m_cst_expr
);
911 /* class unknown_svalue : public svalue. */
913 /* Implementation of svalue::dump_to_pp vfunc for unknown_svalue. */
916 unknown_svalue::dump_to_pp (pretty_printer
*pp
, bool simple
) const
920 pp_string (pp
, "UNKNOWN(");
922 dump_tree (pp
, get_type ());
923 pp_character (pp
, ')');
927 pp_string (pp
, "unknown_svalue(");
929 dump_tree (pp
, get_type ());
930 pp_character (pp
, ')');
934 /* Implementation of svalue::accept vfunc for unknown_svalue. */
937 unknown_svalue::accept (visitor
*v
) const
939 v
->visit_unknown_svalue (this);
942 /* Implementation of svalue::maybe_fold_bits_within vfunc
943 for unknown_svalue. */
946 unknown_svalue::maybe_fold_bits_within (tree type
,
948 region_model_manager
*mgr
) const
950 /* Bits within an unknown_svalue are themselves unknown. */
951 return mgr
->get_or_create_unknown_svalue (type
);
954 /* Get a string for KIND for use in debug dumps. */
957 poison_kind_to_str (enum poison_kind kind
)
963 case POISON_KIND_UNINIT
:
965 case POISON_KIND_FREED
:
967 case POISON_KIND_POPPED_STACK
:
968 return "popped stack";
972 /* class poisoned_svalue : public svalue. */
974 /* Implementation of svalue::dump_to_pp vfunc for poisoned_svalue. */
977 poisoned_svalue::dump_to_pp (pretty_printer
*pp
, bool simple
) const
981 pp_string (pp
, "POISONED(");
982 print_quoted_type (pp
, get_type ());
983 pp_printf (pp
, ", %s)", poison_kind_to_str (m_kind
));
987 pp_string (pp
, "poisoned_svalue(");
988 print_quoted_type (pp
, get_type ());
989 pp_printf (pp
, ", %s)", poison_kind_to_str (m_kind
));
993 /* Implementation of svalue::accept vfunc for poisoned_svalue. */
996 poisoned_svalue::accept (visitor
*v
) const
998 v
->visit_poisoned_svalue (this);
1001 /* Implementation of svalue::maybe_fold_bits_within vfunc
1002 for poisoned_svalue. */
1005 poisoned_svalue::maybe_fold_bits_within (tree type
,
1007 region_model_manager
*mgr
) const
1009 /* Bits within a poisoned value are also poisoned. */
1010 return mgr
->get_or_create_poisoned_svalue (m_kind
, type
);
1013 /* class setjmp_svalue's implementation is in engine.cc, so that it can use
1014 the declaration of exploded_node. */
1016 /* class initial_svalue : public svalue. */
1018 /* Implementation of svalue::dump_to_pp vfunc for initial_svalue. */
1021 initial_svalue::dump_to_pp (pretty_printer
*pp
, bool simple
) const
1025 pp_string (pp
, "INIT_VAL(");
1026 m_reg
->dump_to_pp (pp
, simple
);
1027 pp_string (pp
, ")");
1031 pp_string (pp
, "initial_svalue(");
1032 print_quoted_type (pp
, get_type ());
1033 pp_string (pp
, ", ");
1034 m_reg
->dump_to_pp (pp
, simple
);
1035 pp_string (pp
, ")");
1039 /* Implementation of svalue::accept vfunc for initial_svalue. */
1042 initial_svalue::accept (visitor
*v
) const
1045 v
->visit_initial_svalue (this);
1048 /* Implementation of svalue::implicitly_live_p vfunc for initial_svalue. */
1051 initial_svalue::implicitly_live_p (const svalue_set
*,
1052 const region_model
*model
) const
1054 /* This svalue may be implicitly live if the region still implicitly
1055 has its initial value and is reachable. */
1057 /* It must be a region that exists; we don't want to consider
1058 INIT_VAL(R) as still being implicitly reachable if R is in
1059 a popped stack frame. */
1060 if (model
->region_exists_p (m_reg
))
1062 const svalue
*reg_sval
= model
->get_store_value (m_reg
, NULL
);
1063 if (reg_sval
== this)
1067 /* Assume that the initial values of params for the top level frame
1068 are still live, because (presumably) they're still
1069 live in the external caller. */
1070 if (initial_value_of_param_p ())
1071 if (const frame_region
*frame_reg
= m_reg
->maybe_get_frame_region ())
1072 if (frame_reg
->get_calling_frame () == NULL
)
1078 /* Return true if this is the initial value of a function parameter. */
1081 initial_svalue::initial_value_of_param_p () const
1083 if (tree reg_decl
= m_reg
->maybe_get_decl ())
1084 if (TREE_CODE (reg_decl
) == SSA_NAME
)
1086 tree ssa_name
= reg_decl
;
1087 if (SSA_NAME_IS_DEFAULT_DEF (ssa_name
)
1088 && SSA_NAME_VAR (ssa_name
)
1089 && TREE_CODE (SSA_NAME_VAR (ssa_name
)) == PARM_DECL
)
1095 /* class unaryop_svalue : public svalue. */
1097 /* Implementation of svalue::dump_to_pp vfunc for unaryop_svalue. */
1100 unaryop_svalue::dump_to_pp (pretty_printer
*pp
, bool simple
) const
1104 if (m_op
== VIEW_CONVERT_EXPR
|| m_op
== NOP_EXPR
)
1106 pp_string (pp
, "CAST(");
1107 dump_tree (pp
, get_type ());
1108 pp_string (pp
, ", ");
1109 m_arg
->dump_to_pp (pp
, simple
);
1110 pp_character (pp
, ')');
1114 pp_character (pp
, '(');
1115 pp_string (pp
, get_tree_code_name (m_op
));
1116 //pp_string (pp, op_symbol_code (m_op));
1117 m_arg
->dump_to_pp (pp
, simple
);
1118 pp_character (pp
, ')');
1123 pp_string (pp
, "unaryop_svalue (");
1124 pp_string (pp
, get_tree_code_name (m_op
));
1125 pp_string (pp
, ", ");
1126 m_arg
->dump_to_pp (pp
, simple
);
1127 pp_character (pp
, ')');
1131 /* Implementation of svalue::accept vfunc for unaryop_svalue. */
1134 unaryop_svalue::accept (visitor
*v
) const
1137 v
->visit_unaryop_svalue (this);
1140 /* Implementation of svalue::implicitly_live_p vfunc for unaryop_svalue. */
1143 unaryop_svalue::implicitly_live_p (const svalue_set
*live_svalues
,
1144 const region_model
*model
) const
1146 return get_arg ()->live_p (live_svalues
, model
);
1149 /* Implementation of svalue::maybe_fold_bits_within vfunc
1150 for unaryop_svalue. */
1153 unaryop_svalue::maybe_fold_bits_within (tree type
,
1155 region_model_manager
*mgr
) const
1162 /* A cast of zero is zero. */
1163 if (tree cst
= m_arg
->maybe_get_constant ())
1167 return mgr
->get_or_create_cast (type
, this);
1173 /* Otherwise, don't fold. */
1177 /* class binop_svalue : public svalue. */
1179 /* Return whether OP be printed as an infix operator. */
1182 infix_p (enum tree_code op
)
1194 /* Implementation of svalue::dump_to_pp vfunc for binop_svalue. */
1197 binop_svalue::dump_to_pp (pretty_printer
*pp
, bool simple
) const
1203 /* Print "(A OP B)". */
1204 pp_character (pp
, '(');
1205 m_arg0
->dump_to_pp (pp
, simple
);
1206 pp_string (pp
, op_symbol_code (m_op
));
1207 m_arg1
->dump_to_pp (pp
, simple
);
1208 pp_character (pp
, ')');
1212 /* Print "OP(A, B)". */
1213 pp_string (pp
, op_symbol_code (m_op
));
1214 pp_character (pp
, '(');
1215 m_arg0
->dump_to_pp (pp
, simple
);
1216 pp_string (pp
, ", ");
1217 m_arg1
->dump_to_pp (pp
, simple
);
1218 pp_character (pp
, ')');
1223 pp_string (pp
, "binop_svalue (");
1224 pp_string (pp
, get_tree_code_name (m_op
));
1225 pp_string (pp
, ", ");
1226 m_arg0
->dump_to_pp (pp
, simple
);
1227 pp_string (pp
, ", ");
1228 m_arg1
->dump_to_pp (pp
, simple
);
1229 pp_character (pp
, ')');
1233 /* Implementation of svalue::accept vfunc for binop_svalue. */
1236 binop_svalue::accept (visitor
*v
) const
1240 v
->visit_binop_svalue (this);
1243 /* Implementation of svalue::implicitly_live_p vfunc for binop_svalue. */
1246 binop_svalue::implicitly_live_p (const svalue_set
*live_svalues
,
1247 const region_model
*model
) const
1249 return (get_arg0 ()->live_p (live_svalues
, model
)
1250 && get_arg1 ()->live_p (live_svalues
, model
));
1253 /* class sub_svalue : public svalue. */
1255 /* sub_svalue'c ctor. */
1257 sub_svalue::sub_svalue (tree type
, const svalue
*parent_svalue
,
1258 const region
*subregion
)
1259 : svalue (complexity::from_pair (parent_svalue
->get_complexity (),
1260 subregion
->get_complexity ()),
1262 m_parent_svalue (parent_svalue
), m_subregion (subregion
)
1264 gcc_assert (parent_svalue
->can_have_associated_state_p ());
1267 /* Implementation of svalue::dump_to_pp vfunc for sub_svalue. */
1270 sub_svalue::dump_to_pp (pretty_printer
*pp
, bool simple
) const
1274 pp_string (pp
, "SUB(");
1275 m_parent_svalue
->dump_to_pp (pp
, simple
);
1276 pp_string (pp
, ", ");
1277 m_subregion
->dump_to_pp (pp
, simple
);
1278 pp_character (pp
, ')');
1282 pp_string (pp
, "sub_svalue (");
1283 pp_string (pp
, ", ");
1284 m_parent_svalue
->dump_to_pp (pp
, simple
);
1285 pp_string (pp
, ", ");
1286 m_subregion
->dump_to_pp (pp
, simple
);
1287 pp_character (pp
, ')');
1291 /* Implementation of svalue::accept vfunc for sub_svalue. */
1294 sub_svalue::accept (visitor
*v
) const
1296 m_parent_svalue
->accept (v
);
1297 m_subregion
->accept (v
);
1298 v
->visit_sub_svalue (this);
1301 /* Implementation of svalue::implicitly_live_p vfunc for sub_svalue. */
1304 sub_svalue::implicitly_live_p (const svalue_set
*live_svalues
,
1305 const region_model
*model
) const
1307 return get_parent ()->live_p (live_svalues
, model
);
1310 /* class repeated_svalue : public svalue. */
1312 /* repeated_svalue'c ctor. */
1314 repeated_svalue::repeated_svalue (tree type
,
1315 const svalue
*outer_size
,
1316 const svalue
*inner_svalue
)
1317 : svalue (complexity::from_pair (outer_size
, inner_svalue
), type
),
1318 m_outer_size (outer_size
),
1319 m_inner_svalue (inner_svalue
)
1321 gcc_assert (outer_size
->can_have_associated_state_p ());
1322 gcc_assert (inner_svalue
->can_have_associated_state_p ());
1325 /* Implementation of svalue::dump_to_pp vfunc for repeated_svalue. */
1328 repeated_svalue::dump_to_pp (pretty_printer
*pp
, bool simple
) const
1332 pp_string (pp
, "REPEATED(");
1335 print_quoted_type (pp
, get_type ());
1336 pp_string (pp
, ", ");
1338 pp_string (pp
, "outer_size: ");
1339 m_outer_size
->dump_to_pp (pp
, simple
);
1340 pp_string (pp
, ", inner_val: ");
1341 m_inner_svalue
->dump_to_pp (pp
, simple
);
1342 pp_character (pp
, ')');
1346 pp_string (pp
, "repeated_svalue (");
1349 print_quoted_type (pp
, get_type ());
1350 pp_string (pp
, ", ");
1352 pp_string (pp
, "outer_size: ");
1353 m_outer_size
->dump_to_pp (pp
, simple
);
1354 pp_string (pp
, ", inner_val: ");
1355 m_inner_svalue
->dump_to_pp (pp
, simple
);
1356 pp_character (pp
, ')');
1360 /* Implementation of svalue::accept vfunc for repeated_svalue. */
1363 repeated_svalue::accept (visitor
*v
) const
1365 m_inner_svalue
->accept (v
);
1366 v
->visit_repeated_svalue (this);
1369 /* Implementation of svalue::all_zeroes_p for repeated_svalue. */
1372 repeated_svalue::all_zeroes_p () const
1374 return m_inner_svalue
->all_zeroes_p ();
1377 /* Implementation of svalue::maybe_fold_bits_within vfunc
1378 for repeated_svalue. */
1381 repeated_svalue::maybe_fold_bits_within (tree type
,
1382 const bit_range
&bits
,
1383 region_model_manager
*mgr
) const
1385 const svalue
*innermost_sval
= m_inner_svalue
;
1387 BITS_WITHIN (range, REPEATED_SVALUE (ZERO))
1389 REPEATED_SVALUE (ZERO). */
1390 if (all_zeroes_p ())
1392 byte_range
bytes (0,0);
1393 if (bits
.as_byte_range (&bytes
))
1395 const svalue
*byte_size
1396 = mgr
->get_or_create_int_cst (size_type_node
,
1397 bytes
.m_size_in_bytes
.to_uhwi ());
1398 return mgr
->get_or_create_repeated_svalue (type
, byte_size
,
1404 BITS_WITHIN (range, REPEATED_SVALUE (INNERMOST_SVALUE))
1406 BITS_WITHIN (range - offset, INNERMOST_SVALUE)
1407 if range is fully within one instance of INNERMOST_SVALUE. */
1408 if (tree innermost_type
= innermost_sval
->get_type ())
1410 bit_size_t element_bit_size
;
1411 if (int_size_in_bits (innermost_type
, &element_bit_size
)
1412 && element_bit_size
> 0)
1414 HOST_WIDE_INT start_idx
1415 = (bits
.get_start_bit_offset ()
1416 / element_bit_size
).to_shwi ();
1417 HOST_WIDE_INT last_idx
1418 = (bits
.get_last_bit_offset ()
1419 / element_bit_size
).to_shwi ();
1420 if (start_idx
== last_idx
)
1422 bit_offset_t start_of_element
1423 = start_idx
* element_bit_size
;
1424 bit_range range_within_element
1425 (bits
.m_start_bit_offset
- start_of_element
,
1426 bits
.m_size_in_bits
);
1427 return mgr
->get_or_create_bits_within (type
,
1428 range_within_element
,
1437 /* class bits_within_svalue : public svalue. */
1439 /* bits_within_svalue'c ctor. */
1441 bits_within_svalue::bits_within_svalue (tree type
,
1442 const bit_range
&bits
,
1443 const svalue
*inner_svalue
)
1444 : svalue (complexity (inner_svalue
), type
),
1446 m_inner_svalue (inner_svalue
)
1448 gcc_assert (inner_svalue
->can_have_associated_state_p ());
1451 /* Implementation of svalue::dump_to_pp vfunc for bits_within_svalue. */
1454 bits_within_svalue::dump_to_pp (pretty_printer
*pp
, bool simple
) const
1458 pp_string (pp
, "BITS_WITHIN(");
1461 print_quoted_type (pp
, get_type ());
1462 pp_string (pp
, ", ");
1464 m_bits
.dump_to_pp (pp
);
1465 pp_string (pp
, ", inner_val: ");
1466 m_inner_svalue
->dump_to_pp (pp
, simple
);
1467 pp_character (pp
, ')');
1471 pp_string (pp
, "bits_within_svalue (");
1474 print_quoted_type (pp
, get_type ());
1475 pp_string (pp
, ", ");
1477 m_bits
.dump_to_pp (pp
);
1478 pp_string (pp
, ", inner_val: ");
1479 m_inner_svalue
->dump_to_pp (pp
, simple
);
1480 pp_character (pp
, ')');
1484 /* Implementation of svalue::maybe_fold_bits_within vfunc
1485 for bits_within_svalue. */
1488 bits_within_svalue::maybe_fold_bits_within (tree type
,
1489 const bit_range
&bits
,
1490 region_model_manager
*mgr
) const
1493 BITS_WITHIN (range1, BITS_WITHIN (range2, VAL))
1495 BITS_WITHIN (range1 in range 2, VAL). */
1496 bit_range
offset_bits (m_bits
.get_start_bit_offset ()
1497 + bits
.m_start_bit_offset
,
1498 bits
.m_size_in_bits
);
1499 return mgr
->get_or_create_bits_within (type
, offset_bits
, m_inner_svalue
);
1502 /* Implementation of svalue::accept vfunc for bits_within_svalue. */
1505 bits_within_svalue::accept (visitor
*v
) const
1507 m_inner_svalue
->accept (v
);
1508 v
->visit_bits_within_svalue (this);
1511 /* Implementation of svalue::implicitly_live_p vfunc for bits_within_svalue. */
1514 bits_within_svalue::implicitly_live_p (const svalue_set
*live_svalues
,
1515 const region_model
*model
) const
1517 return m_inner_svalue
->live_p (live_svalues
, model
);
1520 /* class widening_svalue : public svalue. */
1522 /* Implementation of svalue::dump_to_pp vfunc for widening_svalue. */
1525 widening_svalue::dump_to_pp (pretty_printer
*pp
, bool simple
) const
1529 pp_string (pp
, "WIDENING(");
1530 pp_character (pp
, '{');
1531 m_point
.print (pp
, format (false));
1532 pp_string (pp
, "}, ");
1533 m_base_sval
->dump_to_pp (pp
, simple
);
1534 pp_string (pp
, ", ");
1535 m_iter_sval
->dump_to_pp (pp
, simple
);
1536 pp_character (pp
, ')');
1540 pp_string (pp
, "widening_svalue (");
1541 pp_string (pp
, ", ");
1542 pp_character (pp
, '{');
1543 m_point
.print (pp
, format (false));
1544 pp_string (pp
, "}, ");
1545 m_base_sval
->dump_to_pp (pp
, simple
);
1546 pp_string (pp
, ", ");
1547 m_iter_sval
->dump_to_pp (pp
, simple
);
1548 pp_character (pp
, ')');
1552 /* Implementation of svalue::accept vfunc for widening_svalue. */
1555 widening_svalue::accept (visitor
*v
) const
1557 m_base_sval
->accept (v
);
1558 m_iter_sval
->accept (v
);
1559 v
->visit_widening_svalue (this);
1562 /* Attempt to determine in which direction this value is changing
1563 w.r.t. the initial value. */
1565 enum widening_svalue::direction_t
1566 widening_svalue::get_direction () const
1568 tree base_cst
= m_base_sval
->maybe_get_constant ();
1569 if (base_cst
== NULL_TREE
)
1571 tree iter_cst
= m_iter_sval
->maybe_get_constant ();
1572 if (iter_cst
== NULL_TREE
)
1575 tree iter_gt_base
= fold_binary (GT_EXPR
, boolean_type_node
,
1576 iter_cst
, base_cst
);
1577 if (iter_gt_base
== boolean_true_node
)
1578 return DIR_ASCENDING
;
1580 tree iter_lt_base
= fold_binary (LT_EXPR
, boolean_type_node
,
1581 iter_cst
, base_cst
);
1582 if (iter_lt_base
== boolean_true_node
)
1583 return DIR_DESCENDING
;
1588 /* Compare this value against constant RHS_CST. */
1591 widening_svalue::eval_condition_without_cm (enum tree_code op
,
1594 tree base_cst
= m_base_sval
->maybe_get_constant ();
1595 if (base_cst
== NULL_TREE
)
1596 return tristate::TS_UNKNOWN
;
1597 tree iter_cst
= m_iter_sval
->maybe_get_constant ();
1598 if (iter_cst
== NULL_TREE
)
1599 return tristate::TS_UNKNOWN
;
1601 switch (get_direction ())
1606 /* LHS is in [base_cst, +ve infinity), assuming no overflow. */
1612 /* [BASE, +INF) OP RHS:
1613 This is either true or false at +ve ininity,
1614 It can be true for points X where X OP RHS, so we have either
1615 "false", or "unknown". */
1616 tree base_op_rhs
= fold_binary (op
, boolean_type_node
,
1618 if (base_op_rhs
== boolean_true_node
)
1619 return tristate::TS_UNKNOWN
;
1621 return tristate::TS_FALSE
;
1627 /* [BASE, +INF) OP RHS:
1628 This is true at +ve infinity. It will be true everywhere
1629 in the range if BASE >= RHS. */
1630 tree base_op_rhs
= fold_binary (op
, boolean_type_node
,
1632 if (base_op_rhs
== boolean_true_node
)
1633 return tristate::TS_TRUE
;
1635 return tristate::TS_UNKNOWN
;
1640 /* [BASE, +INF) == RHS:
1641 Could this be true at any point in the range? If so we
1642 have "unknown", otherwise we have "false". */
1643 tree base_le_rhs
= fold_binary (LE_EXPR
, boolean_type_node
,
1645 if (base_le_rhs
== boolean_true_node
)
1646 return tristate::TS_UNKNOWN
;
1648 return tristate::TS_FALSE
;
1653 /* [BASE, +INF) != RHS:
1654 Could we have equality at any point in the range? If so we
1655 have "unknown", otherwise we have "true". */
1656 tree base_le_rhs
= fold_binary (LE_EXPR
, boolean_type_node
,
1658 if (base_le_rhs
== boolean_true_node
)
1659 return tristate::TS_UNKNOWN
;
1661 return tristate::TS_TRUE
;
1665 return tristate::TS_UNKNOWN
;
1668 case DIR_DESCENDING
:
1669 /* LHS is in (-ve infinity, base_cst], assuming no overflow. */
1670 return tristate::TS_UNKNOWN
;
1673 return tristate::TS_UNKNOWN
;
1677 /* class placeholder_svalue : public svalue. */
1679 /* Implementation of svalue::dump_to_pp vfunc for placeholder_svalue. */
1682 placeholder_svalue::dump_to_pp (pretty_printer
*pp
, bool simple
) const
1685 pp_printf (pp
, "PLACEHOLDER(%qs)", m_name
);
1687 pp_printf (pp
, "placeholder_svalue (%qs)", m_name
);
1690 /* Implementation of svalue::accept vfunc for placeholder_svalue. */
1693 placeholder_svalue::accept (visitor
*v
) const
1695 v
->visit_placeholder_svalue (this);
1698 /* class unmergeable_svalue : public svalue. */
1700 /* Implementation of svalue::dump_to_pp vfunc for unmergeable_svalue. */
1703 unmergeable_svalue::dump_to_pp (pretty_printer
*pp
, bool simple
) const
1707 pp_string (pp
, "UNMERGEABLE(");
1708 m_arg
->dump_to_pp (pp
, simple
);
1709 pp_character (pp
, ')');
1713 pp_string (pp
, "unmergeable_svalue (");
1714 m_arg
->dump_to_pp (pp
, simple
);
1715 pp_character (pp
, ')');
1719 /* Implementation of svalue::accept vfunc for unmergeable_svalue. */
1722 unmergeable_svalue::accept (visitor
*v
) const
1725 v
->visit_unmergeable_svalue (this);
1728 /* Implementation of svalue::implicitly_live_p vfunc for unmergeable_svalue. */
1731 unmergeable_svalue::implicitly_live_p (const svalue_set
*live_svalues
,
1732 const region_model
*model
) const
1734 return get_arg ()->live_p (live_svalues
, model
);
1737 /* class compound_svalue : public svalue. */
1739 compound_svalue::compound_svalue (tree type
, const binding_map
&map
)
1740 : svalue (calc_complexity (map
), type
), m_map (map
)
1743 for (iterator_t iter
= begin (); iter
!= end (); ++iter
)
1745 /* All keys within the underlying binding_map are required to be concrete,
1747 const binding_key
*key
= (*iter
).first
;
1748 gcc_assert (key
->concrete_p ());
1750 /* We don't nest compound svalues. */
1751 const svalue
*sval
= (*iter
).second
;
1752 gcc_assert (sval
->get_kind () != SK_COMPOUND
);
1757 /* Implementation of svalue::dump_to_pp vfunc for compound_svalue. */
1760 compound_svalue::dump_to_pp (pretty_printer
*pp
, bool simple
) const
1764 pp_string (pp
, "COMPOUND(");
1767 print_quoted_type (pp
, get_type ());
1768 pp_string (pp
, ", ");
1770 pp_character (pp
, '{');
1771 m_map
.dump_to_pp (pp
, simple
, false);
1772 pp_string (pp
, "})");
1776 pp_string (pp
, "compound_svalue (");
1779 print_quoted_type (pp
, get_type ());
1780 pp_string (pp
, ", ");
1782 pp_character (pp
, '{');
1783 m_map
.dump_to_pp (pp
, simple
, false);
1784 pp_string (pp
, "})");
1788 /* Implementation of svalue::accept vfunc for compound_svalue. */
1791 compound_svalue::accept (visitor
*v
) const
1793 for (binding_map::iterator_t iter
= m_map
.begin ();
1794 iter
!= m_map
.end (); ++iter
)
1796 //(*iter).first.accept (v);
1797 (*iter
).second
->accept (v
);
1799 v
->visit_compound_svalue (this);
1802 /* Calculate what the complexity of a compound_svalue instance for MAP
1803 will be, based on the svalues bound within MAP. */
1806 compound_svalue::calc_complexity (const binding_map
&map
)
1808 unsigned num_child_nodes
= 0;
1809 unsigned max_child_depth
= 0;
1810 for (binding_map::iterator_t iter
= map
.begin ();
1811 iter
!= map
.end (); ++iter
)
1813 const complexity
&sval_c
= (*iter
).second
->get_complexity ();
1814 num_child_nodes
+= sval_c
.m_num_nodes
;
1815 max_child_depth
= MAX (max_child_depth
, sval_c
.m_max_depth
);
1817 return complexity (num_child_nodes
+ 1, max_child_depth
+ 1);
1820 /* Implementation of svalue::maybe_fold_bits_within vfunc
1821 for compound_svalue. */
1824 compound_svalue::maybe_fold_bits_within (tree type
,
1825 const bit_range
&bits
,
1826 region_model_manager
*mgr
) const
1828 binding_map result_map
;
1829 for (auto iter
: m_map
)
1831 const binding_key
*key
= iter
.first
;
1832 if (const concrete_binding
*conc_key
1833 = key
->dyn_cast_concrete_binding ())
1835 /* Ignore concrete bindings outside BITS. */
1836 if (!conc_key
->get_bit_range ().intersects_p (bits
))
1839 const svalue
*sval
= iter
.second
;
1840 /* Get the position of conc_key relative to BITS. */
1841 bit_range
result_location (conc_key
->get_start_bit_offset ()
1842 - bits
.get_start_bit_offset (),
1843 conc_key
->get_size_in_bits ());
1844 /* If conc_key starts after BITS, trim off leading bits
1845 from the svalue and adjust binding location. */
1846 if (result_location
.m_start_bit_offset
< 0)
1848 bit_size_t leading_bits_to_drop
1849 = -result_location
.m_start_bit_offset
;
1850 result_location
= bit_range
1851 (0, result_location
.m_size_in_bits
- leading_bits_to_drop
);
1852 bit_range
bits_within_sval (leading_bits_to_drop
,
1853 result_location
.m_size_in_bits
);
1854 /* Trim off leading bits from iter_sval. */
1855 sval
= mgr
->get_or_create_bits_within (NULL_TREE
,
1859 /* If conc_key finishes after BITS, trim off trailing bits
1860 from the svalue and adjust binding location. */
1861 if (conc_key
->get_next_bit_offset ()
1862 > bits
.get_next_bit_offset ())
1864 bit_size_t trailing_bits_to_drop
1865 = (conc_key
->get_next_bit_offset ()
1866 - bits
.get_next_bit_offset ());
1867 result_location
= bit_range
1868 (result_location
.m_start_bit_offset
,
1869 result_location
.m_size_in_bits
- trailing_bits_to_drop
);
1870 bit_range
bits_within_sval (0,
1871 result_location
.m_size_in_bits
);
1872 /* Trim off leading bits from iter_sval. */
1873 sval
= mgr
->get_or_create_bits_within (NULL_TREE
,
1877 const concrete_binding
*offset_conc_key
1878 = mgr
->get_store_manager ()->get_concrete_binding
1880 result_map
.put (offset_conc_key
, sval
);
1883 /* If we have any symbolic keys we can't get it as bits. */
1886 return mgr
->get_or_create_compound_svalue (type
, result_map
);
1889 /* class conjured_svalue : public svalue. */
1891 /* Implementation of svalue::dump_to_pp vfunc for conjured_svalue. */
1894 conjured_svalue::dump_to_pp (pretty_printer
*pp
, bool simple
) const
1898 pp_string (pp
, "CONJURED(");
1899 pp_gimple_stmt_1 (pp
, m_stmt
, 0, (dump_flags_t
)0);
1900 pp_string (pp
, ", ");
1901 m_id_reg
->dump_to_pp (pp
, simple
);
1902 pp_character (pp
, ')');
1906 pp_string (pp
, "conjured_svalue (");
1907 pp_string (pp
, ", ");
1908 pp_gimple_stmt_1 (pp
, m_stmt
, 0, (dump_flags_t
)0);
1909 pp_string (pp
, ", ");
1910 m_id_reg
->dump_to_pp (pp
, simple
);
1911 pp_character (pp
, ')');
1915 /* Implementation of svalue::accept vfunc for conjured_svalue. */
1918 conjured_svalue::accept (visitor
*v
) const
1920 m_id_reg
->accept (v
);
1921 v
->visit_conjured_svalue (this);
1924 /* class asm_output_svalue : public svalue. */
1926 /* Implementation of svalue::dump_to_pp vfunc for asm_output_svalue. */
1929 asm_output_svalue::dump_to_pp (pretty_printer
*pp
, bool simple
) const
1933 pp_printf (pp
, "ASM_OUTPUT(%qs, %%%i, {",
1936 for (unsigned i
= 0; i
< m_num_inputs
; i
++)
1939 pp_string (pp
, ", ");
1940 dump_input (pp
, 0, m_input_arr
[i
], simple
);
1942 pp_string (pp
, "})");
1946 pp_printf (pp
, "asm_output_svalue (%qs, %%%i, {",
1949 for (unsigned i
= 0; i
< m_num_inputs
; i
++)
1952 pp_string (pp
, ", ");
1953 dump_input (pp
, 0, m_input_arr
[i
], simple
);
1955 pp_string (pp
, "})");
1959 /* Subroutine of asm_output_svalue::dump_to_pp. */
1962 asm_output_svalue::dump_input (pretty_printer
*pp
,
1967 pp_printf (pp
, "%%%i: ", input_idx_to_asm_idx (input_idx
));
1968 sval
->dump_to_pp (pp
, simple
);
1971 /* Convert INPUT_IDX from an index into the array of inputs
1972 into the index of all operands for the asm stmt. */
1975 asm_output_svalue::input_idx_to_asm_idx (unsigned input_idx
) const
1977 return input_idx
+ m_num_outputs
;
1980 /* Implementation of svalue::accept vfunc for asm_output_svalue. */
1983 asm_output_svalue::accept (visitor
*v
) const
1985 for (unsigned i
= 0; i
< m_num_inputs
; i
++)
1986 m_input_arr
[i
]->accept (v
);
1987 v
->visit_asm_output_svalue (this);
1990 /* class const_fn_result_svalue : public svalue. */
1992 /* Implementation of svalue::dump_to_pp vfunc for const_fn_result_svalue. */
1995 const_fn_result_svalue::dump_to_pp (pretty_printer
*pp
, bool simple
) const
1999 pp_printf (pp
, "CONST_FN_RESULT(%qD, {", m_fndecl
);
2000 for (unsigned i
= 0; i
< m_num_inputs
; i
++)
2003 pp_string (pp
, ", ");
2004 dump_input (pp
, i
, m_input_arr
[i
], simple
);
2006 pp_string (pp
, "})");
2010 pp_printf (pp
, "CONST_FN_RESULT(%qD, {", m_fndecl
);
2011 for (unsigned i
= 0; i
< m_num_inputs
; i
++)
2014 pp_string (pp
, ", ");
2015 dump_input (pp
, i
, m_input_arr
[i
], simple
);
2017 pp_string (pp
, "})");
2021 /* Subroutine of const_fn_result_svalue::dump_to_pp. */
2024 const_fn_result_svalue::dump_input (pretty_printer
*pp
,
2029 pp_printf (pp
, "arg%i: ", input_idx
);
2030 sval
->dump_to_pp (pp
, simple
);
2033 /* Implementation of svalue::accept vfunc for const_fn_result_svalue. */
2036 const_fn_result_svalue::accept (visitor
*v
) const
2038 for (unsigned i
= 0; i
< m_num_inputs
; i
++)
2039 m_input_arr
[i
]->accept (v
);
2040 v
->visit_const_fn_result_svalue (this);
2045 #endif /* #if ENABLE_ANALYZER */