Line data Source code
1 : /* Symbolic values.
2 : Copyright (C) 2019-2026 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 "analyzer/common.h"
22 :
23 : #include "tree-pretty-print.h"
24 : #include "gimple-pretty-print.h"
25 : #include "fold-const.h"
26 : #include "diagnostic.h"
27 : #include "tree-diagnostic.h"
28 : #include "value-relation.h"
29 : #include "range-op.h"
30 :
31 : #include "text-art/dump.h"
32 :
33 : #include "analyzer/analyzer-logging.h"
34 : #include "analyzer/call-string.h"
35 : #include "analyzer/program-point.h"
36 : #include "analyzer/store.h"
37 : #include "analyzer/svalue.h"
38 : #include "analyzer/region-model.h"
39 :
40 : #if ENABLE_ANALYZER
41 :
42 : namespace ana {
43 :
44 : static int cmp_csts_and_types (const_tree cst1, const_tree cst2);
45 :
46 : /* class svalue and its various subclasses. */
47 :
48 : /* class svalue. */
49 :
50 : /* Dump a tree-like representation of this svalue and its constituent symbols
51 : to stderr, using global_dc's colorization and theming options.
52 :
53 : For example:
54 : . (gdb) call index_sval->dump()
55 : . (27): ‘int’: initial_svalue
56 : . ╰─ m_reg: (26): ‘int’: decl_region(‘x_10(D)’)
57 : . ╰─ parent: (9): frame_region(‘test_bitmask_2’, index: 0, depth: 1)
58 : . ╰─ parent: (1): stack region
59 : . ╰─ parent: (0): root region
60 : */
61 :
62 : DEBUG_FUNCTION void
63 0 : svalue::dump () const
64 : {
65 0 : text_art::dump (*this);
66 0 : }
67 :
68 : /* Dump a representation of this svalue to stderr. */
69 :
70 : DEBUG_FUNCTION void
71 0 : svalue::dump (bool simple) const
72 : {
73 0 : tree_dump_pretty_printer pp (stderr);
74 0 : dump_to_pp (&pp, simple);
75 0 : pp_newline (&pp);
76 0 : }
77 :
78 : /* Generate a textual representation of this svalue for debugging purposes. */
79 :
80 : label_text
81 697 : svalue::get_desc (bool simple) const
82 : {
83 697 : pretty_printer pp;
84 697 : pp_format_decoder (&pp) = default_tree_printer;
85 697 : dump_to_pp (&pp, simple);
86 697 : return label_text::take (xstrdup (pp_formatted_text (&pp)));
87 697 : }
88 :
89 : /* Return a new json::string describing the svalue. */
90 :
91 : std::unique_ptr<json::value>
92 244 : svalue::to_json () const
93 : {
94 244 : label_text desc = get_desc (true);
95 244 : auto sval_js = std::make_unique<json::string> (desc.get ());
96 244 : return sval_js;
97 244 : }
98 :
99 : /* Class for optionally adding open/close paren pairs within
100 : svalue::maybe_print_for_user. */
101 :
102 : class auto_add_parens
103 : {
104 : public:
105 141 : auto_add_parens (pretty_printer *pp,
106 : const svalue *outer_sval,
107 : const svalue &inner_sval)
108 141 : : m_pp (pp),
109 141 : m_needs_parens (needs_parens_p (outer_sval, inner_sval))
110 : {
111 141 : if (m_needs_parens)
112 20 : pp_string (m_pp, "(");
113 141 : }
114 141 : ~auto_add_parens ()
115 : {
116 141 : if (m_needs_parens)
117 20 : pp_string (m_pp, ")");
118 141 : }
119 :
120 : private:
121 141 : static bool needs_parens_p (const svalue *outer_sval,
122 : const svalue &inner_sval)
123 : {
124 141 : if (!outer_sval)
125 : return false;
126 104 : if (inner_sval.get_kind () == SK_BINOP)
127 : return true;
128 : return false;
129 : }
130 :
131 : pretty_printer *m_pp;
132 : bool m_needs_parens;
133 : };
134 :
135 : /* Attempt to print a user-facing description of this svalue to PP,
136 : using MODEL for extracting representative tree values if necessary.
137 : Use OUTER_SVAL (which can be null) to determine if we need to wrap
138 : this value in parentheses. */
139 :
140 : bool
141 141 : svalue::maybe_print_for_user (pretty_printer *pp,
142 : const region_model &model,
143 : const svalue *outer_sval) const
144 : {
145 141 : auto_add_parens p (pp, outer_sval, *this);
146 :
147 141 : switch (get_kind ())
148 : {
149 : default:
150 : break;
151 42 : case SK_CONSTANT:
152 42 : {
153 42 : const constant_svalue *sval = (const constant_svalue *)this;
154 42 : pp_printf (pp, "%E", sval->get_constant ());
155 42 : return true;
156 : }
157 34 : case SK_INITIAL:
158 34 : {
159 34 : const initial_svalue *sval = (const initial_svalue *)this;
160 34 : return sval->get_region ()->maybe_print_for_user (pp, model);
161 : }
162 12 : case SK_UNARYOP:
163 12 : {
164 12 : const unaryop_svalue *sval = (const unaryop_svalue *)this;
165 12 : if (sval->get_op () == NOP_EXPR)
166 : {
167 12 : if (!sval->get_arg ()->maybe_print_for_user (pp, model, outer_sval))
168 : return false;
169 : return true;
170 : }
171 : }
172 : break;
173 48 : case SK_BINOP:
174 48 : {
175 48 : const binop_svalue *sval = (const binop_svalue *)this;
176 48 : switch (sval->get_op ())
177 : {
178 : default:
179 : break;
180 :
181 48 : case PLUS_EXPR:
182 48 : case MINUS_EXPR:
183 48 : case MULT_EXPR:
184 48 : {
185 48 : if (!sval->get_arg0 ()->maybe_print_for_user (pp, model, this))
186 : return false;
187 48 : pp_printf (pp, " %s ", op_symbol_code (sval->get_op ()));
188 48 : if (!sval->get_arg1 ()->maybe_print_for_user (pp, model, this))
189 : return false;
190 : return true;
191 : }
192 : }
193 : }
194 : break;
195 : }
196 :
197 5 : if (tree expr = model.get_representative_tree (this))
198 : {
199 4 : expr = remove_ssa_names (expr);
200 4 : print_expr_for_user (pp, expr);
201 4 : return true;
202 : }
203 :
204 : return false;
205 141 : }
206 :
207 : /* Use DWI to create a text_art::widget describing this svalue in
208 : a tree-like form, using PREFIX as a prefix (e.g. for field names).
209 : We do this via two vfuncs:
210 : (a) print_dump_widget_label, to populate the text of a tree_widget, and
211 : (b) add_dump_widget_children, to add children to the tree_widget. */
212 :
213 : std::unique_ptr<text_art::tree_widget>
214 0 : svalue::make_dump_widget (const text_art::dump_widget_info &dwi,
215 : const char *prefix) const
216 : {
217 0 : pretty_printer pp;
218 0 : pp_format_decoder (&pp) = default_tree_printer;
219 0 : pp_show_color (&pp) = true;
220 :
221 0 : if (prefix)
222 0 : pp_printf (&pp, "%s: ", prefix);
223 :
224 0 : pp_printf (&pp, "(%i): ", get_id ());
225 0 : if (get_type ())
226 0 : pp_printf (&pp, "%qT: ", get_type ());
227 :
228 0 : print_dump_widget_label (&pp);
229 :
230 0 : value_range out;
231 0 : if (maybe_get_value_range (out))
232 : {
233 0 : pp_printf (&pp, " value range: {"),
234 0 : out.print (&pp);
235 0 : pp_string (&pp, "}");
236 : }
237 :
238 0 : std::unique_ptr<text_art::tree_widget> w
239 0 : (text_art::tree_widget::make (dwi, &pp));
240 :
241 0 : add_dump_widget_children (*w, dwi);
242 :
243 0 : return w;
244 0 : }
245 :
246 : /* If this svalue is a constant_svalue, return the underlying tree constant.
247 : Otherwise return NULL_TREE. */
248 :
249 : tree
250 13996643 : svalue::maybe_get_constant () const
251 : {
252 13996643 : const svalue *sval = unwrap_any_unmergeable ();
253 13996643 : if (const constant_svalue *cst_sval = sval->dyn_cast_constant_svalue ())
254 4748509 : return cst_sval->get_constant ();
255 : else
256 : return NULL_TREE;
257 : }
258 :
259 : /* If this svalue is a region_svalue, return the region it points to.
260 : Otherwise return nullptr. */
261 :
262 : const region *
263 393638 : svalue::maybe_get_region () const
264 : {
265 393638 : if (const region_svalue *region_sval = dyn_cast_region_svalue ())
266 38953 : return region_sval->get_pointee ();
267 : else
268 : return nullptr;
269 : }
270 :
271 : /* If this svalue is a cast (i.e a unaryop NOP_EXPR or VIEW_CONVERT_EXPR),
272 : return the underlying svalue.
273 : Otherwise return nullptr. */
274 :
275 : const svalue *
276 13246363 : svalue::maybe_undo_cast () const
277 : {
278 13246363 : if (const unaryop_svalue *unaryop_sval = dyn_cast_unaryop_svalue ())
279 : {
280 889440 : enum tree_code op = unaryop_sval->get_op ();
281 889440 : if (op == NOP_EXPR || op == VIEW_CONVERT_EXPR)
282 856174 : return unaryop_sval->get_arg ();
283 : }
284 : return nullptr;
285 : }
286 :
287 : /* If this svalue is an unmergeable decorator around another svalue, return
288 : the underlying svalue.
289 : Otherwise return this svalue. */
290 :
291 : const svalue *
292 17298515 : svalue::unwrap_any_unmergeable () const
293 : {
294 17298515 : if (const unmergeable_svalue *unmergeable = dyn_cast_unmergeable_svalue ())
295 4370 : return unmergeable->get_arg ();
296 : return this;
297 : }
298 :
299 : /* Attempt to merge THIS with OTHER, returning the merged svalue.
300 : Return nullptr if not mergeable. */
301 :
302 : const svalue *
303 372862 : svalue::can_merge_p (const svalue *other,
304 : region_model_manager *mgr,
305 : model_merger *merger) const
306 : {
307 372862 : if (!(get_type () && other->get_type ()))
308 : return nullptr;
309 :
310 323588 : if (!types_compatible_p (get_type (), other->get_type ()))
311 : return nullptr;
312 :
313 : /* Reject attempts to merge unmergeable svalues. */
314 302134 : if ((get_kind () == SK_UNMERGEABLE)
315 302134 : || (other->get_kind () == SK_UNMERGEABLE))
316 2807 : return nullptr;
317 :
318 : /* Reject attempts to merge poisoned svalues with other svalues
319 : (either non-poisoned, or other kinds of poison), so that e.g.
320 : we identify paths in which a variable is conditionally uninitialized. */
321 299327 : if (get_kind () == SK_POISONED
322 299327 : || other->get_kind () == SK_POISONED)
323 1591 : return nullptr;
324 :
325 : /* Reject attempts to merge NULL pointers with not-NULL-pointers. */
326 297736 : if (POINTER_TYPE_P (get_type ()))
327 : {
328 38411 : bool null0 = false;
329 38411 : bool null1 = false;
330 38411 : if (tree cst0 = maybe_get_constant ())
331 7910 : if (zerop (cst0))
332 38411 : null0 = true;
333 38411 : if (tree cst1 = other->maybe_get_constant ())
334 5321 : if (zerop (cst1))
335 38411 : null1 = true;
336 38411 : if (null0 != null1)
337 : return nullptr;
338 : }
339 :
340 : /* Reject merging svalues that have non-purgable sm-state,
341 : to avoid falsely reporting memory leaks by merging them
342 : with something else. */
343 284727 : if (!merger->mergeable_svalue_p (this))
344 : return nullptr;
345 283618 : if (!merger->mergeable_svalue_p (other))
346 : return nullptr;
347 :
348 : /* Reject attempts to merge pointers that point to different base regions,
349 : except for the case where both are string literals. */
350 282920 : if (auto this_region = maybe_get_region ())
351 3851 : if (auto other_region = other->maybe_get_region ())
352 545 : if (this_region != other_region
353 545 : && (this_region->get_kind () != RK_STRING
354 61 : || other_region->get_kind () != RK_STRING))
355 522 : return nullptr;
356 :
357 : /* Widening. */
358 : /* Merge: (new_cst, existing_cst) -> widen (existing, new). */
359 282398 : if (maybe_get_constant () && other->maybe_get_constant ())
360 3614 : return mgr->get_or_create_widening_svalue (other->get_type (),
361 : merger->get_supernode (),
362 3614 : other, this);
363 :
364 : /* Merger of:
365 : this: BINOP (X, OP, CST)
366 : other: X, where X is non-widening
367 : to: WIDENING (other, this). */
368 278784 : if (const binop_svalue *binop_sval = dyn_cast_binop_svalue ())
369 11272 : if (binop_sval->get_arg0 () == other
370 1672 : && binop_sval->get_arg1 ()->get_kind () == SK_CONSTANT
371 12801 : && other->get_kind () != SK_WIDENING)
372 686 : return mgr->get_or_create_widening_svalue (other->get_type (),
373 : merger->get_supernode (),
374 686 : other, this);
375 :
376 : /* Merge: (Widen(existing_val, V), existing_val) -> Widen (existing_val, V)
377 : and thus get a fixed point. */
378 278098 : if (const widening_svalue *widen_sval = dyn_cast_widening_svalue ())
379 : {
380 8037 : if (other == widen_sval->get_base_svalue ())
381 : return this;
382 1707 : if (other == widen_sval->get_iter_svalue ())
383 : return this;
384 : }
385 :
386 270857 : if (const binop_svalue *binop_sval = dyn_cast_binop_svalue ())
387 10586 : if (const widening_svalue *widen_arg0
388 10586 : = binop_sval->get_arg0 ()->dyn_cast_widening_svalue ())
389 : {
390 3305 : if (other == binop_sval->get_arg1 ())
391 : {
392 : /* Merger of: (Widen(..., OTHER) BINOP X)
393 : and : OTHER
394 : to : (Widen(..., OTHER) BINOP X)
395 : e.g. merge of Widen(0, 1) + 1 with 1 to the Widen(0, 1) + 1. */
396 : return this;
397 : }
398 :
399 : /* Merger of : (Widen() BINOP X)
400 : and : Widen()
401 : to : Widen()
402 : e.g. merge of Widen(0, 1) + 1 and Widen(0, 1) to Widen(0, 1).
403 : However, we want to update constraints for this case, since we're
404 : considering another iteration.
405 : Presumably we also want to ensure that it converges; we don't want
406 : a descending chain of constraints. */
407 2445 : if (other == widen_arg0)
408 : {
409 843 : merger->on_widening_reuse (widen_arg0);
410 843 : return widen_arg0;
411 : }
412 :
413 : /* Merger of:
414 : this: BINOP(WIDENING(BASE, BINOP(BASE, X)), X)
415 : other: BINOP(BASE, X)
416 : to: WIDENING(BASE, BINOP(BASE, X)). */
417 1602 : if (widen_arg0->get_iter_svalue () == other)
418 1424 : if (const binop_svalue *other_binop_sval
419 712 : = other->dyn_cast_binop_svalue ())
420 528 : if (other_binop_sval->get_arg0 () == widen_arg0->get_base_svalue ()
421 528 : && other_binop_sval->get_arg1 () == binop_sval->get_arg1 ())
422 : return widen_arg0;
423 : }
424 :
425 268626 : return mgr->get_or_create_unknown_svalue (get_type ());
426 : }
427 :
428 : /* Determine if this svalue is either within LIVE_SVALUES, or is implicitly
429 : live with respect to LIVE_SVALUES and MODEL.
430 : LIVE_SVALUES can be nullptr, in which case determine if this svalue is
431 : intrinsically live. */
432 :
433 : bool
434 11201908 : svalue::live_p (const svalue_set *live_svalues,
435 : const region_model *model) const
436 : {
437 : /* Determine if SVAL is explicitly live. */
438 11201908 : if (live_svalues)
439 11200058 : if (const_cast<svalue_set *> (live_svalues)->contains (this))
440 : return true;
441 :
442 : /* Otherwise, determine if SVAL is implicitly live due to being made of
443 : other live svalues. */
444 4798975 : return implicitly_live_p (live_svalues, model);
445 : }
446 :
447 : /* Base implementation of svalue::implicitly_live_p. */
448 :
449 : bool
450 191918 : svalue::implicitly_live_p (const svalue_set *, const region_model *) const
451 : {
452 191918 : return false;
453 : }
454 :
455 : /* Comparator for imposing a deterministic order on constants that are
456 : of the same type. */
457 :
458 : static int
459 1540526 : cmp_csts_same_type (const_tree cst1, const_tree cst2)
460 : {
461 1540526 : gcc_assert (TREE_TYPE (cst1) == TREE_TYPE (cst2));
462 1540526 : gcc_assert (TREE_CODE (cst1) == TREE_CODE (cst2));
463 1540526 : switch (TREE_CODE (cst1))
464 : {
465 0 : default:
466 0 : gcc_unreachable ();
467 1540246 : case INTEGER_CST:
468 1540246 : return tree_int_cst_compare (cst1, cst2);
469 0 : case STRING_CST:
470 0 : if (TREE_STRING_LENGTH (cst1) < TREE_STRING_LENGTH (cst2))
471 : return -1;
472 0 : if (TREE_STRING_LENGTH (cst1) > TREE_STRING_LENGTH (cst2))
473 : return 1;
474 0 : return memcmp (TREE_STRING_POINTER (cst1),
475 0 : TREE_STRING_POINTER (cst2),
476 0 : TREE_STRING_LENGTH (cst1));
477 28 : case RAW_DATA_CST:
478 28 : if (RAW_DATA_LENGTH (cst1) < RAW_DATA_LENGTH (cst2))
479 : return -1;
480 28 : if (RAW_DATA_LENGTH (cst1) > RAW_DATA_LENGTH (cst2))
481 : return 1;
482 28 : return memcmp (RAW_DATA_POINTER (cst1),
483 28 : RAW_DATA_POINTER (cst2),
484 28 : RAW_DATA_LENGTH (cst1));
485 188 : case REAL_CST:
486 : /* Impose an arbitrary but deterministic order. */
487 188 : return memcmp (TREE_REAL_CST_PTR (cst1),
488 188 : TREE_REAL_CST_PTR (cst2),
489 188 : sizeof (real_value));
490 64 : case COMPLEX_CST:
491 64 : if (int cmp_real = cmp_csts_and_types (TREE_REALPART (cst1),
492 64 : TREE_REALPART (cst2)))
493 : return cmp_real;
494 24 : return cmp_csts_and_types (TREE_IMAGPART (cst1), TREE_IMAGPART (cst2));
495 0 : case VECTOR_CST:
496 0 : if (int cmp_log2_npatterns
497 0 : = ((int)VECTOR_CST_LOG2_NPATTERNS (cst1)
498 0 : - (int)VECTOR_CST_LOG2_NPATTERNS (cst2)))
499 : return cmp_log2_npatterns;
500 0 : if (int cmp_nelts_per_pattern
501 0 : = ((int)VECTOR_CST_NELTS_PER_PATTERN (cst1)
502 0 : - (int)VECTOR_CST_NELTS_PER_PATTERN (cst2)))
503 : return cmp_nelts_per_pattern;
504 0 : unsigned encoded_nelts = vector_cst_encoded_nelts (cst1);
505 0 : for (unsigned i = 0; i < encoded_nelts; i++)
506 : {
507 0 : const_tree elt1 = VECTOR_CST_ENCODED_ELT (cst1, i);
508 0 : const_tree elt2 = VECTOR_CST_ENCODED_ELT (cst2, i);
509 0 : if (int el_cmp = cmp_csts_and_types (elt1, elt2))
510 : return el_cmp;
511 : }
512 : return 0;
513 : }
514 : }
515 :
516 : /* Comparator for imposing a deterministic order on constants that might
517 : not be of the same type. */
518 :
519 : static int
520 1540546 : cmp_csts_and_types (const_tree cst1, const_tree cst2)
521 : {
522 1540546 : int t1 = TYPE_UID (TREE_TYPE (cst1));
523 1540546 : int t2 = TYPE_UID (TREE_TYPE (cst2));
524 1540546 : if (int cmp_type = t1 - t2)
525 : return cmp_type;
526 1540526 : return cmp_csts_same_type (cst1, cst2);
527 : }
528 :
529 : /* Comparator for imposing a deterministic order on svalues. */
530 :
531 : int
532 44701166 : svalue::cmp_ptr (const svalue *sval1, const svalue *sval2)
533 : {
534 46132995 : if (sval1 == sval2)
535 : return 0;
536 44378824 : if (int cmp_kind = sval1->get_kind () - sval2->get_kind ())
537 : return cmp_kind;
538 16716835 : int t1 = sval1->get_type () ? TYPE_UID (sval1->get_type ()) : -1;
539 16716835 : int t2 = sval2->get_type () ? TYPE_UID (sval2->get_type ()) : -1;
540 16716835 : if (int cmp_type = t1 - t2)
541 : return cmp_type;
542 10554278 : switch (sval1->get_kind ())
543 : {
544 0 : default:
545 0 : gcc_unreachable ();
546 773084 : case SK_REGION:
547 773084 : {
548 773084 : const region_svalue *region_sval1 = (const region_svalue *)sval1;
549 773084 : const region_svalue *region_sval2 = (const region_svalue *)sval2;
550 773084 : return region::cmp_ids (region_sval1->get_pointee (),
551 1546168 : region_sval2->get_pointee ());
552 : }
553 1540458 : break;
554 1540458 : case SK_CONSTANT:
555 1540458 : {
556 1540458 : const constant_svalue *constant_sval1 = (const constant_svalue *)sval1;
557 1540458 : const constant_svalue *constant_sval2 = (const constant_svalue *)sval2;
558 1540458 : const_tree cst1 = constant_sval1->get_constant ();
559 1540458 : const_tree cst2 = constant_sval2->get_constant ();
560 : /* The svalues have the same type, but the underlying trees
561 : might not (for the case where both svalues are typeless). */
562 1540458 : return cmp_csts_and_types (cst1, cst2);
563 : }
564 0 : break;
565 0 : case SK_UNKNOWN:
566 0 : {
567 0 : gcc_assert (sval1 == sval2);
568 : return 0;
569 : }
570 0 : break;
571 0 : case SK_POISONED:
572 0 : {
573 0 : const poisoned_svalue *poisoned_sval1 = (const poisoned_svalue *)sval1;
574 0 : const poisoned_svalue *poisoned_sval2 = (const poisoned_svalue *)sval2;
575 0 : return (static_cast<int> (poisoned_sval1->get_poison_kind ())
576 0 : - static_cast<int> (poisoned_sval2->get_poison_kind ()));
577 : }
578 0 : break;
579 0 : case SK_SETJMP:
580 0 : {
581 0 : const setjmp_svalue *setjmp_sval1 = (const setjmp_svalue *)sval1;
582 0 : const setjmp_svalue *setjmp_sval2 = (const setjmp_svalue *)sval2;
583 0 : const setjmp_record &rec1 = setjmp_sval1->get_setjmp_record ();
584 0 : const setjmp_record &rec2 = setjmp_sval2->get_setjmp_record ();
585 0 : return setjmp_record::cmp (rec1, rec2);
586 : }
587 2082684 : break;
588 2082684 : case SK_INITIAL:
589 2082684 : {
590 2082684 : const initial_svalue *initial_sval1 = (const initial_svalue *)sval1;
591 2082684 : const initial_svalue *initial_sval2 = (const initial_svalue *)sval2;
592 2082684 : return region::cmp_ids (initial_sval1->get_region (),
593 4165368 : initial_sval2->get_region ());
594 : }
595 743022 : break;
596 743022 : case SK_UNARYOP:
597 743022 : {
598 743022 : const unaryop_svalue *unaryop_sval1 = (const unaryop_svalue *)sval1;
599 743022 : const unaryop_svalue *unaryop_sval2 = (const unaryop_svalue *)sval2;
600 743022 : if (int op_cmp = unaryop_sval1->get_op () - unaryop_sval2->get_op ())
601 : return op_cmp;
602 742982 : return svalue::cmp_ptr (unaryop_sval1->get_arg (),
603 742982 : unaryop_sval2->get_arg ());
604 : }
605 1825702 : break;
606 1825702 : case SK_BINOP:
607 1825702 : {
608 1825702 : const binop_svalue *binop_sval1 = (const binop_svalue *)sval1;
609 1825702 : const binop_svalue *binop_sval2 = (const binop_svalue *)sval2;
610 1825702 : if (int op_cmp = binop_sval1->get_op () - binop_sval2->get_op ())
611 : return op_cmp;
612 1801927 : if (int arg0_cmp = svalue::cmp_ptr (binop_sval1->get_arg0 (),
613 : binop_sval2->get_arg0 ()))
614 : return arg0_cmp;
615 688524 : return svalue::cmp_ptr (binop_sval1->get_arg1 (),
616 688524 : binop_sval2->get_arg1 ());
617 : }
618 403654 : break;
619 403654 : case SK_SUB:
620 403654 : {
621 403654 : const sub_svalue *sub_sval1 = (const sub_svalue *)sval1;
622 403654 : const sub_svalue *sub_sval2 = (const sub_svalue *)sval2;
623 403654 : if (int parent_cmp = svalue::cmp_ptr (sub_sval1->get_parent (),
624 : sub_sval2->get_parent ()))
625 : return parent_cmp;
626 403650 : return region::cmp_ids (sub_sval1->get_subregion (),
627 807300 : sub_sval2->get_subregion ());
628 : }
629 299 : break;
630 299 : case SK_REPEATED:
631 299 : {
632 299 : const repeated_svalue *repeated_sval1 = (const repeated_svalue *)sval1;
633 299 : const repeated_svalue *repeated_sval2 = (const repeated_svalue *)sval2;
634 299 : return svalue::cmp_ptr (repeated_sval1->get_inner_svalue (),
635 299 : repeated_sval2->get_inner_svalue ());
636 : }
637 373 : break;
638 373 : case SK_BITS_WITHIN:
639 373 : {
640 373 : const bits_within_svalue *bits_within_sval1
641 : = (const bits_within_svalue *)sval1;
642 373 : const bits_within_svalue *bits_within_sval2
643 : = (const bits_within_svalue *)sval2;
644 373 : if (int cmp = bit_range::cmp (bits_within_sval1->get_bits (),
645 : bits_within_sval2->get_bits ()))
646 : return cmp;
647 0 : return svalue::cmp_ptr (bits_within_sval1->get_inner_svalue (),
648 0 : bits_within_sval2->get_inner_svalue ());
649 : }
650 0 : break;
651 0 : case SK_UNMERGEABLE:
652 0 : {
653 0 : const unmergeable_svalue *unmergeable_sval1
654 : = (const unmergeable_svalue *)sval1;
655 0 : const unmergeable_svalue *unmergeable_sval2
656 : = (const unmergeable_svalue *)sval2;
657 0 : return svalue::cmp_ptr (unmergeable_sval1->get_arg (),
658 0 : unmergeable_sval2->get_arg ());
659 : }
660 0 : break;
661 0 : case SK_PLACEHOLDER:
662 0 : {
663 0 : const placeholder_svalue *placeholder_sval1
664 : = (const placeholder_svalue *)sval1;
665 0 : const placeholder_svalue *placeholder_sval2
666 : = (const placeholder_svalue *)sval2;
667 0 : return strcmp (placeholder_sval1->get_name (),
668 0 : placeholder_sval2->get_name ());
669 : }
670 1713 : break;
671 1713 : case SK_WIDENING:
672 1713 : {
673 1713 : const widening_svalue *widening_sval1 = (const widening_svalue *)sval1;
674 1713 : const widening_svalue *widening_sval2 = (const widening_svalue *)sval2;
675 1713 : if (int index_cmp = (widening_sval1->get_snode ()->m_id
676 1713 : - widening_sval2->get_snode ()->m_id))
677 : return index_cmp;
678 1487 : if (int base_cmp = svalue::cmp_ptr (widening_sval1->get_base_svalue (),
679 : widening_sval2->get_base_svalue ()))
680 : return base_cmp;
681 24 : return svalue::cmp_ptr (widening_sval1->get_iter_svalue (),
682 24 : widening_sval2->get_iter_svalue ());
683 : }
684 28 : break;
685 28 : case SK_COMPOUND:
686 28 : {
687 28 : const compound_svalue *compound_sval1 = (const compound_svalue *)sval1;
688 28 : const compound_svalue *compound_sval2 = (const compound_svalue *)sval2;
689 28 : return concrete_binding_map::cmp
690 28 : (compound_sval1->get_concrete_bindings (),
691 28 : compound_sval2->get_concrete_bindings ());
692 : }
693 3183157 : break;
694 3183157 : case SK_CONJURED:
695 3183157 : {
696 3183157 : const conjured_svalue *conjured_sval1 = (const conjured_svalue *)sval1;
697 3183157 : const conjured_svalue *conjured_sval2 = (const conjured_svalue *)sval2;
698 3183157 : if (int stmt_cmp = (conjured_sval1->get_stmt ()->uid
699 3183157 : - conjured_sval2->get_stmt ()->uid))
700 : return stmt_cmp;
701 37158 : return region::cmp_ids (conjured_sval1->get_id_region (),
702 74316 : conjured_sval2->get_id_region ());
703 : }
704 24 : break;
705 24 : case SK_ASM_OUTPUT:
706 24 : {
707 24 : const asm_output_svalue *asm_output_sval1
708 : = (const asm_output_svalue *)sval1;
709 24 : const asm_output_svalue *asm_output_sval2
710 : = (const asm_output_svalue *)sval2;
711 24 : if (int asm_string_cmp = strcmp (asm_output_sval1->get_asm_string (),
712 : asm_output_sval2->get_asm_string ()))
713 : return asm_string_cmp;
714 24 : if (int output_idx_cmp = ((int)asm_output_sval1->get_output_idx ()
715 24 : - (int)asm_output_sval2->get_output_idx ()))
716 : return output_idx_cmp;
717 24 : if (int cmp = ((int)asm_output_sval1->get_num_inputs ()
718 24 : - (int)asm_output_sval2->get_num_inputs ()))
719 : return cmp;
720 24 : for (unsigned i = 0; i < asm_output_sval1->get_num_inputs (); i++)
721 24 : if (int input_cmp
722 24 : = svalue::cmp_ptr (asm_output_sval1->get_input (i),
723 : asm_output_sval2->get_input (i)))
724 : return input_cmp;
725 : return 0;
726 : }
727 80 : break;
728 80 : case SK_CONST_FN_RESULT:
729 80 : {
730 80 : const const_fn_result_svalue *const_fn_result_sval1
731 : = (const const_fn_result_svalue *)sval1;
732 80 : const const_fn_result_svalue *const_fn_result_sval2
733 : = (const const_fn_result_svalue *)sval2;
734 80 : int d1 = DECL_UID (const_fn_result_sval1->get_fndecl ());
735 80 : int d2 = DECL_UID (const_fn_result_sval2->get_fndecl ());
736 80 : if (int cmp_fndecl = d1 - d2)
737 : return cmp_fndecl;
738 64 : if (int cmp = ((int)const_fn_result_sval1->get_num_inputs ()
739 64 : - (int)const_fn_result_sval2->get_num_inputs ()))
740 : return cmp;
741 48 : for (unsigned i = 0; i < const_fn_result_sval1->get_num_inputs (); i++)
742 48 : if (int input_cmp
743 48 : = svalue::cmp_ptr (const_fn_result_sval1->get_input (i),
744 : const_fn_result_sval2->get_input (i)))
745 : return input_cmp;
746 : return 0;
747 : }
748 : }
749 : }
750 :
751 : /* Comparator for use by vec<const svalue *>::qsort. */
752 :
753 : int
754 7766728 : svalue::cmp_ptr_ptr (const void *p1, const void *p2)
755 : {
756 7766728 : const svalue *sval1 = *(const svalue * const *)p1;
757 7766728 : const svalue *sval2 = *(const svalue * const *)p2;
758 7766728 : return cmp_ptr (sval1, sval2);
759 : }
760 :
761 : /* Subclass of visitor for use in implementing svalue::involves_p. */
762 :
763 : class involvement_visitor : public visitor
764 : {
765 : public:
766 650105 : involvement_visitor (const svalue *needle)
767 650105 : : m_needle (needle), m_found (false) {}
768 :
769 295943 : void visit_initial_svalue (const initial_svalue *candidate) final override
770 : {
771 295943 : if (candidate == m_needle)
772 60 : m_found = true;
773 295943 : }
774 :
775 292303 : void visit_conjured_svalue (const conjured_svalue *candidate) final override
776 : {
777 292303 : if (candidate == m_needle)
778 6516 : m_found = true;
779 292303 : }
780 :
781 5107 : void visit_widening_svalue (const widening_svalue *candidate) final override
782 : {
783 5107 : if (candidate == m_needle)
784 172 : m_found = true;
785 5107 : }
786 :
787 650105 : bool found_p () const { return m_found; }
788 :
789 : private:
790 : const svalue *m_needle;
791 : bool m_found;
792 : };
793 :
794 : /* Return true iff this svalue is defined in terms of OTHER. */
795 :
796 : bool
797 650105 : svalue::involves_p (const svalue *other) const
798 : {
799 : /* Currently only implemented for these kinds. */
800 650105 : gcc_assert (other->get_kind () == SK_INITIAL
801 : || other->get_kind () == SK_CONJURED
802 : || other->get_kind () == SK_WIDENING);
803 :
804 650105 : involvement_visitor v (other);
805 650105 : accept (&v);
806 650105 : return v.found_p ();
807 : }
808 :
809 : /* Extract SUBRANGE from this value, of type TYPE. */
810 :
811 : const svalue *
812 19763 : svalue::extract_bit_range (tree type,
813 : const bit_range &subrange,
814 : region_model_manager *mgr) const
815 : {
816 19763 : return mgr->get_or_create_bits_within (type, subrange, this);
817 : }
818 :
819 : /* Base implementation of svalue::maybe_fold_bits_within vfunc. */
820 :
821 : const svalue *
822 1713 : svalue::maybe_fold_bits_within (tree,
823 : const bit_range &,
824 : region_model_manager *) const
825 : {
826 : /* By default, don't fold. */
827 1713 : return nullptr;
828 : }
829 :
830 : /* Base implementation of svalue::all_zeroes_p.
831 : Return true if this value is known to be all zeroes. */
832 :
833 : bool
834 142930 : svalue::all_zeroes_p () const
835 : {
836 142930 : return false;
837 : }
838 :
839 : /* If this svalue is a pointer, attempt to determine the base region it points
840 : to. Return nullptr on any problems. */
841 :
842 : const region *
843 20686 : svalue::maybe_get_deref_base_region () const
844 : {
845 20686 : const svalue *iter = this;
846 21238 : while (1)
847 : {
848 20962 : switch (iter->get_kind ())
849 : {
850 : default:
851 : return nullptr;
852 :
853 9053 : case SK_REGION:
854 9053 : {
855 9053 : const region_svalue *region_sval
856 9053 : = as_a <const region_svalue *> (iter);
857 9053 : return region_sval->get_pointee ()->get_base_region ();
858 : }
859 :
860 442 : case SK_BINOP:
861 442 : {
862 442 : const binop_svalue *binop_sval
863 442 : = as_a <const binop_svalue *> (iter);
864 442 : switch (binop_sval->get_op ())
865 : {
866 276 : case POINTER_PLUS_EXPR:
867 : /* If we have a symbolic value expressing pointer arithmetic,
868 : use the LHS. */
869 276 : iter = binop_sval->get_arg0 ();
870 276 : continue;
871 :
872 : default:
873 : return nullptr;
874 : }
875 : return nullptr;
876 : }
877 : }
878 276 : }
879 : }
880 :
881 : /* If this svalue is a pointer to the typeinfo instance for a particular
882 : type, return that type. Otherwise return NULL_TREE. */
883 :
884 : tree
885 659 : svalue::maybe_get_type_from_typeinfo () const
886 : {
887 659 : if (const region *reg = maybe_get_region ())
888 494 : if (const decl_region *decl_reg = reg->dyn_cast_decl_region ())
889 494 : return TREE_TYPE (DECL_NAME (decl_reg->get_decl ()));
890 :
891 : return NULL_TREE;
892 : }
893 :
894 : /* Return true if we can get a value_range for TYPE (which could be
895 : NULL_TREE); false otherwise. */
896 :
897 : static bool
898 197160 : type_can_have_value_range_p (tree type)
899 : {
900 197160 : if (!type)
901 : return false;
902 196868 : if (irange::supports_p (type))
903 : return true;
904 37297 : if (frange::supports_p (type))
905 : return true;
906 : return false;
907 : }
908 :
909 : /* Base implementation of svalue::maybe_get_value_range_1 vfunc.
910 : If there is a suitable underlying type, write a "varying" for it to OUT
911 : (for "any value of that type") and return true; otherwise return false. */
912 :
913 : bool
914 99183 : svalue::maybe_get_value_range_1 (value_range &out) const
915 : {
916 99183 : tree type = get_type ();
917 99183 : if (!type_can_have_value_range_p (type))
918 : return false;
919 :
920 63799 : out.set_varying (type);
921 63799 : return true;
922 : }
923 :
924 : /* class region_svalue : public svalue. */
925 :
926 : /* Implementation of svalue::dump_to_pp vfunc for region_svalue. */
927 :
928 : void
929 10017 : region_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
930 : {
931 10017 : if (simple)
932 : {
933 9398 : pp_string (pp, "&");
934 9398 : m_reg->dump_to_pp (pp, simple);
935 : }
936 : else
937 : {
938 619 : pp_string (pp, "region_svalue(");
939 619 : if (get_type ())
940 : {
941 619 : print_quoted_type (pp, get_type ());
942 619 : pp_string (pp, ", ");
943 : }
944 619 : m_reg->dump_to_pp (pp, simple);
945 619 : pp_string (pp, ")");
946 : }
947 10017 : }
948 :
949 : /* Implementation of svalue::print_dump_widget_label vfunc for
950 : region_svalue. */
951 :
952 : void
953 0 : region_svalue::print_dump_widget_label (pretty_printer *pp) const
954 : {
955 0 : pp_printf (pp, "region_svalue: %qs", "&");
956 0 : }
957 :
958 : /* Implementation of svalue::add_dump_widget_children vfunc for
959 : region_svalue. */
960 :
961 : void
962 0 : region_svalue::
963 : add_dump_widget_children (text_art::tree_widget &w,
964 : const text_art::dump_widget_info &dwi) const
965 : {
966 0 : w.add_child (m_reg->make_dump_widget (dwi));
967 0 : }
968 :
969 : /* Implementation of svalue::accept vfunc for region_svalue. */
970 :
971 : void
972 823305 : region_svalue::accept (visitor *v) const
973 : {
974 823305 : m_reg->accept (v);
975 823305 : v->visit_region_svalue (this);
976 823305 : }
977 :
978 : /* Implementation of svalue::implicitly_live_p vfunc for region_svalue. */
979 :
980 : bool
981 268242 : region_svalue::implicitly_live_p (const svalue_set *,
982 : const region_model *model) const
983 : {
984 : /* Pointers into clusters that have escaped should be treated as live. */
985 268242 : const region *base_reg = get_pointee ()->get_base_region ();
986 268242 : const store *store = model->get_store ();
987 268242 : if (const binding_cluster *c = store->get_cluster (base_reg))
988 247421 : if (c->escaped_p ())
989 : return true;
990 :
991 : return false;
992 : }
993 :
994 : /* Evaluate the condition LHS OP RHS.
995 : Subroutine of region_model::eval_condition for when we have a pair of
996 : pointers. */
997 :
998 : tristate
999 910 : region_svalue::eval_condition (const region_svalue *lhs,
1000 : enum tree_code op,
1001 : const region_svalue *rhs,
1002 : const region_model &model)
1003 : {
1004 : /* Convert to region_offset representation, and work with that. */
1005 910 : const region *lhs_reg = lhs->get_pointee ();
1006 910 : const region *rhs_reg = rhs->get_pointee ();
1007 :
1008 910 : region_model_manager *mgr = model.get_manager ();
1009 910 : region_offset lhs_offset = lhs_reg->get_offset (mgr);
1010 910 : region_offset rhs_offset = rhs_reg->get_offset (mgr);
1011 :
1012 910 : return eval_region_offset_comparison (lhs_offset, op, rhs_offset, model);
1013 : }
1014 :
1015 : /* class constant_svalue : public svalue. */
1016 :
1017 : /* Implementation of svalue::dump_to_pp vfunc for constant_svalue. */
1018 :
1019 : void
1020 16558 : constant_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
1021 : {
1022 16558 : if (simple)
1023 : {
1024 15909 : pp_string (pp, "(");
1025 15909 : dump_tree (pp, get_type ());
1026 15909 : pp_string (pp, ")");
1027 15909 : dump_tree (pp, m_cst_expr);
1028 : }
1029 : else
1030 : {
1031 649 : pp_string (pp, "constant_svalue(");
1032 649 : if (get_type ())
1033 : {
1034 649 : print_quoted_type (pp, get_type ());
1035 649 : pp_string (pp, ", ");
1036 : }
1037 649 : dump_tree (pp, m_cst_expr);
1038 649 : pp_string (pp, ")");
1039 : }
1040 16558 : }
1041 :
1042 : /* Implementation of svalue::print_dump_widget_label vfunc for
1043 : constant_svalue. */
1044 :
1045 : void
1046 0 : constant_svalue::print_dump_widget_label (pretty_printer *pp) const
1047 : {
1048 0 : pp_printf (pp, "constant_svalue (%qE)", m_cst_expr);
1049 0 : }
1050 :
1051 : /* Implementation of svalue::add_dump_widget_children vfunc for
1052 : constant_svalue. */
1053 :
1054 : void
1055 0 : constant_svalue::
1056 : add_dump_widget_children (text_art::tree_widget &,
1057 : const text_art::dump_widget_info &) const
1058 : {
1059 : /* No children. */
1060 0 : }
1061 :
1062 : /* Implementation of svalue::accept vfunc for constant_svalue. */
1063 :
1064 : void
1065 9357889 : constant_svalue::accept (visitor *v) const
1066 : {
1067 9357889 : v->visit_constant_svalue (this);
1068 9357889 : }
1069 :
1070 : /* Implementation of svalue::implicitly_live_p vfunc for constant_svalue.
1071 : Constants are implicitly live. */
1072 :
1073 : bool
1074 679022 : constant_svalue::implicitly_live_p (const svalue_set *,
1075 : const region_model *) const
1076 : {
1077 679022 : return true;
1078 : }
1079 :
1080 : /* Given EXPR, a non-NULL expression of boolean type, convert to
1081 : a tristate based on whether this is known to be true, false,
1082 : or is not known. */
1083 :
1084 : static tristate
1085 15540 : tristate_from_boolean_tree_node (tree expr)
1086 : {
1087 15540 : gcc_assert (TREE_TYPE (expr) == boolean_type_node);
1088 :
1089 15540 : if (expr == boolean_true_node)
1090 11383 : return tristate (tristate::TS_TRUE);
1091 4157 : else if (expr == boolean_false_node)
1092 4157 : return tristate (tristate::TS_FALSE);
1093 : else
1094 0 : return tristate (tristate::TS_UNKNOWN);
1095 : }
1096 :
1097 : /* Evaluate the condition LHS OP RHS.
1098 : Subroutine of region_model::eval_condition for when we have a pair of
1099 : constants. */
1100 :
1101 : tristate
1102 16095 : constant_svalue::eval_condition (const constant_svalue *lhs,
1103 : enum tree_code op,
1104 : const constant_svalue *rhs)
1105 : {
1106 16095 : tree lhs_const = lhs->get_constant ();
1107 16095 : tree rhs_const = rhs->get_constant ();
1108 :
1109 16095 : gcc_assert (CONSTANT_CLASS_P (lhs_const));
1110 16095 : gcc_assert (CONSTANT_CLASS_P (rhs_const));
1111 :
1112 16095 : if ((lhs->get_type () == NULL_TREE || rhs->get_type () == NULL_TREE)
1113 366 : && TREE_CODE (lhs_const) == INTEGER_CST
1114 16461 : && TREE_CODE (rhs_const) == INTEGER_CST
1115 : )
1116 : {
1117 366 : if (tree tree_cmp = const_binop (op, boolean_type_node,
1118 : lhs_const, rhs_const))
1119 : {
1120 366 : tristate ts = tristate_from_boolean_tree_node (tree_cmp);
1121 366 : if (ts.is_known ())
1122 366 : return ts;
1123 : }
1124 : }
1125 :
1126 : /* Check for comparable types. */
1127 15729 : if (types_compatible_p (TREE_TYPE (lhs_const), TREE_TYPE (rhs_const)))
1128 : {
1129 15174 : tree tree_cmp
1130 15174 : = fold_binary (op, boolean_type_node, lhs_const, rhs_const);
1131 15174 : tristate ts = tristate_from_boolean_tree_node (tree_cmp);
1132 15174 : if (ts.is_known ())
1133 15174 : return ts;
1134 : }
1135 555 : return tristate::TS_UNKNOWN;
1136 : }
1137 :
1138 : /* Implementation of svalue::maybe_fold_bits_within vfunc
1139 : for constant_svalue. */
1140 :
1141 : const svalue *
1142 442 : constant_svalue::maybe_fold_bits_within (tree type,
1143 : const bit_range &bits,
1144 : region_model_manager *mgr) const
1145 : {
1146 : /* Bits within an all-zero value are also all zero. */
1147 442 : if (zerop (m_cst_expr))
1148 : {
1149 93 : if (type)
1150 92 : return mgr->get_or_create_cast (type, this);
1151 : else
1152 1 : return this;
1153 : }
1154 :
1155 : /* Handle the case of extracting a single bit. */
1156 498 : if (bits.m_size_in_bits == 1
1157 204 : && TREE_CODE (m_cst_expr) == INTEGER_CST
1158 204 : && type
1159 204 : && INTEGRAL_TYPE_P (type)
1160 553 : && tree_fits_uhwi_p (m_cst_expr))
1161 : {
1162 200 : unsigned HOST_WIDE_INT bit = bits.m_start_bit_offset.to_uhwi ();
1163 200 : unsigned HOST_WIDE_INT mask = (1 << bit);
1164 200 : unsigned HOST_WIDE_INT val_as_hwi = tree_to_uhwi (m_cst_expr);
1165 200 : unsigned HOST_WIDE_INT masked_val = val_as_hwi & mask;
1166 200 : int result = masked_val ? 1 : 0;
1167 200 : return mgr->get_or_create_int_cst (type, result);
1168 : }
1169 :
1170 : /* Otherwise, don't fold. */
1171 : return nullptr;
1172 : }
1173 :
1174 : /* Implementation of svalue::all_zeroes_p for constant_svalue. */
1175 :
1176 : bool
1177 118890 : constant_svalue::all_zeroes_p () const
1178 : {
1179 118890 : return zerop (m_cst_expr);
1180 : }
1181 :
1182 :
1183 : /* Implementation of svalue::maybe_get_value_range_1 for constant_svalue.
1184 : If there is a suitable underlying type, write the value_range for the
1185 : single value of m_cst_expr to OUT and return true; otherwise return
1186 : false. */
1187 :
1188 : bool
1189 53488 : constant_svalue::maybe_get_value_range_1 (value_range &out) const
1190 : {
1191 53488 : if (!type_can_have_value_range_p (get_type ()))
1192 : return false;
1193 :
1194 53393 : out = value_range (m_cst_expr, m_cst_expr);
1195 53393 : return true;
1196 : }
1197 :
1198 : /* class unknown_svalue : public svalue. */
1199 :
1200 : /* Implementation of svalue::dump_to_pp vfunc for unknown_svalue. */
1201 :
1202 : void
1203 3670 : unknown_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
1204 : {
1205 3670 : if (simple)
1206 : {
1207 2943 : pp_string (pp, "UNKNOWN(");
1208 2943 : if (get_type ())
1209 2940 : dump_tree (pp, get_type ());
1210 2943 : pp_character (pp, ')');
1211 : }
1212 : else
1213 : {
1214 727 : pp_string (pp, "unknown_svalue(");
1215 727 : if (get_type ())
1216 727 : dump_tree (pp, get_type ());
1217 727 : pp_character (pp, ')');
1218 : }
1219 3670 : }
1220 :
1221 : /* Implementation of svalue::print_dump_widget_label vfunc for
1222 : unknown_svalue. */
1223 :
1224 : void
1225 0 : unknown_svalue::print_dump_widget_label (pretty_printer *pp) const
1226 : {
1227 0 : pp_printf (pp, "unknown_svalue");
1228 0 : }
1229 :
1230 : /* Implementation of svalue::add_dump_widget_children vfunc for
1231 : unknown_svalue. */
1232 :
1233 : void
1234 0 : unknown_svalue::
1235 : add_dump_widget_children (text_art::tree_widget &,
1236 : const text_art::dump_widget_info &) const
1237 : {
1238 : /* No children. */
1239 0 : }
1240 :
1241 : /* Implementation of svalue::accept vfunc for unknown_svalue. */
1242 :
1243 : void
1244 1932302 : unknown_svalue::accept (visitor *v) const
1245 : {
1246 1932302 : v->visit_unknown_svalue (this);
1247 1932302 : }
1248 :
1249 : /* Implementation of svalue::maybe_fold_bits_within vfunc
1250 : for unknown_svalue. */
1251 :
1252 : const svalue *
1253 7172 : unknown_svalue::maybe_fold_bits_within (tree type,
1254 : const bit_range &,
1255 : region_model_manager *mgr) const
1256 : {
1257 : /* Bits within an unknown_svalue are themselves unknown. */
1258 7172 : return mgr->get_or_create_unknown_svalue (type);
1259 : }
1260 :
1261 : bool
1262 17272 : unknown_svalue::maybe_get_value_range_1 (value_range &) const
1263 : {
1264 : /* Don't attempt to participate in range ops. */
1265 17272 : return false;
1266 : }
1267 :
1268 :
1269 : /* Get a string for KIND for use in debug dumps. */
1270 :
1271 : const char *
1272 12 : poison_kind_to_str (enum poison_kind kind)
1273 : {
1274 12 : switch (kind)
1275 : {
1276 0 : default:
1277 0 : gcc_unreachable ();
1278 : case poison_kind::uninit:
1279 : return "uninit";
1280 0 : case poison_kind::freed:
1281 0 : return "freed";
1282 0 : case poison_kind::deleted:
1283 0 : return "deleted";
1284 0 : case poison_kind::popped_stack:
1285 0 : return "popped stack";
1286 : }
1287 : }
1288 :
1289 : /* class poisoned_svalue : public svalue. */
1290 :
1291 : /* Implementation of svalue::dump_to_pp vfunc for poisoned_svalue. */
1292 :
1293 : void
1294 4 : poisoned_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
1295 : {
1296 4 : if (simple)
1297 : {
1298 4 : pp_string (pp, "POISONED(");
1299 4 : print_quoted_type (pp, get_type ());
1300 4 : pp_printf (pp, ", %s)", poison_kind_to_str (m_kind));
1301 : }
1302 : else
1303 : {
1304 0 : pp_string (pp, "poisoned_svalue(");
1305 0 : print_quoted_type (pp, get_type ());
1306 0 : pp_printf (pp, ", %s)", poison_kind_to_str (m_kind));
1307 : }
1308 4 : }
1309 :
1310 : /* Implementation of svalue::print_dump_widget_label vfunc for
1311 : poisoned_svalue. */
1312 :
1313 : void
1314 0 : poisoned_svalue::print_dump_widget_label (pretty_printer *pp) const
1315 : {
1316 0 : pp_printf (pp, "poisoned_svalue(%s)", poison_kind_to_str (m_kind));
1317 0 : }
1318 :
1319 : /* Implementation of svalue::add_dump_widget_children vfunc for
1320 : poisoned_svalue. */
1321 :
1322 : void
1323 0 : poisoned_svalue::
1324 : add_dump_widget_children (text_art::tree_widget &,
1325 : const text_art::dump_widget_info &) const
1326 : {
1327 : /* No children. */
1328 0 : }
1329 :
1330 : /* Implementation of svalue::accept vfunc for poisoned_svalue. */
1331 :
1332 : void
1333 22893 : poisoned_svalue::accept (visitor *v) const
1334 : {
1335 22893 : v->visit_poisoned_svalue (this);
1336 22893 : }
1337 :
1338 : /* Implementation of svalue::maybe_fold_bits_within vfunc
1339 : for poisoned_svalue. */
1340 :
1341 : const svalue *
1342 5893 : poisoned_svalue::maybe_fold_bits_within (tree type,
1343 : const bit_range &,
1344 : region_model_manager *mgr) const
1345 : {
1346 : /* Bits within a poisoned value are also poisoned. */
1347 5893 : return mgr->get_or_create_poisoned_svalue (m_kind, type);
1348 : }
1349 :
1350 : /* class setjmp_svalue's implementation is in setjmp-longjmp.cc. */
1351 :
1352 : /* class initial_svalue : public svalue. */
1353 :
1354 : /* Implementation of svalue::dump_to_pp vfunc for initial_svalue. */
1355 :
1356 : void
1357 12143 : initial_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
1358 : {
1359 12143 : if (simple)
1360 : {
1361 12007 : pp_string (pp, "INIT_VAL(");
1362 12007 : m_reg->dump_to_pp (pp, simple);
1363 12007 : pp_string (pp, ")");
1364 : }
1365 : else
1366 : {
1367 136 : pp_string (pp, "initial_svalue(");
1368 136 : if (get_type ())
1369 : {
1370 136 : print_quoted_type (pp, get_type ());
1371 136 : pp_string (pp, ", ");
1372 : }
1373 136 : m_reg->dump_to_pp (pp, simple);
1374 136 : pp_string (pp, ")");
1375 : }
1376 12143 : }
1377 :
1378 : /* Implementation of svalue::print_dump_widget_label vfunc for
1379 : initial_svalue. */
1380 :
1381 : void
1382 0 : initial_svalue::print_dump_widget_label (pretty_printer *pp) const
1383 : {
1384 0 : pp_printf (pp, "initial_svalue");
1385 0 : }
1386 :
1387 : /* Implementation of svalue::add_dump_widget_children vfunc for
1388 : initial_svalue. */
1389 :
1390 : void
1391 0 : initial_svalue::
1392 : add_dump_widget_children (text_art::tree_widget &w,
1393 : const text_art::dump_widget_info &dwi) const
1394 : {
1395 0 : w.add_child (m_reg->make_dump_widget (dwi, "m_reg"));
1396 0 : }
1397 :
1398 : /* Implementation of svalue::accept vfunc for initial_svalue. */
1399 :
1400 : void
1401 1671362 : initial_svalue::accept (visitor *v) const
1402 : {
1403 1671362 : m_reg->accept (v);
1404 1671362 : v->visit_initial_svalue (this);
1405 1671362 : }
1406 :
1407 : /* Implementation of svalue::implicitly_live_p vfunc for initial_svalue. */
1408 :
1409 : bool
1410 2716386 : initial_svalue::implicitly_live_p (const svalue_set *,
1411 : const region_model *model) const
1412 : {
1413 : /* This svalue may be implicitly live if the region still implicitly
1414 : has its initial value and is reachable. */
1415 :
1416 : /* It must be a region that exists; we don't want to consider
1417 : INIT_VAL(R) as still being implicitly reachable if R is in
1418 : a popped stack frame. */
1419 2716386 : if (model->region_exists_p (m_reg))
1420 : {
1421 2698529 : const svalue *reg_sval = model->get_store_value (m_reg, nullptr);
1422 2698529 : if (reg_sval == this)
1423 : return true;
1424 : }
1425 :
1426 : /* Assume that the initial values of params for the top level frame
1427 : are still live, because (presumably) they're still
1428 : live in the external caller. */
1429 152784 : if (initial_value_of_param_p ())
1430 16901 : if (const frame_region *frame_reg = m_reg->maybe_get_frame_region ())
1431 16901 : if (frame_reg->get_calling_frame () == nullptr)
1432 : return true;
1433 :
1434 : return false;
1435 : }
1436 :
1437 : /* Return true if this is the initial value of a function parameter. */
1438 :
1439 : bool
1440 156990 : initial_svalue::initial_value_of_param_p () const
1441 : {
1442 156990 : if (tree reg_decl = m_reg->maybe_get_decl ())
1443 89942 : if (TREE_CODE (reg_decl) == SSA_NAME)
1444 : {
1445 16990 : tree ssa_name = reg_decl;
1446 16990 : if (SSA_NAME_IS_DEFAULT_DEF (ssa_name)
1447 16990 : && SSA_NAME_VAR (ssa_name)
1448 33980 : && TREE_CODE (SSA_NAME_VAR (ssa_name)) == PARM_DECL)
1449 16973 : return true;
1450 : }
1451 : return false;
1452 : }
1453 :
1454 : /* class unaryop_svalue : public svalue. */
1455 :
1456 : /* Implementation of svalue::dump_to_pp vfunc for unaryop_svalue. */
1457 :
1458 : void
1459 4534 : unaryop_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
1460 : {
1461 4534 : if (simple)
1462 : {
1463 4368 : if (m_op == VIEW_CONVERT_EXPR || m_op == NOP_EXPR)
1464 : {
1465 4187 : pp_string (pp, "CAST(");
1466 4187 : dump_tree (pp, get_type ());
1467 4187 : pp_string (pp, ", ");
1468 4187 : m_arg->dump_to_pp (pp, simple);
1469 4187 : pp_character (pp, ')');
1470 : }
1471 : else
1472 : {
1473 181 : pp_character (pp, '(');
1474 181 : pp_string (pp, get_tree_code_name (m_op));
1475 : //pp_string (pp, op_symbol_code (m_op));
1476 181 : m_arg->dump_to_pp (pp, simple);
1477 181 : pp_character (pp, ')');
1478 : }
1479 : }
1480 : else
1481 : {
1482 166 : pp_string (pp, "unaryop_svalue (");
1483 166 : pp_string (pp, get_tree_code_name (m_op));
1484 166 : pp_string (pp, ", ");
1485 166 : m_arg->dump_to_pp (pp, simple);
1486 166 : pp_character (pp, ')');
1487 : }
1488 4534 : }
1489 :
1490 : /* Implementation of svalue::print_dump_widget_label vfunc for
1491 : unaryop_svalue. */
1492 :
1493 : void
1494 0 : unaryop_svalue::print_dump_widget_label (pretty_printer *pp) const
1495 : {
1496 0 : pp_printf (pp,
1497 : "unaryop_svalue(%s)",
1498 0 : get_tree_code_name (m_op));
1499 0 : }
1500 :
1501 : /* Implementation of svalue::add_dump_widget_children vfunc for
1502 : unaryop_svalue. */
1503 :
1504 : void
1505 0 : unaryop_svalue::
1506 : add_dump_widget_children (text_art::tree_widget &w,
1507 : const text_art::dump_widget_info &dwi) const
1508 : {
1509 0 : w.add_child (m_arg->make_dump_widget (dwi));
1510 0 : }
1511 :
1512 : /* Implementation of svalue::accept vfunc for unaryop_svalue. */
1513 :
1514 : void
1515 7057489 : unaryop_svalue::accept (visitor *v) const
1516 : {
1517 7057489 : m_arg->accept (v);
1518 7057489 : v->visit_unaryop_svalue (this);
1519 7057489 : }
1520 :
1521 : /* Implementation of svalue::implicitly_live_p vfunc for unaryop_svalue. */
1522 :
1523 : bool
1524 1050134 : unaryop_svalue::implicitly_live_p (const svalue_set *live_svalues,
1525 : const region_model *model) const
1526 : {
1527 1050134 : return get_arg ()->live_p (live_svalues, model);
1528 : }
1529 :
1530 : /* Implementation of svalue::maybe_fold_bits_within vfunc
1531 : for unaryop_svalue. */
1532 :
1533 : const svalue *
1534 3402 : unaryop_svalue::maybe_fold_bits_within (tree type,
1535 : const bit_range &,
1536 : region_model_manager *mgr) const
1537 : {
1538 3402 : switch (m_op)
1539 : {
1540 : default:
1541 : break;
1542 3402 : case NOP_EXPR:
1543 : /* A cast of zero is zero. */
1544 3402 : if (tree cst = m_arg->maybe_get_constant ())
1545 3402 : if (zerop (cst))
1546 : {
1547 3402 : if (type)
1548 140 : return mgr->get_or_create_cast (type, this);
1549 : else
1550 3262 : return this;
1551 : }
1552 : break;
1553 : }
1554 : /* Otherwise, don't fold. */
1555 : return nullptr;
1556 : }
1557 :
1558 : /* Implementation of svalue::maybe_get_value_range_1 for unaryop_svalue. */
1559 :
1560 : bool
1561 17363 : unaryop_svalue::maybe_get_value_range_1 (value_range &out) const
1562 : {
1563 17363 : tree type = get_type ();
1564 17363 : if (!type_can_have_value_range_p (type))
1565 : return false;
1566 :
1567 17094 : value_range arg_vr;
1568 17094 : if (m_arg->maybe_get_value_range (arg_vr))
1569 : {
1570 15432 : range_op_handler handler (m_op);
1571 15432 : if (handler
1572 30864 : && handler.operand_check_p (type, arg_vr.type (), type))
1573 : {
1574 : /* For unary ops, range_op_hander::fold_range expects
1575 : a VARYING of the unknown value as the 2nd operand. */
1576 15430 : value_range varying (type);
1577 15430 : varying.set_varying (type);
1578 15430 : out.set_range_class (type);
1579 15430 : if (handler.fold_range (out, type, arg_vr, varying))
1580 15430 : return true;
1581 15430 : }
1582 : }
1583 : return false;
1584 17094 : }
1585 :
1586 : /* class binop_svalue : public svalue. */
1587 :
1588 : /* Return whether OP be printed as an infix operator. */
1589 :
1590 : static bool
1591 10205 : infix_p (enum tree_code op)
1592 : {
1593 0 : switch (op)
1594 : {
1595 : default:
1596 : return true;
1597 0 : case MAX_EXPR:
1598 0 : case MIN_EXPR:
1599 0 : return false;
1600 : }
1601 : }
1602 :
1603 : /* Implementation of svalue::dump_to_pp vfunc for binop_svalue. */
1604 :
1605 : void
1606 10644 : binop_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
1607 : {
1608 10644 : if (simple)
1609 : {
1610 10205 : if (infix_p (m_op))
1611 : {
1612 : /* Print "(A OP B)". */
1613 10205 : pp_character (pp, '(');
1614 10205 : m_arg0->dump_to_pp (pp, simple);
1615 10205 : pp_string (pp, op_symbol_code (m_op));
1616 10205 : m_arg1->dump_to_pp (pp, simple);
1617 10205 : pp_character (pp, ')');
1618 : }
1619 : else
1620 : {
1621 : /* Print "OP(A, B)". */
1622 0 : pp_string (pp, op_symbol_code (m_op));
1623 0 : pp_character (pp, '(');
1624 0 : m_arg0->dump_to_pp (pp, simple);
1625 0 : pp_string (pp, ", ");
1626 0 : m_arg1->dump_to_pp (pp, simple);
1627 0 : pp_character (pp, ')');
1628 : }
1629 : }
1630 : else
1631 : {
1632 439 : pp_string (pp, "binop_svalue (");
1633 439 : pp_string (pp, get_tree_code_name (m_op));
1634 439 : pp_string (pp, ", ");
1635 439 : m_arg0->dump_to_pp (pp, simple);
1636 439 : pp_string (pp, ", ");
1637 439 : m_arg1->dump_to_pp (pp, simple);
1638 439 : pp_character (pp, ')');
1639 : }
1640 10644 : }
1641 :
1642 : /* Implementation of svalue::print_dump_widget_label vfunc for
1643 : binop_svalue. */
1644 :
1645 : void
1646 0 : binop_svalue::print_dump_widget_label (pretty_printer *pp) const
1647 : {
1648 0 : pp_printf (pp,
1649 : "binop_svalue(%s: %qs)",
1650 0 : get_tree_code_name (m_op),
1651 0 : op_symbol_code (m_op));
1652 0 : }
1653 :
1654 : /* Implementation of svalue::add_dump_widget_children vfunc for
1655 : binop_svalue. */
1656 :
1657 : void
1658 0 : binop_svalue::
1659 : add_dump_widget_children (text_art::tree_widget &w,
1660 : const text_art::dump_widget_info &dwi) const
1661 : {
1662 0 : w.add_child (m_arg0->make_dump_widget (dwi));
1663 0 : w.add_child (m_arg1->make_dump_widget (dwi));
1664 0 : }
1665 :
1666 : /* Implementation of svalue::accept vfunc for binop_svalue. */
1667 :
1668 : void
1669 6291369 : binop_svalue::accept (visitor *v) const
1670 : {
1671 6291369 : m_arg0->accept (v);
1672 6291369 : m_arg1->accept (v);
1673 6291369 : v->visit_binop_svalue (this);
1674 6291369 : }
1675 :
1676 : /* Implementation of svalue::implicitly_live_p vfunc for binop_svalue. */
1677 :
1678 : bool
1679 1123957 : binop_svalue::implicitly_live_p (const svalue_set *live_svalues,
1680 : const region_model *model) const
1681 : {
1682 1123957 : return (get_arg0 ()->live_p (live_svalues, model)
1683 1123957 : && get_arg1 ()->live_p (live_svalues, model));
1684 : }
1685 :
1686 : /* class sub_svalue : public svalue. */
1687 :
1688 : /* sub_svalue'c ctor. */
1689 :
1690 2368 : sub_svalue::sub_svalue (symbol::id_t id,
1691 : tree type, const svalue *parent_svalue,
1692 2368 : const region *subregion)
1693 : : svalue (complexity::from_pair (parent_svalue->get_complexity (),
1694 : subregion->get_complexity ()),
1695 : id,
1696 : type),
1697 2368 : m_parent_svalue (parent_svalue), m_subregion (subregion)
1698 : {
1699 2368 : gcc_assert (parent_svalue->can_have_associated_state_p ());
1700 2368 : }
1701 :
1702 : /* Implementation of svalue::maybe_get_value_range_1 for binop_svalue. */
1703 :
1704 : bool
1705 27126 : binop_svalue::maybe_get_value_range_1 (value_range &out) const
1706 : {
1707 27126 : tree type = get_type ();
1708 27126 : if (!type_can_have_value_range_p (type))
1709 : return false;
1710 :
1711 : /* Avoid cases where we have been sloppy about types. */
1712 25437 : if (!m_arg0->get_type ())
1713 : return false;
1714 25437 : if (!m_arg1->get_type ())
1715 : return false;
1716 25437 : if (!range_compatible_p (m_arg0->get_type (), m_arg1->get_type ()))
1717 : return false;
1718 :
1719 25259 : value_range lhs, rhs;
1720 25259 : if (m_arg0->maybe_get_value_range (lhs))
1721 22553 : if (m_arg1->maybe_get_value_range (rhs))
1722 : {
1723 22399 : range_op_handler handler (m_op);
1724 22399 : if (handler
1725 44798 : && handler.operand_check_p (type, lhs.type (), rhs.type ()))
1726 : {
1727 22399 : out.set_range_class (type);
1728 22399 : if (handler.fold_range (out, get_type (), lhs, rhs))
1729 22399 : return true;
1730 : }
1731 : }
1732 : return false;
1733 25259 : }
1734 :
1735 : /* Implementation of svalue::dump_to_pp vfunc for sub_svalue. */
1736 :
1737 : void
1738 1273 : sub_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
1739 : {
1740 1273 : if (simple)
1741 : {
1742 1222 : pp_string (pp, "SUB(");
1743 1222 : m_parent_svalue->dump_to_pp (pp, simple);
1744 1222 : pp_string (pp, ", ");
1745 1222 : m_subregion->dump_to_pp (pp, simple);
1746 1222 : pp_character (pp, ')');
1747 : }
1748 : else
1749 : {
1750 51 : pp_string (pp, "sub_svalue (");
1751 51 : pp_string (pp, ", ");
1752 51 : m_parent_svalue->dump_to_pp (pp, simple);
1753 51 : pp_string (pp, ", ");
1754 51 : m_subregion->dump_to_pp (pp, simple);
1755 51 : pp_character (pp, ')');
1756 : }
1757 1273 : }
1758 :
1759 : /* Implementation of svalue::print_dump_widget_label vfunc for
1760 : sub_svalue. */
1761 :
1762 : void
1763 0 : sub_svalue::print_dump_widget_label (pretty_printer *pp) const
1764 : {
1765 0 : pp_printf (pp, "sub_svalue");
1766 0 : }
1767 :
1768 : /* Implementation of svalue::add_dump_widget_children vfunc for
1769 : sub_svalue. */
1770 :
1771 : void
1772 0 : sub_svalue::
1773 : add_dump_widget_children (text_art::tree_widget &w,
1774 : const text_art::dump_widget_info &dwi) const
1775 : {
1776 0 : w.add_child (m_parent_svalue->make_dump_widget (dwi, "m_parent_svalue"));
1777 0 : w.add_child (m_subregion->make_dump_widget (dwi, "m_subregion"));
1778 0 : }
1779 :
1780 : /* Implementation of svalue::accept vfunc for sub_svalue. */
1781 :
1782 : void
1783 3944317 : sub_svalue::accept (visitor *v) const
1784 : {
1785 3944317 : m_parent_svalue->accept (v);
1786 3944317 : m_subregion->accept (v);
1787 3944317 : v->visit_sub_svalue (this);
1788 3944317 : }
1789 :
1790 : /* Implementation of svalue::implicitly_live_p vfunc for sub_svalue. */
1791 :
1792 : bool
1793 594129 : sub_svalue::implicitly_live_p (const svalue_set *live_svalues,
1794 : const region_model *model) const
1795 : {
1796 594129 : return get_parent ()->live_p (live_svalues, model);
1797 : }
1798 :
1799 : /* class repeated_svalue : public svalue. */
1800 :
1801 : /* repeated_svalue'c ctor. */
1802 :
1803 512 : repeated_svalue::repeated_svalue (symbol::id_t id,
1804 : tree type,
1805 : const svalue *outer_size,
1806 512 : const svalue *inner_svalue)
1807 512 : : svalue (complexity::from_pair (outer_size, inner_svalue), id, type),
1808 512 : m_outer_size (outer_size),
1809 1024 : m_inner_svalue (inner_svalue)
1810 : {
1811 512 : gcc_assert (outer_size->can_have_associated_state_p ());
1812 512 : gcc_assert (inner_svalue->can_have_associated_state_p ());
1813 512 : }
1814 :
1815 : /* Implementation of svalue::dump_to_pp vfunc for repeated_svalue. */
1816 :
1817 : void
1818 0 : repeated_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
1819 : {
1820 0 : if (simple)
1821 : {
1822 0 : pp_string (pp, "REPEATED(");
1823 0 : if (get_type ())
1824 : {
1825 0 : print_quoted_type (pp, get_type ());
1826 0 : pp_string (pp, ", ");
1827 : }
1828 0 : pp_string (pp, "outer_size: ");
1829 0 : m_outer_size->dump_to_pp (pp, simple);
1830 0 : pp_string (pp, ", inner_val: ");
1831 0 : m_inner_svalue->dump_to_pp (pp, simple);
1832 0 : pp_character (pp, ')');
1833 : }
1834 : else
1835 : {
1836 0 : pp_string (pp, "repeated_svalue (");
1837 0 : if (get_type ())
1838 : {
1839 0 : print_quoted_type (pp, get_type ());
1840 0 : pp_string (pp, ", ");
1841 : }
1842 0 : pp_string (pp, "outer_size: ");
1843 0 : m_outer_size->dump_to_pp (pp, simple);
1844 0 : pp_string (pp, ", inner_val: ");
1845 0 : m_inner_svalue->dump_to_pp (pp, simple);
1846 0 : pp_character (pp, ')');
1847 : }
1848 0 : }
1849 :
1850 : /* Implementation of svalue::print_dump_widget_label vfunc for
1851 : repeated_svalue. */
1852 :
1853 : void
1854 0 : repeated_svalue::print_dump_widget_label (pretty_printer *pp) const
1855 : {
1856 0 : pp_printf (pp, "repeated_svalue");
1857 0 : }
1858 :
1859 : /* Implementation of svalue::add_dump_widget_children vfunc for
1860 : repeated_svalue. */
1861 :
1862 : void
1863 0 : repeated_svalue::
1864 : add_dump_widget_children (text_art::tree_widget &w,
1865 : const text_art::dump_widget_info &dwi) const
1866 : {
1867 0 : w.add_child (m_outer_size->make_dump_widget (dwi, "m_outer_size"));
1868 0 : w.add_child (m_inner_svalue->make_dump_widget (dwi, "m_inner_svalue"));
1869 0 : }
1870 :
1871 : /* Implementation of svalue::accept vfunc for repeated_svalue. */
1872 :
1873 : void
1874 45091 : repeated_svalue::accept (visitor *v) const
1875 : {
1876 45091 : m_inner_svalue->accept (v);
1877 45091 : v->visit_repeated_svalue (this);
1878 45091 : }
1879 :
1880 : /* Implementation of svalue::all_zeroes_p for repeated_svalue. */
1881 :
1882 : bool
1883 1925 : repeated_svalue::all_zeroes_p () const
1884 : {
1885 1925 : return m_inner_svalue->all_zeroes_p ();
1886 : }
1887 :
1888 : /* Implementation of svalue::maybe_fold_bits_within vfunc
1889 : for repeated_svalue. */
1890 :
1891 : const svalue *
1892 1625 : repeated_svalue::maybe_fold_bits_within (tree type,
1893 : const bit_range &bits,
1894 : region_model_manager *mgr) const
1895 : {
1896 1625 : const svalue *innermost_sval = m_inner_svalue;
1897 : /* Fold
1898 : BITS_WITHIN (range, REPEATED_SVALUE (ZERO))
1899 : to:
1900 : REPEATED_SVALUE (ZERO). */
1901 1625 : if (all_zeroes_p ())
1902 : {
1903 1313 : byte_range bytes (0,0);
1904 1313 : if (bits.as_byte_range (&bytes))
1905 : {
1906 1313 : const svalue *byte_size
1907 1313 : = mgr->get_or_create_int_cst (size_type_node,
1908 1313 : bytes.m_size_in_bytes.to_uhwi ());
1909 1313 : return mgr->get_or_create_repeated_svalue (type, byte_size,
1910 1313 : innermost_sval);
1911 : }
1912 : }
1913 :
1914 : /* Fold:
1915 : BITS_WITHIN (range, REPEATED_SVALUE (INNERMOST_SVALUE))
1916 : to:
1917 : BITS_WITHIN (range - offset, INNERMOST_SVALUE)
1918 : if range is fully within one instance of INNERMOST_SVALUE. */
1919 312 : if (tree innermost_type = innermost_sval->get_type ())
1920 : {
1921 312 : bit_size_t element_bit_size;
1922 312 : if (int_size_in_bits (innermost_type, &element_bit_size)
1923 312 : && element_bit_size > 0)
1924 : {
1925 312 : HOST_WIDE_INT start_idx
1926 312 : = (bits.get_start_bit_offset ()
1927 312 : / element_bit_size).to_shwi ();
1928 312 : HOST_WIDE_INT last_idx
1929 312 : = (bits.get_last_bit_offset ()
1930 312 : / element_bit_size).to_shwi ();
1931 312 : if (start_idx == last_idx)
1932 : {
1933 288 : bit_offset_t start_of_element
1934 288 : = start_idx * element_bit_size;
1935 288 : bit_range range_within_element
1936 288 : (bits.m_start_bit_offset - start_of_element,
1937 288 : bits.m_size_in_bits);
1938 288 : return mgr->get_or_create_bits_within (type,
1939 : range_within_element,
1940 : innermost_sval);
1941 : }
1942 : }
1943 : }
1944 :
1945 : return nullptr;
1946 : }
1947 :
1948 : /* class bits_within_svalue : public svalue. */
1949 :
1950 : /* bits_within_svalue'c ctor. */
1951 :
1952 771 : bits_within_svalue::bits_within_svalue (symbol::id_t id,
1953 : tree type,
1954 : const bit_range &bits,
1955 771 : const svalue *inner_svalue)
1956 771 : : svalue (complexity (inner_svalue), id, type),
1957 771 : m_bits (bits),
1958 771 : m_inner_svalue (inner_svalue)
1959 : {
1960 771 : gcc_assert (inner_svalue->can_have_associated_state_p ());
1961 771 : }
1962 :
1963 : /* Implementation of svalue::dump_to_pp vfunc for bits_within_svalue. */
1964 :
1965 : void
1966 610 : bits_within_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
1967 : {
1968 610 : if (simple)
1969 : {
1970 504 : pp_string (pp, "BITS_WITHIN(");
1971 504 : if (get_type ())
1972 : {
1973 0 : print_quoted_type (pp, get_type ());
1974 0 : pp_string (pp, ", ");
1975 : }
1976 504 : m_bits.dump_to_pp (pp);
1977 504 : pp_string (pp, ", inner_val: ");
1978 504 : m_inner_svalue->dump_to_pp (pp, simple);
1979 504 : pp_character (pp, ')');
1980 : }
1981 : else
1982 : {
1983 106 : pp_string (pp, "bits_within_svalue (");
1984 106 : if (get_type ())
1985 : {
1986 0 : print_quoted_type (pp, get_type ());
1987 0 : pp_string (pp, ", ");
1988 : }
1989 106 : m_bits.dump_to_pp (pp);
1990 106 : pp_string (pp, ", inner_val: ");
1991 106 : m_inner_svalue->dump_to_pp (pp, simple);
1992 106 : pp_character (pp, ')');
1993 : }
1994 610 : }
1995 :
1996 : /* Implementation of svalue::print_dump_widget_label vfunc for
1997 : bits_within_svalue. */
1998 :
1999 : void
2000 0 : bits_within_svalue::print_dump_widget_label (pretty_printer *pp) const
2001 : {
2002 0 : pp_printf (pp, "bits_within_svalue: ");
2003 0 : m_bits.dump_to_pp (pp);
2004 0 : }
2005 :
2006 : /* Implementation of svalue::add_dump_widget_children vfunc for
2007 : bits_within_svalue. */
2008 :
2009 : void
2010 0 : bits_within_svalue::
2011 : add_dump_widget_children (text_art::tree_widget &w,
2012 : const text_art::dump_widget_info &dwi) const
2013 : {
2014 0 : w.add_child (m_inner_svalue->make_dump_widget (dwi, "m_inner_svalue"));
2015 0 : }
2016 :
2017 : /* Implementation of svalue::maybe_fold_bits_within vfunc
2018 : for bits_within_svalue. */
2019 :
2020 : const svalue *
2021 793 : bits_within_svalue::maybe_fold_bits_within (tree type,
2022 : const bit_range &bits,
2023 : region_model_manager *mgr) const
2024 : {
2025 : /* Fold:
2026 : BITS_WITHIN (range1, BITS_WITHIN (range2, VAL))
2027 : to:
2028 : BITS_WITHIN (range1 in range 2, VAL). */
2029 1586 : bit_range offset_bits (m_bits.get_start_bit_offset ()
2030 793 : + bits.m_start_bit_offset,
2031 793 : bits.m_size_in_bits);
2032 793 : return mgr->get_or_create_bits_within (type, offset_bits, m_inner_svalue);
2033 : }
2034 :
2035 : /* Implementation of svalue::accept vfunc for bits_within_svalue. */
2036 :
2037 : void
2038 48834 : bits_within_svalue::accept (visitor *v) const
2039 : {
2040 48834 : m_inner_svalue->accept (v);
2041 48834 : v->visit_bits_within_svalue (this);
2042 48834 : }
2043 :
2044 : /* Implementation of svalue::implicitly_live_p vfunc for bits_within_svalue. */
2045 :
2046 : bool
2047 701 : bits_within_svalue::implicitly_live_p (const svalue_set *live_svalues,
2048 : const region_model *model) const
2049 : {
2050 701 : return m_inner_svalue->live_p (live_svalues, model);
2051 : }
2052 :
2053 : /* class widening_svalue : public svalue. */
2054 :
2055 : /* Implementation of svalue::dump_to_pp vfunc for widening_svalue. */
2056 :
2057 : void
2058 3901 : widening_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
2059 : {
2060 3901 : if (simple)
2061 : {
2062 3677 : pp_string (pp, "WIDENING(");
2063 3677 : pp_character (pp, '{');
2064 3677 : m_snode->print (pp);
2065 3677 : pp_string (pp, "}, ");
2066 3677 : m_base_sval->dump_to_pp (pp, simple);
2067 3677 : pp_string (pp, ", ");
2068 3677 : m_iter_sval->dump_to_pp (pp, simple);
2069 3677 : pp_character (pp, ')');
2070 : }
2071 : else
2072 : {
2073 224 : pp_string (pp, "widening_svalue (");
2074 224 : pp_string (pp, ", ");
2075 224 : pp_character (pp, '{');
2076 224 : m_snode->print (pp);
2077 224 : pp_string (pp, "}, ");
2078 224 : m_base_sval->dump_to_pp (pp, simple);
2079 224 : pp_string (pp, ", ");
2080 224 : m_iter_sval->dump_to_pp (pp, simple);
2081 224 : pp_character (pp, ')');
2082 : }
2083 3901 : }
2084 :
2085 : /* Implementation of svalue::print_dump_widget_label vfunc for
2086 : widening_svalue. */
2087 :
2088 : void
2089 0 : widening_svalue::print_dump_widget_label (pretty_printer *pp) const
2090 : {
2091 0 : pp_printf (pp, "widening_svalue at ");
2092 0 : m_snode->print (pp);
2093 0 : }
2094 :
2095 : /* Implementation of svalue::add_dump_widget_children vfunc for
2096 : widening_svalue. */
2097 :
2098 : void
2099 0 : widening_svalue::
2100 : add_dump_widget_children (text_art::tree_widget &w,
2101 : const text_art::dump_widget_info &dwi) const
2102 : {
2103 0 : w.add_child (m_base_sval->make_dump_widget (dwi, "m_base_sval"));
2104 0 : w.add_child (m_iter_sval->make_dump_widget (dwi, "m_iter_sval"));
2105 0 : }
2106 :
2107 : /* Implementation of svalue::accept vfunc for widening_svalue. */
2108 :
2109 : void
2110 116686 : widening_svalue::accept (visitor *v) const
2111 : {
2112 116686 : m_base_sval->accept (v);
2113 116686 : m_iter_sval->accept (v);
2114 116686 : v->visit_widening_svalue (this);
2115 116686 : }
2116 :
2117 : /* Attempt to determine in which direction this value is changing
2118 : w.r.t. the initial value. */
2119 :
2120 : enum widening_svalue::direction_t
2121 1912 : widening_svalue::get_direction () const
2122 : {
2123 1912 : tree base_cst = m_base_sval->maybe_get_constant ();
2124 1912 : if (base_cst == NULL_TREE)
2125 : return DIR_UNKNOWN;
2126 1912 : tree iter_cst = m_iter_sval->maybe_get_constant ();
2127 1912 : if (iter_cst == NULL_TREE)
2128 : return DIR_UNKNOWN;
2129 :
2130 1912 : tree iter_gt_base = fold_binary (GT_EXPR, boolean_type_node,
2131 : iter_cst, base_cst);
2132 1912 : if (iter_gt_base == boolean_true_node)
2133 : return DIR_ASCENDING;
2134 :
2135 475 : tree iter_lt_base = fold_binary (LT_EXPR, boolean_type_node,
2136 : iter_cst, base_cst);
2137 475 : if (iter_lt_base == boolean_true_node)
2138 : return DIR_DESCENDING;
2139 :
2140 : return DIR_UNKNOWN;
2141 : }
2142 :
2143 : /* Compare this value against constant RHS_CST. */
2144 :
2145 : tristate
2146 2910 : widening_svalue::eval_condition_without_cm (enum tree_code op,
2147 : tree rhs_cst) const
2148 : {
2149 2910 : tree base_cst = m_base_sval->maybe_get_constant ();
2150 2910 : if (base_cst == NULL_TREE)
2151 1006 : return tristate::TS_UNKNOWN;
2152 1904 : tree iter_cst = m_iter_sval->maybe_get_constant ();
2153 1904 : if (iter_cst == NULL_TREE)
2154 0 : return tristate::TS_UNKNOWN;
2155 :
2156 1904 : switch (get_direction ())
2157 : {
2158 0 : default:
2159 0 : gcc_unreachable ();
2160 1429 : case DIR_ASCENDING:
2161 : /* LHS is in [base_cst, +ve infinity), assuming no overflow. */
2162 1429 : switch (op)
2163 : {
2164 281 : case LE_EXPR:
2165 281 : case LT_EXPR:
2166 281 : {
2167 : /* [BASE, +INF) OP RHS:
2168 : This is either true or false at +ve ininity,
2169 : It can be true for points X where X OP RHS, so we have either
2170 : "false", or "unknown". */
2171 281 : tree base_op_rhs = fold_binary (op, boolean_type_node,
2172 : base_cst, rhs_cst);
2173 281 : if (base_op_rhs == boolean_true_node)
2174 265 : return tristate::TS_UNKNOWN;
2175 : else
2176 16 : return tristate::TS_FALSE;
2177 : }
2178 :
2179 808 : case GE_EXPR:
2180 808 : case GT_EXPR:
2181 808 : {
2182 : /* [BASE, +INF) OP RHS:
2183 : This is true at +ve infinity. It will be true everywhere
2184 : in the range if BASE >= RHS. */
2185 808 : tree base_op_rhs = fold_binary (op, boolean_type_node,
2186 : base_cst, rhs_cst);
2187 808 : if (base_op_rhs == boolean_true_node)
2188 65 : return tristate::TS_TRUE;
2189 : else
2190 743 : return tristate::TS_UNKNOWN;
2191 : }
2192 :
2193 168 : case EQ_EXPR:
2194 168 : {
2195 : /* [BASE, +INF) == RHS:
2196 : Could this be true at any point in the range? If so we
2197 : have "unknown", otherwise we have "false". */
2198 168 : tree base_le_rhs = fold_binary (LE_EXPR, boolean_type_node,
2199 : base_cst, rhs_cst);
2200 168 : if (base_le_rhs == boolean_true_node)
2201 158 : return tristate::TS_UNKNOWN;
2202 : else
2203 10 : return tristate::TS_FALSE;
2204 : }
2205 :
2206 172 : case NE_EXPR:
2207 172 : {
2208 : /* [BASE, +INF) != RHS:
2209 : Could we have equality at any point in the range? If so we
2210 : have "unknown", otherwise we have "true". */
2211 172 : tree base_le_rhs = fold_binary (LE_EXPR, boolean_type_node,
2212 : base_cst, rhs_cst);
2213 172 : if (base_le_rhs == boolean_true_node)
2214 162 : return tristate::TS_UNKNOWN;
2215 : else
2216 10 : return tristate::TS_TRUE;
2217 : }
2218 :
2219 0 : default:
2220 0 : return tristate::TS_UNKNOWN;
2221 : }
2222 :
2223 447 : case DIR_DESCENDING:
2224 : /* LHS is in (-ve infinity, base_cst], assuming no overflow. */
2225 447 : return tristate::TS_UNKNOWN;
2226 :
2227 28 : case DIR_UNKNOWN:
2228 28 : return tristate::TS_UNKNOWN;
2229 : }
2230 : }
2231 :
2232 : /* class placeholder_svalue : public svalue. */
2233 :
2234 : /* Implementation of svalue::dump_to_pp vfunc for placeholder_svalue. */
2235 :
2236 : void
2237 0 : placeholder_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
2238 : {
2239 0 : if (simple)
2240 0 : pp_printf (pp, "PLACEHOLDER(%qs)", m_name);
2241 : else
2242 0 : pp_printf (pp, "placeholder_svalue (%qs)", m_name);
2243 0 : }
2244 :
2245 : /* Implementation of svalue::print_dump_widget_label vfunc for
2246 : placeholder_svalue. */
2247 :
2248 : void
2249 0 : placeholder_svalue::print_dump_widget_label (pretty_printer *pp) const
2250 : {
2251 0 : pp_printf (pp, "placeholder_svalue: %qs", m_name);
2252 0 : }
2253 :
2254 : /* Implementation of svalue::add_dump_widget_children vfunc for
2255 : placeholder_svalue. */
2256 :
2257 : void
2258 0 : placeholder_svalue::
2259 : add_dump_widget_children (text_art::tree_widget &,
2260 : const text_art::dump_widget_info &) const
2261 : {
2262 : /* No children. */
2263 0 : }
2264 :
2265 : /* Implementation of svalue::accept vfunc for placeholder_svalue. */
2266 :
2267 : void
2268 38158 : placeholder_svalue::accept (visitor *v) const
2269 : {
2270 38158 : v->visit_placeholder_svalue (this);
2271 38158 : }
2272 :
2273 : /* class unmergeable_svalue : public svalue. */
2274 :
2275 : /* Implementation of svalue::dump_to_pp vfunc for unmergeable_svalue. */
2276 :
2277 : void
2278 20 : unmergeable_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
2279 : {
2280 20 : if (simple)
2281 : {
2282 20 : pp_string (pp, "UNMERGEABLE(");
2283 20 : m_arg->dump_to_pp (pp, simple);
2284 20 : pp_character (pp, ')');
2285 : }
2286 : else
2287 : {
2288 0 : pp_string (pp, "unmergeable_svalue (");
2289 0 : m_arg->dump_to_pp (pp, simple);
2290 0 : pp_character (pp, ')');
2291 : }
2292 20 : }
2293 :
2294 : /* Implementation of svalue::print_dump_widget_label vfunc for
2295 : unmergeable_svalue. */
2296 :
2297 : void
2298 0 : unmergeable_svalue::print_dump_widget_label (pretty_printer *pp) const
2299 : {
2300 0 : pp_printf (pp, "unmergeable_svalue");
2301 0 : }
2302 :
2303 : /* Implementation of svalue::add_dump_widget_children vfunc for
2304 : unmergeable_svalue. */
2305 :
2306 : void
2307 0 : unmergeable_svalue::
2308 : add_dump_widget_children (text_art::tree_widget &w,
2309 : const text_art::dump_widget_info &dwi) const
2310 : {
2311 0 : w.add_child (m_arg->make_dump_widget (dwi));
2312 0 : }
2313 :
2314 : /* Implementation of svalue::accept vfunc for unmergeable_svalue. */
2315 :
2316 : void
2317 6752 : unmergeable_svalue::accept (visitor *v) const
2318 : {
2319 6752 : m_arg->accept (v);
2320 6752 : v->visit_unmergeable_svalue (this);
2321 6752 : }
2322 :
2323 : /* Implementation of svalue::implicitly_live_p vfunc for unmergeable_svalue. */
2324 :
2325 : bool
2326 894 : unmergeable_svalue::implicitly_live_p (const svalue_set *live_svalues,
2327 : const region_model *model) const
2328 : {
2329 894 : return get_arg ()->live_p (live_svalues, model);
2330 : }
2331 :
2332 : /* class compound_svalue : public svalue. */
2333 :
2334 611 : compound_svalue::compound_svalue (symbol::id_t id,
2335 : tree type,
2336 611 : concrete_binding_map &&map)
2337 611 : : svalue (map.calc_complexity (), id, type), m_map (std::move (map))
2338 : {
2339 : #if CHECKING_P
2340 2518 : for (auto iter : *this)
2341 : {
2342 : /* We don't nest compound svalues. */
2343 1907 : const svalue *sval = iter.second;
2344 1907 : gcc_assert (sval->get_kind () != SK_COMPOUND);
2345 : }
2346 : #endif
2347 611 : }
2348 :
2349 50 : compound_svalue::compound_svalue (symbol::id_t id,
2350 : tree type,
2351 50 : const concrete_binding_map &map)
2352 50 : : svalue (map.calc_complexity (), id, type), m_map (map)
2353 : {
2354 : #if CHECKING_P
2355 122 : for (auto iter : *this)
2356 : {
2357 : /* We don't nest compound svalues. */
2358 72 : const svalue *sval = iter.second;
2359 72 : gcc_assert (sval->get_kind () != SK_COMPOUND);
2360 : }
2361 : #endif
2362 50 : }
2363 :
2364 : /* Implementation of svalue::dump_to_pp vfunc for compound_svalue. */
2365 :
2366 : void
2367 2 : compound_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
2368 : {
2369 2 : if (simple)
2370 : {
2371 2 : pp_string (pp, "COMPOUND(");
2372 2 : if (get_type ())
2373 : {
2374 0 : print_quoted_type (pp, get_type ());
2375 0 : pp_string (pp, ", ");
2376 : }
2377 2 : pp_character (pp, '{');
2378 2 : m_map.dump_to_pp (pp, simple, false);
2379 2 : pp_string (pp, "})");
2380 : }
2381 : else
2382 : {
2383 0 : pp_string (pp, "compound_svalue (");
2384 0 : if (get_type ())
2385 : {
2386 0 : print_quoted_type (pp, get_type ());
2387 0 : pp_string (pp, ", ");
2388 : }
2389 0 : pp_character (pp, '{');
2390 0 : m_map.dump_to_pp (pp, simple, false);
2391 0 : pp_string (pp, "})");
2392 : }
2393 2 : }
2394 :
2395 : /* Implementation of svalue::print_dump_widget_label vfunc for
2396 : compound_svalue. */
2397 :
2398 : void
2399 0 : compound_svalue::print_dump_widget_label (pretty_printer *pp) const
2400 : {
2401 0 : pp_printf (pp, "compound_svalue");
2402 0 : }
2403 :
2404 : /* Implementation of svalue::add_dump_widget_children vfunc for
2405 : compound_svalue. */
2406 :
2407 : void
2408 0 : compound_svalue::
2409 : add_dump_widget_children (text_art::tree_widget &w,
2410 : const text_art::dump_widget_info &dwi) const
2411 : {
2412 0 : m_map.add_to_tree_widget (w, dwi);
2413 0 : }
2414 :
2415 : /* Implementation of svalue::accept vfunc for compound_svalue. */
2416 :
2417 : void
2418 38 : compound_svalue::accept (visitor *v) const
2419 : {
2420 114 : for (auto iter : m_map)
2421 76 : iter.second->accept (v);
2422 38 : v->visit_compound_svalue (this);
2423 38 : }
2424 :
2425 : /* Implementation of svalue::maybe_fold_bits_within vfunc
2426 : for compound_svalue. */
2427 :
2428 : const svalue *
2429 56 : compound_svalue::maybe_fold_bits_within (tree type,
2430 : const bit_range &bits,
2431 : region_model_manager *mgr) const
2432 : {
2433 56 : concrete_binding_map result_map;
2434 256 : for (auto iter : m_map)
2435 : {
2436 200 : const bit_range &iter_bits = iter.first;
2437 :
2438 : /* Ignore concrete bindings outside BITS. */
2439 200 : if (!iter_bits.intersects_p (bits))
2440 28 : continue;
2441 :
2442 172 : const svalue *sval = iter.second;
2443 : /* Get the position of iter_bits relative to BITS. */
2444 172 : bit_range result_location (iter_bits.get_start_bit_offset ()
2445 172 : - bits.get_start_bit_offset (),
2446 172 : iter_bits.m_size_in_bits);
2447 : /* If iter_bits starts after BITS, trim off leading bits
2448 : from the svalue and adjust binding location. */
2449 172 : if (result_location.m_start_bit_offset < 0)
2450 : {
2451 0 : bit_size_t leading_bits_to_drop
2452 0 : = -result_location.m_start_bit_offset;
2453 0 : result_location = bit_range
2454 0 : (0, result_location.m_size_in_bits - leading_bits_to_drop);
2455 0 : bit_range bits_within_sval (leading_bits_to_drop,
2456 0 : result_location.m_size_in_bits);
2457 : /* Trim off leading bits from iter_sval. */
2458 0 : sval = mgr->get_or_create_bits_within (NULL_TREE,
2459 : bits_within_sval,
2460 : sval);
2461 : }
2462 : /* If iter_bits finishes after BITS, trim off trailing bits
2463 : from the svalue and adjust binding location. */
2464 344 : if (iter_bits.get_next_bit_offset ()
2465 344 : > bits.get_next_bit_offset ())
2466 : {
2467 44 : bit_size_t trailing_bits_to_drop
2468 44 : = (iter_bits.get_next_bit_offset ()
2469 44 : - bits.get_next_bit_offset ());
2470 44 : result_location = bit_range
2471 : (result_location.m_start_bit_offset,
2472 44 : result_location.m_size_in_bits - trailing_bits_to_drop);
2473 44 : bit_range bits_within_sval (0,
2474 44 : result_location.m_size_in_bits);
2475 : /* Trim off leading bits from iter_sval. */
2476 44 : sval = mgr->get_or_create_bits_within (NULL_TREE,
2477 : bits_within_sval,
2478 : sval);
2479 : }
2480 172 : result_map.insert (result_location, sval);
2481 : }
2482 56 : return mgr->get_or_create_compound_svalue (type, std::move (result_map));
2483 56 : }
2484 :
2485 : /* class conjured_svalue : public svalue. */
2486 :
2487 : /* Implementation of svalue::dump_to_pp vfunc for conjured_svalue. */
2488 :
2489 : void
2490 3194 : conjured_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
2491 : {
2492 3194 : if (simple)
2493 : {
2494 2804 : pp_string (pp, "CONJURED(");
2495 2804 : pp_gimple_stmt_1 (pp, m_stmt, 0, (dump_flags_t)0);
2496 2804 : pp_string (pp, ", ");
2497 2804 : m_id_reg->dump_to_pp (pp, simple);
2498 2804 : pp_character (pp, ')');
2499 : }
2500 : else
2501 : {
2502 390 : pp_string (pp, "conjured_svalue (");
2503 390 : if (get_type ())
2504 : {
2505 390 : print_quoted_type (pp, get_type ());
2506 390 : pp_string (pp, ", ");
2507 : }
2508 390 : pp_gimple_stmt_1 (pp, m_stmt, 0, (dump_flags_t)0);
2509 390 : pp_string (pp, ", ");
2510 390 : m_id_reg->dump_to_pp (pp, simple);
2511 390 : pp_character (pp, ')');
2512 : }
2513 3194 : }
2514 :
2515 : /* Implementation of svalue::print_dump_widget_label vfunc for
2516 : conjured_svalue. */
2517 :
2518 : void
2519 0 : conjured_svalue::print_dump_widget_label (pretty_printer *pp) const
2520 : {
2521 0 : pp_printf (pp, "conjured_svalue (");
2522 0 : pp_gimple_stmt_1 (pp, m_stmt, 0, (dump_flags_t)0);
2523 0 : if (m_idx != 0)
2524 0 : pp_printf (pp, ", %i", m_idx);
2525 0 : pp_character (pp, ')');
2526 0 : }
2527 :
2528 : /* Implementation of svalue::add_dump_widget_children vfunc for
2529 : conjured_svalue. */
2530 :
2531 : void
2532 0 : conjured_svalue::
2533 : add_dump_widget_children (text_art::tree_widget &w,
2534 : const text_art::dump_widget_info &dwi) const
2535 : {
2536 0 : w.add_child (m_id_reg->make_dump_widget (dwi));
2537 0 : }
2538 :
2539 : /* Implementation of svalue::accept vfunc for conjured_svalue. */
2540 :
2541 : void
2542 5321969 : conjured_svalue::accept (visitor *v) const
2543 : {
2544 5321969 : m_id_reg->accept (v);
2545 5321969 : v->visit_conjured_svalue (this);
2546 5321969 : }
2547 :
2548 : /* Return true iff this conjured_svalue is for the LHS of the
2549 : stmt that conjured it. */
2550 :
2551 : bool
2552 0 : conjured_svalue::lhs_value_p () const
2553 : {
2554 0 : if (tree decl = m_id_reg->maybe_get_decl ())
2555 0 : return decl == gimple_get_lhs (m_stmt);
2556 : return false;
2557 : }
2558 :
2559 : /* class asm_output_svalue : public svalue. */
2560 :
2561 : /* Implementation of svalue::dump_to_pp vfunc for asm_output_svalue. */
2562 :
2563 : void
2564 52 : asm_output_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
2565 : {
2566 52 : if (simple)
2567 : {
2568 52 : pp_printf (pp, "ASM_OUTPUT(%qs, %%%i, {",
2569 : get_asm_string (),
2570 : get_output_idx ());
2571 144 : for (unsigned i = 0; i < m_num_inputs; i++)
2572 : {
2573 92 : if (i > 0)
2574 40 : pp_string (pp, ", ");
2575 92 : dump_input (pp, 0, m_input_arr[i], simple);
2576 : }
2577 52 : pp_string (pp, "})");
2578 : }
2579 : else
2580 : {
2581 0 : pp_printf (pp, "asm_output_svalue (%qs, %%%i, {",
2582 : get_asm_string (),
2583 : get_output_idx ());
2584 0 : for (unsigned i = 0; i < m_num_inputs; i++)
2585 : {
2586 0 : if (i > 0)
2587 0 : pp_string (pp, ", ");
2588 0 : dump_input (pp, 0, m_input_arr[i], simple);
2589 : }
2590 0 : pp_string (pp, "})");
2591 : }
2592 52 : }
2593 :
2594 : /* Implementation of svalue::print_dump_widget_label vfunc for
2595 : asm_output_svalue. */
2596 :
2597 : void
2598 0 : asm_output_svalue::print_dump_widget_label (pretty_printer *pp) const
2599 : {
2600 0 : pp_printf (pp, "asm_output_svalue(%qs, %%%i)",
2601 : get_asm_string (),
2602 : get_output_idx ());
2603 0 : }
2604 :
2605 : /* Implementation of svalue::add_dump_widget_children vfunc for
2606 : asm_output_svalue. */
2607 :
2608 : void
2609 0 : asm_output_svalue::
2610 : add_dump_widget_children (text_art::tree_widget &w,
2611 : const text_art::dump_widget_info &dwi) const
2612 : {
2613 0 : for (unsigned i = 0; i < m_num_inputs; i++)
2614 : {
2615 0 : pretty_printer pp;
2616 0 : pp_printf (&pp, "arg %i", i);
2617 0 : w.add_child (m_input_arr[i]->make_dump_widget (dwi,
2618 : pp_formatted_text (&pp)));
2619 0 : }
2620 0 : }
2621 :
2622 : /* Subroutine of asm_output_svalue::dump_to_pp. */
2623 :
2624 : void
2625 92 : asm_output_svalue::dump_input (pretty_printer *pp,
2626 : unsigned input_idx,
2627 : const svalue *sval,
2628 : bool simple) const
2629 : {
2630 92 : pp_printf (pp, "%%%i: ", input_idx_to_asm_idx (input_idx));
2631 92 : sval->dump_to_pp (pp, simple);
2632 92 : }
2633 :
2634 : /* Convert INPUT_IDX from an index into the array of inputs
2635 : into the index of all operands for the asm stmt. */
2636 :
2637 : unsigned
2638 92 : asm_output_svalue::input_idx_to_asm_idx (unsigned input_idx) const
2639 : {
2640 92 : return input_idx + m_num_outputs;
2641 : }
2642 :
2643 : /* Implementation of svalue::accept vfunc for asm_output_svalue. */
2644 :
2645 : void
2646 6099 : asm_output_svalue::accept (visitor *v) const
2647 : {
2648 16803 : for (unsigned i = 0; i < m_num_inputs; i++)
2649 10704 : m_input_arr[i]->accept (v);
2650 6099 : v->visit_asm_output_svalue (this);
2651 6099 : }
2652 :
2653 : /* class const_fn_result_svalue : public svalue. */
2654 :
2655 : /* Implementation of svalue::dump_to_pp vfunc for const_fn_result_svalue. */
2656 :
2657 : void
2658 4391 : const_fn_result_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
2659 : {
2660 4391 : if (simple)
2661 : {
2662 3945 : pp_printf (pp, "CONST_FN_RESULT(%qD, {", m_fndecl);
2663 3993 : for (unsigned i = 0; i < m_num_inputs; i++)
2664 : {
2665 48 : if (i > 0)
2666 0 : pp_string (pp, ", ");
2667 48 : dump_input (pp, i, m_input_arr[i], simple);
2668 : }
2669 3945 : pp_string (pp, "})");
2670 : }
2671 : else
2672 : {
2673 446 : pp_printf (pp, "CONST_FN_RESULT(%qD, {", m_fndecl);
2674 446 : for (unsigned i = 0; i < m_num_inputs; i++)
2675 : {
2676 0 : if (i > 0)
2677 0 : pp_string (pp, ", ");
2678 0 : dump_input (pp, i, m_input_arr[i], simple);
2679 : }
2680 446 : pp_string (pp, "})");
2681 : }
2682 4391 : }
2683 :
2684 : /* Implementation of svalue::print_dump_widget_label vfunc for
2685 : const_fn_result_svalue. */
2686 :
2687 : void
2688 0 : const_fn_result_svalue::print_dump_widget_label (pretty_printer *pp) const
2689 : {
2690 0 : pp_printf (pp, "const_fn_result_svalue: %qD", m_fndecl);
2691 0 : }
2692 :
2693 : /* Implementation of svalue::add_dump_widget_children vfunc for
2694 : const_fn_result_svalue. */
2695 :
2696 : void
2697 0 : const_fn_result_svalue::
2698 : add_dump_widget_children (text_art::tree_widget &w,
2699 : const text_art::dump_widget_info &dwi) const
2700 : {
2701 0 : for (unsigned i = 0; i < m_num_inputs; i++)
2702 : {
2703 0 : pretty_printer pp;
2704 0 : pp_printf (&pp, "arg %i", i);
2705 0 : w.add_child (m_input_arr[i]->make_dump_widget (dwi,
2706 : pp_formatted_text (&pp)));
2707 0 : }
2708 0 : }
2709 :
2710 : /* Subroutine of const_fn_result_svalue::dump_to_pp. */
2711 :
2712 : void
2713 48 : const_fn_result_svalue::dump_input (pretty_printer *pp,
2714 : unsigned input_idx,
2715 : const svalue *sval,
2716 : bool simple) const
2717 : {
2718 48 : pp_printf (pp, "arg%i: ", input_idx);
2719 48 : sval->dump_to_pp (pp, simple);
2720 48 : }
2721 :
2722 : /* Implementation of svalue::accept vfunc for const_fn_result_svalue. */
2723 :
2724 : void
2725 8497 : const_fn_result_svalue::accept (visitor *v) const
2726 : {
2727 14306 : for (unsigned i = 0; i < m_num_inputs; i++)
2728 5809 : m_input_arr[i]->accept (v);
2729 8497 : v->visit_const_fn_result_svalue (this);
2730 8497 : }
2731 :
2732 : } // namespace ana
2733 :
2734 : #endif /* #if ENABLE_ANALYZER */
|