analyzer: Fix up some -Wformat* warnings
[official-gcc.git] / gcc / analyzer / call-summary.cc
bloba569bb94cec560ef05a3441412b4caf34608de91
1 /* Classes for working with summaries of function calls.
2 Copyright (C) 2022 David Malcolm <dmalcolm@redhat.com>.
4 This file is part of GCC.
6 GCC is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3, or (at your option)
9 any later version.
11 GCC is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3. If not see
18 <http://www.gnu.org/licenses/>. */
20 #include "config.h"
21 #define INCLUDE_MEMORY
22 #include "system.h"
23 #include "coretypes.h"
24 #include "tree.h"
25 #include "tree-dfa.h"
26 #include "diagnostic-core.h"
27 #include "diagnostic.h"
28 #include "tree-diagnostic.h"
29 #include "analyzer/analyzer.h"
30 #include "analyzer/region-model.h"
31 #include "analyzer/call-summary.h"
32 #include "analyzer/exploded-graph.h"
34 #if ENABLE_ANALYZER
36 namespace ana {
38 /* class call_summary. */
40 const program_state &
41 call_summary::get_state () const
43 return m_enode->get_state ();
46 tree
47 call_summary::get_fndecl () const
49 return m_enode->get_point ().get_fndecl ();
52 label_text
53 call_summary::get_desc () const
55 pretty_printer pp;
56 pp_format_decoder (&pp) = default_tree_printer;
58 get_user_facing_desc (&pp);
59 if (flag_analyzer_verbose_edges)
60 pp_printf (&pp, " (call summary; EN: %i)", m_enode->m_index);
62 return label_text::take (xstrdup (pp_formatted_text (&pp)));
65 /* Generate a user-facing description of this call summary.c
66 This has various heuristics for distinguishing between different
67 summaries.
68 This will help with debugging, too. */
70 void
71 call_summary::get_user_facing_desc (pretty_printer *pp) const
73 tree fndecl = get_fndecl ();
75 /* If there are multiple summaries, try to use the return value to
76 distinguish between them. */
77 if (m_per_fn_data->m_summaries.length () > 1)
79 if (tree result = DECL_RESULT (fndecl))
81 const region *result_reg
82 = get_state ().m_region_model->get_lvalue (result, NULL);
83 const svalue *result_sval
84 = get_state ().m_region_model->get_store_value (result_reg, NULL);
85 switch (result_sval->get_kind ())
87 default:
88 break;
89 case SK_REGION:
91 const region_svalue *region_sval
92 = as_a <const region_svalue *> (result_sval);
93 const region *pointee_reg = region_sval->get_pointee ();
94 switch (pointee_reg->get_kind ())
96 default:
97 break;
98 case RK_HEAP_ALLOCATED:
99 pp_printf (pp,
100 "when %qE returns pointer"
101 " to heap-allocated buffer",
102 fndecl);
103 return;
106 break;
107 case SK_CONSTANT:
109 const constant_svalue *constant_sval
110 = as_a <const constant_svalue *> (result_sval);
111 tree cst = constant_sval->get_constant ();
112 if (POINTER_TYPE_P (TREE_TYPE (result))
113 && zerop (cst))
114 pp_printf (pp, "when %qE returns NULL", fndecl);
115 else
116 pp_printf (pp, "when %qE returns %qE", fndecl, cst);
117 return;
123 /* Fallback. */
124 pp_printf (pp, "when %qE returns", fndecl);
127 /* Dump a multiline representation of this object to PP. */
129 void
130 call_summary::dump_to_pp (const extrinsic_state &ext_state,
131 pretty_printer *pp,
132 bool simple) const
134 label_text desc = get_desc ();
135 pp_printf (pp, "desc: %qs", desc.get ());
136 pp_newline (pp);
138 get_state ().dump_to_pp (ext_state, simple, true, pp);
141 /* Dump a multiline representation of this object to FILE. */
143 void
144 call_summary::dump (const extrinsic_state &ext_state,
145 FILE *fp,
146 bool simple) const
148 pretty_printer pp;
149 pp_format_decoder (&pp) = default_tree_printer;
150 pp_show_color (&pp) = pp_show_color (global_dc->printer);
151 pp.buffer->stream = fp;
152 dump_to_pp (ext_state, &pp, simple);
153 pp_flush (&pp);
156 /* Dump a multiline representation of this object to stderr. */
158 DEBUG_FUNCTION void
159 call_summary::dump (const extrinsic_state &ext_state, bool simple) const
161 dump (ext_state, stderr, simple);
164 /* class call_summary_replay. */
166 /* call_summary_replay's ctor.
167 Populate the cache with params for the summary based on
168 arguments at the caller. */
170 call_summary_replay::call_summary_replay (const call_details &cd,
171 const function &called_fn,
172 call_summary *summary,
173 const extrinsic_state &ext_state)
174 : m_cd (cd),
175 m_summary (summary),
176 m_ext_state (ext_state)
178 region_model_manager *mgr = cd.get_manager ();
180 // populate params based on args
181 tree fndecl = called_fn.decl;
183 /* Get a frame_region for use with respect to the summary.
184 This will be a top-level frame, since that's what's in
185 the summary. */
186 const frame_region *summary_frame
187 = mgr->get_frame_region (NULL, called_fn);
189 unsigned idx = 0;
190 for (tree iter_parm = DECL_ARGUMENTS (fndecl); iter_parm;
191 iter_parm = DECL_CHAIN (iter_parm), ++idx)
193 /* If there's a mismatching declaration, the call stmt might
194 not have enough args. Handle this case by leaving the
195 rest of the params as uninitialized. */
196 if (idx >= cd.num_args ())
197 break;
198 const svalue *caller_arg_sval = cd.get_arg_svalue (idx);
199 tree parm_lval = iter_parm;
200 if (tree parm_default_ssa = get_ssa_default_def (called_fn, iter_parm))
201 parm_lval = parm_default_ssa;
202 const region *summary_parm_reg
203 = summary_frame->get_region_for_local (mgr, parm_lval, cd.get_ctxt ());
204 const svalue *summary_initial_parm_reg
205 = mgr->get_or_create_initial_value (summary_parm_reg);
206 add_svalue_mapping (summary_initial_parm_reg, caller_arg_sval);
209 /* Handle any variadic args. */
210 unsigned va_arg_idx = 0;
211 for (; idx < cd.num_args (); idx++, va_arg_idx++)
213 const svalue *caller_arg_sval = cd.get_arg_svalue (idx);
214 const region *summary_var_arg_reg
215 = mgr->get_var_arg_region (summary_frame, va_arg_idx);
216 const svalue *summary_initial_var_arg_reg
217 = mgr->get_or_create_initial_value (summary_var_arg_reg);
218 add_svalue_mapping (summary_initial_var_arg_reg, caller_arg_sval);
222 /* Try to convert SUMMARY_SVAL in the summary to a corresponding svalue
223 in the caller, caching the result.
225 Return NULL if the conversion is not possible. */
227 const svalue *
228 call_summary_replay::convert_svalue_from_summary (const svalue *summary_sval)
230 gcc_assert (summary_sval);
232 if (const svalue **slot
233 = m_map_svalue_from_summary_to_caller.get (summary_sval))
234 return *slot;
236 const svalue *caller_sval = convert_svalue_from_summary_1 (summary_sval);
238 /* Add to cache. */
239 add_svalue_mapping (summary_sval, caller_sval);
241 return caller_sval;
244 /* Implementation of call_summary_replay::convert_svalue_from_summary. */
246 const svalue *
247 call_summary_replay::convert_svalue_from_summary_1 (const svalue *summary_sval)
249 gcc_assert (summary_sval);
251 switch (summary_sval->get_kind ())
253 default:
254 gcc_unreachable ();
255 case SK_REGION:
257 const region_svalue *region_summary_sval
258 = as_a <const region_svalue *> (summary_sval);
259 const region *summary_reg = region_summary_sval->get_pointee ();
260 const region *caller_reg = convert_region_from_summary (summary_reg);
261 if (!caller_reg)
262 return NULL;
263 region_model_manager *mgr = get_manager ();
264 const svalue *caller_ptr
265 = mgr->get_ptr_svalue (summary_sval->get_type (),
266 caller_reg);
267 return caller_ptr;
269 break;
271 case SK_CONSTANT:
272 case SK_PLACEHOLDER:
273 case SK_POISONED:
274 case SK_UNKNOWN:
275 return summary_sval;
277 case SK_SETJMP:
278 return NULL; // TODO
280 case SK_INITIAL:
282 const initial_svalue *initial_summary_sval
283 = as_a <const initial_svalue *> (summary_sval);
284 /* Params should already be in the cache, courtesy of the ctor. */
285 gcc_assert (!initial_summary_sval->initial_value_of_param_p ());
287 /* Initial value of region within the summary is the value of the
288 region at the point of the call. */
289 const region *summary_reg = initial_summary_sval->get_region ();
290 const region *caller_reg = convert_region_from_summary (summary_reg);
291 if (!caller_reg)
292 return NULL;
293 const svalue *caller_sval
294 = m_cd.get_model ()->get_store_value (caller_reg, m_cd.get_ctxt ());
295 return caller_sval;
297 break;
298 case SK_UNARYOP:
300 const unaryop_svalue *unaryop_summary_sval
301 = as_a <const unaryop_svalue *> (summary_sval);
302 const svalue *summary_arg = unaryop_summary_sval->get_arg ();
303 const svalue *caller_arg = convert_svalue_from_summary (summary_arg);
304 if (!caller_arg)
305 return NULL;
306 region_model_manager *mgr = get_manager ();
307 return mgr->get_or_create_unaryop (summary_sval->get_type (),
308 unaryop_summary_sval->get_op (),
309 caller_arg);
311 break;
312 case SK_BINOP:
314 const binop_svalue *binop_summary_sval
315 = as_a <const binop_svalue *> (summary_sval);
316 const svalue *summary_arg0 = binop_summary_sval->get_arg0 ();
317 const svalue *caller_arg0 = convert_svalue_from_summary (summary_arg0);
318 if (!caller_arg0)
319 return NULL;
320 const svalue *summary_arg1 = binop_summary_sval->get_arg1 ();
321 const svalue *caller_arg1 = convert_svalue_from_summary (summary_arg1);
322 if (!caller_arg1)
323 return NULL;
324 region_model_manager *mgr = get_manager ();
325 return mgr->get_or_create_binop (summary_sval->get_type (),
326 binop_summary_sval->get_op (),
327 caller_arg0,
328 caller_arg1);
330 break;
331 case SK_SUB:
333 const sub_svalue *sub_summary_sval
334 = as_a <const sub_svalue *> (summary_sval);
335 region_model_manager *mgr = get_manager ();
336 const svalue *summary_parent_sval = sub_summary_sval->get_parent ();
337 if (!summary_parent_sval)
338 return NULL;
339 const region *summary_subregion = sub_summary_sval->get_subregion ();
340 if (!summary_subregion)
341 return NULL;
342 return mgr->get_or_create_sub_svalue (summary_sval->get_type (),
343 summary_parent_sval,
344 summary_subregion);
346 break;
347 case SK_REPEATED:
349 const repeated_svalue *repeated_summary_sval
350 = as_a <const repeated_svalue *> (summary_sval);
351 const svalue *summary_outer_size
352 = repeated_summary_sval->get_outer_size ();
353 const svalue *caller_outer_size
354 = convert_svalue_from_summary (summary_outer_size);
355 if (!caller_outer_size)
356 return NULL;
357 const svalue *summary_inner_sval
358 = repeated_summary_sval->get_inner_svalue ();
359 const svalue *caller_inner_sval
360 = convert_svalue_from_summary (summary_inner_sval);
361 if (!caller_inner_sval)
362 return NULL;
363 region_model_manager *mgr = get_manager ();
364 return mgr->get_or_create_repeated_svalue (summary_sval->get_type (),
365 caller_outer_size,
366 caller_inner_sval);
368 break;
369 case SK_BITS_WITHIN:
371 const bits_within_svalue *bits_within_summary_sval
372 = as_a <const bits_within_svalue *> (summary_sval);
373 const bit_range &bits = bits_within_summary_sval->get_bits ();
374 const svalue *summary_inner_sval
375 = bits_within_summary_sval->get_inner_svalue ();
376 const svalue *caller_inner_sval
377 = convert_svalue_from_summary (summary_inner_sval);
378 if (!caller_inner_sval)
379 return NULL;
380 region_model_manager *mgr = get_manager ();
381 return mgr->get_or_create_bits_within (summary_sval->get_type (),
382 bits,
383 caller_inner_sval);
385 break;
386 case SK_UNMERGEABLE:
388 const unmergeable_svalue *unmergeable_summary_sval
389 = as_a <const unmergeable_svalue *> (summary_sval);
390 const svalue *summary_arg_sval = unmergeable_summary_sval->get_arg ();
391 const svalue *caller_arg_sval
392 = convert_svalue_from_summary (summary_arg_sval);
393 if (!caller_arg_sval)
394 return NULL;
395 region_model_manager *mgr = get_manager ();
396 return mgr->get_or_create_unmergeable (caller_arg_sval);
398 break;
399 case SK_WIDENING:
401 const widening_svalue *widening_summary_sval
402 = as_a <const widening_svalue *> (summary_sval);
403 const function_point &point = widening_summary_sval->get_point ();
404 const svalue *summary_base_sval
405 = widening_summary_sval->get_base_svalue ();
406 const svalue *caller_base_sval
407 = convert_svalue_from_summary (summary_base_sval);
408 if (!(caller_base_sval
409 && caller_base_sval->can_have_associated_state_p ()))
410 return NULL;
411 const svalue *summary_iter_sval
412 = widening_summary_sval->get_iter_svalue ();
413 const svalue *caller_iter_sval
414 = convert_svalue_from_summary (summary_iter_sval);
415 if (!(caller_iter_sval
416 && caller_iter_sval->can_have_associated_state_p ()))
417 return NULL;
418 region_model_manager *mgr = get_manager ();
419 return mgr->get_or_create_widening_svalue
420 (summary_iter_sval->get_type (),
421 point,
422 caller_base_sval,
423 caller_iter_sval);
425 break;
426 case SK_COMPOUND:
428 const compound_svalue *compound_summary_sval
429 = as_a <const compound_svalue *> (summary_sval);
430 region_model_manager *mgr = get_manager ();
431 store_manager *store_mgr = mgr->get_store_manager ();
432 binding_map caller_map;
433 auto_vec <const binding_key *> summary_keys;
434 for (auto kv : *compound_summary_sval)
435 summary_keys.safe_push (kv.first);
436 summary_keys.qsort (binding_key::cmp_ptrs);
437 for (auto key : summary_keys)
439 gcc_assert (key->concrete_p ());
440 /* No remapping is needed for concrete binding keys. */
442 const svalue *bound_summary_sval
443 = compound_summary_sval->get_map ().get (key);
444 const svalue *caller_sval
445 = convert_svalue_from_summary (bound_summary_sval);
446 if (!caller_sval)
447 caller_sval = mgr->get_or_create_unknown_svalue (NULL_TREE);
449 if (const compound_svalue *inner_compound_sval
450 = caller_sval->dyn_cast_compound_svalue ())
452 const concrete_binding *outer_key
453 = as_a <const concrete_binding *> (key);
454 for (auto inner_kv : *inner_compound_sval)
456 // These should already be mapped to the caller.
457 const binding_key *inner_key = inner_kv.first;
458 const svalue *inner_sval = inner_kv.second;
459 gcc_assert (inner_key->concrete_p ());
460 const concrete_binding *concrete_key
461 = as_a <const concrete_binding *> (inner_key);
462 bit_offset_t effective_start
463 = (concrete_key->get_start_bit_offset ()
464 + outer_key->get_start_bit_offset ());
465 const concrete_binding *effective_concrete_key
466 = store_mgr->get_concrete_binding
467 (effective_start,
468 concrete_key->get_size_in_bits ());
469 caller_map.put (effective_concrete_key, inner_sval);
472 else
473 caller_map.put (key, caller_sval);
475 return mgr->get_or_create_compound_svalue (summary_sval->get_type (),
476 caller_map);
478 break;
479 case SK_CONJURED:
481 region_model_manager *mgr = get_manager ();
482 return mgr->get_or_create_unknown_svalue (summary_sval->get_type ());
484 break;
485 case SK_ASM_OUTPUT:
487 const asm_output_svalue *asm_output_summary_sval
488 = as_a <const asm_output_svalue *> (summary_sval);
489 const char *asm_string = asm_output_summary_sval->get_asm_string ();
490 unsigned output_idx = asm_output_summary_sval->get_output_idx ();
491 unsigned num_inputs = asm_output_summary_sval->get_num_inputs ();
492 unsigned num_outputs = asm_output_summary_sval->get_num_outputs ();
493 auto_vec<const svalue *> inputs (num_inputs);
494 for (unsigned idx = 0; idx < num_inputs; idx++)
496 const svalue *summary_input
497 = asm_output_summary_sval->get_input (idx);
498 const svalue *caller_input
499 = convert_svalue_from_summary (summary_input);
500 if (!caller_input)
501 return NULL;
502 inputs.safe_push (caller_input);
504 region_model_manager *mgr = get_manager ();
505 return mgr->get_or_create_asm_output_svalue (summary_sval->get_type (),
506 asm_string,
507 output_idx,
508 num_outputs,
509 inputs);
511 break;
512 case SK_CONST_FN_RESULT:
514 const const_fn_result_svalue *const_fn_result_summary_sval
515 = as_a <const const_fn_result_svalue *> (summary_sval);
516 tree fndecl = const_fn_result_summary_sval->get_fndecl ();
517 unsigned num_inputs = const_fn_result_summary_sval->get_num_inputs ();
518 auto_vec<const svalue *> inputs (num_inputs);
519 for (unsigned idx = 0; idx < num_inputs; idx++)
521 const svalue *summary_input
522 = const_fn_result_summary_sval->get_input (idx);
523 const svalue *caller_input
524 = convert_svalue_from_summary (summary_input);
525 if (!caller_input)
526 return NULL;
527 inputs.safe_push (caller_input);
529 region_model_manager *mgr = get_manager ();
530 return mgr->get_or_create_const_fn_result_svalue
531 (summary_sval->get_type (),
532 fndecl,
533 inputs);
535 break;
539 /* Try to convert SUMMARY_REG in the summary to a corresponding region
540 in the caller, caching the result.
542 Return NULL if the conversion is not possible. */
544 const region *
545 call_summary_replay::convert_region_from_summary (const region *summary_reg)
547 gcc_assert (summary_reg);
549 if (const region **slot
550 = m_map_region_from_summary_to_caller.get (summary_reg))
551 return *slot;
553 const region *caller_reg = convert_region_from_summary_1 (summary_reg);
555 /* Add to cache. */
556 add_region_mapping (summary_reg, caller_reg);
558 return caller_reg;
561 /* Implementation of call_summary_replay::convert_region_from_summary. */
563 const region *
564 call_summary_replay::convert_region_from_summary_1 (const region *summary_reg)
566 gcc_assert (summary_reg);
568 region_model_manager *mgr = get_manager ();
569 switch (summary_reg->get_kind ())
571 default:
572 gcc_unreachable ();
573 /* Top-level regions. */
574 case RK_FRAME:
575 case RK_GLOBALS:
576 case RK_CODE:
577 case RK_STACK:
578 case RK_HEAP:
579 case RK_THREAD_LOCAL:
580 case RK_ROOT:
581 /* These should never be pointed to by a region_svalue. */
582 gcc_unreachable ();
584 case RK_FUNCTION:
585 case RK_LABEL:
586 case RK_STRING:
587 case RK_ERRNO:
588 case RK_UNKNOWN:
589 case RK_PRIVATE:
590 /* We can reuse these regions directly. */
591 return summary_reg;
593 case RK_SYMBOLIC:
595 const symbolic_region *summary_symbolic_reg
596 = as_a <const symbolic_region *> (summary_reg);
597 const svalue *summary_ptr_sval = summary_symbolic_reg->get_pointer ();
598 const svalue *caller_ptr_sval
599 = convert_svalue_from_summary (summary_ptr_sval);
600 if (!caller_ptr_sval)
601 return NULL;
602 const region *caller_reg
603 = get_caller_model ()->deref_rvalue (caller_ptr_sval,
604 NULL_TREE,
605 get_ctxt ());
606 return caller_reg;
608 break;
610 case RK_DECL:
612 const decl_region *summary_decl_reg
613 = as_a <const decl_region *> (summary_reg);
614 tree decl = summary_decl_reg->get_decl ();
615 switch (TREE_CODE (decl))
617 default:
618 gcc_unreachable ();
619 case SSA_NAME:
620 /* We don't care about writes to locals within
621 the summary. */
622 return NULL;
623 case VAR_DECL:
624 /* We don't care about writes to locals within
625 the summary. */
626 if (is_global_var (decl))
627 /* If it's a global, we can reuse the region directly. */
628 return summary_reg;
629 else
630 /* Otherwise, we don't care about locals. */
631 return NULL;
632 case RESULT_DECL:
633 return m_cd.get_lhs_region ();
634 case PARM_DECL:
635 /* Writes (by value) to parms should be visible to the caller. */
636 return NULL;
639 break;
640 case RK_FIELD:
642 const field_region *summary_field_reg
643 = as_a <const field_region *> (summary_reg);
644 const region *summary_parent_reg = summary_reg->get_parent_region ();
645 const region *caller_parent_reg
646 = convert_region_from_summary (summary_parent_reg);
647 if (!caller_parent_reg)
648 return NULL;
649 tree field = summary_field_reg->get_field ();
650 return mgr->get_field_region (caller_parent_reg, field);
652 break;
653 case RK_ELEMENT:
655 const element_region *summary_element_reg
656 = as_a <const element_region *> (summary_reg);
657 const region *summary_parent_reg = summary_reg->get_parent_region ();
658 const region *caller_parent_reg
659 = convert_region_from_summary (summary_parent_reg);
660 if (!caller_parent_reg)
661 return NULL;
662 const svalue *summary_index = summary_element_reg->get_index ();
663 const svalue *caller_index
664 = convert_svalue_from_summary (summary_index);
665 if (!caller_index)
666 return NULL;
667 return mgr->get_element_region (caller_parent_reg,
668 summary_reg->get_type (),
669 caller_index);
671 break;
672 case RK_OFFSET:
674 const offset_region *summary_offset_reg
675 = as_a <const offset_region *> (summary_reg);
676 const region *summary_parent_reg = summary_reg->get_parent_region ();
677 const region *caller_parent_reg
678 = convert_region_from_summary (summary_parent_reg);
679 if (!caller_parent_reg)
680 return NULL;
681 const svalue *summary_byte_offset
682 = summary_offset_reg->get_byte_offset ();
683 const svalue *caller_byte_offset
684 = convert_svalue_from_summary (summary_byte_offset);
685 if (!caller_byte_offset)
686 return NULL;
687 return mgr->get_offset_region (caller_parent_reg,
688 summary_reg->get_type (),
689 caller_byte_offset);
691 break;
692 case RK_SIZED:
694 const sized_region *summary_sized_reg
695 = as_a <const sized_region *> (summary_reg);
696 const region *summary_parent_reg = summary_reg->get_parent_region ();
697 const region *caller_parent_reg
698 = convert_region_from_summary (summary_parent_reg);
699 if (!caller_parent_reg)
700 return NULL;
701 const svalue *summary_byte_size
702 = summary_sized_reg->get_byte_size_sval (mgr);
703 const svalue *caller_byte_size
704 = convert_svalue_from_summary (summary_byte_size);
705 if (!caller_byte_size)
706 return NULL;
707 return mgr->get_sized_region (caller_parent_reg,
708 summary_reg->get_type (),
709 caller_byte_size);
711 break;
712 case RK_CAST:
714 const cast_region *summary_cast_reg
715 = as_a <const cast_region *> (summary_reg);
716 const region *summary_original_reg
717 = summary_cast_reg->get_original_region ();
718 const region *caller_original_reg
719 = convert_region_from_summary (summary_original_reg);
720 if (!caller_original_reg)
721 return NULL;
722 return mgr->get_cast_region (caller_original_reg,
723 summary_reg->get_type ());
725 break;
726 case RK_HEAP_ALLOCATED:
728 /* If we have a heap-allocated region in the summary, then
729 it was allocated within the callee.
730 Create a new heap-allocated region to summarize this. */
731 auto_bitmap heap_regs_in_use;
732 get_caller_model ()->get_referenced_base_regions (heap_regs_in_use);
733 return mgr->get_or_create_region_for_heap_alloc (heap_regs_in_use);
735 break;
736 case RK_ALLOCA:
737 return NULL;
738 case RK_BIT_RANGE:
740 const bit_range_region *summary_bit_range_reg
741 = as_a <const bit_range_region *> (summary_reg);
742 const region *summary_parent_reg = summary_reg->get_parent_region ();
743 const region *caller_parent_reg
744 = convert_region_from_summary (summary_parent_reg);
745 if (!caller_parent_reg)
746 return NULL;
747 const bit_range &bits = summary_bit_range_reg->get_bits ();
748 return mgr->get_bit_range (caller_parent_reg,
749 summary_reg->get_type (),
750 bits);
752 break;
753 case RK_VAR_ARG:
754 return NULL;
758 /* Try to convert SUMMARY_KEY in the summary to a corresponding binding key
759 in the caller.
761 Return NULL if the conversion is not possible. */
763 const binding_key *
764 call_summary_replay::convert_key_from_summary (const binding_key *summary_key)
766 if (summary_key->concrete_p ())
767 return summary_key;
769 const symbolic_binding *symbolic_key = (const symbolic_binding *)summary_key;
770 const region *summary_reg = symbolic_key->get_region ();
771 const region *caller_reg = convert_region_from_summary (summary_reg);
772 if (!caller_reg)
773 return NULL;
774 region_model_manager *mgr = get_manager ();
775 store_manager *store_mgr = mgr->get_store_manager ();
776 return store_mgr->get_symbolic_binding (caller_reg);
779 /* Record that SUMMARY_SVAL maps to CALLER_SVAL for this replay. */
781 void
782 call_summary_replay::add_svalue_mapping (const svalue *summary_sval,
783 const svalue *caller_sval)
785 gcc_assert (summary_sval);
786 // CALLER_SVAL can be NULL
787 m_map_svalue_from_summary_to_caller.put (summary_sval, caller_sval);
790 /* Record that SUMMARY_REG maps to CALLER_REG for this replay. */
792 void
793 call_summary_replay::add_region_mapping (const region *summary_reg,
794 const region *caller_reg)
796 gcc_assert (summary_reg);
797 // CALLER_REG can be NULL
798 m_map_region_from_summary_to_caller.put (summary_reg, caller_reg);
801 /* Dump a multiline representation of this object to PP. */
803 void
804 call_summary_replay::dump_to_pp (pretty_printer *pp, bool simple) const
806 pp_newline (pp);
807 pp_string (pp, "CALL DETAILS:");
808 pp_newline (pp);
809 m_cd.dump_to_pp (pp, simple);
811 pp_newline (pp);
812 pp_string (pp, "CALLEE SUMMARY:");
813 pp_newline (pp);
814 m_summary->dump_to_pp (m_ext_state, pp, simple);
816 /* Current state of caller (could be in mid-update). */
817 pp_newline (pp);
818 pp_string (pp, "CALLER:");
819 pp_newline (pp);
820 m_cd.get_model ()->dump_to_pp (pp, simple, true);
822 pp_newline (pp);
823 pp_string (pp, "REPLAY STATE:");
824 pp_newline (pp);
825 pp_string (pp, "svalue mappings from summary to caller:");
826 pp_newline (pp);
827 auto_vec <const svalue *> summary_svals;
828 for (auto kv : m_map_svalue_from_summary_to_caller)
829 summary_svals.safe_push (kv.first);
830 summary_svals.qsort (svalue::cmp_ptr_ptr);
831 for (auto summary_sval : summary_svals)
833 pp_string (pp, "sval in summary: ");
834 summary_sval->dump_to_pp (pp, simple);
835 pp_newline (pp);
837 const svalue *caller_sval
838 = *((const_cast<svalue_map_t &>
839 (m_map_svalue_from_summary_to_caller)).get (summary_sval));
840 pp_string (pp, " sval in caller: ");
841 caller_sval->dump_to_pp (pp, simple);
842 pp_newline (pp);
845 pp_newline (pp);
846 pp_string (pp, "region mappings from summary to caller:");
847 pp_newline (pp);
848 auto_vec <const region *> summary_regs;
849 for (auto kv : m_map_region_from_summary_to_caller)
850 summary_regs.safe_push (kv.first);
851 summary_regs.qsort (region::cmp_ptr_ptr);
852 for (auto summary_reg : summary_regs)
854 pp_string (pp, "reg in summary: ");
855 if (summary_reg)
856 summary_reg->dump_to_pp (pp, simple);
857 else
858 pp_string (pp, "(null)");
859 pp_newline (pp);
861 const region *caller_reg
862 = *((const_cast<region_map_t &>
863 (m_map_region_from_summary_to_caller)).get (summary_reg));
864 pp_string (pp, " reg in caller: ");
865 if (caller_reg)
866 caller_reg->dump_to_pp (pp, simple);
867 else
868 pp_string (pp, "(null)");
869 pp_newline (pp);
873 /* Dump a multiline representation of this object to FILE. */
875 void
876 call_summary_replay::dump (FILE *fp, bool simple) const
878 pretty_printer pp;
879 pp_format_decoder (&pp) = default_tree_printer;
880 pp_show_color (&pp) = pp_show_color (global_dc->printer);
881 pp.buffer->stream = fp;
882 dump_to_pp (&pp, simple);
883 pp_flush (&pp);
886 /* Dump a multiline representation of this object to stderr. */
888 DEBUG_FUNCTION void
889 call_summary_replay::dump (bool simple) const
891 dump (stderr, simple);
894 } // namespace ana
896 #endif /* #if ENABLE_ANALYZER */