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