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