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