xref: /netbsd-src/external/gpl3/gcc/dist/gcc/analyzer/svalue.cc (revision b1e838363e3c6fc78a55519254d99869742dd33c)
1 /* Symbolic values.
2    Copyright (C) 2019-2022 Free Software Foundation, Inc.
3    Contributed by David Malcolm <dmalcolm@redhat.com>.
4 
5 This file is part of GCC.
6 
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)
10 any later version.
11 
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.
16 
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/>.  */
20 
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "tree.h"
25 #include "diagnostic-core.h"
26 #include "gimple-pretty-print.h"
27 #include "function.h"
28 #include "basic-block.h"
29 #include "gimple.h"
30 #include "gimple-iterator.h"
31 #include "diagnostic-core.h"
32 #include "graphviz.h"
33 #include "options.h"
34 #include "cgraph.h"
35 #include "tree-dfa.h"
36 #include "stringpool.h"
37 #include "convert.h"
38 #include "target.h"
39 #include "fold-const.h"
40 #include "tree-pretty-print.h"
41 #include "tristate.h"
42 #include "bitmap.h"
43 #include "selftest.h"
44 #include "function.h"
45 #include "json.h"
46 #include "analyzer/analyzer.h"
47 #include "analyzer/analyzer-logging.h"
48 #include "options.h"
49 #include "cgraph.h"
50 #include "cfg.h"
51 #include "digraph.h"
52 #include "analyzer/call-string.h"
53 #include "analyzer/program-point.h"
54 #include "analyzer/store.h"
55 #include "analyzer/svalue.h"
56 #include "analyzer/region-model.h"
57 
58 #if ENABLE_ANALYZER
59 
60 namespace ana {
61 
62 static int cmp_csts_and_types (const_tree cst1, const_tree cst2);
63 
64 /* class svalue and its various subclasses.  */
65 
66 /* class svalue.  */
67 
68 /* Dump a representation of this svalue to stderr.  */
69 
70 DEBUG_FUNCTION void
dump(bool simple) const71 svalue::dump (bool simple) const
72 {
73   pretty_printer pp;
74   pp_format_decoder (&pp) = default_tree_printer;
75   pp_show_color (&pp) = pp_show_color (global_dc->printer);
76   pp.buffer->stream = stderr;
77   dump_to_pp (&pp, simple);
78   pp_newline (&pp);
79   pp_flush (&pp);
80 }
81 
82 /* Generate a textual representation of this svalue for debugging purposes.  */
83 
84 label_text
get_desc(bool simple) const85 svalue::get_desc (bool simple) const
86 {
87   pretty_printer pp;
88   pp_format_decoder (&pp) = default_tree_printer;
89   dump_to_pp (&pp, simple);
90   return label_text::take (xstrdup (pp_formatted_text (&pp)));
91 }
92 
93 /* Return a new json::string describing the svalue.  */
94 
95 json::value *
to_json() const96 svalue::to_json () const
97 {
98   label_text desc = get_desc (true);
99   json::value *sval_js = new json::string (desc.m_buffer);
100   desc.maybe_free ();
101   return sval_js;
102 }
103 
104 /* If this svalue is a constant_svalue, return the underlying tree constant.
105    Otherwise return NULL_TREE.  */
106 
107 tree
maybe_get_constant() const108 svalue::maybe_get_constant () const
109 {
110   const svalue *sval = unwrap_any_unmergeable ();
111   if (const constant_svalue *cst_sval = sval->dyn_cast_constant_svalue ())
112     return cst_sval->get_constant ();
113   else
114     return NULL_TREE;
115 }
116 
117 /* If this svalue is a region_svalue, return the region it points to.
118    Otherwise return NULL.  */
119 
120 const region *
maybe_get_region() const121 svalue::maybe_get_region () const
122 {
123   if (const region_svalue *region_sval = dyn_cast_region_svalue ())
124     return region_sval->get_pointee ();
125   else
126     return NULL;
127 }
128 
129 /* If this svalue is a cast (i.e a unaryop NOP_EXPR or VIEW_CONVERT_EXPR),
130    return the underlying svalue.
131    Otherwise return NULL.  */
132 
133 const svalue *
maybe_undo_cast() const134 svalue::maybe_undo_cast () const
135 {
136   if (const unaryop_svalue *unaryop_sval = dyn_cast_unaryop_svalue ())
137     {
138       enum tree_code op = unaryop_sval->get_op ();
139       if (op == NOP_EXPR || op == VIEW_CONVERT_EXPR)
140 	return unaryop_sval->get_arg ();
141     }
142   return NULL;
143 }
144 
145 /* If this svalue is an unmergeable decorator around another svalue, return
146    the underlying svalue.
147    Otherwise return this svalue.  */
148 
149 const svalue *
unwrap_any_unmergeable() const150 svalue::unwrap_any_unmergeable () const
151 {
152   if (const unmergeable_svalue *unmergeable = dyn_cast_unmergeable_svalue ())
153     return unmergeable->get_arg ();
154   return this;
155 }
156 
157 /* Attempt to merge THIS with OTHER, returning the merged svalue.
158    Return NULL if not mergeable.  */
159 
160 const svalue *
can_merge_p(const svalue * other,region_model_manager * mgr,model_merger * merger) const161 svalue::can_merge_p (const svalue *other,
162 		     region_model_manager *mgr,
163 		     model_merger *merger) const
164 {
165   if (!(get_type () && other->get_type ()))
166     return NULL;
167 
168   if (!types_compatible_p (get_type (), other->get_type ()))
169     return NULL;
170 
171   /* Reject attempts to merge unmergeable svalues.  */
172   if ((get_kind () == SK_UNMERGEABLE)
173       || (other->get_kind () == SK_UNMERGEABLE))
174     return NULL;
175 
176   /* Reject attempts to merge poisoned svalues with other svalues
177      (either non-poisoned, or other kinds of poison), so that e.g.
178      we identify paths in which a variable is conditionally uninitialized.  */
179   if (get_kind () == SK_POISONED
180       || other->get_kind () == SK_POISONED)
181     return NULL;
182 
183   /* Reject attempts to merge NULL pointers with not-NULL-pointers.  */
184   if (POINTER_TYPE_P (get_type ()))
185     {
186       bool null0 = false;
187       bool null1 = false;
188       if (tree cst0 = maybe_get_constant ())
189 	if (zerop (cst0))
190 	  null0 = true;
191       if (tree cst1 = other->maybe_get_constant ())
192 	if (zerop (cst1))
193 	  null1 = true;
194       if (null0 != null1)
195 	return NULL;
196     }
197 
198   /* Reject merging svalues that have non-purgable sm-state,
199      to avoid falsely reporting memory leaks by merging them
200      with something else.  */
201   if (!merger->mergeable_svalue_p (this))
202     return NULL;
203   if (!merger->mergeable_svalue_p (other))
204     return NULL;
205 
206   /* Widening.  */
207   /* Merge: (new_cst, existing_cst) -> widen (existing, new).  */
208   if (maybe_get_constant () && other->maybe_get_constant ())
209     {
210       return mgr->get_or_create_widening_svalue (other->get_type (),
211 						 merger->m_point,
212 						 other, this);
213     }
214 
215   /* Merger of:
216 	 this: BINOP (X, OP, CST)
217 	other: X, where X is non-widening
218 	   to: WIDENING (other, this).  */
219   if (const binop_svalue *binop_sval = dyn_cast_binop_svalue ())
220     if (binop_sval->get_arg0 () == other
221 	&& binop_sval->get_arg1 ()->get_kind () == SK_CONSTANT
222 	&& other->get_kind () != SK_WIDENING)
223       return mgr->get_or_create_widening_svalue (other->get_type (),
224 						 merger->m_point,
225 						 other, this);
226 
227   /* Merge: (Widen(existing_val, V), existing_val) -> Widen (existing_val, V)
228      and thus get a fixed point.  */
229   if (const widening_svalue *widen_sval = dyn_cast_widening_svalue ())
230     {
231       if (other == widen_sval->get_base_svalue ())
232 	return this;
233       if (other == widen_sval->get_iter_svalue ())
234 	return this;
235     }
236 
237   if (const binop_svalue *binop_sval = dyn_cast_binop_svalue ())
238     if (const widening_svalue *widen_arg0
239 	= binop_sval->get_arg0 ()->dyn_cast_widening_svalue ())
240       {
241 	if (other == binop_sval->get_arg1 ())
242 	  {
243 	    /* Merger of: (Widen(..., OTHER) BINOP X)
244 	       and      : OTHER
245 	       to       : (Widen(..., OTHER) BINOP X)
246 	       e.g. merge of Widen(0, 1) + 1 with 1 to the Widen(0, 1) + 1.  */
247 	    return this;
248 	  }
249 
250 	/* Merger of : (Widen() BINOP X)
251 	   and       : Widen()
252 	   to        : Widen()
253 	   e.g. merge of Widen(0, 1) + 1 and Widen(0, 1) to Widen(0, 1).
254 	   However, we want to update constraints for this case, since we're
255 	   considering another iteration.
256 	   Presumably we also want to ensure that it converges; we don't want
257 	   a descending chain of constraints.  */
258 	if (other == widen_arg0)
259 	  {
260 	    return widen_arg0;
261 	  }
262 
263 	/* Merger of:
264 	    this: BINOP(WIDENING(BASE, BINOP(BASE, X)), X)
265 	   other: BINOP(BASE, X)
266 	      to: WIDENING(BASE, BINOP(BASE, X)).  */
267 	if (widen_arg0->get_iter_svalue () == other)
268 	  if (const binop_svalue *other_binop_sval
269 		= other->dyn_cast_binop_svalue ())
270 	    if (other_binop_sval->get_arg0 () == widen_arg0->get_base_svalue ()
271 		&& other_binop_sval->get_arg1 () == binop_sval->get_arg1 ())
272 	      return widen_arg0;
273       }
274 
275   return mgr->get_or_create_unknown_svalue (get_type ());
276 }
277 
278 /* Determine if this svalue is either within LIVE_SVALUES, or is implicitly
279    live with respect to LIVE_SVALUES and MODEL.
280    LIVE_SVALUES can be NULL, in which case determine if this svalue is
281    intrinsically live.  */
282 
283 bool
live_p(const svalue_set * live_svalues,const region_model * model) const284 svalue::live_p (const svalue_set *live_svalues,
285 		const region_model *model) const
286 {
287   /* Determine if SVAL is explicitly live.  */
288   if (live_svalues)
289     if (const_cast<svalue_set *> (live_svalues)->contains (this))
290       return true;
291 
292   /* Otherwise, determine if SVAL is implicitly live due to being made of
293      other live svalues.  */
294   return implicitly_live_p (live_svalues, model);
295 }
296 
297 /* Base implementation of svalue::implicitly_live_p.  */
298 
299 bool
implicitly_live_p(const svalue_set *,const region_model *) const300 svalue::implicitly_live_p (const svalue_set *, const region_model *) const
301 {
302   return false;
303 }
304 
305 /* Comparator for imposing a deterministic order on constants that are
306    of the same type.  */
307 
308 static int
cmp_csts_same_type(const_tree cst1,const_tree cst2)309 cmp_csts_same_type (const_tree cst1, const_tree cst2)
310 {
311   gcc_assert (TREE_TYPE (cst1) == TREE_TYPE (cst2));
312   gcc_assert (TREE_CODE (cst1) == TREE_CODE (cst2));
313   switch (TREE_CODE (cst1))
314     {
315     default:
316       gcc_unreachable ();
317     case INTEGER_CST:
318       return tree_int_cst_compare (cst1, cst2);
319     case STRING_CST:
320       return strcmp (TREE_STRING_POINTER (cst1),
321 		     TREE_STRING_POINTER (cst2));
322     case REAL_CST:
323       /* Impose an arbitrary but deterministic order.  */
324       return memcmp (TREE_REAL_CST_PTR (cst1),
325 		     TREE_REAL_CST_PTR (cst2),
326 		     sizeof (real_value));
327     case COMPLEX_CST:
328       if (int cmp_real = cmp_csts_and_types (TREE_REALPART (cst1),
329 					     TREE_REALPART (cst2)))
330 	return cmp_real;
331       return cmp_csts_and_types (TREE_IMAGPART (cst1), TREE_IMAGPART (cst2));
332     case VECTOR_CST:
333       if (int cmp_log2_npatterns
334 	    = ((int)VECTOR_CST_LOG2_NPATTERNS (cst1)
335 	       - (int)VECTOR_CST_LOG2_NPATTERNS (cst2)))
336 	return cmp_log2_npatterns;
337       if (int cmp_nelts_per_pattern
338 	    = ((int)VECTOR_CST_NELTS_PER_PATTERN (cst1)
339 	       - (int)VECTOR_CST_NELTS_PER_PATTERN (cst2)))
340 	return cmp_nelts_per_pattern;
341       unsigned encoded_nelts = vector_cst_encoded_nelts (cst1);
342       for (unsigned i = 0; i < encoded_nelts; i++)
343 	{
344 	  const_tree elt1 = VECTOR_CST_ENCODED_ELT (cst1, i);
345 	  const_tree elt2 = VECTOR_CST_ENCODED_ELT (cst2, i);
346 	  if (int el_cmp = cmp_csts_and_types (elt1, elt2))
347 	    return el_cmp;
348 	}
349       return 0;
350     }
351 }
352 
353 /* Comparator for imposing a deterministic order on constants that might
354    not be of the same type.  */
355 
356 static int
cmp_csts_and_types(const_tree cst1,const_tree cst2)357 cmp_csts_and_types (const_tree cst1, const_tree cst2)
358 {
359   int t1 = TYPE_UID (TREE_TYPE (cst1));
360   int t2 = TYPE_UID (TREE_TYPE (cst2));
361   if (int cmp_type = t1 - t2)
362     return cmp_type;
363   return cmp_csts_same_type (cst1, cst2);
364 }
365 
366 /* Comparator for imposing a deterministic order on svalues.  */
367 
368 int
cmp_ptr(const svalue * sval1,const svalue * sval2)369 svalue::cmp_ptr (const svalue *sval1, const svalue *sval2)
370 {
371   if (sval1 == sval2)
372     return 0;
373   if (int cmp_kind = sval1->get_kind () - sval2->get_kind ())
374     return cmp_kind;
375   int t1 = sval1->get_type () ? TYPE_UID (sval1->get_type ()) : -1;
376   int t2 = sval2->get_type () ? TYPE_UID (sval2->get_type ()) : -1;
377   if (int cmp_type = t1 - t2)
378     return cmp_type;
379   switch (sval1->get_kind ())
380     {
381     default:
382       gcc_unreachable ();
383     case SK_REGION:
384       {
385 	const region_svalue *region_sval1 = (const region_svalue *)sval1;
386 	const region_svalue *region_sval2 = (const region_svalue *)sval2;
387 	return region::cmp_ids (region_sval1->get_pointee (),
388 				region_sval2->get_pointee ());
389       }
390       break;
391     case SK_CONSTANT:
392       {
393 	const constant_svalue *constant_sval1 = (const constant_svalue *)sval1;
394 	const constant_svalue *constant_sval2 = (const constant_svalue *)sval2;
395 	const_tree cst1 = constant_sval1->get_constant ();
396 	const_tree cst2 = constant_sval2->get_constant ();
397 	return cmp_csts_same_type (cst1, cst2);
398       }
399       break;
400     case SK_UNKNOWN:
401       {
402 	gcc_assert (sval1 == sval2);
403 	return 0;
404       }
405       break;
406     case SK_POISONED:
407       {
408 	const poisoned_svalue *poisoned_sval1 = (const poisoned_svalue *)sval1;
409 	const poisoned_svalue *poisoned_sval2 = (const poisoned_svalue *)sval2;
410 	return (poisoned_sval1->get_poison_kind ()
411 		- poisoned_sval2->get_poison_kind ());
412       }
413       break;
414     case SK_SETJMP:
415       {
416 	const setjmp_svalue *setjmp_sval1 = (const setjmp_svalue *)sval1;
417 	const setjmp_svalue *setjmp_sval2 = (const setjmp_svalue *)sval2;
418 	const setjmp_record &rec1 = setjmp_sval1->get_setjmp_record ();
419 	const setjmp_record &rec2 = setjmp_sval2->get_setjmp_record ();
420 	return setjmp_record::cmp (rec1, rec2);
421       }
422       break;
423     case SK_INITIAL:
424       {
425 	const initial_svalue *initial_sval1 = (const initial_svalue *)sval1;
426 	const initial_svalue *initial_sval2 = (const initial_svalue *)sval2;
427 	return region::cmp_ids (initial_sval1->get_region (),
428 				initial_sval2->get_region ());
429       }
430       break;
431     case SK_UNARYOP:
432       {
433 	const unaryop_svalue *unaryop_sval1 = (const unaryop_svalue *)sval1;
434 	const unaryop_svalue *unaryop_sval2 = (const unaryop_svalue *)sval2;
435 	if (int op_cmp = unaryop_sval1->get_op () - unaryop_sval2->get_op ())
436 	  return op_cmp;
437 	return svalue::cmp_ptr (unaryop_sval1->get_arg (),
438 				unaryop_sval2->get_arg ());
439       }
440       break;
441     case SK_BINOP:
442       {
443 	const binop_svalue *binop_sval1 = (const binop_svalue *)sval1;
444 	const binop_svalue *binop_sval2 = (const binop_svalue *)sval2;
445 	if (int op_cmp = binop_sval1->get_op () - binop_sval2->get_op ())
446 	  return op_cmp;
447 	if (int arg0_cmp = svalue::cmp_ptr (binop_sval1->get_arg0 (),
448 					    binop_sval2->get_arg0 ()))
449 	  return arg0_cmp;
450 	return svalue::cmp_ptr (binop_sval1->get_arg1 (),
451 				binop_sval2->get_arg1 ());
452       }
453       break;
454     case SK_SUB:
455       {
456 	const sub_svalue *sub_sval1 = (const sub_svalue *)sval1;
457 	const sub_svalue *sub_sval2 = (const sub_svalue *)sval2;
458 	if (int parent_cmp = svalue::cmp_ptr (sub_sval1->get_parent (),
459 					      sub_sval2->get_parent ()))
460 	  return parent_cmp;
461 	return region::cmp_ids (sub_sval1->get_subregion (),
462 				sub_sval2->get_subregion ());
463       }
464       break;
465     case SK_REPEATED:
466       {
467 	const repeated_svalue *repeated_sval1 = (const repeated_svalue *)sval1;
468 	const repeated_svalue *repeated_sval2 = (const repeated_svalue *)sval2;
469 	return svalue::cmp_ptr (repeated_sval1->get_inner_svalue (),
470 				repeated_sval2->get_inner_svalue ());
471       }
472       break;
473     case SK_BITS_WITHIN:
474       {
475 	const bits_within_svalue *bits_within_sval1
476 	  = (const bits_within_svalue *)sval1;
477 	const bits_within_svalue *bits_within_sval2
478 	  = (const bits_within_svalue *)sval2;
479 	if (int cmp = bit_range::cmp (bits_within_sval1->get_bits (),
480 				       bits_within_sval2->get_bits ()))
481 	  return cmp;
482 	return svalue::cmp_ptr (bits_within_sval1->get_inner_svalue (),
483 				bits_within_sval2->get_inner_svalue ());
484       }
485       break;
486     case SK_UNMERGEABLE:
487       {
488 	const unmergeable_svalue *unmergeable_sval1
489 	  = (const unmergeable_svalue *)sval1;
490 	const unmergeable_svalue *unmergeable_sval2
491 	  = (const unmergeable_svalue *)sval2;
492 	return svalue::cmp_ptr (unmergeable_sval1->get_arg (),
493 				unmergeable_sval2->get_arg ());
494       }
495       break;
496     case SK_PLACEHOLDER:
497       {
498 	const placeholder_svalue *placeholder_sval1
499 	  = (const placeholder_svalue *)sval1;
500 	const placeholder_svalue *placeholder_sval2
501 	  = (const placeholder_svalue *)sval2;
502 	return strcmp (placeholder_sval1->get_name (),
503 		       placeholder_sval2->get_name ());
504       }
505       break;
506     case SK_WIDENING:
507       {
508 	const widening_svalue *widening_sval1 = (const widening_svalue *)sval1;
509 	const widening_svalue *widening_sval2 = (const widening_svalue *)sval2;
510 	if (int point_cmp = function_point::cmp (widening_sval1->get_point (),
511 						 widening_sval2->get_point ()))
512 	  return point_cmp;
513 	if (int base_cmp = svalue::cmp_ptr (widening_sval1->get_base_svalue (),
514 					    widening_sval2->get_base_svalue ()))
515 	  return base_cmp;
516 	return svalue::cmp_ptr (widening_sval1->get_iter_svalue (),
517 				widening_sval2->get_iter_svalue ());
518       }
519       break;
520     case SK_COMPOUND:
521       {
522 	const compound_svalue *compound_sval1 = (const compound_svalue *)sval1;
523 	const compound_svalue *compound_sval2 = (const compound_svalue *)sval2;
524 	return binding_map::cmp (compound_sval1->get_map (),
525 				 compound_sval2->get_map ());
526       }
527       break;
528     case SK_CONJURED:
529       {
530 	const conjured_svalue *conjured_sval1 = (const conjured_svalue *)sval1;
531 	const conjured_svalue *conjured_sval2 = (const conjured_svalue *)sval2;
532 	if (int stmt_cmp = (conjured_sval1->get_stmt ()->uid
533 			    - conjured_sval2->get_stmt ()->uid))
534 	  return stmt_cmp;
535 	return region::cmp_ids (conjured_sval1->get_id_region (),
536 				conjured_sval2->get_id_region ());
537       }
538       break;
539     case SK_ASM_OUTPUT:
540       {
541 	const asm_output_svalue *asm_output_sval1
542 	  = (const asm_output_svalue *)sval1;
543 	const asm_output_svalue *asm_output_sval2
544 	  = (const asm_output_svalue *)sval2;
545 	if (int asm_string_cmp = strcmp (asm_output_sval1->get_asm_string (),
546 					 asm_output_sval2->get_asm_string ()))
547 	  return asm_string_cmp;
548 	if (int output_idx_cmp = ((int)asm_output_sval1->get_output_idx ()
549 				  - (int)asm_output_sval2->get_output_idx ()))
550 	  return output_idx_cmp;
551 	if (int cmp = ((int)asm_output_sval1->get_num_inputs ()
552 		       - (int)asm_output_sval2->get_num_inputs ()))
553 	  return cmp;
554 	for (unsigned i = 0; i < asm_output_sval1->get_num_inputs (); i++)
555 	  if (int input_cmp
556 	      = svalue::cmp_ptr (asm_output_sval1->get_input (i),
557 				 asm_output_sval2->get_input (i)))
558 	    return input_cmp;
559 	return 0;
560       }
561       break;
562     case SK_CONST_FN_RESULT:
563       {
564 	const const_fn_result_svalue *const_fn_result_sval1
565 	  = (const const_fn_result_svalue *)sval1;
566 	const const_fn_result_svalue *const_fn_result_sval2
567 	  = (const const_fn_result_svalue *)sval2;
568 	int d1 = DECL_UID (const_fn_result_sval1->get_fndecl ());
569 	int d2 = DECL_UID (const_fn_result_sval2->get_fndecl ());
570 	if (int cmp_fndecl = d1 - d2)
571 	  return cmp_fndecl;
572 	if (int cmp = ((int)const_fn_result_sval1->get_num_inputs ()
573 		       - (int)const_fn_result_sval2->get_num_inputs ()))
574 	  return cmp;
575 	for (unsigned i = 0; i < const_fn_result_sval1->get_num_inputs (); i++)
576 	  if (int input_cmp
577 	      = svalue::cmp_ptr (const_fn_result_sval1->get_input (i),
578 				 const_fn_result_sval2->get_input (i)))
579 	    return input_cmp;
580 	return 0;
581       }
582     }
583 }
584 
585 /* Comparator for use by vec<const svalue *>::qsort.  */
586 
587 int
cmp_ptr_ptr(const void * p1,const void * p2)588 svalue::cmp_ptr_ptr (const void *p1, const void *p2)
589 {
590   const svalue *sval1 = *(const svalue * const *)p1;
591   const svalue *sval2 = *(const svalue * const *)p2;
592   return cmp_ptr (sval1, sval2);
593 }
594 
595 /* Subclass of visitor for use in implementing svalue::involves_p.  */
596 
597 class involvement_visitor : public visitor
598 {
599 public:
involvement_visitor(const svalue * needle)600   involvement_visitor (const svalue *needle)
601   : m_needle (needle), m_found (false) {}
602 
visit_initial_svalue(const initial_svalue * candidate)603   void visit_initial_svalue (const initial_svalue *candidate)
604   {
605     if (candidate == m_needle)
606       m_found = true;
607   }
608 
visit_conjured_svalue(const conjured_svalue * candidate)609   void visit_conjured_svalue (const conjured_svalue *candidate)
610   {
611     if (candidate == m_needle)
612       m_found = true;
613   }
614 
found_p() const615   bool found_p () const { return m_found; }
616 
617 private:
618   const svalue *m_needle;
619   bool m_found;
620 };
621 
622 /* Return true iff this svalue is defined in terms of OTHER.  */
623 
624 bool
involves_p(const svalue * other) const625 svalue::involves_p (const svalue *other) const
626 {
627   /* Currently only implemented for these kinds.  */
628   gcc_assert (other->get_kind () == SK_INITIAL
629 	      || other->get_kind () == SK_CONJURED);
630 
631   involvement_visitor v (other);
632   accept (&v);
633   return v.found_p ();
634 }
635 
636 /* Extract SUBRANGE from this value, of type TYPE.  */
637 
638 const svalue *
extract_bit_range(tree type,const bit_range & subrange,region_model_manager * mgr) const639 svalue::extract_bit_range (tree type,
640 			   const bit_range &subrange,
641 			   region_model_manager *mgr) const
642 {
643   return mgr->get_or_create_bits_within (type, subrange, this);
644 }
645 
646 /* Base implementation of svalue::maybe_fold_bits_within vfunc.  */
647 
648 const svalue *
maybe_fold_bits_within(tree,const bit_range &,region_model_manager *) const649 svalue::maybe_fold_bits_within (tree,
650 				const bit_range &,
651 				region_model_manager *) const
652 {
653   /* By default, don't fold.  */
654   return NULL;
655 }
656 
657 /* Base implementation of svalue::all_zeroes_p.
658    Return true if this value is known to be all zeroes.  */
659 
660 bool
all_zeroes_p() const661 svalue::all_zeroes_p () const
662 {
663   return false;
664 }
665 
666 /* If this svalue is a pointer, attempt to determine the base region it points
667    to.  Return NULL on any problems.  */
668 
669 const region *
maybe_get_deref_base_region() const670 svalue::maybe_get_deref_base_region () const
671 {
672   const svalue *iter = this;
673   while (1)
674     {
675       switch (iter->get_kind ())
676 	{
677 	default:
678 	  return NULL;
679 
680 	case SK_REGION:
681 	  {
682 	    const region_svalue *region_sval
683 	      = as_a <const region_svalue *> (iter);
684 	    return region_sval->get_pointee ()->get_base_region ();
685 	  }
686 
687 	case SK_BINOP:
688 	  {
689 	    const binop_svalue *binop_sval
690 	      = as_a <const binop_svalue *> (iter);
691 	    switch (binop_sval->get_op ())
692 	      {
693 	      case POINTER_PLUS_EXPR:
694 		/* If we have a symbolic value expressing pointer arithmetic,
695 		   use the LHS.  */
696 		iter = binop_sval->get_arg0 ();
697 		continue;
698 
699 	      default:
700 		return NULL;
701 	      }
702 	    return NULL;
703 	  }
704 	}
705     }
706 }
707 
708 /* class region_svalue : public svalue.  */
709 
710 /* Implementation of svalue::dump_to_pp vfunc for region_svalue.  */
711 
712 void
dump_to_pp(pretty_printer * pp,bool simple) const713 region_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
714 {
715   if (simple)
716     {
717       pp_string (pp, "&");
718       m_reg->dump_to_pp (pp, simple);
719     }
720   else
721     {
722       pp_string (pp, "region_svalue(");
723       print_quoted_type (pp, get_type ());
724       pp_string (pp, ", ");
725       m_reg->dump_to_pp (pp, simple);
726       pp_string (pp, ")");
727     }
728 }
729 
730 /* Implementation of svalue::accept vfunc for region_svalue.  */
731 
732 void
accept(visitor * v) const733 region_svalue::accept (visitor *v) const
734 {
735   v->visit_region_svalue (this);
736   m_reg->accept (v);
737 }
738 
739 /* Implementation of svalue::implicitly_live_p vfunc for region_svalue.  */
740 
741 bool
implicitly_live_p(const svalue_set *,const region_model * model) const742 region_svalue::implicitly_live_p (const svalue_set *,
743 				  const region_model *model) const
744 {
745   /* Pointers into clusters that have escaped should be treated as live.  */
746   const region *base_reg = get_pointee ()->get_base_region ();
747   const store *store = model->get_store ();
748   if (const binding_cluster *c = store->get_cluster (base_reg))
749     if (c->escaped_p ())
750 	return true;
751 
752   return false;
753 }
754 
755 /* Evaluate the condition LHS OP RHS.
756    Subroutine of region_model::eval_condition for when we have a pair of
757    pointers.  */
758 
759 tristate
eval_condition(const region_svalue * lhs,enum tree_code op,const region_svalue * rhs)760 region_svalue::eval_condition (const region_svalue *lhs,
761 			       enum tree_code op,
762 			       const region_svalue *rhs)
763 {
764   /* See if they point to the same region.  */
765   const region *lhs_reg = lhs->get_pointee ();
766   const region *rhs_reg = rhs->get_pointee ();
767   bool ptr_equality = lhs_reg == rhs_reg;
768   switch (op)
769     {
770     default:
771       gcc_unreachable ();
772 
773     case EQ_EXPR:
774       if (ptr_equality)
775 	return tristate::TS_TRUE;
776       else
777 	return tristate::TS_FALSE;
778       break;
779 
780     case NE_EXPR:
781       if (ptr_equality)
782 	return tristate::TS_FALSE;
783       else
784 	return tristate::TS_TRUE;
785       break;
786 
787     case GE_EXPR:
788     case LE_EXPR:
789       if (ptr_equality)
790 	return tristate::TS_TRUE;
791       break;
792 
793     case GT_EXPR:
794     case LT_EXPR:
795       if (ptr_equality)
796 	return tristate::TS_FALSE;
797       break;
798     }
799 
800   return tristate::TS_UNKNOWN;
801 }
802 
803 /* class constant_svalue : public svalue.  */
804 
805 /* Implementation of svalue::dump_to_pp vfunc for constant_svalue.  */
806 
807 void
dump_to_pp(pretty_printer * pp,bool simple) const808 constant_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
809 {
810   if (simple)
811     {
812       pp_string (pp, "(");
813       dump_tree (pp, get_type ());
814       pp_string (pp, ")");
815       dump_tree (pp, m_cst_expr);
816     }
817   else
818     {
819       pp_string (pp, "constant_svalue(");
820       print_quoted_type (pp, get_type ());
821       pp_string (pp, ", ");
822       dump_tree (pp, m_cst_expr);
823       pp_string (pp, ")");
824     }
825 }
826 
827 /* Implementation of svalue::accept vfunc for constant_svalue.  */
828 
829 void
accept(visitor * v) const830 constant_svalue::accept (visitor *v) const
831 {
832   v->visit_constant_svalue (this);
833 }
834 
835 /* Implementation of svalue::implicitly_live_p vfunc for constant_svalue.
836    Constants are implicitly live.  */
837 
838 bool
implicitly_live_p(const svalue_set *,const region_model *) const839 constant_svalue::implicitly_live_p (const svalue_set *,
840 				    const region_model *) const
841 {
842   return true;
843 }
844 
845 /* Evaluate the condition LHS OP RHS.
846    Subroutine of region_model::eval_condition for when we have a pair of
847    constants.  */
848 
849 tristate
eval_condition(const constant_svalue * lhs,enum tree_code op,const constant_svalue * rhs)850 constant_svalue::eval_condition (const constant_svalue *lhs,
851 				  enum tree_code op,
852 				  const constant_svalue *rhs)
853 {
854   tree lhs_const = lhs->get_constant ();
855   tree rhs_const = rhs->get_constant ();
856 
857   gcc_assert (CONSTANT_CLASS_P (lhs_const));
858   gcc_assert (CONSTANT_CLASS_P (rhs_const));
859 
860   /* Check for comparable types.  */
861   if (types_compatible_p (TREE_TYPE (lhs_const), TREE_TYPE (rhs_const)))
862     {
863       tree comparison
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);
869     }
870   return tristate::TS_UNKNOWN;
871 }
872 
873 /* Implementation of svalue::maybe_fold_bits_within vfunc
874    for constant_svalue.  */
875 
876 const svalue *
maybe_fold_bits_within(tree type,const bit_range &,region_model_manager * mgr) const877 constant_svalue::maybe_fold_bits_within (tree type,
878 					 const bit_range &,
879 					 region_model_manager *mgr) const
880 {
881   /* Bits within an all-zero value are also all zero.  */
882   if (zerop (m_cst_expr))
883     {
884       if (type)
885 	return mgr->get_or_create_cast (type, this);
886       else
887 	return this;
888     }
889   /* Otherwise, don't fold.  */
890   return NULL;
891 }
892 
893 /* Implementation of svalue::all_zeroes_p for constant_svalue.  */
894 
895 bool
all_zeroes_p() const896 constant_svalue::all_zeroes_p () const
897 {
898   return zerop (m_cst_expr);
899 }
900 
901 /* class unknown_svalue : public svalue.  */
902 
903 /* Implementation of svalue::dump_to_pp vfunc for unknown_svalue.  */
904 
905 void
dump_to_pp(pretty_printer * pp,bool simple) const906 unknown_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
907 {
908   if (simple)
909     {
910       pp_string (pp, "UNKNOWN(");
911       if (get_type ())
912 	dump_tree (pp, get_type ());
913       pp_character (pp, ')');
914     }
915   else
916     {
917       pp_string (pp, "unknown_svalue(");
918       if (get_type ())
919 	dump_tree (pp, get_type ());
920       pp_character (pp, ')');
921     }
922 }
923 
924 /* Implementation of svalue::accept vfunc for unknown_svalue.  */
925 
926 void
accept(visitor * v) const927 unknown_svalue::accept (visitor *v) const
928 {
929   v->visit_unknown_svalue (this);
930 }
931 
932 /* Implementation of svalue::maybe_fold_bits_within vfunc
933    for unknown_svalue.  */
934 
935 const svalue *
maybe_fold_bits_within(tree type,const bit_range &,region_model_manager * mgr) const936 unknown_svalue::maybe_fold_bits_within (tree type,
937 					const bit_range &,
938 					region_model_manager *mgr) const
939 {
940   /* Bits within an unknown_svalue are themselves unknown.  */
941   return mgr->get_or_create_unknown_svalue (type);
942 }
943 
944 /* Get a string for KIND for use in debug dumps.  */
945 
946 const char *
poison_kind_to_str(enum poison_kind kind)947 poison_kind_to_str (enum poison_kind kind)
948 {
949   switch (kind)
950     {
951     default:
952       gcc_unreachable ();
953     case POISON_KIND_UNINIT:
954       return "uninit";
955     case POISON_KIND_FREED:
956       return "freed";
957     case POISON_KIND_POPPED_STACK:
958       return "popped stack";
959     }
960 }
961 
962 /* class poisoned_svalue : public svalue.  */
963 
964 /* Implementation of svalue::dump_to_pp vfunc for poisoned_svalue.  */
965 
966 void
dump_to_pp(pretty_printer * pp,bool simple) const967 poisoned_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
968 {
969   if (simple)
970     {
971       pp_string (pp, "POISONED(");
972       print_quoted_type (pp, get_type ());
973       pp_printf (pp, ", %s)", poison_kind_to_str (m_kind));
974     }
975   else
976     {
977       pp_string (pp, "poisoned_svalue(");
978       print_quoted_type (pp, get_type ());
979       pp_printf (pp, ", %s)", poison_kind_to_str (m_kind));
980     }
981 }
982 
983 /* Implementation of svalue::accept vfunc for poisoned_svalue.  */
984 
985 void
accept(visitor * v) const986 poisoned_svalue::accept (visitor *v) const
987 {
988   v->visit_poisoned_svalue (this);
989 }
990 
991 /* Implementation of svalue::maybe_fold_bits_within vfunc
992    for poisoned_svalue.  */
993 
994 const svalue *
maybe_fold_bits_within(tree type,const bit_range &,region_model_manager * mgr) const995 poisoned_svalue::maybe_fold_bits_within (tree type,
996 					 const bit_range &,
997 					 region_model_manager *mgr) const
998 {
999   /* Bits within a poisoned value are also poisoned.  */
1000   return mgr->get_or_create_poisoned_svalue (m_kind, type);
1001 }
1002 
1003 /* class setjmp_svalue's implementation is in engine.cc, so that it can use
1004    the declaration of exploded_node.  */
1005 
1006 /* class initial_svalue : public svalue.  */
1007 
1008 /* Implementation of svalue::dump_to_pp vfunc for initial_svalue.  */
1009 
1010 void
dump_to_pp(pretty_printer * pp,bool simple) const1011 initial_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
1012 {
1013   if (simple)
1014     {
1015       pp_string (pp, "INIT_VAL(");
1016       m_reg->dump_to_pp (pp, simple);
1017       pp_string (pp, ")");
1018     }
1019   else
1020     {
1021       pp_string (pp, "initial_svalue(");
1022       print_quoted_type (pp, get_type ());
1023       pp_string (pp, ", ");
1024       m_reg->dump_to_pp (pp, simple);
1025       pp_string (pp, ")");
1026     }
1027 }
1028 
1029 /* Implementation of svalue::accept vfunc for initial_svalue.  */
1030 
1031 void
accept(visitor * v) const1032 initial_svalue::accept (visitor *v) const
1033 {
1034   v->visit_initial_svalue (this);
1035   m_reg->accept (v);
1036 }
1037 
1038 /* Implementation of svalue::implicitly_live_p vfunc for initial_svalue.  */
1039 
1040 bool
implicitly_live_p(const svalue_set *,const region_model * model) const1041 initial_svalue::implicitly_live_p (const svalue_set *,
1042 				   const region_model *model) const
1043 {
1044   /* This svalue may be implicitly live if the region still implicitly
1045      has its initial value and is reachable.  */
1046 
1047   /* It must be a region that exists; we don't want to consider
1048      INIT_VAL(R) as still being implicitly reachable if R is in
1049      a popped stack frame.  */
1050   if (model->region_exists_p (m_reg))
1051     {
1052       const svalue *reg_sval = model->get_store_value (m_reg, NULL);
1053       if (reg_sval == this)
1054 	return true;
1055     }
1056 
1057   /* Assume that the initial values of params for the top level frame
1058      are still live, because (presumably) they're still
1059      live in the external caller.  */
1060   if (initial_value_of_param_p ())
1061     if (const frame_region *frame_reg = m_reg->maybe_get_frame_region ())
1062       if (frame_reg->get_calling_frame () == NULL)
1063 	return true;
1064 
1065   return false;
1066 }
1067 
1068 /* Return true if this is the initial value of a function parameter.  */
1069 
1070 bool
initial_value_of_param_p() const1071 initial_svalue::initial_value_of_param_p () const
1072 {
1073   if (tree reg_decl = m_reg->maybe_get_decl ())
1074     if (TREE_CODE (reg_decl) == SSA_NAME)
1075       {
1076 	tree ssa_name = reg_decl;
1077 	if (SSA_NAME_IS_DEFAULT_DEF (ssa_name)
1078 	    && SSA_NAME_VAR (ssa_name)
1079 	    && TREE_CODE (SSA_NAME_VAR (ssa_name)) == PARM_DECL)
1080 	  return true;
1081       }
1082   return false;
1083 }
1084 
1085 /* class unaryop_svalue : public svalue.  */
1086 
1087 /* Implementation of svalue::dump_to_pp vfunc for unaryop_svalue.  */
1088 
1089 void
dump_to_pp(pretty_printer * pp,bool simple) const1090 unaryop_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
1091 {
1092   if (simple)
1093     {
1094       if (m_op == VIEW_CONVERT_EXPR || m_op == NOP_EXPR)
1095 	{
1096 	  pp_string (pp, "CAST(");
1097 	  dump_tree (pp, get_type ());
1098 	  pp_string (pp, ", ");
1099 	  m_arg->dump_to_pp (pp, simple);
1100 	  pp_character (pp, ')');
1101 	}
1102       else
1103 	{
1104 	  pp_character (pp, '(');
1105 	  pp_string (pp, get_tree_code_name (m_op));
1106 	  //pp_string (pp, op_symbol_code (m_op));
1107 	  m_arg->dump_to_pp (pp, simple);
1108 	  pp_character (pp, ')');
1109 	}
1110     }
1111   else
1112     {
1113       pp_string (pp, "unaryop_svalue (");
1114       pp_string (pp, get_tree_code_name (m_op));
1115       pp_string (pp, ", ");
1116       m_arg->dump_to_pp (pp, simple);
1117       pp_character (pp, ')');
1118     }
1119 }
1120 
1121 /* Implementation of svalue::accept vfunc for unaryop_svalue.  */
1122 
1123 void
accept(visitor * v) const1124 unaryop_svalue::accept (visitor *v) const
1125 {
1126   v->visit_unaryop_svalue (this);
1127   m_arg->accept (v);
1128 }
1129 
1130 /* Implementation of svalue::implicitly_live_p vfunc for unaryop_svalue.  */
1131 
1132 bool
implicitly_live_p(const svalue_set * live_svalues,const region_model * model) const1133 unaryop_svalue::implicitly_live_p (const svalue_set *live_svalues,
1134 				   const region_model *model) const
1135 {
1136   return get_arg ()->live_p (live_svalues, model);
1137 }
1138 
1139 /* Implementation of svalue::maybe_fold_bits_within vfunc
1140    for unaryop_svalue.  */
1141 
1142 const svalue *
maybe_fold_bits_within(tree type,const bit_range &,region_model_manager * mgr) const1143 unaryop_svalue::maybe_fold_bits_within (tree type,
1144 					const bit_range &,
1145 					region_model_manager *mgr) const
1146 {
1147   switch (m_op)
1148     {
1149     default:
1150       break;
1151     case NOP_EXPR:
1152       /* A cast of zero is zero.  */
1153       if (tree cst = m_arg->maybe_get_constant ())
1154 	if (zerop (cst))
1155 	  {
1156 	    if (type)
1157 	      return mgr->get_or_create_cast (type, this);
1158 	    else
1159 	      return this;
1160 	  }
1161       break;
1162     }
1163   /* Otherwise, don't fold.  */
1164   return NULL;
1165 }
1166 
1167 /* class binop_svalue : public svalue.  */
1168 
1169 /* Return whether OP be printed as an infix operator.  */
1170 
1171 static bool
infix_p(enum tree_code op)1172 infix_p (enum tree_code op)
1173 {
1174   switch (op)
1175     {
1176     default:
1177       return true;
1178     case MAX_EXPR:
1179     case MIN_EXPR:
1180       return false;
1181     }
1182 }
1183 
1184 /* Implementation of svalue::dump_to_pp vfunc for binop_svalue.  */
1185 
1186 void
dump_to_pp(pretty_printer * pp,bool simple) const1187 binop_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
1188 {
1189   if (simple)
1190     {
1191       if (infix_p (m_op))
1192 	{
1193 	  /* Print "(A OP B)".  */
1194 	  pp_character (pp, '(');
1195 	  m_arg0->dump_to_pp (pp, simple);
1196 	  pp_string (pp, op_symbol_code (m_op));
1197 	  m_arg1->dump_to_pp (pp, simple);
1198 	  pp_character (pp, ')');
1199 	}
1200       else
1201 	{
1202 	  /* Print "OP(A, B)".  */
1203 	  pp_string (pp, op_symbol_code (m_op));
1204 	  pp_character (pp, '(');
1205 	  m_arg0->dump_to_pp (pp, simple);
1206 	  pp_string (pp, ", ");
1207 	  m_arg1->dump_to_pp (pp, simple);
1208 	  pp_character (pp, ')');
1209 	}
1210     }
1211   else
1212     {
1213       pp_string (pp, "binop_svalue (");
1214       pp_string (pp, get_tree_code_name (m_op));
1215       pp_string (pp, ", ");
1216       m_arg0->dump_to_pp (pp, simple);
1217       pp_string (pp, ", ");
1218       m_arg1->dump_to_pp (pp, simple);
1219       pp_character (pp, ')');
1220     }
1221 }
1222 
1223 /* Implementation of svalue::accept vfunc for binop_svalue.  */
1224 
1225 void
accept(visitor * v) const1226 binop_svalue::accept (visitor *v) const
1227 {
1228   v->visit_binop_svalue (this);
1229   m_arg0->accept (v);
1230   m_arg1->accept (v);
1231 }
1232 
1233 /* Implementation of svalue::implicitly_live_p vfunc for binop_svalue.  */
1234 
1235 bool
implicitly_live_p(const svalue_set * live_svalues,const region_model * model) const1236 binop_svalue::implicitly_live_p (const svalue_set *live_svalues,
1237 				 const region_model *model) const
1238 {
1239   return (get_arg0 ()->live_p (live_svalues, model)
1240 	  && get_arg1 ()->live_p (live_svalues, model));
1241 }
1242 
1243 /* class sub_svalue : public svalue.  */
1244 
1245 /* sub_svalue'c ctor.  */
1246 
sub_svalue(tree type,const svalue * parent_svalue,const region * subregion)1247 sub_svalue::sub_svalue (tree type, const svalue *parent_svalue,
1248 			const region *subregion)
1249 : svalue (complexity::from_pair (parent_svalue->get_complexity (),
1250 				 subregion->get_complexity ()),
1251 	  type),
1252   m_parent_svalue (parent_svalue), m_subregion (subregion)
1253 {
1254   gcc_assert (parent_svalue->can_have_associated_state_p ());
1255 }
1256 
1257 /* Implementation of svalue::dump_to_pp vfunc for sub_svalue.  */
1258 
1259 void
dump_to_pp(pretty_printer * pp,bool simple) const1260 sub_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
1261 {
1262   if (simple)
1263     {
1264       pp_string (pp, "SUB(");
1265       m_parent_svalue->dump_to_pp (pp, simple);
1266       pp_string (pp, ", ");
1267       m_subregion->dump_to_pp (pp, simple);
1268       pp_character (pp, ')');
1269     }
1270   else
1271     {
1272       pp_string (pp, "sub_svalue (");
1273       pp_string (pp, ", ");
1274       m_parent_svalue->dump_to_pp (pp, simple);
1275       pp_string (pp, ", ");
1276       m_subregion->dump_to_pp (pp, simple);
1277       pp_character (pp, ')');
1278     }
1279 }
1280 
1281 /* Implementation of svalue::accept vfunc for sub_svalue.  */
1282 
1283 void
accept(visitor * v) const1284 sub_svalue::accept (visitor *v) const
1285 {
1286   v->visit_sub_svalue (this);
1287   m_parent_svalue->accept (v);
1288   m_subregion->accept (v);
1289 }
1290 
1291 /* Implementation of svalue::implicitly_live_p vfunc for sub_svalue.  */
1292 
1293 bool
implicitly_live_p(const svalue_set * live_svalues,const region_model * model) const1294 sub_svalue::implicitly_live_p (const svalue_set *live_svalues,
1295 			       const region_model *model) const
1296 {
1297   return get_parent ()->live_p (live_svalues, model);
1298 }
1299 
1300 /* class repeated_svalue : public svalue.  */
1301 
1302 /* repeated_svalue'c ctor.  */
1303 
repeated_svalue(tree type,const svalue * outer_size,const svalue * inner_svalue)1304 repeated_svalue::repeated_svalue (tree type,
1305 				  const svalue *outer_size,
1306 				  const svalue *inner_svalue)
1307 : svalue (complexity::from_pair (outer_size, inner_svalue), type),
1308   m_outer_size (outer_size),
1309   m_inner_svalue (inner_svalue)
1310 {
1311   gcc_assert (outer_size->can_have_associated_state_p ());
1312   gcc_assert (inner_svalue->can_have_associated_state_p ());
1313 }
1314 
1315 /* Implementation of svalue::dump_to_pp vfunc for repeated_svalue.  */
1316 
1317 void
dump_to_pp(pretty_printer * pp,bool simple) const1318 repeated_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
1319 {
1320   if (simple)
1321     {
1322       pp_string (pp, "REPEATED(");
1323       if (get_type ())
1324 	{
1325 	  print_quoted_type (pp, get_type ());
1326 	  pp_string (pp, ", ");
1327 	}
1328       pp_string (pp, "outer_size: ");
1329       m_outer_size->dump_to_pp (pp, simple);
1330       pp_string (pp, ", inner_val: ");
1331       m_inner_svalue->dump_to_pp (pp, simple);
1332       pp_character (pp, ')');
1333     }
1334   else
1335     {
1336       pp_string (pp, "repeated_svalue (");
1337       if (get_type ())
1338 	{
1339 	  print_quoted_type (pp, get_type ());
1340 	  pp_string (pp, ", ");
1341 	}
1342       pp_string (pp, "outer_size: ");
1343       m_outer_size->dump_to_pp (pp, simple);
1344       pp_string (pp, ", inner_val: ");
1345       m_inner_svalue->dump_to_pp (pp, simple);
1346       pp_character (pp, ')');
1347     }
1348 }
1349 
1350 /* Implementation of svalue::accept vfunc for repeated_svalue.  */
1351 
1352 void
accept(visitor * v) const1353 repeated_svalue::accept (visitor *v) const
1354 {
1355   v->visit_repeated_svalue (this);
1356   m_inner_svalue->accept (v);
1357 }
1358 
1359 /* Implementation of svalue::all_zeroes_p for repeated_svalue.  */
1360 
1361 bool
all_zeroes_p() const1362 repeated_svalue::all_zeroes_p () const
1363 {
1364   return m_inner_svalue->all_zeroes_p ();
1365 }
1366 
1367 /* Implementation of svalue::maybe_fold_bits_within vfunc
1368    for repeated_svalue.  */
1369 
1370 const svalue *
maybe_fold_bits_within(tree type,const bit_range & bits,region_model_manager * mgr) const1371 repeated_svalue::maybe_fold_bits_within (tree type,
1372 					 const bit_range &bits,
1373 					 region_model_manager *mgr) const
1374 {
1375   const svalue *innermost_sval = m_inner_svalue;
1376   /* Fold
1377        BITS_WITHIN (range, REPEATED_SVALUE (ZERO))
1378      to:
1379        REPEATED_SVALUE (ZERO).  */
1380   if (all_zeroes_p ())
1381     {
1382       byte_range bytes (0,0);
1383       if (bits.as_byte_range (&bytes))
1384 	{
1385 	  const svalue *byte_size
1386 	    = mgr->get_or_create_int_cst (size_type_node,
1387 					  bytes.m_size_in_bytes.to_uhwi ());
1388 	  return mgr->get_or_create_repeated_svalue (type, byte_size,
1389 						     innermost_sval);
1390 	}
1391     }
1392 
1393   /* Fold:
1394        BITS_WITHIN (range, REPEATED_SVALUE (INNERMOST_SVALUE))
1395      to:
1396        BITS_WITHIN (range - offset, INNERMOST_SVALUE)
1397      if range is fully within one instance of INNERMOST_SVALUE.  */
1398   if (tree innermost_type = innermost_sval->get_type ())
1399     {
1400       bit_size_t element_bit_size;
1401       if (int_size_in_bits (innermost_type, &element_bit_size)
1402 	  && element_bit_size > 0)
1403 	{
1404 	  HOST_WIDE_INT start_idx
1405 	    = (bits.get_start_bit_offset ()
1406 	       / element_bit_size).to_shwi ();
1407 	  HOST_WIDE_INT last_idx
1408 	    = (bits.get_last_bit_offset ()
1409 	       / element_bit_size).to_shwi ();
1410 	  if (start_idx == last_idx)
1411 	    {
1412 	      bit_offset_t start_of_element
1413 		= start_idx * element_bit_size;
1414 	      bit_range range_within_element
1415 		(bits.m_start_bit_offset - start_of_element,
1416 		 bits.m_size_in_bits);
1417 	      return mgr->get_or_create_bits_within (type,
1418 						     range_within_element,
1419 						     innermost_sval);
1420 	    }
1421 	}
1422     }
1423 
1424   return NULL;
1425 }
1426 
1427 /* class bits_within_svalue : public svalue.  */
1428 
1429 /* bits_within_svalue'c ctor.  */
1430 
bits_within_svalue(tree type,const bit_range & bits,const svalue * inner_svalue)1431 bits_within_svalue::bits_within_svalue (tree type,
1432 					const bit_range &bits,
1433 					const svalue *inner_svalue)
1434 : svalue (complexity (inner_svalue), type),
1435   m_bits (bits),
1436   m_inner_svalue (inner_svalue)
1437 {
1438   gcc_assert (inner_svalue->can_have_associated_state_p ());
1439 }
1440 
1441 /* Implementation of svalue::dump_to_pp vfunc for bits_within_svalue.  */
1442 
1443 void
dump_to_pp(pretty_printer * pp,bool simple) const1444 bits_within_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
1445 {
1446   if (simple)
1447     {
1448       pp_string (pp, "BITS_WITHIN(");
1449       if (get_type ())
1450 	{
1451 	  print_quoted_type (pp, get_type ());
1452 	  pp_string (pp, ", ");
1453 	}
1454       m_bits.dump_to_pp (pp);
1455       pp_string (pp, ", inner_val: ");
1456       m_inner_svalue->dump_to_pp (pp, simple);
1457       pp_character (pp, ')');
1458     }
1459   else
1460     {
1461       pp_string (pp, "bits_within_svalue (");
1462       if (get_type ())
1463 	{
1464 	  print_quoted_type (pp, get_type ());
1465 	  pp_string (pp, ", ");
1466 	}
1467       m_bits.dump_to_pp (pp);
1468       pp_string (pp, ", inner_val: ");
1469       m_inner_svalue->dump_to_pp (pp, simple);
1470       pp_character (pp, ')');
1471     }
1472 }
1473 
1474 /* Implementation of svalue::maybe_fold_bits_within vfunc
1475    for bits_within_svalue.  */
1476 
1477 const svalue *
maybe_fold_bits_within(tree type,const bit_range & bits,region_model_manager * mgr) const1478 bits_within_svalue::maybe_fold_bits_within (tree type,
1479 					    const bit_range &bits,
1480 					    region_model_manager *mgr) const
1481 {
1482   /* Fold:
1483        BITS_WITHIN (range1, BITS_WITHIN (range2, VAL))
1484      to:
1485        BITS_WITHIN (range1 in range 2, VAL).  */
1486   bit_range offset_bits (m_bits.get_start_bit_offset ()
1487 			 + bits.m_start_bit_offset,
1488 			 bits.m_size_in_bits);
1489   return mgr->get_or_create_bits_within (type, offset_bits, m_inner_svalue);
1490 }
1491 
1492 /* Implementation of svalue::accept vfunc for bits_within_svalue.  */
1493 
1494 void
accept(visitor * v) const1495 bits_within_svalue::accept (visitor *v) const
1496 {
1497   v->visit_bits_within_svalue (this);
1498   m_inner_svalue->accept (v);
1499 }
1500 
1501 /* Implementation of svalue::implicitly_live_p vfunc for bits_within_svalue.  */
1502 
1503 bool
implicitly_live_p(const svalue_set * live_svalues,const region_model * model) const1504 bits_within_svalue::implicitly_live_p (const svalue_set *live_svalues,
1505 				       const region_model *model) const
1506 {
1507   return m_inner_svalue->live_p (live_svalues, model);
1508 }
1509 
1510 /* class widening_svalue : public svalue.  */
1511 
1512 /* Implementation of svalue::dump_to_pp vfunc for widening_svalue.  */
1513 
1514 void
dump_to_pp(pretty_printer * pp,bool simple) const1515 widening_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
1516 {
1517   if (simple)
1518     {
1519       pp_string (pp, "WIDENING(");
1520       pp_character (pp, '{');
1521       m_point.print (pp, format (false));
1522       pp_string (pp, "}, ");
1523       m_base_sval->dump_to_pp (pp, simple);
1524       pp_string (pp, ", ");
1525       m_iter_sval->dump_to_pp (pp, simple);
1526       pp_character (pp, ')');
1527     }
1528   else
1529     {
1530       pp_string (pp, "widening_svalue (");
1531       pp_string (pp, ", ");
1532       pp_character (pp, '{');
1533       m_point.print (pp, format (false));
1534       pp_string (pp, "}, ");
1535       m_base_sval->dump_to_pp (pp, simple);
1536       pp_string (pp, ", ");
1537       m_iter_sval->dump_to_pp (pp, simple);
1538       pp_character (pp, ')');
1539     }
1540 }
1541 
1542 /* Implementation of svalue::accept vfunc for widening_svalue.  */
1543 
1544 void
accept(visitor * v) const1545 widening_svalue::accept (visitor *v) const
1546 {
1547   v->visit_widening_svalue (this);
1548   m_base_sval->accept (v);
1549   m_iter_sval->accept (v);
1550 }
1551 
1552 /* Attempt to determine in which direction this value is changing
1553    w.r.t. the initial value.  */
1554 
1555 enum widening_svalue::direction_t
get_direction() const1556 widening_svalue::get_direction () const
1557 {
1558   tree base_cst = m_base_sval->maybe_get_constant ();
1559   if (base_cst == NULL_TREE)
1560     return DIR_UNKNOWN;
1561   tree iter_cst = m_iter_sval->maybe_get_constant ();
1562   if (iter_cst == NULL_TREE)
1563     return DIR_UNKNOWN;
1564 
1565   tree iter_gt_base = fold_binary (GT_EXPR, boolean_type_node,
1566 				   iter_cst, base_cst);
1567   if (iter_gt_base == boolean_true_node)
1568     return DIR_ASCENDING;
1569 
1570   tree iter_lt_base = fold_binary (LT_EXPR, boolean_type_node,
1571 				   iter_cst, base_cst);
1572   if (iter_lt_base == boolean_true_node)
1573     return DIR_DESCENDING;
1574 
1575   return DIR_UNKNOWN;
1576 }
1577 
1578 /* Compare this value against constant RHS_CST.  */
1579 
1580 tristate
eval_condition_without_cm(enum tree_code op,tree rhs_cst) const1581 widening_svalue::eval_condition_without_cm (enum tree_code op,
1582 					    tree rhs_cst) const
1583 {
1584   tree base_cst = m_base_sval->maybe_get_constant ();
1585   if (base_cst == NULL_TREE)
1586     return tristate::TS_UNKNOWN;
1587   tree iter_cst = m_iter_sval->maybe_get_constant ();
1588   if (iter_cst == NULL_TREE)
1589     return tristate::TS_UNKNOWN;
1590 
1591   switch (get_direction ())
1592     {
1593     default:
1594       gcc_unreachable ();
1595     case DIR_ASCENDING:
1596       /* LHS is in [base_cst, +ve infinity), assuming no overflow.  */
1597       switch (op)
1598 	{
1599 	case LE_EXPR:
1600 	case LT_EXPR:
1601 	  {
1602 	    /* [BASE, +INF) OP RHS:
1603 	       This is either true or false at +ve ininity,
1604 	       It can be true for points X where X OP RHS, so we have either
1605 	       "false", or "unknown".  */
1606 	    tree base_op_rhs = fold_binary (op, boolean_type_node,
1607 					    base_cst, rhs_cst);
1608 	    if (base_op_rhs == boolean_true_node)
1609 	      return tristate::TS_UNKNOWN;
1610 	    else
1611 	      return tristate::TS_FALSE;
1612 	  }
1613 
1614 	case GE_EXPR:
1615 	case GT_EXPR:
1616 	  {
1617 	    /* [BASE, +INF) OP RHS:
1618 	       This is true at +ve infinity.  It will be true everywhere
1619 	       in the range if BASE >= RHS.  */
1620 	    tree base_op_rhs = fold_binary (op, boolean_type_node,
1621 					    base_cst, rhs_cst);
1622 	    if (base_op_rhs == boolean_true_node)
1623 	      return tristate::TS_TRUE;
1624 	    else
1625 	      return tristate::TS_UNKNOWN;
1626 	  }
1627 
1628 	case EQ_EXPR:
1629 	  {
1630 	    /* [BASE, +INF) == RHS:
1631 	       Could this be true at any point in the range?  If so we
1632 	       have "unknown", otherwise we have "false".  */
1633 	    tree base_le_rhs = fold_binary (LE_EXPR, boolean_type_node,
1634 					    base_cst, rhs_cst);
1635 	    if (base_le_rhs == boolean_true_node)
1636 	      return tristate::TS_UNKNOWN;
1637 	    else
1638 	      return tristate::TS_FALSE;
1639 	  }
1640 
1641 	case NE_EXPR:
1642 	  {
1643 	    /* [BASE, +INF) != RHS:
1644 	       Could we have equality at any point in the range?  If so we
1645 	       have "unknown", otherwise we have "true".  */
1646 	    tree base_le_rhs = fold_binary (LE_EXPR, boolean_type_node,
1647 					    base_cst, rhs_cst);
1648 	    if (base_le_rhs == boolean_true_node)
1649 	      return tristate::TS_UNKNOWN;
1650 	    else
1651 	      return tristate::TS_TRUE;
1652 	  }
1653 
1654 	default:
1655 	  return tristate::TS_UNKNOWN;
1656 	}
1657 
1658     case DIR_DESCENDING:
1659       /* LHS is in (-ve infinity, base_cst], assuming no overflow.  */
1660       return tristate::TS_UNKNOWN;
1661 
1662     case DIR_UNKNOWN:
1663       return tristate::TS_UNKNOWN;
1664     }
1665 }
1666 
1667 /* class placeholder_svalue : public svalue.  */
1668 
1669 /* Implementation of svalue::dump_to_pp vfunc for placeholder_svalue.  */
1670 
1671 void
dump_to_pp(pretty_printer * pp,bool simple) const1672 placeholder_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
1673 {
1674   if (simple)
1675     pp_printf (pp, "PLACEHOLDER(%qs)", m_name);
1676   else
1677     pp_printf (pp, "placeholder_svalue (%qs)", m_name);
1678 }
1679 
1680 /* Implementation of svalue::accept vfunc for placeholder_svalue.  */
1681 
1682 void
accept(visitor * v) const1683 placeholder_svalue::accept (visitor *v) const
1684 {
1685   v->visit_placeholder_svalue (this);
1686 }
1687 
1688 /* class unmergeable_svalue : public svalue.  */
1689 
1690 /* Implementation of svalue::dump_to_pp vfunc for unmergeable_svalue.  */
1691 
1692 void
dump_to_pp(pretty_printer * pp,bool simple) const1693 unmergeable_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
1694 {
1695   if (simple)
1696     {
1697       pp_string (pp, "UNMERGEABLE(");
1698       m_arg->dump_to_pp (pp, simple);
1699       pp_character (pp, ')');
1700     }
1701   else
1702     {
1703       pp_string (pp, "unmergeable_svalue (");
1704       m_arg->dump_to_pp (pp, simple);
1705       pp_character (pp, ')');
1706     }
1707 }
1708 
1709 /* Implementation of svalue::accept vfunc for unmergeable_svalue.  */
1710 
1711 void
accept(visitor * v) const1712 unmergeable_svalue::accept (visitor *v) const
1713 {
1714   v->visit_unmergeable_svalue (this);
1715   m_arg->accept (v);
1716 }
1717 
1718 /* Implementation of svalue::implicitly_live_p vfunc for unmergeable_svalue.  */
1719 
1720 bool
implicitly_live_p(const svalue_set * live_svalues,const region_model * model) const1721 unmergeable_svalue::implicitly_live_p (const svalue_set *live_svalues,
1722 				       const region_model *model) const
1723 {
1724   return get_arg ()->live_p (live_svalues, model);
1725 }
1726 
1727 /* class compound_svalue : public svalue.  */
1728 
compound_svalue(tree type,const binding_map & map)1729 compound_svalue::compound_svalue (tree type, const binding_map &map)
1730 : svalue (calc_complexity (map), type), m_map (map)
1731 {
1732   /* All keys within the underlying binding_map are required to be concrete,
1733      not symbolic.  */
1734 #if CHECKING_P
1735   for (iterator_t iter = begin (); iter != end (); ++iter)
1736     {
1737       const binding_key *key = (*iter).first;
1738       gcc_assert (key->concrete_p ());
1739     }
1740 #endif
1741 }
1742 
1743 /* Implementation of svalue::dump_to_pp vfunc for compound_svalue.  */
1744 
1745 void
dump_to_pp(pretty_printer * pp,bool simple) const1746 compound_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
1747 {
1748   if (simple)
1749     {
1750       pp_string (pp, "COMPOUND(");
1751       if (get_type ())
1752 	{
1753 	  print_quoted_type (pp, get_type ());
1754 	  pp_string (pp, ", ");
1755 	}
1756       pp_character (pp, '{');
1757       m_map.dump_to_pp (pp, simple, false);
1758       pp_string (pp, "})");
1759     }
1760   else
1761     {
1762       pp_string (pp, "compound_svalue (");
1763       if (get_type ())
1764 	{
1765 	  print_quoted_type (pp, get_type ());
1766 	  pp_string (pp, ", ");
1767 	}
1768       pp_character (pp, '{');
1769       m_map.dump_to_pp (pp, simple, false);
1770       pp_string (pp, "})");
1771     }
1772 }
1773 
1774 /* Implementation of svalue::accept vfunc for compound_svalue.  */
1775 
1776 void
accept(visitor * v) const1777 compound_svalue::accept (visitor *v) const
1778 {
1779   v->visit_compound_svalue (this);
1780   for (binding_map::iterator_t iter = m_map.begin ();
1781        iter != m_map.end (); ++iter)
1782     {
1783       //(*iter).first.accept (v);
1784       (*iter).second->accept (v);
1785     }
1786 }
1787 
1788 /* Calculate what the complexity of a compound_svalue instance for MAP
1789    will be, based on the svalues bound within MAP.  */
1790 
1791 complexity
calc_complexity(const binding_map & map)1792 compound_svalue::calc_complexity (const binding_map &map)
1793 {
1794   unsigned num_child_nodes = 0;
1795   unsigned max_child_depth = 0;
1796   for (binding_map::iterator_t iter = map.begin ();
1797        iter != map.end (); ++iter)
1798     {
1799       const complexity &sval_c = (*iter).second->get_complexity ();
1800       num_child_nodes += sval_c.m_num_nodes;
1801       max_child_depth = MAX (max_child_depth, sval_c.m_max_depth);
1802     }
1803   return complexity (num_child_nodes + 1, max_child_depth + 1);
1804 }
1805 
1806 /* Implementation of svalue::maybe_fold_bits_within vfunc
1807    for compound_svalue.  */
1808 
1809 const svalue *
maybe_fold_bits_within(tree type,const bit_range & bits,region_model_manager * mgr) const1810 compound_svalue::maybe_fold_bits_within (tree type,
1811 					 const bit_range &bits,
1812 					 region_model_manager *mgr) const
1813 {
1814   binding_map result_map;
1815   for (auto iter : m_map)
1816     {
1817       const binding_key *key = iter.first;
1818       if (const concrete_binding *conc_key
1819 	  = key->dyn_cast_concrete_binding ())
1820 	{
1821 	  /* Ignore concrete bindings outside BITS.  */
1822 	  if (!conc_key->get_bit_range ().intersects_p (bits))
1823 	    continue;
1824 
1825 	  const svalue *sval = iter.second;
1826 	  /* Get the position of conc_key relative to BITS.  */
1827 	  bit_range result_location (conc_key->get_start_bit_offset ()
1828 				     - bits.get_start_bit_offset (),
1829 				     conc_key->get_size_in_bits ());
1830 	  /* If conc_key starts after BITS, trim off leading bits
1831 	     from the svalue and adjust binding location.  */
1832 	  if (result_location.m_start_bit_offset < 0)
1833 	    {
1834 	      bit_size_t leading_bits_to_drop
1835 		= -result_location.m_start_bit_offset;
1836 	      result_location = bit_range
1837 		(0, result_location.m_size_in_bits - leading_bits_to_drop);
1838 	      bit_range bits_within_sval (leading_bits_to_drop,
1839 					  result_location.m_size_in_bits);
1840 	      /* Trim off leading bits from iter_sval.  */
1841 	      sval = mgr->get_or_create_bits_within (NULL_TREE,
1842 						     bits_within_sval,
1843 						     sval);
1844 	    }
1845 	  /* If conc_key finishes after BITS, trim off trailing bits
1846 	     from the svalue and adjust binding location.  */
1847 	  if (conc_key->get_next_bit_offset ()
1848 	      > bits.get_next_bit_offset ())
1849 	    {
1850 	      bit_size_t trailing_bits_to_drop
1851 		= (conc_key->get_next_bit_offset ()
1852 		   - bits.get_next_bit_offset ());
1853 	      result_location = bit_range
1854 		(result_location.m_start_bit_offset,
1855 		 result_location.m_size_in_bits - trailing_bits_to_drop);
1856 	      bit_range bits_within_sval (0,
1857 					  result_location.m_size_in_bits);
1858 	      /* Trim off leading bits from iter_sval.  */
1859 	      sval = mgr->get_or_create_bits_within (NULL_TREE,
1860 						     bits_within_sval,
1861 						     sval);
1862 	    }
1863 	  const concrete_binding *offset_conc_key
1864 	    = mgr->get_store_manager ()->get_concrete_binding
1865 		(result_location);
1866 	  result_map.put (offset_conc_key, sval);
1867 	}
1868       else
1869 	/* If we have any symbolic keys we can't get it as bits.  */
1870 	return NULL;
1871     }
1872   return mgr->get_or_create_compound_svalue (type, result_map);
1873 }
1874 
1875 /* class conjured_svalue : public svalue.  */
1876 
1877 /* Implementation of svalue::dump_to_pp vfunc for conjured_svalue.  */
1878 
1879 void
dump_to_pp(pretty_printer * pp,bool simple) const1880 conjured_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
1881 {
1882   if (simple)
1883     {
1884       pp_string (pp, "CONJURED(");
1885       pp_gimple_stmt_1 (pp, m_stmt, 0, (dump_flags_t)0);
1886       pp_string (pp, ", ");
1887       m_id_reg->dump_to_pp (pp, simple);
1888       pp_character (pp, ')');
1889     }
1890   else
1891     {
1892       pp_string (pp, "conjured_svalue (");
1893       pp_string (pp, ", ");
1894       pp_gimple_stmt_1 (pp, m_stmt, 0, (dump_flags_t)0);
1895       pp_string (pp, ", ");
1896       m_id_reg->dump_to_pp (pp, simple);
1897       pp_character (pp, ')');
1898     }
1899 }
1900 
1901 /* Implementation of svalue::accept vfunc for conjured_svalue.  */
1902 
1903 void
accept(visitor * v) const1904 conjured_svalue::accept (visitor *v) const
1905 {
1906   v->visit_conjured_svalue (this);
1907   m_id_reg->accept (v);
1908 }
1909 
1910 /* class asm_output_svalue : public svalue.  */
1911 
1912 /* Implementation of svalue::dump_to_pp vfunc for asm_output_svalue.  */
1913 
1914 void
dump_to_pp(pretty_printer * pp,bool simple) const1915 asm_output_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
1916 {
1917   if (simple)
1918     {
1919       pp_printf (pp, "ASM_OUTPUT(%qs, %%%i, {",
1920 		 get_asm_string (),
1921 		 get_output_idx ());
1922       for (unsigned i = 0; i < m_num_inputs; i++)
1923 	{
1924 	  if (i > 0)
1925 	    pp_string (pp, ", ");
1926 	  dump_input (pp, 0, m_input_arr[i], simple);
1927 	}
1928       pp_string (pp, "})");
1929     }
1930   else
1931     {
1932       pp_printf (pp, "asm_output_svalue (%qs, %%%i, {",
1933 		 get_asm_string (),
1934 		 get_output_idx ());
1935       for (unsigned i = 0; i < m_num_inputs; i++)
1936 	{
1937 	  if (i > 0)
1938 	    pp_string (pp, ", ");
1939 	  dump_input (pp, 0, m_input_arr[i], simple);
1940 	}
1941       pp_string (pp, "})");
1942     }
1943 }
1944 
1945 /* Subroutine of asm_output_svalue::dump_to_pp.  */
1946 
1947 void
dump_input(pretty_printer * pp,unsigned input_idx,const svalue * sval,bool simple) const1948 asm_output_svalue::dump_input (pretty_printer *pp,
1949 			       unsigned input_idx,
1950 			       const svalue *sval,
1951 			       bool simple) const
1952 {
1953   pp_printf (pp, "%%%i: ", input_idx_to_asm_idx (input_idx));
1954   sval->dump_to_pp (pp, simple);
1955 }
1956 
1957 /* Convert INPUT_IDX from an index into the array of inputs
1958    into the index of all operands for the asm stmt.  */
1959 
1960 unsigned
input_idx_to_asm_idx(unsigned input_idx) const1961 asm_output_svalue::input_idx_to_asm_idx (unsigned input_idx) const
1962 {
1963   return input_idx + m_num_outputs;
1964 }
1965 
1966 /* Implementation of svalue::accept vfunc for asm_output_svalue.  */
1967 
1968 void
accept(visitor * v) const1969 asm_output_svalue::accept (visitor *v) const
1970 {
1971   v->visit_asm_output_svalue (this);
1972   for (unsigned i = 0; i < m_num_inputs; i++)
1973     m_input_arr[i]->accept (v);
1974 }
1975 
1976 /* class const_fn_result_svalue : public svalue.  */
1977 
1978 /* Implementation of svalue::dump_to_pp vfunc for const_fn_result_svalue.  */
1979 
1980 void
dump_to_pp(pretty_printer * pp,bool simple) const1981 const_fn_result_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
1982 {
1983   if (simple)
1984     {
1985       pp_printf (pp, "CONST_FN_RESULT(%qD, {", m_fndecl);
1986       for (unsigned i = 0; i < m_num_inputs; i++)
1987 	{
1988 	  if (i > 0)
1989 	    pp_string (pp, ", ");
1990 	  dump_input (pp, i, m_input_arr[i], simple);
1991 	}
1992       pp_string (pp, "})");
1993     }
1994   else
1995     {
1996       pp_printf (pp, "CONST_FN_RESULT(%qD, {", m_fndecl);
1997       for (unsigned i = 0; i < m_num_inputs; i++)
1998 	{
1999 	  if (i > 0)
2000 	    pp_string (pp, ", ");
2001 	  dump_input (pp, i, m_input_arr[i], simple);
2002 	}
2003       pp_string (pp, "})");
2004     }
2005 }
2006 
2007 /* Subroutine of const_fn_result_svalue::dump_to_pp.  */
2008 
2009 void
dump_input(pretty_printer * pp,unsigned input_idx,const svalue * sval,bool simple) const2010 const_fn_result_svalue::dump_input (pretty_printer *pp,
2011 				    unsigned input_idx,
2012 				    const svalue *sval,
2013 				    bool simple) const
2014 {
2015   pp_printf (pp, "arg%i: ", input_idx);
2016   sval->dump_to_pp (pp, simple);
2017 }
2018 
2019 /* Implementation of svalue::accept vfunc for const_fn_result_svalue.  */
2020 
2021 void
accept(visitor * v) const2022 const_fn_result_svalue::accept (visitor *v) const
2023 {
2024   v->visit_const_fn_result_svalue (this);
2025   for (unsigned i = 0; i < m_num_inputs; i++)
2026     m_input_arr[i]->accept (v);
2027 }
2028 
2029 } // namespace ana
2030 
2031 #endif /* #if ENABLE_ANALYZER */
2032