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 14021873 : svalue::maybe_get_constant () const
251 : {
252 14021873 : const svalue *sval = unwrap_any_unmergeable ();
253 14021873 : if (const constant_svalue *cst_sval = sval->dyn_cast_constant_svalue ())
254 4623691 : 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 382036 : svalue::maybe_get_region () const
264 : {
265 382036 : if (const region_svalue *region_sval = dyn_cast_region_svalue ())
266 38309 : 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 13264637 : svalue::maybe_undo_cast () const
277 : {
278 13264637 : if (const unaryop_svalue *unaryop_sval = dyn_cast_unaryop_svalue ())
279 : {
280 940454 : enum tree_code op = unaryop_sval->get_op ();
281 940454 : if (op == NOP_EXPR || op == VIEW_CONVERT_EXPR)
282 907384 : 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 17272931 : svalue::unwrap_any_unmergeable () const
293 : {
294 17272931 : 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 362212 : svalue::can_merge_p (const svalue *other,
304 : region_model_manager *mgr,
305 : model_merger *merger) const
306 : {
307 362212 : if (!(get_type () && other->get_type ()))
308 : return nullptr;
309 :
310 313722 : if (!types_compatible_p (get_type (), other->get_type ()))
311 : return nullptr;
312 :
313 : /* Reject attempts to merge unmergeable svalues. */
314 292538 : if ((get_kind () == SK_UNMERGEABLE)
315 292538 : || (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 289731 : if (get_kind () == SK_POISONED
322 289731 : || other->get_kind () == SK_POISONED)
323 1591 : return nullptr;
324 :
325 : /* Reject attempts to merge NULL pointers with not-NULL-pointers. */
326 288140 : if (POINTER_TYPE_P (get_type ()))
327 : {
328 38665 : bool null0 = false;
329 38665 : bool null1 = false;
330 38665 : if (tree cst0 = maybe_get_constant ())
331 8021 : if (zerop (cst0))
332 38665 : null0 = true;
333 38665 : if (tree cst1 = other->maybe_get_constant ())
334 5285 : if (zerop (cst1))
335 38665 : null1 = true;
336 38665 : 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 275056 : if (!merger->mergeable_svalue_p (this))
344 : return nullptr;
345 273938 : 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 273241 : if (auto this_region = maybe_get_region ())
351 4004 : 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 272719 : if (maybe_get_constant () && other->maybe_get_constant ())
360 3602 : return mgr->get_or_create_widening_svalue (other->get_type (),
361 : merger->get_supernode (),
362 3602 : 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 269117 : if (const binop_svalue *binop_sval = dyn_cast_binop_svalue ())
369 12077 : if (binop_sval->get_arg0 () == other
370 1654 : && binop_sval->get_arg1 ()->get_kind () == SK_CONSTANT
371 13607 : && other->get_kind () != SK_WIDENING)
372 687 : return mgr->get_or_create_widening_svalue (other->get_type (),
373 : merger->get_supernode (),
374 687 : other, this);
375 :
376 : /* Merge: (Widen(existing_val, V), existing_val) -> Widen (existing_val, V)
377 : and thus get a fixed point. */
378 268430 : if (const widening_svalue *widen_sval = dyn_cast_widening_svalue ())
379 : {
380 8122 : if (other == widen_sval->get_base_svalue ())
381 : return this;
382 1782 : if (other == widen_sval->get_iter_svalue ())
383 : return this;
384 : }
385 :
386 261192 : if (const binop_svalue *binop_sval = dyn_cast_binop_svalue ())
387 11390 : if (const widening_svalue *widen_arg0
388 11390 : = binop_sval->get_arg0 ()->dyn_cast_widening_svalue ())
389 : {
390 3386 : 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 2526 : 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 1683 : if (widen_arg0->get_iter_svalue () == other)
418 1426 : if (const binop_svalue *other_binop_sval
419 713 : = other->dyn_cast_binop_svalue ())
420 529 : if (other_binop_sval->get_arg0 () == widen_arg0->get_base_svalue ()
421 529 : && other_binop_sval->get_arg1 () == binop_sval->get_arg1 ())
422 : return widen_arg0;
423 : }
424 :
425 258960 : 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 11065523 : svalue::live_p (const svalue_set *live_svalues,
435 : const region_model *model) const
436 : {
437 : /* Determine if SVAL is explicitly live. */
438 11065523 : if (live_svalues)
439 11063673 : 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 4772664 : return implicitly_live_p (live_svalues, model);
445 : }
446 :
447 : /* Base implementation of svalue::implicitly_live_p. */
448 :
449 : bool
450 191244 : svalue::implicitly_live_p (const svalue_set *, const region_model *) const
451 : {
452 191244 : 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 1525016 : cmp_csts_same_type (const_tree cst1, const_tree cst2)
460 : {
461 1525016 : gcc_assert (TREE_TYPE (cst1) == TREE_TYPE (cst2));
462 1525016 : gcc_assert (TREE_CODE (cst1) == TREE_CODE (cst2));
463 1525016 : switch (TREE_CODE (cst1))
464 : {
465 0 : default:
466 0 : gcc_unreachable ();
467 1524736 : case INTEGER_CST:
468 1524736 : 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 1525038 : cmp_csts_and_types (const_tree cst1, const_tree cst2)
521 : {
522 1525038 : int t1 = TYPE_UID (TREE_TYPE (cst1));
523 1525038 : int t2 = TYPE_UID (TREE_TYPE (cst2));
524 1525038 : if (int cmp_type = t1 - t2)
525 : return cmp_type;
526 1525016 : return cmp_csts_same_type (cst1, cst2);
527 : }
528 :
529 : /* Comparator for imposing a deterministic order on svalues. */
530 :
531 : int
532 43860362 : svalue::cmp_ptr (const svalue *sval1, const svalue *sval2)
533 : {
534 45296168 : if (sval1 == sval2)
535 : return 0;
536 43537883 : if (int cmp_kind = sval1->get_kind () - sval2->get_kind ())
537 : return cmp_kind;
538 16462287 : int t1 = sval1->get_type () ? TYPE_UID (sval1->get_type ()) : -1;
539 16462287 : int t2 = sval2->get_type () ? TYPE_UID (sval2->get_type ()) : -1;
540 16462287 : if (int cmp_type = t1 - t2)
541 : return cmp_type;
542 10530637 : switch (sval1->get_kind ())
543 : {
544 0 : default:
545 0 : gcc_unreachable ();
546 768567 : case SK_REGION:
547 768567 : {
548 768567 : const region_svalue *region_sval1 = (const region_svalue *)sval1;
549 768567 : const region_svalue *region_sval2 = (const region_svalue *)sval2;
550 768567 : return region::cmp_ids (region_sval1->get_pointee (),
551 1537134 : region_sval2->get_pointee ());
552 : }
553 1524950 : break;
554 1524950 : case SK_CONSTANT:
555 1524950 : {
556 1524950 : const constant_svalue *constant_sval1 = (const constant_svalue *)sval1;
557 1524950 : const constant_svalue *constant_sval2 = (const constant_svalue *)sval2;
558 1524950 : const_tree cst1 = constant_sval1->get_constant ();
559 1524950 : 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 1524950 : 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 2075024 : break;
588 2075024 : case SK_INITIAL:
589 2075024 : {
590 2075024 : const initial_svalue *initial_sval1 = (const initial_svalue *)sval1;
591 2075024 : const initial_svalue *initial_sval2 = (const initial_svalue *)sval2;
592 2075024 : return region::cmp_ids (initial_sval1->get_region (),
593 4150048 : initial_sval2->get_region ());
594 : }
595 743019 : break;
596 743019 : case SK_UNARYOP:
597 743019 : {
598 743019 : const unaryop_svalue *unaryop_sval1 = (const unaryop_svalue *)sval1;
599 743019 : const unaryop_svalue *unaryop_sval2 = (const unaryop_svalue *)sval2;
600 743019 : if (int op_cmp = unaryop_sval1->get_op () - unaryop_sval2->get_op ())
601 : return op_cmp;
602 742979 : return svalue::cmp_ptr (unaryop_sval1->get_arg (),
603 742979 : unaryop_sval2->get_arg ());
604 : }
605 1829703 : break;
606 1829703 : case SK_BINOP:
607 1829703 : {
608 1829703 : const binop_svalue *binop_sval1 = (const binop_svalue *)sval1;
609 1829703 : const binop_svalue *binop_sval2 = (const binop_svalue *)sval2;
610 1829703 : if (int op_cmp = binop_sval1->get_op () - binop_sval2->get_op ())
611 : return op_cmp;
612 1805929 : if (int arg0_cmp = svalue::cmp_ptr (binop_sval1->get_arg0 (),
613 : binop_sval2->get_arg0 ()))
614 : return arg0_cmp;
615 692496 : return svalue::cmp_ptr (binop_sval1->get_arg1 (),
616 692496 : 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 307 : break;
630 307 : case SK_REPEATED:
631 307 : {
632 307 : const repeated_svalue *repeated_sval1 = (const repeated_svalue *)sval1;
633 307 : const repeated_svalue *repeated_sval2 = (const repeated_svalue *)sval2;
634 307 : return svalue::cmp_ptr (repeated_sval1->get_inner_svalue (),
635 307 : repeated_sval2->get_inner_svalue ());
636 : }
637 375 : break;
638 375 : case SK_BITS_WITHIN:
639 375 : {
640 375 : const bits_within_svalue *bits_within_sval1
641 : = (const bits_within_svalue *)sval1;
642 375 : const bits_within_svalue *bits_within_sval2
643 : = (const bits_within_svalue *)sval2;
644 375 : 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 1711 : break;
671 1711 : case SK_WIDENING:
672 1711 : {
673 1711 : const widening_svalue *widening_sval1 = (const widening_svalue *)sval1;
674 1711 : const widening_svalue *widening_sval2 = (const widening_svalue *)sval2;
675 1711 : if (int index_cmp = (widening_sval1->get_snode ()->m_id
676 1711 : - widening_sval2->get_snode ()->m_id))
677 : return index_cmp;
678 1483 : 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 3183195 : break;
694 3183195 : case SK_CONJURED:
695 3183195 : {
696 3183195 : const conjured_svalue *conjured_sval1 = (const conjured_svalue *)sval1;
697 3183195 : const conjured_svalue *conjured_sval2 = (const conjured_svalue *)sval2;
698 3183195 : if (int stmt_cmp = (conjured_sval1->get_stmt ()->uid
699 3183195 : - conjured_sval2->get_stmt ()->uid))
700 : return stmt_cmp;
701 37198 : return region::cmp_ids (conjured_sval1->get_id_region (),
702 74396 : 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 7758022 : svalue::cmp_ptr_ptr (const void *p1, const void *p2)
755 : {
756 7758022 : const svalue *sval1 = *(const svalue * const *)p1;
757 7758022 : const svalue *sval2 = *(const svalue * const *)p2;
758 7758022 : 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 648056 : involvement_visitor (const svalue *needle)
767 648056 : : m_needle (needle), m_found (false) {}
768 :
769 293587 : void visit_initial_svalue (const initial_svalue *candidate) final override
770 : {
771 293587 : if (candidate == m_needle)
772 60 : m_found = true;
773 293587 : }
774 :
775 291973 : void visit_conjured_svalue (const conjured_svalue *candidate) final override
776 : {
777 291973 : if (candidate == m_needle)
778 6548 : m_found = true;
779 291973 : }
780 :
781 5113 : void visit_widening_svalue (const widening_svalue *candidate) final override
782 : {
783 5113 : if (candidate == m_needle)
784 172 : m_found = true;
785 5113 : }
786 :
787 648056 : 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 648056 : svalue::involves_p (const svalue *other) const
798 : {
799 : /* Currently only implemented for these kinds. */
800 648056 : gcc_assert (other->get_kind () == SK_INITIAL
801 : || other->get_kind () == SK_CONJURED
802 : || other->get_kind () == SK_WIDENING);
803 :
804 648056 : involvement_visitor v (other);
805 648056 : accept (&v);
806 648056 : return v.found_p ();
807 : }
808 :
809 : /* Extract SUBRANGE from this value, of type TYPE. */
810 :
811 : const svalue *
812 19540 : svalue::extract_bit_range (tree type,
813 : const bit_range &subrange,
814 : region_model_manager *mgr) const
815 : {
816 19540 : 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 1712 : svalue::maybe_fold_bits_within (tree,
823 : const bit_range &,
824 : region_model_manager *) const
825 : {
826 : /* By default, don't fold. */
827 1712 : 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 139441 : svalue::all_zeroes_p () const
835 : {
836 139441 : 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 20399 : svalue::maybe_get_deref_base_region () const
844 : {
845 20399 : const svalue *iter = this;
846 20727 : while (1)
847 : {
848 20563 : switch (iter->get_kind ())
849 : {
850 : default:
851 : return nullptr;
852 :
853 8905 : case SK_REGION:
854 8905 : {
855 8905 : const region_svalue *region_sval
856 8905 : = as_a <const region_svalue *> (iter);
857 8905 : return region_sval->get_pointee ()->get_base_region ();
858 : }
859 :
860 330 : case SK_BINOP:
861 330 : {
862 330 : const binop_svalue *binop_sval
863 330 : = as_a <const binop_svalue *> (iter);
864 330 : switch (binop_sval->get_op ())
865 : {
866 164 : case POINTER_PLUS_EXPR:
867 : /* If we have a symbolic value expressing pointer arithmetic,
868 : use the LHS. */
869 164 : iter = binop_sval->get_arg0 ();
870 164 : continue;
871 :
872 : default:
873 : return nullptr;
874 : }
875 : return nullptr;
876 : }
877 : }
878 164 : }
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 191492 : type_can_have_value_range_p (tree type)
899 : {
900 191492 : if (!type)
901 : return false;
902 191416 : if (irange::supports_p (type))
903 : return true;
904 35358 : 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 96491 : svalue::maybe_get_value_range_1 (value_range &out) const
915 : {
916 96491 : tree type = get_type ();
917 96491 : if (!type_can_have_value_range_p (type))
918 : return false;
919 :
920 63021 : out.set_varying (type);
921 63021 : 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 10045 : region_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
930 : {
931 10045 : if (simple)
932 : {
933 9426 : pp_string (pp, "&");
934 9426 : 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 10045 : }
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 752881 : region_svalue::accept (visitor *v) const
973 : {
974 752881 : m_reg->accept (v);
975 752881 : v->visit_region_svalue (this);
976 752881 : }
977 :
978 : /* Implementation of svalue::implicitly_live_p vfunc for region_svalue. */
979 :
980 : bool
981 262669 : 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 262669 : const region *base_reg = get_pointee ()->get_base_region ();
986 262669 : const store *store = model->get_store ();
987 262669 : if (const binding_cluster *c = store->get_cluster (base_reg))
988 242549 : 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 344 : region_svalue::eval_condition (const region_svalue *lhs,
1000 : enum tree_code op,
1001 : const region_svalue *rhs)
1002 : {
1003 : /* See if they point to the same region. */
1004 344 : const region *lhs_reg = lhs->get_pointee ();
1005 344 : const region *rhs_reg = rhs->get_pointee ();
1006 344 : bool ptr_equality = lhs_reg == rhs_reg;
1007 344 : switch (op)
1008 : {
1009 0 : default:
1010 0 : gcc_unreachable ();
1011 :
1012 73 : case EQ_EXPR:
1013 73 : if (ptr_equality)
1014 0 : return tristate::TS_TRUE;
1015 : else
1016 73 : return tristate::TS_FALSE;
1017 263 : break;
1018 :
1019 263 : case NE_EXPR:
1020 263 : if (ptr_equality)
1021 0 : return tristate::TS_FALSE;
1022 : else
1023 263 : return tristate::TS_TRUE;
1024 4 : break;
1025 :
1026 4 : case GE_EXPR:
1027 4 : case LE_EXPR:
1028 4 : if (ptr_equality)
1029 0 : return tristate::TS_TRUE;
1030 : break;
1031 :
1032 4 : case GT_EXPR:
1033 4 : case LT_EXPR:
1034 4 : if (ptr_equality)
1035 0 : return tristate::TS_FALSE;
1036 : break;
1037 : }
1038 :
1039 8 : return tristate::TS_UNKNOWN;
1040 : }
1041 :
1042 : /* class constant_svalue : public svalue. */
1043 :
1044 : /* Implementation of svalue::dump_to_pp vfunc for constant_svalue. */
1045 :
1046 : void
1047 16442 : constant_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
1048 : {
1049 16442 : if (simple)
1050 : {
1051 15793 : pp_string (pp, "(");
1052 15793 : dump_tree (pp, get_type ());
1053 15793 : pp_string (pp, ")");
1054 15793 : dump_tree (pp, m_cst_expr);
1055 : }
1056 : else
1057 : {
1058 649 : pp_string (pp, "constant_svalue(");
1059 649 : if (get_type ())
1060 : {
1061 649 : print_quoted_type (pp, get_type ());
1062 649 : pp_string (pp, ", ");
1063 : }
1064 649 : dump_tree (pp, m_cst_expr);
1065 649 : pp_string (pp, ")");
1066 : }
1067 16442 : }
1068 :
1069 : /* Implementation of svalue::print_dump_widget_label vfunc for
1070 : constant_svalue. */
1071 :
1072 : void
1073 0 : constant_svalue::print_dump_widget_label (pretty_printer *pp) const
1074 : {
1075 0 : pp_printf (pp, "constant_svalue (%qE)", m_cst_expr);
1076 0 : }
1077 :
1078 : /* Implementation of svalue::add_dump_widget_children vfunc for
1079 : constant_svalue. */
1080 :
1081 : void
1082 0 : constant_svalue::
1083 : add_dump_widget_children (text_art::tree_widget &,
1084 : const text_art::dump_widget_info &) const
1085 : {
1086 : /* No children. */
1087 0 : }
1088 :
1089 : /* Implementation of svalue::accept vfunc for constant_svalue. */
1090 :
1091 : void
1092 9319468 : constant_svalue::accept (visitor *v) const
1093 : {
1094 9319468 : v->visit_constant_svalue (this);
1095 9319468 : }
1096 :
1097 : /* Implementation of svalue::implicitly_live_p vfunc for constant_svalue.
1098 : Constants are implicitly live. */
1099 :
1100 : bool
1101 678048 : constant_svalue::implicitly_live_p (const svalue_set *,
1102 : const region_model *) const
1103 : {
1104 678048 : return true;
1105 : }
1106 :
1107 : /* Given EXPR, a non-NULL expression of boolean type, convert to
1108 : a tristate based on whether this is known to be true, false,
1109 : or is not known. */
1110 :
1111 : static tristate
1112 14635 : tristate_from_boolean_tree_node (tree expr)
1113 : {
1114 14635 : gcc_assert (TREE_TYPE (expr) == boolean_type_node);
1115 :
1116 14635 : if (expr == boolean_true_node)
1117 10661 : return tristate (tristate::TS_TRUE);
1118 3974 : else if (expr == boolean_false_node)
1119 3974 : return tristate (tristate::TS_FALSE);
1120 : else
1121 0 : return tristate (tristate::TS_UNKNOWN);
1122 : }
1123 :
1124 : /* Evaluate the condition LHS OP RHS.
1125 : Subroutine of region_model::eval_condition for when we have a pair of
1126 : constants. */
1127 :
1128 : tristate
1129 15190 : constant_svalue::eval_condition (const constant_svalue *lhs,
1130 : enum tree_code op,
1131 : const constant_svalue *rhs)
1132 : {
1133 15190 : tree lhs_const = lhs->get_constant ();
1134 15190 : tree rhs_const = rhs->get_constant ();
1135 :
1136 15190 : gcc_assert (CONSTANT_CLASS_P (lhs_const));
1137 15190 : gcc_assert (CONSTANT_CLASS_P (rhs_const));
1138 :
1139 15190 : if ((lhs->get_type () == NULL_TREE || rhs->get_type () == NULL_TREE)
1140 366 : && TREE_CODE (lhs_const) == INTEGER_CST
1141 15556 : && TREE_CODE (rhs_const) == INTEGER_CST
1142 : )
1143 : {
1144 366 : if (tree tree_cmp = const_binop (op, boolean_type_node,
1145 : lhs_const, rhs_const))
1146 : {
1147 366 : tristate ts = tristate_from_boolean_tree_node (tree_cmp);
1148 366 : if (ts.is_known ())
1149 366 : return ts;
1150 : }
1151 : }
1152 :
1153 : /* Check for comparable types. */
1154 14824 : if (types_compatible_p (TREE_TYPE (lhs_const), TREE_TYPE (rhs_const)))
1155 : {
1156 14269 : tree tree_cmp
1157 14269 : = fold_binary (op, boolean_type_node, lhs_const, rhs_const);
1158 14269 : tristate ts = tristate_from_boolean_tree_node (tree_cmp);
1159 14269 : if (ts.is_known ())
1160 14269 : return ts;
1161 : }
1162 555 : return tristate::TS_UNKNOWN;
1163 : }
1164 :
1165 : /* Implementation of svalue::maybe_fold_bits_within vfunc
1166 : for constant_svalue. */
1167 :
1168 : const svalue *
1169 442 : constant_svalue::maybe_fold_bits_within (tree type,
1170 : const bit_range &bits,
1171 : region_model_manager *mgr) const
1172 : {
1173 : /* Bits within an all-zero value are also all zero. */
1174 442 : if (zerop (m_cst_expr))
1175 : {
1176 93 : if (type)
1177 92 : return mgr->get_or_create_cast (type, this);
1178 : else
1179 1 : return this;
1180 : }
1181 :
1182 : /* Handle the case of extracting a single bit. */
1183 498 : if (bits.m_size_in_bits == 1
1184 204 : && TREE_CODE (m_cst_expr) == INTEGER_CST
1185 204 : && type
1186 204 : && INTEGRAL_TYPE_P (type)
1187 553 : && tree_fits_uhwi_p (m_cst_expr))
1188 : {
1189 200 : unsigned HOST_WIDE_INT bit = bits.m_start_bit_offset.to_uhwi ();
1190 200 : unsigned HOST_WIDE_INT mask = (1 << bit);
1191 200 : unsigned HOST_WIDE_INT val_as_hwi = tree_to_uhwi (m_cst_expr);
1192 200 : unsigned HOST_WIDE_INT masked_val = val_as_hwi & mask;
1193 200 : int result = masked_val ? 1 : 0;
1194 200 : return mgr->get_or_create_int_cst (type, result);
1195 : }
1196 :
1197 : /* Otherwise, don't fold. */
1198 : return nullptr;
1199 : }
1200 :
1201 : /* Implementation of svalue::all_zeroes_p for constant_svalue. */
1202 :
1203 : bool
1204 115780 : constant_svalue::all_zeroes_p () const
1205 : {
1206 115780 : return zerop (m_cst_expr);
1207 : }
1208 :
1209 :
1210 : /* Implementation of svalue::maybe_get_value_range_1 for constant_svalue.
1211 : If there is a suitable underlying type, write the value_range for the
1212 : single value of m_cst_expr to OUT and return true; otherwise return
1213 : false. */
1214 :
1215 : bool
1216 52668 : constant_svalue::maybe_get_value_range_1 (value_range &out) const
1217 : {
1218 52668 : if (!type_can_have_value_range_p (get_type ()))
1219 : return false;
1220 :
1221 52573 : out = value_range (m_cst_expr, m_cst_expr);
1222 52573 : return true;
1223 : }
1224 :
1225 : /* class unknown_svalue : public svalue. */
1226 :
1227 : /* Implementation of svalue::dump_to_pp vfunc for unknown_svalue. */
1228 :
1229 : void
1230 3670 : unknown_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
1231 : {
1232 3670 : if (simple)
1233 : {
1234 2943 : pp_string (pp, "UNKNOWN(");
1235 2943 : if (get_type ())
1236 2940 : dump_tree (pp, get_type ());
1237 2943 : pp_character (pp, ')');
1238 : }
1239 : else
1240 : {
1241 727 : pp_string (pp, "unknown_svalue(");
1242 727 : if (get_type ())
1243 727 : dump_tree (pp, get_type ());
1244 727 : pp_character (pp, ')');
1245 : }
1246 3670 : }
1247 :
1248 : /* Implementation of svalue::print_dump_widget_label vfunc for
1249 : unknown_svalue. */
1250 :
1251 : void
1252 0 : unknown_svalue::print_dump_widget_label (pretty_printer *pp) const
1253 : {
1254 0 : pp_printf (pp, "unknown_svalue");
1255 0 : }
1256 :
1257 : /* Implementation of svalue::add_dump_widget_children vfunc for
1258 : unknown_svalue. */
1259 :
1260 : void
1261 0 : unknown_svalue::
1262 : add_dump_widget_children (text_art::tree_widget &,
1263 : const text_art::dump_widget_info &) const
1264 : {
1265 : /* No children. */
1266 0 : }
1267 :
1268 : /* Implementation of svalue::accept vfunc for unknown_svalue. */
1269 :
1270 : void
1271 1900379 : unknown_svalue::accept (visitor *v) const
1272 : {
1273 1900379 : v->visit_unknown_svalue (this);
1274 1900379 : }
1275 :
1276 : /* Implementation of svalue::maybe_fold_bits_within vfunc
1277 : for unknown_svalue. */
1278 :
1279 : const svalue *
1280 7142 : unknown_svalue::maybe_fold_bits_within (tree type,
1281 : const bit_range &,
1282 : region_model_manager *mgr) const
1283 : {
1284 : /* Bits within an unknown_svalue are themselves unknown. */
1285 7142 : return mgr->get_or_create_unknown_svalue (type);
1286 : }
1287 :
1288 : bool
1289 16994 : unknown_svalue::maybe_get_value_range_1 (value_range &) const
1290 : {
1291 : /* Don't attempt to participate in range ops. */
1292 16994 : return false;
1293 : }
1294 :
1295 :
1296 : /* Get a string for KIND for use in debug dumps. */
1297 :
1298 : const char *
1299 12 : poison_kind_to_str (enum poison_kind kind)
1300 : {
1301 12 : switch (kind)
1302 : {
1303 0 : default:
1304 0 : gcc_unreachable ();
1305 : case poison_kind::uninit:
1306 : return "uninit";
1307 0 : case poison_kind::freed:
1308 0 : return "freed";
1309 0 : case poison_kind::deleted:
1310 0 : return "deleted";
1311 0 : case poison_kind::popped_stack:
1312 0 : return "popped stack";
1313 : }
1314 : }
1315 :
1316 : /* class poisoned_svalue : public svalue. */
1317 :
1318 : /* Implementation of svalue::dump_to_pp vfunc for poisoned_svalue. */
1319 :
1320 : void
1321 4 : poisoned_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
1322 : {
1323 4 : if (simple)
1324 : {
1325 4 : pp_string (pp, "POISONED(");
1326 4 : print_quoted_type (pp, get_type ());
1327 4 : pp_printf (pp, ", %s)", poison_kind_to_str (m_kind));
1328 : }
1329 : else
1330 : {
1331 0 : pp_string (pp, "poisoned_svalue(");
1332 0 : print_quoted_type (pp, get_type ());
1333 0 : pp_printf (pp, ", %s)", poison_kind_to_str (m_kind));
1334 : }
1335 4 : }
1336 :
1337 : /* Implementation of svalue::print_dump_widget_label vfunc for
1338 : poisoned_svalue. */
1339 :
1340 : void
1341 0 : poisoned_svalue::print_dump_widget_label (pretty_printer *pp) const
1342 : {
1343 0 : pp_printf (pp, "poisoned_svalue(%s)", poison_kind_to_str (m_kind));
1344 0 : }
1345 :
1346 : /* Implementation of svalue::add_dump_widget_children vfunc for
1347 : poisoned_svalue. */
1348 :
1349 : void
1350 0 : poisoned_svalue::
1351 : add_dump_widget_children (text_art::tree_widget &,
1352 : const text_art::dump_widget_info &) const
1353 : {
1354 : /* No children. */
1355 0 : }
1356 :
1357 : /* Implementation of svalue::accept vfunc for poisoned_svalue. */
1358 :
1359 : void
1360 12768 : poisoned_svalue::accept (visitor *v) const
1361 : {
1362 12768 : v->visit_poisoned_svalue (this);
1363 12768 : }
1364 :
1365 : /* Implementation of svalue::maybe_fold_bits_within vfunc
1366 : for poisoned_svalue. */
1367 :
1368 : const svalue *
1369 5701 : poisoned_svalue::maybe_fold_bits_within (tree type,
1370 : const bit_range &,
1371 : region_model_manager *mgr) const
1372 : {
1373 : /* Bits within a poisoned value are also poisoned. */
1374 5701 : return mgr->get_or_create_poisoned_svalue (m_kind, type);
1375 : }
1376 :
1377 : /* class setjmp_svalue's implementation is in setjmp-longjmp.cc. */
1378 :
1379 : /* class initial_svalue : public svalue. */
1380 :
1381 : /* Implementation of svalue::dump_to_pp vfunc for initial_svalue. */
1382 :
1383 : void
1384 11953 : initial_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
1385 : {
1386 11953 : if (simple)
1387 : {
1388 11817 : pp_string (pp, "INIT_VAL(");
1389 11817 : m_reg->dump_to_pp (pp, simple);
1390 11817 : pp_string (pp, ")");
1391 : }
1392 : else
1393 : {
1394 136 : pp_string (pp, "initial_svalue(");
1395 136 : if (get_type ())
1396 : {
1397 136 : print_quoted_type (pp, get_type ());
1398 136 : pp_string (pp, ", ");
1399 : }
1400 136 : m_reg->dump_to_pp (pp, simple);
1401 136 : pp_string (pp, ")");
1402 : }
1403 11953 : }
1404 :
1405 : /* Implementation of svalue::print_dump_widget_label vfunc for
1406 : initial_svalue. */
1407 :
1408 : void
1409 0 : initial_svalue::print_dump_widget_label (pretty_printer *pp) const
1410 : {
1411 0 : pp_printf (pp, "initial_svalue");
1412 0 : }
1413 :
1414 : /* Implementation of svalue::add_dump_widget_children vfunc for
1415 : initial_svalue. */
1416 :
1417 : void
1418 0 : initial_svalue::
1419 : add_dump_widget_children (text_art::tree_widget &w,
1420 : const text_art::dump_widget_info &dwi) const
1421 : {
1422 0 : w.add_child (m_reg->make_dump_widget (dwi, "m_reg"));
1423 0 : }
1424 :
1425 : /* Implementation of svalue::accept vfunc for initial_svalue. */
1426 :
1427 : void
1428 1569048 : initial_svalue::accept (visitor *v) const
1429 : {
1430 1569048 : m_reg->accept (v);
1431 1569048 : v->visit_initial_svalue (this);
1432 1569048 : }
1433 :
1434 : /* Implementation of svalue::implicitly_live_p vfunc for initial_svalue. */
1435 :
1436 : bool
1437 2647090 : initial_svalue::implicitly_live_p (const svalue_set *,
1438 : const region_model *model) const
1439 : {
1440 : /* This svalue may be implicitly live if the region still implicitly
1441 : has its initial value and is reachable. */
1442 :
1443 : /* It must be a region that exists; we don't want to consider
1444 : INIT_VAL(R) as still being implicitly reachable if R is in
1445 : a popped stack frame. */
1446 2647090 : if (model->region_exists_p (m_reg))
1447 : {
1448 2630757 : const svalue *reg_sval = model->get_store_value (m_reg, nullptr);
1449 2630757 : if (reg_sval == this)
1450 : return true;
1451 : }
1452 :
1453 : /* Assume that the initial values of params for the top level frame
1454 : are still live, because (presumably) they're still
1455 : live in the external caller. */
1456 150008 : if (initial_value_of_param_p ())
1457 15431 : if (const frame_region *frame_reg = m_reg->maybe_get_frame_region ())
1458 15431 : if (frame_reg->get_calling_frame () == nullptr)
1459 : return true;
1460 :
1461 : return false;
1462 : }
1463 :
1464 : /* Return true if this is the initial value of a function parameter. */
1465 :
1466 : bool
1467 154174 : initial_svalue::initial_value_of_param_p () const
1468 : {
1469 154174 : if (tree reg_decl = m_reg->maybe_get_decl ())
1470 88403 : if (TREE_CODE (reg_decl) == SSA_NAME)
1471 : {
1472 15478 : tree ssa_name = reg_decl;
1473 15478 : if (SSA_NAME_IS_DEFAULT_DEF (ssa_name)
1474 15478 : && SSA_NAME_VAR (ssa_name)
1475 30956 : && TREE_CODE (SSA_NAME_VAR (ssa_name)) == PARM_DECL)
1476 15463 : return true;
1477 : }
1478 : return false;
1479 : }
1480 :
1481 : /* class unaryop_svalue : public svalue. */
1482 :
1483 : /* Implementation of svalue::dump_to_pp vfunc for unaryop_svalue. */
1484 :
1485 : void
1486 4548 : unaryop_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
1487 : {
1488 4548 : if (simple)
1489 : {
1490 4382 : if (m_op == VIEW_CONVERT_EXPR || m_op == NOP_EXPR)
1491 : {
1492 4201 : pp_string (pp, "CAST(");
1493 4201 : dump_tree (pp, get_type ());
1494 4201 : pp_string (pp, ", ");
1495 4201 : m_arg->dump_to_pp (pp, simple);
1496 4201 : pp_character (pp, ')');
1497 : }
1498 : else
1499 : {
1500 181 : pp_character (pp, '(');
1501 181 : pp_string (pp, get_tree_code_name (m_op));
1502 : //pp_string (pp, op_symbol_code (m_op));
1503 181 : m_arg->dump_to_pp (pp, simple);
1504 181 : pp_character (pp, ')');
1505 : }
1506 : }
1507 : else
1508 : {
1509 166 : pp_string (pp, "unaryop_svalue (");
1510 166 : pp_string (pp, get_tree_code_name (m_op));
1511 166 : pp_string (pp, ", ");
1512 166 : m_arg->dump_to_pp (pp, simple);
1513 166 : pp_character (pp, ')');
1514 : }
1515 4548 : }
1516 :
1517 : /* Implementation of svalue::print_dump_widget_label vfunc for
1518 : unaryop_svalue. */
1519 :
1520 : void
1521 0 : unaryop_svalue::print_dump_widget_label (pretty_printer *pp) const
1522 : {
1523 0 : pp_printf (pp,
1524 : "unaryop_svalue(%s)",
1525 0 : get_tree_code_name (m_op));
1526 0 : }
1527 :
1528 : /* Implementation of svalue::add_dump_widget_children vfunc for
1529 : unaryop_svalue. */
1530 :
1531 : void
1532 0 : unaryop_svalue::
1533 : add_dump_widget_children (text_art::tree_widget &w,
1534 : const text_art::dump_widget_info &dwi) const
1535 : {
1536 0 : w.add_child (m_arg->make_dump_widget (dwi));
1537 0 : }
1538 :
1539 : /* Implementation of svalue::accept vfunc for unaryop_svalue. */
1540 :
1541 : void
1542 7054495 : unaryop_svalue::accept (visitor *v) const
1543 : {
1544 7054495 : m_arg->accept (v);
1545 7054495 : v->visit_unaryop_svalue (this);
1546 7054495 : }
1547 :
1548 : /* Implementation of svalue::implicitly_live_p vfunc for unaryop_svalue. */
1549 :
1550 : bool
1551 1046277 : unaryop_svalue::implicitly_live_p (const svalue_set *live_svalues,
1552 : const region_model *model) const
1553 : {
1554 1046277 : return get_arg ()->live_p (live_svalues, model);
1555 : }
1556 :
1557 : /* Implementation of svalue::maybe_fold_bits_within vfunc
1558 : for unaryop_svalue. */
1559 :
1560 : const svalue *
1561 3402 : unaryop_svalue::maybe_fold_bits_within (tree type,
1562 : const bit_range &,
1563 : region_model_manager *mgr) const
1564 : {
1565 3402 : switch (m_op)
1566 : {
1567 : default:
1568 : break;
1569 3402 : case NOP_EXPR:
1570 : /* A cast of zero is zero. */
1571 3402 : if (tree cst = m_arg->maybe_get_constant ())
1572 3402 : if (zerop (cst))
1573 : {
1574 3402 : if (type)
1575 140 : return mgr->get_or_create_cast (type, this);
1576 : else
1577 3262 : return this;
1578 : }
1579 : break;
1580 : }
1581 : /* Otherwise, don't fold. */
1582 : return nullptr;
1583 : }
1584 :
1585 : /* Implementation of svalue::maybe_get_value_range_1 for unaryop_svalue. */
1586 :
1587 : bool
1588 16061 : unaryop_svalue::maybe_get_value_range_1 (value_range &out) const
1589 : {
1590 16061 : tree type = get_type ();
1591 16061 : if (!type_can_have_value_range_p (type))
1592 : return false;
1593 :
1594 16027 : value_range arg_vr;
1595 16027 : if (m_arg->maybe_get_value_range (arg_vr))
1596 : {
1597 15136 : range_op_handler handler (m_op);
1598 15136 : if (handler
1599 30272 : && handler.operand_check_p (type, arg_vr.type (), type))
1600 : {
1601 : /* For unary ops, range_op_hander::fold_range expects
1602 : a VARYING of the unknown value as the 2nd operand. */
1603 15134 : value_range varying (type);
1604 15134 : varying.set_varying (type);
1605 15134 : out.set_range_class (type);
1606 15134 : if (handler.fold_range (out, type, arg_vr, varying))
1607 15134 : return true;
1608 15134 : }
1609 : }
1610 : return false;
1611 16027 : }
1612 :
1613 : /* class binop_svalue : public svalue. */
1614 :
1615 : /* Return whether OP be printed as an infix operator. */
1616 :
1617 : static bool
1618 10065 : infix_p (enum tree_code op)
1619 : {
1620 0 : switch (op)
1621 : {
1622 : default:
1623 : return true;
1624 0 : case MAX_EXPR:
1625 0 : case MIN_EXPR:
1626 0 : return false;
1627 : }
1628 : }
1629 :
1630 : /* Implementation of svalue::dump_to_pp vfunc for binop_svalue. */
1631 :
1632 : void
1633 10504 : binop_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
1634 : {
1635 10504 : if (simple)
1636 : {
1637 10065 : if (infix_p (m_op))
1638 : {
1639 : /* Print "(A OP B)". */
1640 10065 : pp_character (pp, '(');
1641 10065 : m_arg0->dump_to_pp (pp, simple);
1642 10065 : pp_string (pp, op_symbol_code (m_op));
1643 10065 : m_arg1->dump_to_pp (pp, simple);
1644 10065 : pp_character (pp, ')');
1645 : }
1646 : else
1647 : {
1648 : /* Print "OP(A, B)". */
1649 0 : pp_string (pp, op_symbol_code (m_op));
1650 0 : pp_character (pp, '(');
1651 0 : m_arg0->dump_to_pp (pp, simple);
1652 0 : pp_string (pp, ", ");
1653 0 : m_arg1->dump_to_pp (pp, simple);
1654 0 : pp_character (pp, ')');
1655 : }
1656 : }
1657 : else
1658 : {
1659 439 : pp_string (pp, "binop_svalue (");
1660 439 : pp_string (pp, get_tree_code_name (m_op));
1661 439 : pp_string (pp, ", ");
1662 439 : m_arg0->dump_to_pp (pp, simple);
1663 439 : pp_string (pp, ", ");
1664 439 : m_arg1->dump_to_pp (pp, simple);
1665 439 : pp_character (pp, ')');
1666 : }
1667 10504 : }
1668 :
1669 : /* Implementation of svalue::print_dump_widget_label vfunc for
1670 : binop_svalue. */
1671 :
1672 : void
1673 0 : binop_svalue::print_dump_widget_label (pretty_printer *pp) const
1674 : {
1675 0 : pp_printf (pp,
1676 : "binop_svalue(%s: %qs)",
1677 0 : get_tree_code_name (m_op),
1678 0 : op_symbol_code (m_op));
1679 0 : }
1680 :
1681 : /* Implementation of svalue::add_dump_widget_children vfunc for
1682 : binop_svalue. */
1683 :
1684 : void
1685 0 : binop_svalue::
1686 : add_dump_widget_children (text_art::tree_widget &w,
1687 : const text_art::dump_widget_info &dwi) const
1688 : {
1689 0 : w.add_child (m_arg0->make_dump_widget (dwi));
1690 0 : w.add_child (m_arg1->make_dump_widget (dwi));
1691 0 : }
1692 :
1693 : /* Implementation of svalue::accept vfunc for binop_svalue. */
1694 :
1695 : void
1696 6260618 : binop_svalue::accept (visitor *v) const
1697 : {
1698 6260618 : m_arg0->accept (v);
1699 6260618 : m_arg1->accept (v);
1700 6260618 : v->visit_binop_svalue (this);
1701 6260618 : }
1702 :
1703 : /* Implementation of svalue::implicitly_live_p vfunc for binop_svalue. */
1704 :
1705 : bool
1706 1122414 : binop_svalue::implicitly_live_p (const svalue_set *live_svalues,
1707 : const region_model *model) const
1708 : {
1709 1122414 : return (get_arg0 ()->live_p (live_svalues, model)
1710 1122414 : && get_arg1 ()->live_p (live_svalues, model));
1711 : }
1712 :
1713 : /* class sub_svalue : public svalue. */
1714 :
1715 : /* sub_svalue'c ctor. */
1716 :
1717 2331 : sub_svalue::sub_svalue (symbol::id_t id,
1718 : tree type, const svalue *parent_svalue,
1719 2331 : const region *subregion)
1720 : : svalue (complexity::from_pair (parent_svalue->get_complexity (),
1721 : subregion->get_complexity ()),
1722 : id,
1723 : type),
1724 2331 : m_parent_svalue (parent_svalue), m_subregion (subregion)
1725 : {
1726 2331 : gcc_assert (parent_svalue->can_have_associated_state_p ());
1727 2331 : }
1728 :
1729 : /* Implementation of svalue::maybe_get_value_range_1 for binop_svalue. */
1730 :
1731 : bool
1732 26272 : binop_svalue::maybe_get_value_range_1 (value_range &out) const
1733 : {
1734 26272 : tree type = get_type ();
1735 26272 : if (!type_can_have_value_range_p (type))
1736 : return false;
1737 :
1738 : /* Avoid cases where we have been sloppy about types. */
1739 24589 : if (!m_arg0->get_type ())
1740 : return false;
1741 24589 : if (!m_arg1->get_type ())
1742 : return false;
1743 24589 : if (!range_compatible_p (m_arg0->get_type (), m_arg1->get_type ()))
1744 : return false;
1745 :
1746 24411 : value_range lhs, rhs;
1747 24411 : if (m_arg0->maybe_get_value_range (lhs))
1748 22293 : if (m_arg1->maybe_get_value_range (rhs))
1749 : {
1750 22139 : range_op_handler handler (m_op);
1751 22139 : if (handler)
1752 : {
1753 22139 : out.set_range_class (type);
1754 22139 : if (handler.fold_range (out, get_type (), lhs, rhs))
1755 22139 : return true;
1756 : }
1757 : }
1758 : return false;
1759 24411 : }
1760 :
1761 : /* Implementation of svalue::dump_to_pp vfunc for sub_svalue. */
1762 :
1763 : void
1764 1273 : sub_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
1765 : {
1766 1273 : if (simple)
1767 : {
1768 1222 : pp_string (pp, "SUB(");
1769 1222 : m_parent_svalue->dump_to_pp (pp, simple);
1770 1222 : pp_string (pp, ", ");
1771 1222 : m_subregion->dump_to_pp (pp, simple);
1772 1222 : pp_character (pp, ')');
1773 : }
1774 : else
1775 : {
1776 51 : pp_string (pp, "sub_svalue (");
1777 51 : pp_string (pp, ", ");
1778 51 : m_parent_svalue->dump_to_pp (pp, simple);
1779 51 : pp_string (pp, ", ");
1780 51 : m_subregion->dump_to_pp (pp, simple);
1781 51 : pp_character (pp, ')');
1782 : }
1783 1273 : }
1784 :
1785 : /* Implementation of svalue::print_dump_widget_label vfunc for
1786 : sub_svalue. */
1787 :
1788 : void
1789 0 : sub_svalue::print_dump_widget_label (pretty_printer *pp) const
1790 : {
1791 0 : pp_printf (pp, "sub_svalue");
1792 0 : }
1793 :
1794 : /* Implementation of svalue::add_dump_widget_children vfunc for
1795 : sub_svalue. */
1796 :
1797 : void
1798 0 : sub_svalue::
1799 : add_dump_widget_children (text_art::tree_widget &w,
1800 : const text_art::dump_widget_info &dwi) const
1801 : {
1802 0 : w.add_child (m_parent_svalue->make_dump_widget (dwi, "m_parent_svalue"));
1803 0 : w.add_child (m_subregion->make_dump_widget (dwi, "m_subregion"));
1804 0 : }
1805 :
1806 : /* Implementation of svalue::accept vfunc for sub_svalue. */
1807 :
1808 : void
1809 3944631 : sub_svalue::accept (visitor *v) const
1810 : {
1811 3944631 : m_parent_svalue->accept (v);
1812 3944631 : m_subregion->accept (v);
1813 3944631 : v->visit_sub_svalue (this);
1814 3944631 : }
1815 :
1816 : /* Implementation of svalue::implicitly_live_p vfunc for sub_svalue. */
1817 :
1818 : bool
1819 594129 : sub_svalue::implicitly_live_p (const svalue_set *live_svalues,
1820 : const region_model *model) const
1821 : {
1822 594129 : return get_parent ()->live_p (live_svalues, model);
1823 : }
1824 :
1825 : /* class repeated_svalue : public svalue. */
1826 :
1827 : /* repeated_svalue'c ctor. */
1828 :
1829 512 : repeated_svalue::repeated_svalue (symbol::id_t id,
1830 : tree type,
1831 : const svalue *outer_size,
1832 512 : const svalue *inner_svalue)
1833 512 : : svalue (complexity::from_pair (outer_size, inner_svalue), id, type),
1834 512 : m_outer_size (outer_size),
1835 1024 : m_inner_svalue (inner_svalue)
1836 : {
1837 512 : gcc_assert (outer_size->can_have_associated_state_p ());
1838 512 : gcc_assert (inner_svalue->can_have_associated_state_p ());
1839 512 : }
1840 :
1841 : /* Implementation of svalue::dump_to_pp vfunc for repeated_svalue. */
1842 :
1843 : void
1844 0 : repeated_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
1845 : {
1846 0 : if (simple)
1847 : {
1848 0 : pp_string (pp, "REPEATED(");
1849 0 : if (get_type ())
1850 : {
1851 0 : print_quoted_type (pp, get_type ());
1852 0 : pp_string (pp, ", ");
1853 : }
1854 0 : pp_string (pp, "outer_size: ");
1855 0 : m_outer_size->dump_to_pp (pp, simple);
1856 0 : pp_string (pp, ", inner_val: ");
1857 0 : m_inner_svalue->dump_to_pp (pp, simple);
1858 0 : pp_character (pp, ')');
1859 : }
1860 : else
1861 : {
1862 0 : pp_string (pp, "repeated_svalue (");
1863 0 : if (get_type ())
1864 : {
1865 0 : print_quoted_type (pp, get_type ());
1866 0 : pp_string (pp, ", ");
1867 : }
1868 0 : pp_string (pp, "outer_size: ");
1869 0 : m_outer_size->dump_to_pp (pp, simple);
1870 0 : pp_string (pp, ", inner_val: ");
1871 0 : m_inner_svalue->dump_to_pp (pp, simple);
1872 0 : pp_character (pp, ')');
1873 : }
1874 0 : }
1875 :
1876 : /* Implementation of svalue::print_dump_widget_label vfunc for
1877 : repeated_svalue. */
1878 :
1879 : void
1880 0 : repeated_svalue::print_dump_widget_label (pretty_printer *pp) const
1881 : {
1882 0 : pp_printf (pp, "repeated_svalue");
1883 0 : }
1884 :
1885 : /* Implementation of svalue::add_dump_widget_children vfunc for
1886 : repeated_svalue. */
1887 :
1888 : void
1889 0 : repeated_svalue::
1890 : add_dump_widget_children (text_art::tree_widget &w,
1891 : const text_art::dump_widget_info &dwi) const
1892 : {
1893 0 : w.add_child (m_outer_size->make_dump_widget (dwi, "m_outer_size"));
1894 0 : w.add_child (m_inner_svalue->make_dump_widget (dwi, "m_inner_svalue"));
1895 0 : }
1896 :
1897 : /* Implementation of svalue::accept vfunc for repeated_svalue. */
1898 :
1899 : void
1900 45188 : repeated_svalue::accept (visitor *v) const
1901 : {
1902 45188 : m_inner_svalue->accept (v);
1903 45188 : v->visit_repeated_svalue (this);
1904 45188 : }
1905 :
1906 : /* Implementation of svalue::all_zeroes_p for repeated_svalue. */
1907 :
1908 : bool
1909 1925 : repeated_svalue::all_zeroes_p () const
1910 : {
1911 1925 : return m_inner_svalue->all_zeroes_p ();
1912 : }
1913 :
1914 : /* Implementation of svalue::maybe_fold_bits_within vfunc
1915 : for repeated_svalue. */
1916 :
1917 : const svalue *
1918 1625 : repeated_svalue::maybe_fold_bits_within (tree type,
1919 : const bit_range &bits,
1920 : region_model_manager *mgr) const
1921 : {
1922 1625 : const svalue *innermost_sval = m_inner_svalue;
1923 : /* Fold
1924 : BITS_WITHIN (range, REPEATED_SVALUE (ZERO))
1925 : to:
1926 : REPEATED_SVALUE (ZERO). */
1927 1625 : if (all_zeroes_p ())
1928 : {
1929 1313 : byte_range bytes (0,0);
1930 1313 : if (bits.as_byte_range (&bytes))
1931 : {
1932 1313 : const svalue *byte_size
1933 1313 : = mgr->get_or_create_int_cst (size_type_node,
1934 1313 : bytes.m_size_in_bytes.to_uhwi ());
1935 1313 : return mgr->get_or_create_repeated_svalue (type, byte_size,
1936 1313 : innermost_sval);
1937 : }
1938 : }
1939 :
1940 : /* Fold:
1941 : BITS_WITHIN (range, REPEATED_SVALUE (INNERMOST_SVALUE))
1942 : to:
1943 : BITS_WITHIN (range - offset, INNERMOST_SVALUE)
1944 : if range is fully within one instance of INNERMOST_SVALUE. */
1945 312 : if (tree innermost_type = innermost_sval->get_type ())
1946 : {
1947 312 : bit_size_t element_bit_size;
1948 312 : if (int_size_in_bits (innermost_type, &element_bit_size)
1949 312 : && element_bit_size > 0)
1950 : {
1951 312 : HOST_WIDE_INT start_idx
1952 312 : = (bits.get_start_bit_offset ()
1953 312 : / element_bit_size).to_shwi ();
1954 312 : HOST_WIDE_INT last_idx
1955 312 : = (bits.get_last_bit_offset ()
1956 312 : / element_bit_size).to_shwi ();
1957 312 : if (start_idx == last_idx)
1958 : {
1959 288 : bit_offset_t start_of_element
1960 288 : = start_idx * element_bit_size;
1961 288 : bit_range range_within_element
1962 288 : (bits.m_start_bit_offset - start_of_element,
1963 288 : bits.m_size_in_bits);
1964 288 : return mgr->get_or_create_bits_within (type,
1965 : range_within_element,
1966 : innermost_sval);
1967 : }
1968 : }
1969 : }
1970 :
1971 : return nullptr;
1972 : }
1973 :
1974 : /* class bits_within_svalue : public svalue. */
1975 :
1976 : /* bits_within_svalue'c ctor. */
1977 :
1978 763 : bits_within_svalue::bits_within_svalue (symbol::id_t id,
1979 : tree type,
1980 : const bit_range &bits,
1981 763 : const svalue *inner_svalue)
1982 763 : : svalue (complexity (inner_svalue), id, type),
1983 763 : m_bits (bits),
1984 763 : m_inner_svalue (inner_svalue)
1985 : {
1986 763 : gcc_assert (inner_svalue->can_have_associated_state_p ());
1987 763 : }
1988 :
1989 : /* Implementation of svalue::dump_to_pp vfunc for bits_within_svalue. */
1990 :
1991 : void
1992 610 : bits_within_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
1993 : {
1994 610 : if (simple)
1995 : {
1996 504 : pp_string (pp, "BITS_WITHIN(");
1997 504 : if (get_type ())
1998 : {
1999 0 : print_quoted_type (pp, get_type ());
2000 0 : pp_string (pp, ", ");
2001 : }
2002 504 : m_bits.dump_to_pp (pp);
2003 504 : pp_string (pp, ", inner_val: ");
2004 504 : m_inner_svalue->dump_to_pp (pp, simple);
2005 504 : pp_character (pp, ')');
2006 : }
2007 : else
2008 : {
2009 106 : pp_string (pp, "bits_within_svalue (");
2010 106 : if (get_type ())
2011 : {
2012 0 : print_quoted_type (pp, get_type ());
2013 0 : pp_string (pp, ", ");
2014 : }
2015 106 : m_bits.dump_to_pp (pp);
2016 106 : pp_string (pp, ", inner_val: ");
2017 106 : m_inner_svalue->dump_to_pp (pp, simple);
2018 106 : pp_character (pp, ')');
2019 : }
2020 610 : }
2021 :
2022 : /* Implementation of svalue::print_dump_widget_label vfunc for
2023 : bits_within_svalue. */
2024 :
2025 : void
2026 0 : bits_within_svalue::print_dump_widget_label (pretty_printer *pp) const
2027 : {
2028 0 : pp_printf (pp, "bits_within_svalue: ");
2029 0 : m_bits.dump_to_pp (pp);
2030 0 : }
2031 :
2032 : /* Implementation of svalue::add_dump_widget_children vfunc for
2033 : bits_within_svalue. */
2034 :
2035 : void
2036 0 : bits_within_svalue::
2037 : add_dump_widget_children (text_art::tree_widget &w,
2038 : const text_art::dump_widget_info &dwi) const
2039 : {
2040 0 : w.add_child (m_inner_svalue->make_dump_widget (dwi, "m_inner_svalue"));
2041 0 : }
2042 :
2043 : /* Implementation of svalue::maybe_fold_bits_within vfunc
2044 : for bits_within_svalue. */
2045 :
2046 : const svalue *
2047 777 : bits_within_svalue::maybe_fold_bits_within (tree type,
2048 : const bit_range &bits,
2049 : region_model_manager *mgr) const
2050 : {
2051 : /* Fold:
2052 : BITS_WITHIN (range1, BITS_WITHIN (range2, VAL))
2053 : to:
2054 : BITS_WITHIN (range1 in range 2, VAL). */
2055 1554 : bit_range offset_bits (m_bits.get_start_bit_offset ()
2056 777 : + bits.m_start_bit_offset,
2057 777 : bits.m_size_in_bits);
2058 777 : return mgr->get_or_create_bits_within (type, offset_bits, m_inner_svalue);
2059 : }
2060 :
2061 : /* Implementation of svalue::accept vfunc for bits_within_svalue. */
2062 :
2063 : void
2064 49232 : bits_within_svalue::accept (visitor *v) const
2065 : {
2066 49232 : m_inner_svalue->accept (v);
2067 49232 : v->visit_bits_within_svalue (this);
2068 49232 : }
2069 :
2070 : /* Implementation of svalue::implicitly_live_p vfunc for bits_within_svalue. */
2071 :
2072 : bool
2073 695 : bits_within_svalue::implicitly_live_p (const svalue_set *live_svalues,
2074 : const region_model *model) const
2075 : {
2076 695 : return m_inner_svalue->live_p (live_svalues, model);
2077 : }
2078 :
2079 : /* class widening_svalue : public svalue. */
2080 :
2081 : /* Implementation of svalue::dump_to_pp vfunc for widening_svalue. */
2082 :
2083 : void
2084 3901 : widening_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
2085 : {
2086 3901 : if (simple)
2087 : {
2088 3677 : pp_string (pp, "WIDENING(");
2089 3677 : pp_character (pp, '{');
2090 3677 : m_snode->print (pp);
2091 3677 : pp_string (pp, "}, ");
2092 3677 : m_base_sval->dump_to_pp (pp, simple);
2093 3677 : pp_string (pp, ", ");
2094 3677 : m_iter_sval->dump_to_pp (pp, simple);
2095 3677 : pp_character (pp, ')');
2096 : }
2097 : else
2098 : {
2099 224 : pp_string (pp, "widening_svalue (");
2100 224 : pp_string (pp, ", ");
2101 224 : pp_character (pp, '{');
2102 224 : m_snode->print (pp);
2103 224 : pp_string (pp, "}, ");
2104 224 : m_base_sval->dump_to_pp (pp, simple);
2105 224 : pp_string (pp, ", ");
2106 224 : m_iter_sval->dump_to_pp (pp, simple);
2107 224 : pp_character (pp, ')');
2108 : }
2109 3901 : }
2110 :
2111 : /* Implementation of svalue::print_dump_widget_label vfunc for
2112 : widening_svalue. */
2113 :
2114 : void
2115 0 : widening_svalue::print_dump_widget_label (pretty_printer *pp) const
2116 : {
2117 0 : pp_printf (pp, "widening_svalue at ");
2118 0 : m_snode->print (pp);
2119 0 : }
2120 :
2121 : /* Implementation of svalue::add_dump_widget_children vfunc for
2122 : widening_svalue. */
2123 :
2124 : void
2125 0 : widening_svalue::
2126 : add_dump_widget_children (text_art::tree_widget &w,
2127 : const text_art::dump_widget_info &dwi) const
2128 : {
2129 0 : w.add_child (m_base_sval->make_dump_widget (dwi, "m_base_sval"));
2130 0 : w.add_child (m_iter_sval->make_dump_widget (dwi, "m_iter_sval"));
2131 0 : }
2132 :
2133 : /* Implementation of svalue::accept vfunc for widening_svalue. */
2134 :
2135 : void
2136 116984 : widening_svalue::accept (visitor *v) const
2137 : {
2138 116984 : m_base_sval->accept (v);
2139 116984 : m_iter_sval->accept (v);
2140 116984 : v->visit_widening_svalue (this);
2141 116984 : }
2142 :
2143 : /* Attempt to determine in which direction this value is changing
2144 : w.r.t. the initial value. */
2145 :
2146 : enum widening_svalue::direction_t
2147 1922 : widening_svalue::get_direction () const
2148 : {
2149 1922 : tree base_cst = m_base_sval->maybe_get_constant ();
2150 1922 : if (base_cst == NULL_TREE)
2151 : return DIR_UNKNOWN;
2152 1922 : tree iter_cst = m_iter_sval->maybe_get_constant ();
2153 1922 : if (iter_cst == NULL_TREE)
2154 : return DIR_UNKNOWN;
2155 :
2156 1922 : tree iter_gt_base = fold_binary (GT_EXPR, boolean_type_node,
2157 : iter_cst, base_cst);
2158 1922 : if (iter_gt_base == boolean_true_node)
2159 : return DIR_ASCENDING;
2160 :
2161 489 : tree iter_lt_base = fold_binary (LT_EXPR, boolean_type_node,
2162 : iter_cst, base_cst);
2163 489 : if (iter_lt_base == boolean_true_node)
2164 : return DIR_DESCENDING;
2165 :
2166 : return DIR_UNKNOWN;
2167 : }
2168 :
2169 : /* Compare this value against constant RHS_CST. */
2170 :
2171 : tristate
2172 2934 : widening_svalue::eval_condition_without_cm (enum tree_code op,
2173 : tree rhs_cst) const
2174 : {
2175 2934 : tree base_cst = m_base_sval->maybe_get_constant ();
2176 2934 : if (base_cst == NULL_TREE)
2177 1020 : return tristate::TS_UNKNOWN;
2178 1914 : tree iter_cst = m_iter_sval->maybe_get_constant ();
2179 1914 : if (iter_cst == NULL_TREE)
2180 0 : return tristate::TS_UNKNOWN;
2181 :
2182 1914 : switch (get_direction ())
2183 : {
2184 0 : default:
2185 0 : gcc_unreachable ();
2186 1425 : case DIR_ASCENDING:
2187 : /* LHS is in [base_cst, +ve infinity), assuming no overflow. */
2188 1425 : switch (op)
2189 : {
2190 281 : case LE_EXPR:
2191 281 : case LT_EXPR:
2192 281 : {
2193 : /* [BASE, +INF) OP RHS:
2194 : This is either true or false at +ve ininity,
2195 : It can be true for points X where X OP RHS, so we have either
2196 : "false", or "unknown". */
2197 281 : tree base_op_rhs = fold_binary (op, boolean_type_node,
2198 : base_cst, rhs_cst);
2199 281 : if (base_op_rhs == boolean_true_node)
2200 265 : return tristate::TS_UNKNOWN;
2201 : else
2202 16 : return tristate::TS_FALSE;
2203 : }
2204 :
2205 804 : case GE_EXPR:
2206 804 : case GT_EXPR:
2207 804 : {
2208 : /* [BASE, +INF) OP RHS:
2209 : This is true at +ve infinity. It will be true everywhere
2210 : in the range if BASE >= RHS. */
2211 804 : tree base_op_rhs = fold_binary (op, boolean_type_node,
2212 : base_cst, rhs_cst);
2213 804 : if (base_op_rhs == boolean_true_node)
2214 61 : return tristate::TS_TRUE;
2215 : else
2216 743 : return tristate::TS_UNKNOWN;
2217 : }
2218 :
2219 168 : case EQ_EXPR:
2220 168 : {
2221 : /* [BASE, +INF) == RHS:
2222 : Could this be true at any point in the range? If so we
2223 : have "unknown", otherwise we have "false". */
2224 168 : tree base_le_rhs = fold_binary (LE_EXPR, boolean_type_node,
2225 : base_cst, rhs_cst);
2226 168 : if (base_le_rhs == boolean_true_node)
2227 158 : return tristate::TS_UNKNOWN;
2228 : else
2229 10 : return tristate::TS_FALSE;
2230 : }
2231 :
2232 172 : case NE_EXPR:
2233 172 : {
2234 : /* [BASE, +INF) != RHS:
2235 : Could we have equality at any point in the range? If so we
2236 : have "unknown", otherwise we have "true". */
2237 172 : tree base_le_rhs = fold_binary (LE_EXPR, boolean_type_node,
2238 : base_cst, rhs_cst);
2239 172 : if (base_le_rhs == boolean_true_node)
2240 162 : return tristate::TS_UNKNOWN;
2241 : else
2242 10 : return tristate::TS_TRUE;
2243 : }
2244 :
2245 0 : default:
2246 0 : return tristate::TS_UNKNOWN;
2247 : }
2248 :
2249 447 : case DIR_DESCENDING:
2250 : /* LHS is in (-ve infinity, base_cst], assuming no overflow. */
2251 447 : return tristate::TS_UNKNOWN;
2252 :
2253 42 : case DIR_UNKNOWN:
2254 42 : return tristate::TS_UNKNOWN;
2255 : }
2256 : }
2257 :
2258 : /* class placeholder_svalue : public svalue. */
2259 :
2260 : /* Implementation of svalue::dump_to_pp vfunc for placeholder_svalue. */
2261 :
2262 : void
2263 0 : placeholder_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
2264 : {
2265 0 : if (simple)
2266 0 : pp_printf (pp, "PLACEHOLDER(%qs)", m_name);
2267 : else
2268 0 : pp_printf (pp, "placeholder_svalue (%qs)", m_name);
2269 0 : }
2270 :
2271 : /* Implementation of svalue::print_dump_widget_label vfunc for
2272 : placeholder_svalue. */
2273 :
2274 : void
2275 0 : placeholder_svalue::print_dump_widget_label (pretty_printer *pp) const
2276 : {
2277 0 : pp_printf (pp, "placeholder_svalue: %qs", m_name);
2278 0 : }
2279 :
2280 : /* Implementation of svalue::add_dump_widget_children vfunc for
2281 : placeholder_svalue. */
2282 :
2283 : void
2284 0 : placeholder_svalue::
2285 : add_dump_widget_children (text_art::tree_widget &,
2286 : const text_art::dump_widget_info &) const
2287 : {
2288 : /* No children. */
2289 0 : }
2290 :
2291 : /* Implementation of svalue::accept vfunc for placeholder_svalue. */
2292 :
2293 : void
2294 38169 : placeholder_svalue::accept (visitor *v) const
2295 : {
2296 38169 : v->visit_placeholder_svalue (this);
2297 38169 : }
2298 :
2299 : /* class unmergeable_svalue : public svalue. */
2300 :
2301 : /* Implementation of svalue::dump_to_pp vfunc for unmergeable_svalue. */
2302 :
2303 : void
2304 20 : unmergeable_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
2305 : {
2306 20 : if (simple)
2307 : {
2308 20 : pp_string (pp, "UNMERGEABLE(");
2309 20 : m_arg->dump_to_pp (pp, simple);
2310 20 : pp_character (pp, ')');
2311 : }
2312 : else
2313 : {
2314 0 : pp_string (pp, "unmergeable_svalue (");
2315 0 : m_arg->dump_to_pp (pp, simple);
2316 0 : pp_character (pp, ')');
2317 : }
2318 20 : }
2319 :
2320 : /* Implementation of svalue::print_dump_widget_label vfunc for
2321 : unmergeable_svalue. */
2322 :
2323 : void
2324 0 : unmergeable_svalue::print_dump_widget_label (pretty_printer *pp) const
2325 : {
2326 0 : pp_printf (pp, "unmergeable_svalue");
2327 0 : }
2328 :
2329 : /* Implementation of svalue::add_dump_widget_children vfunc for
2330 : unmergeable_svalue. */
2331 :
2332 : void
2333 0 : unmergeable_svalue::
2334 : add_dump_widget_children (text_art::tree_widget &w,
2335 : const text_art::dump_widget_info &dwi) const
2336 : {
2337 0 : w.add_child (m_arg->make_dump_widget (dwi));
2338 0 : }
2339 :
2340 : /* Implementation of svalue::accept vfunc for unmergeable_svalue. */
2341 :
2342 : void
2343 6752 : unmergeable_svalue::accept (visitor *v) const
2344 : {
2345 6752 : m_arg->accept (v);
2346 6752 : v->visit_unmergeable_svalue (this);
2347 6752 : }
2348 :
2349 : /* Implementation of svalue::implicitly_live_p vfunc for unmergeable_svalue. */
2350 :
2351 : bool
2352 894 : unmergeable_svalue::implicitly_live_p (const svalue_set *live_svalues,
2353 : const region_model *model) const
2354 : {
2355 894 : return get_arg ()->live_p (live_svalues, model);
2356 : }
2357 :
2358 : /* class compound_svalue : public svalue. */
2359 :
2360 562 : compound_svalue::compound_svalue (symbol::id_t id,
2361 : tree type,
2362 562 : concrete_binding_map &&map)
2363 562 : : svalue (map.calc_complexity (), id, type), m_map (std::move (map))
2364 : {
2365 : #if CHECKING_P
2366 2374 : for (auto iter : *this)
2367 : {
2368 : /* We don't nest compound svalues. */
2369 1812 : const svalue *sval = iter.second;
2370 1812 : gcc_assert (sval->get_kind () != SK_COMPOUND);
2371 : }
2372 : #endif
2373 562 : }
2374 :
2375 50 : compound_svalue::compound_svalue (symbol::id_t id,
2376 : tree type,
2377 50 : const concrete_binding_map &map)
2378 50 : : svalue (map.calc_complexity (), id, type), m_map (map)
2379 : {
2380 : #if CHECKING_P
2381 122 : for (auto iter : *this)
2382 : {
2383 : /* We don't nest compound svalues. */
2384 72 : const svalue *sval = iter.second;
2385 72 : gcc_assert (sval->get_kind () != SK_COMPOUND);
2386 : }
2387 : #endif
2388 50 : }
2389 :
2390 : /* Implementation of svalue::dump_to_pp vfunc for compound_svalue. */
2391 :
2392 : void
2393 2 : compound_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
2394 : {
2395 2 : if (simple)
2396 : {
2397 2 : pp_string (pp, "COMPOUND(");
2398 2 : if (get_type ())
2399 : {
2400 0 : print_quoted_type (pp, get_type ());
2401 0 : pp_string (pp, ", ");
2402 : }
2403 2 : pp_character (pp, '{');
2404 2 : m_map.dump_to_pp (pp, simple, false);
2405 2 : pp_string (pp, "})");
2406 : }
2407 : else
2408 : {
2409 0 : pp_string (pp, "compound_svalue (");
2410 0 : if (get_type ())
2411 : {
2412 0 : print_quoted_type (pp, get_type ());
2413 0 : pp_string (pp, ", ");
2414 : }
2415 0 : pp_character (pp, '{');
2416 0 : m_map.dump_to_pp (pp, simple, false);
2417 0 : pp_string (pp, "})");
2418 : }
2419 2 : }
2420 :
2421 : /* Implementation of svalue::print_dump_widget_label vfunc for
2422 : compound_svalue. */
2423 :
2424 : void
2425 0 : compound_svalue::print_dump_widget_label (pretty_printer *pp) const
2426 : {
2427 0 : pp_printf (pp, "compound_svalue");
2428 0 : }
2429 :
2430 : /* Implementation of svalue::add_dump_widget_children vfunc for
2431 : compound_svalue. */
2432 :
2433 : void
2434 0 : compound_svalue::
2435 : add_dump_widget_children (text_art::tree_widget &w,
2436 : const text_art::dump_widget_info &dwi) const
2437 : {
2438 0 : m_map.add_to_tree_widget (w, dwi);
2439 0 : }
2440 :
2441 : /* Implementation of svalue::accept vfunc for compound_svalue. */
2442 :
2443 : void
2444 38 : compound_svalue::accept (visitor *v) const
2445 : {
2446 114 : for (auto iter : m_map)
2447 76 : iter.second->accept (v);
2448 38 : v->visit_compound_svalue (this);
2449 38 : }
2450 :
2451 : /* Implementation of svalue::maybe_fold_bits_within vfunc
2452 : for compound_svalue. */
2453 :
2454 : const svalue *
2455 56 : compound_svalue::maybe_fold_bits_within (tree type,
2456 : const bit_range &bits,
2457 : region_model_manager *mgr) const
2458 : {
2459 56 : concrete_binding_map result_map;
2460 256 : for (auto iter : m_map)
2461 : {
2462 200 : const bit_range &iter_bits = iter.first;
2463 :
2464 : /* Ignore concrete bindings outside BITS. */
2465 200 : if (!iter_bits.intersects_p (bits))
2466 28 : continue;
2467 :
2468 172 : const svalue *sval = iter.second;
2469 : /* Get the position of iter_bits relative to BITS. */
2470 172 : bit_range result_location (iter_bits.get_start_bit_offset ()
2471 172 : - bits.get_start_bit_offset (),
2472 172 : iter_bits.m_size_in_bits);
2473 : /* If iter_bits starts after BITS, trim off leading bits
2474 : from the svalue and adjust binding location. */
2475 172 : if (result_location.m_start_bit_offset < 0)
2476 : {
2477 0 : bit_size_t leading_bits_to_drop
2478 0 : = -result_location.m_start_bit_offset;
2479 0 : result_location = bit_range
2480 0 : (0, result_location.m_size_in_bits - leading_bits_to_drop);
2481 0 : bit_range bits_within_sval (leading_bits_to_drop,
2482 0 : result_location.m_size_in_bits);
2483 : /* Trim off leading bits from iter_sval. */
2484 0 : sval = mgr->get_or_create_bits_within (NULL_TREE,
2485 : bits_within_sval,
2486 : sval);
2487 : }
2488 : /* If iter_bits finishes after BITS, trim off trailing bits
2489 : from the svalue and adjust binding location. */
2490 344 : if (iter_bits.get_next_bit_offset ()
2491 344 : > bits.get_next_bit_offset ())
2492 : {
2493 44 : bit_size_t trailing_bits_to_drop
2494 44 : = (iter_bits.get_next_bit_offset ()
2495 44 : - bits.get_next_bit_offset ());
2496 44 : result_location = bit_range
2497 : (result_location.m_start_bit_offset,
2498 44 : result_location.m_size_in_bits - trailing_bits_to_drop);
2499 44 : bit_range bits_within_sval (0,
2500 44 : result_location.m_size_in_bits);
2501 : /* Trim off leading bits from iter_sval. */
2502 44 : sval = mgr->get_or_create_bits_within (NULL_TREE,
2503 : bits_within_sval,
2504 : sval);
2505 : }
2506 172 : result_map.insert (result_location, sval);
2507 : }
2508 56 : return mgr->get_or_create_compound_svalue (type, std::move (result_map));
2509 56 : }
2510 :
2511 : /* class conjured_svalue : public svalue. */
2512 :
2513 : /* Implementation of svalue::dump_to_pp vfunc for conjured_svalue. */
2514 :
2515 : void
2516 3194 : conjured_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
2517 : {
2518 3194 : if (simple)
2519 : {
2520 2804 : pp_string (pp, "CONJURED(");
2521 2804 : pp_gimple_stmt_1 (pp, m_stmt, 0, (dump_flags_t)0);
2522 2804 : pp_string (pp, ", ");
2523 2804 : m_id_reg->dump_to_pp (pp, simple);
2524 2804 : pp_character (pp, ')');
2525 : }
2526 : else
2527 : {
2528 390 : pp_string (pp, "conjured_svalue (");
2529 390 : if (get_type ())
2530 : {
2531 390 : print_quoted_type (pp, get_type ());
2532 390 : pp_string (pp, ", ");
2533 : }
2534 390 : pp_gimple_stmt_1 (pp, m_stmt, 0, (dump_flags_t)0);
2535 390 : pp_string (pp, ", ");
2536 390 : m_id_reg->dump_to_pp (pp, simple);
2537 390 : pp_character (pp, ')');
2538 : }
2539 3194 : }
2540 :
2541 : /* Implementation of svalue::print_dump_widget_label vfunc for
2542 : conjured_svalue. */
2543 :
2544 : void
2545 0 : conjured_svalue::print_dump_widget_label (pretty_printer *pp) const
2546 : {
2547 0 : pp_printf (pp, "conjured_svalue (");
2548 0 : pp_gimple_stmt_1 (pp, m_stmt, 0, (dump_flags_t)0);
2549 0 : if (m_idx != 0)
2550 0 : pp_printf (pp, ", %i", m_idx);
2551 0 : pp_character (pp, ')');
2552 0 : }
2553 :
2554 : /* Implementation of svalue::add_dump_widget_children vfunc for
2555 : conjured_svalue. */
2556 :
2557 : void
2558 0 : conjured_svalue::
2559 : add_dump_widget_children (text_art::tree_widget &w,
2560 : const text_art::dump_widget_info &dwi) const
2561 : {
2562 0 : w.add_child (m_id_reg->make_dump_widget (dwi));
2563 0 : }
2564 :
2565 : /* Implementation of svalue::accept vfunc for conjured_svalue. */
2566 :
2567 : void
2568 5303000 : conjured_svalue::accept (visitor *v) const
2569 : {
2570 5303000 : m_id_reg->accept (v);
2571 5303000 : v->visit_conjured_svalue (this);
2572 5303000 : }
2573 :
2574 : /* Return true iff this conjured_svalue is for the LHS of the
2575 : stmt that conjured it. */
2576 :
2577 : bool
2578 0 : conjured_svalue::lhs_value_p () const
2579 : {
2580 0 : if (tree decl = m_id_reg->maybe_get_decl ())
2581 0 : return decl == gimple_get_lhs (m_stmt);
2582 : return false;
2583 : }
2584 :
2585 : /* class asm_output_svalue : public svalue. */
2586 :
2587 : /* Implementation of svalue::dump_to_pp vfunc for asm_output_svalue. */
2588 :
2589 : void
2590 52 : asm_output_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
2591 : {
2592 52 : if (simple)
2593 : {
2594 52 : pp_printf (pp, "ASM_OUTPUT(%qs, %%%i, {",
2595 : get_asm_string (),
2596 : get_output_idx ());
2597 144 : for (unsigned i = 0; i < m_num_inputs; i++)
2598 : {
2599 92 : if (i > 0)
2600 40 : pp_string (pp, ", ");
2601 92 : dump_input (pp, 0, m_input_arr[i], simple);
2602 : }
2603 52 : pp_string (pp, "})");
2604 : }
2605 : else
2606 : {
2607 0 : pp_printf (pp, "asm_output_svalue (%qs, %%%i, {",
2608 : get_asm_string (),
2609 : get_output_idx ());
2610 0 : for (unsigned i = 0; i < m_num_inputs; i++)
2611 : {
2612 0 : if (i > 0)
2613 0 : pp_string (pp, ", ");
2614 0 : dump_input (pp, 0, m_input_arr[i], simple);
2615 : }
2616 0 : pp_string (pp, "})");
2617 : }
2618 52 : }
2619 :
2620 : /* Implementation of svalue::print_dump_widget_label vfunc for
2621 : asm_output_svalue. */
2622 :
2623 : void
2624 0 : asm_output_svalue::print_dump_widget_label (pretty_printer *pp) const
2625 : {
2626 0 : pp_printf (pp, "asm_output_svalue(%qs, %%%i)",
2627 : get_asm_string (),
2628 : get_output_idx ());
2629 0 : }
2630 :
2631 : /* Implementation of svalue::add_dump_widget_children vfunc for
2632 : asm_output_svalue. */
2633 :
2634 : void
2635 0 : asm_output_svalue::
2636 : add_dump_widget_children (text_art::tree_widget &w,
2637 : const text_art::dump_widget_info &dwi) const
2638 : {
2639 0 : for (unsigned i = 0; i < m_num_inputs; i++)
2640 : {
2641 0 : pretty_printer pp;
2642 0 : pp_printf (&pp, "arg %i", i);
2643 0 : w.add_child (m_input_arr[i]->make_dump_widget (dwi,
2644 : pp_formatted_text (&pp)));
2645 0 : }
2646 0 : }
2647 :
2648 : /* Subroutine of asm_output_svalue::dump_to_pp. */
2649 :
2650 : void
2651 92 : asm_output_svalue::dump_input (pretty_printer *pp,
2652 : unsigned input_idx,
2653 : const svalue *sval,
2654 : bool simple) const
2655 : {
2656 92 : pp_printf (pp, "%%%i: ", input_idx_to_asm_idx (input_idx));
2657 92 : sval->dump_to_pp (pp, simple);
2658 92 : }
2659 :
2660 : /* Convert INPUT_IDX from an index into the array of inputs
2661 : into the index of all operands for the asm stmt. */
2662 :
2663 : unsigned
2664 92 : asm_output_svalue::input_idx_to_asm_idx (unsigned input_idx) const
2665 : {
2666 92 : return input_idx + m_num_outputs;
2667 : }
2668 :
2669 : /* Implementation of svalue::accept vfunc for asm_output_svalue. */
2670 :
2671 : void
2672 6099 : asm_output_svalue::accept (visitor *v) const
2673 : {
2674 16803 : for (unsigned i = 0; i < m_num_inputs; i++)
2675 10704 : m_input_arr[i]->accept (v);
2676 6099 : v->visit_asm_output_svalue (this);
2677 6099 : }
2678 :
2679 : /* class const_fn_result_svalue : public svalue. */
2680 :
2681 : /* Implementation of svalue::dump_to_pp vfunc for const_fn_result_svalue. */
2682 :
2683 : void
2684 4391 : const_fn_result_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
2685 : {
2686 4391 : if (simple)
2687 : {
2688 3945 : pp_printf (pp, "CONST_FN_RESULT(%qD, {", m_fndecl);
2689 3993 : for (unsigned i = 0; i < m_num_inputs; i++)
2690 : {
2691 48 : if (i > 0)
2692 0 : pp_string (pp, ", ");
2693 48 : dump_input (pp, i, m_input_arr[i], simple);
2694 : }
2695 3945 : pp_string (pp, "})");
2696 : }
2697 : else
2698 : {
2699 446 : pp_printf (pp, "CONST_FN_RESULT(%qD, {", m_fndecl);
2700 446 : for (unsigned i = 0; i < m_num_inputs; i++)
2701 : {
2702 0 : if (i > 0)
2703 0 : pp_string (pp, ", ");
2704 0 : dump_input (pp, i, m_input_arr[i], simple);
2705 : }
2706 446 : pp_string (pp, "})");
2707 : }
2708 4391 : }
2709 :
2710 : /* Implementation of svalue::print_dump_widget_label vfunc for
2711 : const_fn_result_svalue. */
2712 :
2713 : void
2714 0 : const_fn_result_svalue::print_dump_widget_label (pretty_printer *pp) const
2715 : {
2716 0 : pp_printf (pp, "const_fn_result_svalue: %qD", m_fndecl);
2717 0 : }
2718 :
2719 : /* Implementation of svalue::add_dump_widget_children vfunc for
2720 : const_fn_result_svalue. */
2721 :
2722 : void
2723 0 : const_fn_result_svalue::
2724 : add_dump_widget_children (text_art::tree_widget &w,
2725 : const text_art::dump_widget_info &dwi) const
2726 : {
2727 0 : for (unsigned i = 0; i < m_num_inputs; i++)
2728 : {
2729 0 : pretty_printer pp;
2730 0 : pp_printf (&pp, "arg %i", i);
2731 0 : w.add_child (m_input_arr[i]->make_dump_widget (dwi,
2732 : pp_formatted_text (&pp)));
2733 0 : }
2734 0 : }
2735 :
2736 : /* Subroutine of const_fn_result_svalue::dump_to_pp. */
2737 :
2738 : void
2739 48 : const_fn_result_svalue::dump_input (pretty_printer *pp,
2740 : unsigned input_idx,
2741 : const svalue *sval,
2742 : bool simple) const
2743 : {
2744 48 : pp_printf (pp, "arg%i: ", input_idx);
2745 48 : sval->dump_to_pp (pp, simple);
2746 48 : }
2747 :
2748 : /* Implementation of svalue::accept vfunc for const_fn_result_svalue. */
2749 :
2750 : void
2751 8497 : const_fn_result_svalue::accept (visitor *v) const
2752 : {
2753 14306 : for (unsigned i = 0; i < m_num_inputs; i++)
2754 5809 : m_input_arr[i]->accept (v);
2755 8497 : v->visit_const_fn_result_svalue (this);
2756 8497 : }
2757 :
2758 : } // namespace ana
2759 :
2760 : #endif /* #if ENABLE_ANALYZER */
|