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