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