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(");
719 print_quoted_type (pp
, get_type ());
720 pp_string (pp
, ", ");
722 m_reg
->dump_to_pp (pp
, simple
);
727 /* Implementation of svalue::accept vfunc for region_svalue. */
730 region_svalue::accept (visitor
*v
) const
733 v
->visit_region_svalue (this);
736 /* Implementation of svalue::implicitly_live_p vfunc for region_svalue. */
739 region_svalue::implicitly_live_p (const svalue_set
*,
740 const region_model
*model
) const
742 /* Pointers into clusters that have escaped should be treated as live. */
743 const region
*base_reg
= get_pointee ()->get_base_region ();
744 const store
*store
= model
->get_store ();
745 if (const binding_cluster
*c
= store
->get_cluster (base_reg
))
752 /* Evaluate the condition LHS OP RHS.
753 Subroutine of region_model::eval_condition for when we have a pair of
757 region_svalue::eval_condition (const region_svalue
*lhs
,
759 const region_svalue
*rhs
)
761 /* See if they point to the same region. */
762 const region
*lhs_reg
= lhs
->get_pointee ();
763 const region
*rhs_reg
= rhs
->get_pointee ();
764 bool ptr_equality
= lhs_reg
== rhs_reg
;
772 return tristate::TS_TRUE
;
774 return tristate::TS_FALSE
;
779 return tristate::TS_FALSE
;
781 return tristate::TS_TRUE
;
787 return tristate::TS_TRUE
;
793 return tristate::TS_FALSE
;
797 return tristate::TS_UNKNOWN
;
800 /* class constant_svalue : public svalue. */
802 /* Implementation of svalue::dump_to_pp vfunc for constant_svalue. */
805 constant_svalue::dump_to_pp (pretty_printer
*pp
, bool simple
) const
810 dump_tree (pp
, get_type ());
812 dump_tree (pp
, m_cst_expr
);
816 pp_string (pp
, "constant_svalue(");
819 print_quoted_type (pp
, get_type ());
820 pp_string (pp
, ", ");
822 dump_tree (pp
, m_cst_expr
);
827 /* Implementation of svalue::accept vfunc for constant_svalue. */
830 constant_svalue::accept (visitor
*v
) const
832 v
->visit_constant_svalue (this);
835 /* Implementation of svalue::implicitly_live_p vfunc for constant_svalue.
836 Constants are implicitly live. */
839 constant_svalue::implicitly_live_p (const svalue_set
*,
840 const region_model
*) const
845 /* Evaluate the condition LHS OP RHS.
846 Subroutine of region_model::eval_condition for when we have a pair of
850 constant_svalue::eval_condition (const constant_svalue
*lhs
,
852 const constant_svalue
*rhs
)
854 tree lhs_const
= lhs
->get_constant ();
855 tree rhs_const
= rhs
->get_constant ();
857 gcc_assert (CONSTANT_CLASS_P (lhs_const
));
858 gcc_assert (CONSTANT_CLASS_P (rhs_const
));
860 /* Check for comparable types. */
861 if (types_compatible_p (TREE_TYPE (lhs_const
), TREE_TYPE (rhs_const
)))
864 = fold_binary (op
, boolean_type_node
, lhs_const
, rhs_const
);
865 if (comparison
== boolean_true_node
)
866 return tristate (tristate::TS_TRUE
);
867 if (comparison
== boolean_false_node
)
868 return tristate (tristate::TS_FALSE
);
870 return tristate::TS_UNKNOWN
;
873 /* Implementation of svalue::maybe_fold_bits_within vfunc
874 for constant_svalue. */
877 constant_svalue::maybe_fold_bits_within (tree type
,
878 const bit_range
&bits
,
879 region_model_manager
*mgr
) const
881 /* Bits within an all-zero value are also all zero. */
882 if (zerop (m_cst_expr
))
885 return mgr
->get_or_create_cast (type
, this);
890 /* Handle the case of extracting a single bit. */
891 if (bits
.m_size_in_bits
== 1
892 && TREE_CODE (m_cst_expr
) == INTEGER_CST
894 && INTEGRAL_TYPE_P (type
)
895 && tree_fits_uhwi_p (m_cst_expr
))
897 unsigned HOST_WIDE_INT bit
= bits
.m_start_bit_offset
.to_uhwi ();
898 unsigned HOST_WIDE_INT mask
= (1 << bit
);
899 unsigned HOST_WIDE_INT val_as_hwi
= tree_to_uhwi (m_cst_expr
);
900 unsigned HOST_WIDE_INT masked_val
= val_as_hwi
& mask
;
901 int result
= masked_val
? 1 : 0;
902 return mgr
->get_or_create_int_cst (type
, result
);
905 /* Otherwise, don't fold. */
909 /* Implementation of svalue::all_zeroes_p for constant_svalue. */
912 constant_svalue::all_zeroes_p () const
914 return zerop (m_cst_expr
);
917 /* class unknown_svalue : public svalue. */
919 /* Implementation of svalue::dump_to_pp vfunc for unknown_svalue. */
922 unknown_svalue::dump_to_pp (pretty_printer
*pp
, bool simple
) const
926 pp_string (pp
, "UNKNOWN(");
928 dump_tree (pp
, get_type ());
929 pp_character (pp
, ')');
933 pp_string (pp
, "unknown_svalue(");
935 dump_tree (pp
, get_type ());
936 pp_character (pp
, ')');
940 /* Implementation of svalue::accept vfunc for unknown_svalue. */
943 unknown_svalue::accept (visitor
*v
) const
945 v
->visit_unknown_svalue (this);
948 /* Implementation of svalue::maybe_fold_bits_within vfunc
949 for unknown_svalue. */
952 unknown_svalue::maybe_fold_bits_within (tree type
,
954 region_model_manager
*mgr
) const
956 /* Bits within an unknown_svalue are themselves unknown. */
957 return mgr
->get_or_create_unknown_svalue (type
);
960 /* Get a string for KIND for use in debug dumps. */
963 poison_kind_to_str (enum poison_kind kind
)
969 case POISON_KIND_UNINIT
:
971 case POISON_KIND_FREED
:
973 case POISON_KIND_DELETED
:
975 case POISON_KIND_POPPED_STACK
:
976 return "popped stack";
980 /* class poisoned_svalue : public svalue. */
982 /* Implementation of svalue::dump_to_pp vfunc for poisoned_svalue. */
985 poisoned_svalue::dump_to_pp (pretty_printer
*pp
, bool simple
) const
989 pp_string (pp
, "POISONED(");
990 print_quoted_type (pp
, get_type ());
991 pp_printf (pp
, ", %s)", poison_kind_to_str (m_kind
));
995 pp_string (pp
, "poisoned_svalue(");
996 print_quoted_type (pp
, get_type ());
997 pp_printf (pp
, ", %s)", poison_kind_to_str (m_kind
));
1001 /* Implementation of svalue::accept vfunc for poisoned_svalue. */
1004 poisoned_svalue::accept (visitor
*v
) const
1006 v
->visit_poisoned_svalue (this);
1009 /* Implementation of svalue::maybe_fold_bits_within vfunc
1010 for poisoned_svalue. */
1013 poisoned_svalue::maybe_fold_bits_within (tree type
,
1015 region_model_manager
*mgr
) const
1017 /* Bits within a poisoned value are also poisoned. */
1018 return mgr
->get_or_create_poisoned_svalue (m_kind
, type
);
1021 /* class setjmp_svalue's implementation is in engine.cc, so that it can use
1022 the declaration of exploded_node. */
1024 /* class initial_svalue : public svalue. */
1026 /* Implementation of svalue::dump_to_pp vfunc for initial_svalue. */
1029 initial_svalue::dump_to_pp (pretty_printer
*pp
, bool simple
) const
1033 pp_string (pp
, "INIT_VAL(");
1034 m_reg
->dump_to_pp (pp
, simple
);
1035 pp_string (pp
, ")");
1039 pp_string (pp
, "initial_svalue(");
1042 print_quoted_type (pp
, get_type ());
1043 pp_string (pp
, ", ");
1045 m_reg
->dump_to_pp (pp
, simple
);
1046 pp_string (pp
, ")");
1050 /* Implementation of svalue::accept vfunc for initial_svalue. */
1053 initial_svalue::accept (visitor
*v
) const
1056 v
->visit_initial_svalue (this);
1059 /* Implementation of svalue::implicitly_live_p vfunc for initial_svalue. */
1062 initial_svalue::implicitly_live_p (const svalue_set
*,
1063 const region_model
*model
) const
1065 /* This svalue may be implicitly live if the region still implicitly
1066 has its initial value and is reachable. */
1068 /* It must be a region that exists; we don't want to consider
1069 INIT_VAL(R) as still being implicitly reachable if R is in
1070 a popped stack frame. */
1071 if (model
->region_exists_p (m_reg
))
1073 const svalue
*reg_sval
= model
->get_store_value (m_reg
, NULL
);
1074 if (reg_sval
== this)
1078 /* Assume that the initial values of params for the top level frame
1079 are still live, because (presumably) they're still
1080 live in the external caller. */
1081 if (initial_value_of_param_p ())
1082 if (const frame_region
*frame_reg
= m_reg
->maybe_get_frame_region ())
1083 if (frame_reg
->get_calling_frame () == NULL
)
1089 /* Return true if this is the initial value of a function parameter. */
1092 initial_svalue::initial_value_of_param_p () const
1094 if (tree reg_decl
= m_reg
->maybe_get_decl ())
1095 if (TREE_CODE (reg_decl
) == SSA_NAME
)
1097 tree ssa_name
= reg_decl
;
1098 if (SSA_NAME_IS_DEFAULT_DEF (ssa_name
)
1099 && SSA_NAME_VAR (ssa_name
)
1100 && TREE_CODE (SSA_NAME_VAR (ssa_name
)) == PARM_DECL
)
1106 /* class unaryop_svalue : public svalue. */
1108 /* Implementation of svalue::dump_to_pp vfunc for unaryop_svalue. */
1111 unaryop_svalue::dump_to_pp (pretty_printer
*pp
, bool simple
) const
1115 if (m_op
== VIEW_CONVERT_EXPR
|| m_op
== NOP_EXPR
)
1117 pp_string (pp
, "CAST(");
1118 dump_tree (pp
, get_type ());
1119 pp_string (pp
, ", ");
1120 m_arg
->dump_to_pp (pp
, simple
);
1121 pp_character (pp
, ')');
1125 pp_character (pp
, '(');
1126 pp_string (pp
, get_tree_code_name (m_op
));
1127 //pp_string (pp, op_symbol_code (m_op));
1128 m_arg
->dump_to_pp (pp
, simple
);
1129 pp_character (pp
, ')');
1134 pp_string (pp
, "unaryop_svalue (");
1135 pp_string (pp
, get_tree_code_name (m_op
));
1136 pp_string (pp
, ", ");
1137 m_arg
->dump_to_pp (pp
, simple
);
1138 pp_character (pp
, ')');
1142 /* Implementation of svalue::accept vfunc for unaryop_svalue. */
1145 unaryop_svalue::accept (visitor
*v
) const
1148 v
->visit_unaryop_svalue (this);
1151 /* Implementation of svalue::implicitly_live_p vfunc for unaryop_svalue. */
1154 unaryop_svalue::implicitly_live_p (const svalue_set
*live_svalues
,
1155 const region_model
*model
) const
1157 return get_arg ()->live_p (live_svalues
, model
);
1160 /* Implementation of svalue::maybe_fold_bits_within vfunc
1161 for unaryop_svalue. */
1164 unaryop_svalue::maybe_fold_bits_within (tree type
,
1166 region_model_manager
*mgr
) const
1173 /* A cast of zero is zero. */
1174 if (tree cst
= m_arg
->maybe_get_constant ())
1178 return mgr
->get_or_create_cast (type
, this);
1184 /* Otherwise, don't fold. */
1188 /* class binop_svalue : public svalue. */
1190 /* Return whether OP be printed as an infix operator. */
1193 infix_p (enum tree_code op
)
1205 /* Implementation of svalue::dump_to_pp vfunc for binop_svalue. */
1208 binop_svalue::dump_to_pp (pretty_printer
*pp
, bool simple
) const
1214 /* Print "(A OP B)". */
1215 pp_character (pp
, '(');
1216 m_arg0
->dump_to_pp (pp
, simple
);
1217 pp_string (pp
, op_symbol_code (m_op
));
1218 m_arg1
->dump_to_pp (pp
, simple
);
1219 pp_character (pp
, ')');
1223 /* Print "OP(A, B)". */
1224 pp_string (pp
, op_symbol_code (m_op
));
1225 pp_character (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
, ')');
1234 pp_string (pp
, "binop_svalue (");
1235 pp_string (pp
, get_tree_code_name (m_op
));
1236 pp_string (pp
, ", ");
1237 m_arg0
->dump_to_pp (pp
, simple
);
1238 pp_string (pp
, ", ");
1239 m_arg1
->dump_to_pp (pp
, simple
);
1240 pp_character (pp
, ')');
1244 /* Implementation of svalue::accept vfunc for binop_svalue. */
1247 binop_svalue::accept (visitor
*v
) const
1251 v
->visit_binop_svalue (this);
1254 /* Implementation of svalue::implicitly_live_p vfunc for binop_svalue. */
1257 binop_svalue::implicitly_live_p (const svalue_set
*live_svalues
,
1258 const region_model
*model
) const
1260 return (get_arg0 ()->live_p (live_svalues
, model
)
1261 && get_arg1 ()->live_p (live_svalues
, model
));
1264 /* class sub_svalue : public svalue. */
1266 /* sub_svalue'c ctor. */
1268 sub_svalue::sub_svalue (symbol::id_t id
,
1269 tree type
, const svalue
*parent_svalue
,
1270 const region
*subregion
)
1271 : svalue (complexity::from_pair (parent_svalue
->get_complexity (),
1272 subregion
->get_complexity ()),
1275 m_parent_svalue (parent_svalue
), m_subregion (subregion
)
1277 gcc_assert (parent_svalue
->can_have_associated_state_p ());
1280 /* Implementation of svalue::dump_to_pp vfunc for sub_svalue. */
1283 sub_svalue::dump_to_pp (pretty_printer
*pp
, bool simple
) const
1287 pp_string (pp
, "SUB(");
1288 m_parent_svalue
->dump_to_pp (pp
, simple
);
1289 pp_string (pp
, ", ");
1290 m_subregion
->dump_to_pp (pp
, simple
);
1291 pp_character (pp
, ')');
1295 pp_string (pp
, "sub_svalue (");
1296 pp_string (pp
, ", ");
1297 m_parent_svalue
->dump_to_pp (pp
, simple
);
1298 pp_string (pp
, ", ");
1299 m_subregion
->dump_to_pp (pp
, simple
);
1300 pp_character (pp
, ')');
1304 /* Implementation of svalue::accept vfunc for sub_svalue. */
1307 sub_svalue::accept (visitor
*v
) const
1309 m_parent_svalue
->accept (v
);
1310 m_subregion
->accept (v
);
1311 v
->visit_sub_svalue (this);
1314 /* Implementation of svalue::implicitly_live_p vfunc for sub_svalue. */
1317 sub_svalue::implicitly_live_p (const svalue_set
*live_svalues
,
1318 const region_model
*model
) const
1320 return get_parent ()->live_p (live_svalues
, model
);
1323 /* class repeated_svalue : public svalue. */
1325 /* repeated_svalue'c ctor. */
1327 repeated_svalue::repeated_svalue (symbol::id_t id
,
1329 const svalue
*outer_size
,
1330 const svalue
*inner_svalue
)
1331 : svalue (complexity::from_pair (outer_size
, inner_svalue
), id
, type
),
1332 m_outer_size (outer_size
),
1333 m_inner_svalue (inner_svalue
)
1335 gcc_assert (outer_size
->can_have_associated_state_p ());
1336 gcc_assert (inner_svalue
->can_have_associated_state_p ());
1339 /* Implementation of svalue::dump_to_pp vfunc for repeated_svalue. */
1342 repeated_svalue::dump_to_pp (pretty_printer
*pp
, bool simple
) const
1346 pp_string (pp
, "REPEATED(");
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 pp_string (pp
, "repeated_svalue (");
1363 print_quoted_type (pp
, get_type ());
1364 pp_string (pp
, ", ");
1366 pp_string (pp
, "outer_size: ");
1367 m_outer_size
->dump_to_pp (pp
, simple
);
1368 pp_string (pp
, ", inner_val: ");
1369 m_inner_svalue
->dump_to_pp (pp
, simple
);
1370 pp_character (pp
, ')');
1374 /* Implementation of svalue::accept vfunc for repeated_svalue. */
1377 repeated_svalue::accept (visitor
*v
) const
1379 m_inner_svalue
->accept (v
);
1380 v
->visit_repeated_svalue (this);
1383 /* Implementation of svalue::all_zeroes_p for repeated_svalue. */
1386 repeated_svalue::all_zeroes_p () const
1388 return m_inner_svalue
->all_zeroes_p ();
1391 /* Implementation of svalue::maybe_fold_bits_within vfunc
1392 for repeated_svalue. */
1395 repeated_svalue::maybe_fold_bits_within (tree type
,
1396 const bit_range
&bits
,
1397 region_model_manager
*mgr
) const
1399 const svalue
*innermost_sval
= m_inner_svalue
;
1401 BITS_WITHIN (range, REPEATED_SVALUE (ZERO))
1403 REPEATED_SVALUE (ZERO). */
1404 if (all_zeroes_p ())
1406 byte_range
bytes (0,0);
1407 if (bits
.as_byte_range (&bytes
))
1409 const svalue
*byte_size
1410 = mgr
->get_or_create_int_cst (size_type_node
,
1411 bytes
.m_size_in_bytes
.to_uhwi ());
1412 return mgr
->get_or_create_repeated_svalue (type
, byte_size
,
1418 BITS_WITHIN (range, REPEATED_SVALUE (INNERMOST_SVALUE))
1420 BITS_WITHIN (range - offset, INNERMOST_SVALUE)
1421 if range is fully within one instance of INNERMOST_SVALUE. */
1422 if (tree innermost_type
= innermost_sval
->get_type ())
1424 bit_size_t element_bit_size
;
1425 if (int_size_in_bits (innermost_type
, &element_bit_size
)
1426 && element_bit_size
> 0)
1428 HOST_WIDE_INT start_idx
1429 = (bits
.get_start_bit_offset ()
1430 / element_bit_size
).to_shwi ();
1431 HOST_WIDE_INT last_idx
1432 = (bits
.get_last_bit_offset ()
1433 / element_bit_size
).to_shwi ();
1434 if (start_idx
== last_idx
)
1436 bit_offset_t start_of_element
1437 = start_idx
* element_bit_size
;
1438 bit_range range_within_element
1439 (bits
.m_start_bit_offset
- start_of_element
,
1440 bits
.m_size_in_bits
);
1441 return mgr
->get_or_create_bits_within (type
,
1442 range_within_element
,
1451 /* class bits_within_svalue : public svalue. */
1453 /* bits_within_svalue'c ctor. */
1455 bits_within_svalue::bits_within_svalue (symbol::id_t id
,
1457 const bit_range
&bits
,
1458 const svalue
*inner_svalue
)
1459 : svalue (complexity (inner_svalue
), id
, type
),
1461 m_inner_svalue (inner_svalue
)
1463 gcc_assert (inner_svalue
->can_have_associated_state_p ());
1466 /* Implementation of svalue::dump_to_pp vfunc for bits_within_svalue. */
1469 bits_within_svalue::dump_to_pp (pretty_printer
*pp
, bool simple
) const
1473 pp_string (pp
, "BITS_WITHIN(");
1476 print_quoted_type (pp
, get_type ());
1477 pp_string (pp
, ", ");
1479 m_bits
.dump_to_pp (pp
);
1480 pp_string (pp
, ", inner_val: ");
1481 m_inner_svalue
->dump_to_pp (pp
, simple
);
1482 pp_character (pp
, ')');
1486 pp_string (pp
, "bits_within_svalue (");
1489 print_quoted_type (pp
, get_type ());
1490 pp_string (pp
, ", ");
1492 m_bits
.dump_to_pp (pp
);
1493 pp_string (pp
, ", inner_val: ");
1494 m_inner_svalue
->dump_to_pp (pp
, simple
);
1495 pp_character (pp
, ')');
1499 /* Implementation of svalue::maybe_fold_bits_within vfunc
1500 for bits_within_svalue. */
1503 bits_within_svalue::maybe_fold_bits_within (tree type
,
1504 const bit_range
&bits
,
1505 region_model_manager
*mgr
) const
1508 BITS_WITHIN (range1, BITS_WITHIN (range2, VAL))
1510 BITS_WITHIN (range1 in range 2, VAL). */
1511 bit_range
offset_bits (m_bits
.get_start_bit_offset ()
1512 + bits
.m_start_bit_offset
,
1513 bits
.m_size_in_bits
);
1514 return mgr
->get_or_create_bits_within (type
, offset_bits
, m_inner_svalue
);
1517 /* Implementation of svalue::accept vfunc for bits_within_svalue. */
1520 bits_within_svalue::accept (visitor
*v
) const
1522 m_inner_svalue
->accept (v
);
1523 v
->visit_bits_within_svalue (this);
1526 /* Implementation of svalue::implicitly_live_p vfunc for bits_within_svalue. */
1529 bits_within_svalue::implicitly_live_p (const svalue_set
*live_svalues
,
1530 const region_model
*model
) const
1532 return m_inner_svalue
->live_p (live_svalues
, model
);
1535 /* class widening_svalue : public svalue. */
1537 /* Implementation of svalue::dump_to_pp vfunc for widening_svalue. */
1540 widening_svalue::dump_to_pp (pretty_printer
*pp
, bool simple
) const
1544 pp_string (pp
, "WIDENING(");
1545 pp_character (pp
, '{');
1546 m_point
.print (pp
, format (false));
1547 pp_string (pp
, "}, ");
1548 m_base_sval
->dump_to_pp (pp
, simple
);
1549 pp_string (pp
, ", ");
1550 m_iter_sval
->dump_to_pp (pp
, simple
);
1551 pp_character (pp
, ')');
1555 pp_string (pp
, "widening_svalue (");
1556 pp_string (pp
, ", ");
1557 pp_character (pp
, '{');
1558 m_point
.print (pp
, format (false));
1559 pp_string (pp
, "}, ");
1560 m_base_sval
->dump_to_pp (pp
, simple
);
1561 pp_string (pp
, ", ");
1562 m_iter_sval
->dump_to_pp (pp
, simple
);
1563 pp_character (pp
, ')');
1567 /* Implementation of svalue::accept vfunc for widening_svalue. */
1570 widening_svalue::accept (visitor
*v
) const
1572 m_base_sval
->accept (v
);
1573 m_iter_sval
->accept (v
);
1574 v
->visit_widening_svalue (this);
1577 /* Attempt to determine in which direction this value is changing
1578 w.r.t. the initial value. */
1580 enum widening_svalue::direction_t
1581 widening_svalue::get_direction () const
1583 tree base_cst
= m_base_sval
->maybe_get_constant ();
1584 if (base_cst
== NULL_TREE
)
1586 tree iter_cst
= m_iter_sval
->maybe_get_constant ();
1587 if (iter_cst
== NULL_TREE
)
1590 tree iter_gt_base
= fold_binary (GT_EXPR
, boolean_type_node
,
1591 iter_cst
, base_cst
);
1592 if (iter_gt_base
== boolean_true_node
)
1593 return DIR_ASCENDING
;
1595 tree iter_lt_base
= fold_binary (LT_EXPR
, boolean_type_node
,
1596 iter_cst
, base_cst
);
1597 if (iter_lt_base
== boolean_true_node
)
1598 return DIR_DESCENDING
;
1603 /* Compare this value against constant RHS_CST. */
1606 widening_svalue::eval_condition_without_cm (enum tree_code op
,
1609 tree base_cst
= m_base_sval
->maybe_get_constant ();
1610 if (base_cst
== NULL_TREE
)
1611 return tristate::TS_UNKNOWN
;
1612 tree iter_cst
= m_iter_sval
->maybe_get_constant ();
1613 if (iter_cst
== NULL_TREE
)
1614 return tristate::TS_UNKNOWN
;
1616 switch (get_direction ())
1621 /* LHS is in [base_cst, +ve infinity), assuming no overflow. */
1627 /* [BASE, +INF) OP RHS:
1628 This is either true or false at +ve ininity,
1629 It can be true for points X where X OP RHS, so we have either
1630 "false", or "unknown". */
1631 tree base_op_rhs
= fold_binary (op
, boolean_type_node
,
1633 if (base_op_rhs
== boolean_true_node
)
1634 return tristate::TS_UNKNOWN
;
1636 return tristate::TS_FALSE
;
1642 /* [BASE, +INF) OP RHS:
1643 This is true at +ve infinity. It will be true everywhere
1644 in the range if BASE >= RHS. */
1645 tree base_op_rhs
= fold_binary (op
, boolean_type_node
,
1647 if (base_op_rhs
== boolean_true_node
)
1648 return tristate::TS_TRUE
;
1650 return tristate::TS_UNKNOWN
;
1655 /* [BASE, +INF) == RHS:
1656 Could this be true at any point in the range? If so we
1657 have "unknown", otherwise we have "false". */
1658 tree base_le_rhs
= fold_binary (LE_EXPR
, boolean_type_node
,
1660 if (base_le_rhs
== boolean_true_node
)
1661 return tristate::TS_UNKNOWN
;
1663 return tristate::TS_FALSE
;
1668 /* [BASE, +INF) != RHS:
1669 Could we have equality at any point in the range? If so we
1670 have "unknown", otherwise we have "true". */
1671 tree base_le_rhs
= fold_binary (LE_EXPR
, boolean_type_node
,
1673 if (base_le_rhs
== boolean_true_node
)
1674 return tristate::TS_UNKNOWN
;
1676 return tristate::TS_TRUE
;
1680 return tristate::TS_UNKNOWN
;
1683 case DIR_DESCENDING
:
1684 /* LHS is in (-ve infinity, base_cst], assuming no overflow. */
1685 return tristate::TS_UNKNOWN
;
1688 return tristate::TS_UNKNOWN
;
1692 /* class placeholder_svalue : public svalue. */
1694 /* Implementation of svalue::dump_to_pp vfunc for placeholder_svalue. */
1697 placeholder_svalue::dump_to_pp (pretty_printer
*pp
, bool simple
) const
1700 pp_printf (pp
, "PLACEHOLDER(%qs)", m_name
);
1702 pp_printf (pp
, "placeholder_svalue (%qs)", m_name
);
1705 /* Implementation of svalue::accept vfunc for placeholder_svalue. */
1708 placeholder_svalue::accept (visitor
*v
) const
1710 v
->visit_placeholder_svalue (this);
1713 /* class unmergeable_svalue : public svalue. */
1715 /* Implementation of svalue::dump_to_pp vfunc for unmergeable_svalue. */
1718 unmergeable_svalue::dump_to_pp (pretty_printer
*pp
, bool simple
) const
1722 pp_string (pp
, "UNMERGEABLE(");
1723 m_arg
->dump_to_pp (pp
, simple
);
1724 pp_character (pp
, ')');
1728 pp_string (pp
, "unmergeable_svalue (");
1729 m_arg
->dump_to_pp (pp
, simple
);
1730 pp_character (pp
, ')');
1734 /* Implementation of svalue::accept vfunc for unmergeable_svalue. */
1737 unmergeable_svalue::accept (visitor
*v
) const
1740 v
->visit_unmergeable_svalue (this);
1743 /* Implementation of svalue::implicitly_live_p vfunc for unmergeable_svalue. */
1746 unmergeable_svalue::implicitly_live_p (const svalue_set
*live_svalues
,
1747 const region_model
*model
) const
1749 return get_arg ()->live_p (live_svalues
, model
);
1752 /* class compound_svalue : public svalue. */
1754 compound_svalue::compound_svalue (symbol::id_t id
,
1756 const binding_map
&map
)
1757 : svalue (calc_complexity (map
), id
, type
), m_map (map
)
1760 for (iterator_t iter
= begin (); iter
!= end (); ++iter
)
1762 /* All keys within the underlying binding_map are required to be concrete,
1764 const binding_key
*key
= (*iter
).first
;
1765 gcc_assert (key
->concrete_p ());
1767 /* We don't nest compound svalues. */
1768 const svalue
*sval
= (*iter
).second
;
1769 gcc_assert (sval
->get_kind () != SK_COMPOUND
);
1774 /* Implementation of svalue::dump_to_pp vfunc for compound_svalue. */
1777 compound_svalue::dump_to_pp (pretty_printer
*pp
, bool simple
) const
1781 pp_string (pp
, "COMPOUND(");
1784 print_quoted_type (pp
, get_type ());
1785 pp_string (pp
, ", ");
1787 pp_character (pp
, '{');
1788 m_map
.dump_to_pp (pp
, simple
, false);
1789 pp_string (pp
, "})");
1793 pp_string (pp
, "compound_svalue (");
1796 print_quoted_type (pp
, get_type ());
1797 pp_string (pp
, ", ");
1799 pp_character (pp
, '{');
1800 m_map
.dump_to_pp (pp
, simple
, false);
1801 pp_string (pp
, "})");
1805 /* Implementation of svalue::accept vfunc for compound_svalue. */
1808 compound_svalue::accept (visitor
*v
) const
1810 for (binding_map::iterator_t iter
= m_map
.begin ();
1811 iter
!= m_map
.end (); ++iter
)
1813 //(*iter).first.accept (v);
1814 (*iter
).second
->accept (v
);
1816 v
->visit_compound_svalue (this);
1819 /* Calculate what the complexity of a compound_svalue instance for MAP
1820 will be, based on the svalues bound within MAP. */
1823 compound_svalue::calc_complexity (const binding_map
&map
)
1825 unsigned num_child_nodes
= 0;
1826 unsigned max_child_depth
= 0;
1827 for (binding_map::iterator_t iter
= map
.begin ();
1828 iter
!= map
.end (); ++iter
)
1830 const complexity
&sval_c
= (*iter
).second
->get_complexity ();
1831 num_child_nodes
+= sval_c
.m_num_nodes
;
1832 max_child_depth
= MAX (max_child_depth
, sval_c
.m_max_depth
);
1834 return complexity (num_child_nodes
+ 1, max_child_depth
+ 1);
1837 /* Implementation of svalue::maybe_fold_bits_within vfunc
1838 for compound_svalue. */
1841 compound_svalue::maybe_fold_bits_within (tree type
,
1842 const bit_range
&bits
,
1843 region_model_manager
*mgr
) const
1845 binding_map result_map
;
1846 for (auto iter
: m_map
)
1848 const binding_key
*key
= iter
.first
;
1849 if (const concrete_binding
*conc_key
1850 = key
->dyn_cast_concrete_binding ())
1852 /* Ignore concrete bindings outside BITS. */
1853 if (!conc_key
->get_bit_range ().intersects_p (bits
))
1856 const svalue
*sval
= iter
.second
;
1857 /* Get the position of conc_key relative to BITS. */
1858 bit_range
result_location (conc_key
->get_start_bit_offset ()
1859 - bits
.get_start_bit_offset (),
1860 conc_key
->get_size_in_bits ());
1861 /* If conc_key starts after BITS, trim off leading bits
1862 from the svalue and adjust binding location. */
1863 if (result_location
.m_start_bit_offset
< 0)
1865 bit_size_t leading_bits_to_drop
1866 = -result_location
.m_start_bit_offset
;
1867 result_location
= bit_range
1868 (0, result_location
.m_size_in_bits
- leading_bits_to_drop
);
1869 bit_range
bits_within_sval (leading_bits_to_drop
,
1870 result_location
.m_size_in_bits
);
1871 /* Trim off leading bits from iter_sval. */
1872 sval
= mgr
->get_or_create_bits_within (NULL_TREE
,
1876 /* If conc_key finishes after BITS, trim off trailing bits
1877 from the svalue and adjust binding location. */
1878 if (conc_key
->get_next_bit_offset ()
1879 > bits
.get_next_bit_offset ())
1881 bit_size_t trailing_bits_to_drop
1882 = (conc_key
->get_next_bit_offset ()
1883 - bits
.get_next_bit_offset ());
1884 result_location
= bit_range
1885 (result_location
.m_start_bit_offset
,
1886 result_location
.m_size_in_bits
- trailing_bits_to_drop
);
1887 bit_range
bits_within_sval (0,
1888 result_location
.m_size_in_bits
);
1889 /* Trim off leading bits from iter_sval. */
1890 sval
= mgr
->get_or_create_bits_within (NULL_TREE
,
1894 const concrete_binding
*offset_conc_key
1895 = mgr
->get_store_manager ()->get_concrete_binding
1897 result_map
.put (offset_conc_key
, sval
);
1900 /* If we have any symbolic keys we can't get it as bits. */
1903 return mgr
->get_or_create_compound_svalue (type
, result_map
);
1906 /* class conjured_svalue : public svalue. */
1908 /* Implementation of svalue::dump_to_pp vfunc for conjured_svalue. */
1911 conjured_svalue::dump_to_pp (pretty_printer
*pp
, bool simple
) const
1915 pp_string (pp
, "CONJURED(");
1916 pp_gimple_stmt_1 (pp
, m_stmt
, 0, (dump_flags_t
)0);
1917 pp_string (pp
, ", ");
1918 m_id_reg
->dump_to_pp (pp
, simple
);
1919 pp_character (pp
, ')');
1923 pp_string (pp
, "conjured_svalue (");
1926 print_quoted_type (pp
, get_type ());
1927 pp_string (pp
, ", ");
1929 pp_gimple_stmt_1 (pp
, m_stmt
, 0, (dump_flags_t
)0);
1930 pp_string (pp
, ", ");
1931 m_id_reg
->dump_to_pp (pp
, simple
);
1932 pp_character (pp
, ')');
1936 /* Implementation of svalue::accept vfunc for conjured_svalue. */
1939 conjured_svalue::accept (visitor
*v
) const
1941 m_id_reg
->accept (v
);
1942 v
->visit_conjured_svalue (this);
1945 /* Return true iff this conjured_svalue is for the LHS of the
1946 stmt that conjured it. */
1949 conjured_svalue::lhs_value_p () const
1951 if (tree decl
= m_id_reg
->maybe_get_decl ())
1952 return decl
== gimple_get_lhs (m_stmt
);
1956 /* class asm_output_svalue : public svalue. */
1958 /* Implementation of svalue::dump_to_pp vfunc for asm_output_svalue. */
1961 asm_output_svalue::dump_to_pp (pretty_printer
*pp
, bool simple
) const
1965 pp_printf (pp
, "ASM_OUTPUT(%qs, %%%i, {",
1968 for (unsigned i
= 0; i
< m_num_inputs
; i
++)
1971 pp_string (pp
, ", ");
1972 dump_input (pp
, 0, m_input_arr
[i
], simple
);
1974 pp_string (pp
, "})");
1978 pp_printf (pp
, "asm_output_svalue (%qs, %%%i, {",
1981 for (unsigned i
= 0; i
< m_num_inputs
; i
++)
1984 pp_string (pp
, ", ");
1985 dump_input (pp
, 0, m_input_arr
[i
], simple
);
1987 pp_string (pp
, "})");
1991 /* Subroutine of asm_output_svalue::dump_to_pp. */
1994 asm_output_svalue::dump_input (pretty_printer
*pp
,
1999 pp_printf (pp
, "%%%i: ", input_idx_to_asm_idx (input_idx
));
2000 sval
->dump_to_pp (pp
, simple
);
2003 /* Convert INPUT_IDX from an index into the array of inputs
2004 into the index of all operands for the asm stmt. */
2007 asm_output_svalue::input_idx_to_asm_idx (unsigned input_idx
) const
2009 return input_idx
+ m_num_outputs
;
2012 /* Implementation of svalue::accept vfunc for asm_output_svalue. */
2015 asm_output_svalue::accept (visitor
*v
) const
2017 for (unsigned i
= 0; i
< m_num_inputs
; i
++)
2018 m_input_arr
[i
]->accept (v
);
2019 v
->visit_asm_output_svalue (this);
2022 /* class const_fn_result_svalue : public svalue. */
2024 /* Implementation of svalue::dump_to_pp vfunc for const_fn_result_svalue. */
2027 const_fn_result_svalue::dump_to_pp (pretty_printer
*pp
, bool simple
) const
2031 pp_printf (pp
, "CONST_FN_RESULT(%qD, {", m_fndecl
);
2032 for (unsigned i
= 0; i
< m_num_inputs
; i
++)
2035 pp_string (pp
, ", ");
2036 dump_input (pp
, i
, m_input_arr
[i
], simple
);
2038 pp_string (pp
, "})");
2042 pp_printf (pp
, "CONST_FN_RESULT(%qD, {", m_fndecl
);
2043 for (unsigned i
= 0; i
< m_num_inputs
; i
++)
2046 pp_string (pp
, ", ");
2047 dump_input (pp
, i
, m_input_arr
[i
], simple
);
2049 pp_string (pp
, "})");
2053 /* Subroutine of const_fn_result_svalue::dump_to_pp. */
2056 const_fn_result_svalue::dump_input (pretty_printer
*pp
,
2061 pp_printf (pp
, "arg%i: ", input_idx
);
2062 sval
->dump_to_pp (pp
, simple
);
2065 /* Implementation of svalue::accept vfunc for const_fn_result_svalue. */
2068 const_fn_result_svalue::accept (visitor
*v
) const
2070 for (unsigned i
= 0; i
< m_num_inputs
; i
++)
2071 m_input_arr
[i
]->accept (v
);
2072 v
->visit_const_fn_result_svalue (this);
2077 #endif /* #if ENABLE_ANALYZER */