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