]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/analyzer/svalue.cc
Update copyright years.
[thirdparty/gcc.git] / gcc / analyzer / svalue.cc
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_MEMORY
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
53 #if ENABLE_ANALYZER
54
55 namespace ana {
56
57 static int cmp_csts_and_types (const_tree cst1, const_tree cst2);
58
59 /* class svalue and its various subclasses. */
60
61 /* class svalue. */
62
63 /* Dump a representation of this svalue to stderr. */
64
65 DEBUG_FUNCTION void
66 svalue::dump (bool simple) const
67 {
68 pretty_printer pp;
69 pp_format_decoder (&pp) = default_tree_printer;
70 pp_show_color (&pp) = pp_show_color (global_dc->printer);
71 pp.buffer->stream = stderr;
72 dump_to_pp (&pp, simple);
73 pp_newline (&pp);
74 pp_flush (&pp);
75 }
76
77 /* Generate a textual representation of this svalue for debugging purposes. */
78
79 label_text
80 svalue::get_desc (bool simple) const
81 {
82 pretty_printer pp;
83 pp_format_decoder (&pp) = default_tree_printer;
84 dump_to_pp (&pp, simple);
85 return label_text::take (xstrdup (pp_formatted_text (&pp)));
86 }
87
88 /* Return a new json::string describing the svalue. */
89
90 json::value *
91 svalue::to_json () const
92 {
93 label_text desc = get_desc (true);
94 json::value *sval_js = new json::string (desc.get ());
95 return sval_js;
96 }
97
98 /* If this svalue is a constant_svalue, return the underlying tree constant.
99 Otherwise return NULL_TREE. */
100
101 tree
102 svalue::maybe_get_constant () const
103 {
104 const svalue *sval = unwrap_any_unmergeable ();
105 if (const constant_svalue *cst_sval = sval->dyn_cast_constant_svalue ())
106 return cst_sval->get_constant ();
107 else
108 return NULL_TREE;
109 }
110
111 /* If this svalue is a region_svalue, return the region it points to.
112 Otherwise return NULL. */
113
114 const region *
115 svalue::maybe_get_region () const
116 {
117 if (const region_svalue *region_sval = dyn_cast_region_svalue ())
118 return region_sval->get_pointee ();
119 else
120 return NULL;
121 }
122
123 /* If this svalue is a cast (i.e a unaryop NOP_EXPR or VIEW_CONVERT_EXPR),
124 return the underlying svalue.
125 Otherwise return NULL. */
126
127 const svalue *
128 svalue::maybe_undo_cast () const
129 {
130 if (const unaryop_svalue *unaryop_sval = dyn_cast_unaryop_svalue ())
131 {
132 enum tree_code op = unaryop_sval->get_op ();
133 if (op == NOP_EXPR || op == VIEW_CONVERT_EXPR)
134 return unaryop_sval->get_arg ();
135 }
136 return NULL;
137 }
138
139 /* If this svalue is an unmergeable decorator around another svalue, return
140 the underlying svalue.
141 Otherwise return this svalue. */
142
143 const svalue *
144 svalue::unwrap_any_unmergeable () const
145 {
146 if (const unmergeable_svalue *unmergeable = dyn_cast_unmergeable_svalue ())
147 return unmergeable->get_arg ();
148 return this;
149 }
150
151 /* Attempt to merge THIS with OTHER, returning the merged svalue.
152 Return NULL if not mergeable. */
153
154 const svalue *
155 svalue::can_merge_p (const svalue *other,
156 region_model_manager *mgr,
157 model_merger *merger) const
158 {
159 if (!(get_type () && other->get_type ()))
160 return NULL;
161
162 if (!types_compatible_p (get_type (), other->get_type ()))
163 return NULL;
164
165 /* Reject attempts to merge unmergeable svalues. */
166 if ((get_kind () == SK_UNMERGEABLE)
167 || (other->get_kind () == SK_UNMERGEABLE))
168 return NULL;
169
170 /* Reject attempts to merge poisoned svalues with other svalues
171 (either non-poisoned, or other kinds of poison), so that e.g.
172 we identify paths in which a variable is conditionally uninitialized. */
173 if (get_kind () == SK_POISONED
174 || other->get_kind () == SK_POISONED)
175 return NULL;
176
177 /* Reject attempts to merge NULL pointers with not-NULL-pointers. */
178 if (POINTER_TYPE_P (get_type ()))
179 {
180 bool null0 = false;
181 bool null1 = false;
182 if (tree cst0 = maybe_get_constant ())
183 if (zerop (cst0))
184 null0 = true;
185 if (tree cst1 = other->maybe_get_constant ())
186 if (zerop (cst1))
187 null1 = true;
188 if (null0 != null1)
189 return NULL;
190 }
191
192 /* Reject merging svalues that have non-purgable sm-state,
193 to avoid falsely reporting memory leaks by merging them
194 with something else. */
195 if (!merger->mergeable_svalue_p (this))
196 return NULL;
197 if (!merger->mergeable_svalue_p (other))
198 return NULL;
199
200 /* Widening. */
201 /* Merge: (new_cst, existing_cst) -> widen (existing, new). */
202 if (maybe_get_constant () && other->maybe_get_constant ())
203 {
204 return mgr->get_or_create_widening_svalue (other->get_type (),
205 merger->get_function_point (),
206 other, this);
207 }
208
209 /* Merger of:
210 this: BINOP (X, OP, CST)
211 other: X, where X is non-widening
212 to: WIDENING (other, this). */
213 if (const binop_svalue *binop_sval = dyn_cast_binop_svalue ())
214 if (binop_sval->get_arg0 () == other
215 && binop_sval->get_arg1 ()->get_kind () == SK_CONSTANT
216 && other->get_kind () != SK_WIDENING)
217 return mgr->get_or_create_widening_svalue (other->get_type (),
218 merger->get_function_point (),
219 other, this);
220
221 /* Merge: (Widen(existing_val, V), existing_val) -> Widen (existing_val, V)
222 and thus get a fixed point. */
223 if (const widening_svalue *widen_sval = dyn_cast_widening_svalue ())
224 {
225 if (other == widen_sval->get_base_svalue ())
226 return this;
227 if (other == widen_sval->get_iter_svalue ())
228 return this;
229 }
230
231 if (const binop_svalue *binop_sval = dyn_cast_binop_svalue ())
232 if (const widening_svalue *widen_arg0
233 = binop_sval->get_arg0 ()->dyn_cast_widening_svalue ())
234 {
235 if (other == binop_sval->get_arg1 ())
236 {
237 /* Merger of: (Widen(..., OTHER) BINOP X)
238 and : OTHER
239 to : (Widen(..., OTHER) BINOP X)
240 e.g. merge of Widen(0, 1) + 1 with 1 to the Widen(0, 1) + 1. */
241 return this;
242 }
243
244 /* Merger of : (Widen() BINOP X)
245 and : Widen()
246 to : Widen()
247 e.g. merge of Widen(0, 1) + 1 and Widen(0, 1) to Widen(0, 1).
248 However, we want to update constraints for this case, since we're
249 considering another iteration.
250 Presumably we also want to ensure that it converges; we don't want
251 a descending chain of constraints. */
252 if (other == widen_arg0)
253 {
254 merger->on_widening_reuse (widen_arg0);
255 return widen_arg0;
256 }
257
258 /* Merger of:
259 this: BINOP(WIDENING(BASE, BINOP(BASE, X)), X)
260 other: BINOP(BASE, X)
261 to: WIDENING(BASE, BINOP(BASE, X)). */
262 if (widen_arg0->get_iter_svalue () == other)
263 if (const binop_svalue *other_binop_sval
264 = other->dyn_cast_binop_svalue ())
265 if (other_binop_sval->get_arg0 () == widen_arg0->get_base_svalue ()
266 && other_binop_sval->get_arg1 () == binop_sval->get_arg1 ())
267 return widen_arg0;
268 }
269
270 return mgr->get_or_create_unknown_svalue (get_type ());
271 }
272
273 /* Determine if this svalue is either within LIVE_SVALUES, or is implicitly
274 live with respect to LIVE_SVALUES and MODEL.
275 LIVE_SVALUES can be NULL, in which case determine if this svalue is
276 intrinsically live. */
277
278 bool
279 svalue::live_p (const svalue_set *live_svalues,
280 const region_model *model) const
281 {
282 /* Determine if SVAL is explicitly live. */
283 if (live_svalues)
284 if (const_cast<svalue_set *> (live_svalues)->contains (this))
285 return true;
286
287 /* Otherwise, determine if SVAL is implicitly live due to being made of
288 other live svalues. */
289 return implicitly_live_p (live_svalues, model);
290 }
291
292 /* Base implementation of svalue::implicitly_live_p. */
293
294 bool
295 svalue::implicitly_live_p (const svalue_set *, const region_model *) const
296 {
297 return false;
298 }
299
300 /* Comparator for imposing a deterministic order on constants that are
301 of the same type. */
302
303 static int
304 cmp_csts_same_type (const_tree cst1, const_tree cst2)
305 {
306 gcc_assert (TREE_TYPE (cst1) == TREE_TYPE (cst2));
307 gcc_assert (TREE_CODE (cst1) == TREE_CODE (cst2));
308 switch (TREE_CODE (cst1))
309 {
310 default:
311 gcc_unreachable ();
312 case INTEGER_CST:
313 return tree_int_cst_compare (cst1, cst2);
314 case STRING_CST:
315 return strcmp (TREE_STRING_POINTER (cst1),
316 TREE_STRING_POINTER (cst2));
317 case REAL_CST:
318 /* Impose an arbitrary but deterministic order. */
319 return memcmp (TREE_REAL_CST_PTR (cst1),
320 TREE_REAL_CST_PTR (cst2),
321 sizeof (real_value));
322 case COMPLEX_CST:
323 if (int cmp_real = cmp_csts_and_types (TREE_REALPART (cst1),
324 TREE_REALPART (cst2)))
325 return cmp_real;
326 return cmp_csts_and_types (TREE_IMAGPART (cst1), TREE_IMAGPART (cst2));
327 case VECTOR_CST:
328 if (int cmp_log2_npatterns
329 = ((int)VECTOR_CST_LOG2_NPATTERNS (cst1)
330 - (int)VECTOR_CST_LOG2_NPATTERNS (cst2)))
331 return cmp_log2_npatterns;
332 if (int cmp_nelts_per_pattern
333 = ((int)VECTOR_CST_NELTS_PER_PATTERN (cst1)
334 - (int)VECTOR_CST_NELTS_PER_PATTERN (cst2)))
335 return cmp_nelts_per_pattern;
336 unsigned encoded_nelts = vector_cst_encoded_nelts (cst1);
337 for (unsigned i = 0; i < encoded_nelts; i++)
338 {
339 const_tree elt1 = VECTOR_CST_ENCODED_ELT (cst1, i);
340 const_tree elt2 = VECTOR_CST_ENCODED_ELT (cst2, i);
341 if (int el_cmp = cmp_csts_and_types (elt1, elt2))
342 return el_cmp;
343 }
344 return 0;
345 }
346 }
347
348 /* Comparator for imposing a deterministic order on constants that might
349 not be of the same type. */
350
351 static int
352 cmp_csts_and_types (const_tree cst1, const_tree cst2)
353 {
354 int t1 = TYPE_UID (TREE_TYPE (cst1));
355 int t2 = TYPE_UID (TREE_TYPE (cst2));
356 if (int cmp_type = t1 - t2)
357 return cmp_type;
358 return cmp_csts_same_type (cst1, cst2);
359 }
360
361 /* Comparator for imposing a deterministic order on svalues. */
362
363 int
364 svalue::cmp_ptr (const svalue *sval1, const svalue *sval2)
365 {
366 if (sval1 == sval2)
367 return 0;
368 if (int cmp_kind = sval1->get_kind () - sval2->get_kind ())
369 return cmp_kind;
370 int t1 = sval1->get_type () ? TYPE_UID (sval1->get_type ()) : -1;
371 int t2 = sval2->get_type () ? TYPE_UID (sval2->get_type ()) : -1;
372 if (int cmp_type = t1 - t2)
373 return cmp_type;
374 switch (sval1->get_kind ())
375 {
376 default:
377 gcc_unreachable ();
378 case SK_REGION:
379 {
380 const region_svalue *region_sval1 = (const region_svalue *)sval1;
381 const region_svalue *region_sval2 = (const region_svalue *)sval2;
382 return region::cmp_ids (region_sval1->get_pointee (),
383 region_sval2->get_pointee ());
384 }
385 break;
386 case SK_CONSTANT:
387 {
388 const constant_svalue *constant_sval1 = (const constant_svalue *)sval1;
389 const constant_svalue *constant_sval2 = (const constant_svalue *)sval2;
390 const_tree cst1 = constant_sval1->get_constant ();
391 const_tree cst2 = constant_sval2->get_constant ();
392 return cmp_csts_same_type (cst1, cst2);
393 }
394 break;
395 case SK_UNKNOWN:
396 {
397 gcc_assert (sval1 == sval2);
398 return 0;
399 }
400 break;
401 case SK_POISONED:
402 {
403 const poisoned_svalue *poisoned_sval1 = (const poisoned_svalue *)sval1;
404 const poisoned_svalue *poisoned_sval2 = (const poisoned_svalue *)sval2;
405 return (poisoned_sval1->get_poison_kind ()
406 - poisoned_sval2->get_poison_kind ());
407 }
408 break;
409 case SK_SETJMP:
410 {
411 const setjmp_svalue *setjmp_sval1 = (const setjmp_svalue *)sval1;
412 const setjmp_svalue *setjmp_sval2 = (const setjmp_svalue *)sval2;
413 const setjmp_record &rec1 = setjmp_sval1->get_setjmp_record ();
414 const setjmp_record &rec2 = setjmp_sval2->get_setjmp_record ();
415 return setjmp_record::cmp (rec1, rec2);
416 }
417 break;
418 case SK_INITIAL:
419 {
420 const initial_svalue *initial_sval1 = (const initial_svalue *)sval1;
421 const initial_svalue *initial_sval2 = (const initial_svalue *)sval2;
422 return region::cmp_ids (initial_sval1->get_region (),
423 initial_sval2->get_region ());
424 }
425 break;
426 case SK_UNARYOP:
427 {
428 const unaryop_svalue *unaryop_sval1 = (const unaryop_svalue *)sval1;
429 const unaryop_svalue *unaryop_sval2 = (const unaryop_svalue *)sval2;
430 if (int op_cmp = unaryop_sval1->get_op () - unaryop_sval2->get_op ())
431 return op_cmp;
432 return svalue::cmp_ptr (unaryop_sval1->get_arg (),
433 unaryop_sval2->get_arg ());
434 }
435 break;
436 case SK_BINOP:
437 {
438 const binop_svalue *binop_sval1 = (const binop_svalue *)sval1;
439 const binop_svalue *binop_sval2 = (const binop_svalue *)sval2;
440 if (int op_cmp = binop_sval1->get_op () - binop_sval2->get_op ())
441 return op_cmp;
442 if (int arg0_cmp = svalue::cmp_ptr (binop_sval1->get_arg0 (),
443 binop_sval2->get_arg0 ()))
444 return arg0_cmp;
445 return svalue::cmp_ptr (binop_sval1->get_arg1 (),
446 binop_sval2->get_arg1 ());
447 }
448 break;
449 case SK_SUB:
450 {
451 const sub_svalue *sub_sval1 = (const sub_svalue *)sval1;
452 const sub_svalue *sub_sval2 = (const sub_svalue *)sval2;
453 if (int parent_cmp = svalue::cmp_ptr (sub_sval1->get_parent (),
454 sub_sval2->get_parent ()))
455 return parent_cmp;
456 return region::cmp_ids (sub_sval1->get_subregion (),
457 sub_sval2->get_subregion ());
458 }
459 break;
460 case SK_REPEATED:
461 {
462 const repeated_svalue *repeated_sval1 = (const repeated_svalue *)sval1;
463 const repeated_svalue *repeated_sval2 = (const repeated_svalue *)sval2;
464 return svalue::cmp_ptr (repeated_sval1->get_inner_svalue (),
465 repeated_sval2->get_inner_svalue ());
466 }
467 break;
468 case SK_BITS_WITHIN:
469 {
470 const bits_within_svalue *bits_within_sval1
471 = (const bits_within_svalue *)sval1;
472 const bits_within_svalue *bits_within_sval2
473 = (const bits_within_svalue *)sval2;
474 if (int cmp = bit_range::cmp (bits_within_sval1->get_bits (),
475 bits_within_sval2->get_bits ()))
476 return cmp;
477 return svalue::cmp_ptr (bits_within_sval1->get_inner_svalue (),
478 bits_within_sval2->get_inner_svalue ());
479 }
480 break;
481 case SK_UNMERGEABLE:
482 {
483 const unmergeable_svalue *unmergeable_sval1
484 = (const unmergeable_svalue *)sval1;
485 const unmergeable_svalue *unmergeable_sval2
486 = (const unmergeable_svalue *)sval2;
487 return svalue::cmp_ptr (unmergeable_sval1->get_arg (),
488 unmergeable_sval2->get_arg ());
489 }
490 break;
491 case SK_PLACEHOLDER:
492 {
493 const placeholder_svalue *placeholder_sval1
494 = (const placeholder_svalue *)sval1;
495 const placeholder_svalue *placeholder_sval2
496 = (const placeholder_svalue *)sval2;
497 return strcmp (placeholder_sval1->get_name (),
498 placeholder_sval2->get_name ());
499 }
500 break;
501 case SK_WIDENING:
502 {
503 const widening_svalue *widening_sval1 = (const widening_svalue *)sval1;
504 const widening_svalue *widening_sval2 = (const widening_svalue *)sval2;
505 if (int point_cmp = function_point::cmp (widening_sval1->get_point (),
506 widening_sval2->get_point ()))
507 return point_cmp;
508 if (int base_cmp = svalue::cmp_ptr (widening_sval1->get_base_svalue (),
509 widening_sval2->get_base_svalue ()))
510 return base_cmp;
511 return svalue::cmp_ptr (widening_sval1->get_iter_svalue (),
512 widening_sval2->get_iter_svalue ());
513 }
514 break;
515 case SK_COMPOUND:
516 {
517 const compound_svalue *compound_sval1 = (const compound_svalue *)sval1;
518 const compound_svalue *compound_sval2 = (const compound_svalue *)sval2;
519 return binding_map::cmp (compound_sval1->get_map (),
520 compound_sval2->get_map ());
521 }
522 break;
523 case SK_CONJURED:
524 {
525 const conjured_svalue *conjured_sval1 = (const conjured_svalue *)sval1;
526 const conjured_svalue *conjured_sval2 = (const conjured_svalue *)sval2;
527 if (int stmt_cmp = (conjured_sval1->get_stmt ()->uid
528 - conjured_sval2->get_stmt ()->uid))
529 return stmt_cmp;
530 return region::cmp_ids (conjured_sval1->get_id_region (),
531 conjured_sval2->get_id_region ());
532 }
533 break;
534 case SK_ASM_OUTPUT:
535 {
536 const asm_output_svalue *asm_output_sval1
537 = (const asm_output_svalue *)sval1;
538 const asm_output_svalue *asm_output_sval2
539 = (const asm_output_svalue *)sval2;
540 if (int asm_string_cmp = strcmp (asm_output_sval1->get_asm_string (),
541 asm_output_sval2->get_asm_string ()))
542 return asm_string_cmp;
543 if (int output_idx_cmp = ((int)asm_output_sval1->get_output_idx ()
544 - (int)asm_output_sval2->get_output_idx ()))
545 return output_idx_cmp;
546 if (int cmp = ((int)asm_output_sval1->get_num_inputs ()
547 - (int)asm_output_sval2->get_num_inputs ()))
548 return cmp;
549 for (unsigned i = 0; i < asm_output_sval1->get_num_inputs (); i++)
550 if (int input_cmp
551 = svalue::cmp_ptr (asm_output_sval1->get_input (i),
552 asm_output_sval2->get_input (i)))
553 return input_cmp;
554 return 0;
555 }
556 break;
557 case SK_CONST_FN_RESULT:
558 {
559 const const_fn_result_svalue *const_fn_result_sval1
560 = (const const_fn_result_svalue *)sval1;
561 const const_fn_result_svalue *const_fn_result_sval2
562 = (const const_fn_result_svalue *)sval2;
563 int d1 = DECL_UID (const_fn_result_sval1->get_fndecl ());
564 int d2 = DECL_UID (const_fn_result_sval2->get_fndecl ());
565 if (int cmp_fndecl = d1 - d2)
566 return cmp_fndecl;
567 if (int cmp = ((int)const_fn_result_sval1->get_num_inputs ()
568 - (int)const_fn_result_sval2->get_num_inputs ()))
569 return cmp;
570 for (unsigned i = 0; i < const_fn_result_sval1->get_num_inputs (); i++)
571 if (int input_cmp
572 = svalue::cmp_ptr (const_fn_result_sval1->get_input (i),
573 const_fn_result_sval2->get_input (i)))
574 return input_cmp;
575 return 0;
576 }
577 }
578 }
579
580 /* Comparator for use by vec<const svalue *>::qsort. */
581
582 int
583 svalue::cmp_ptr_ptr (const void *p1, const void *p2)
584 {
585 const svalue *sval1 = *(const svalue * const *)p1;
586 const svalue *sval2 = *(const svalue * const *)p2;
587 return cmp_ptr (sval1, sval2);
588 }
589
590 /* Subclass of visitor for use in implementing svalue::involves_p. */
591
592 class involvement_visitor : public visitor
593 {
594 public:
595 involvement_visitor (const svalue *needle)
596 : m_needle (needle), m_found (false) {}
597
598 void visit_initial_svalue (const initial_svalue *candidate) final override
599 {
600 if (candidate == m_needle)
601 m_found = true;
602 }
603
604 void visit_conjured_svalue (const conjured_svalue *candidate) final override
605 {
606 if (candidate == m_needle)
607 m_found = true;
608 }
609
610 void visit_widening_svalue (const widening_svalue *candidate) final override
611 {
612 if (candidate == m_needle)
613 m_found = true;
614 }
615
616 bool found_p () const { return m_found; }
617
618 private:
619 const svalue *m_needle;
620 bool m_found;
621 };
622
623 /* Return true iff this svalue is defined in terms of OTHER. */
624
625 bool
626 svalue::involves_p (const svalue *other) const
627 {
628 /* Currently only implemented for these kinds. */
629 gcc_assert (other->get_kind () == SK_INITIAL
630 || other->get_kind () == SK_CONJURED
631 || other->get_kind () == SK_WIDENING);
632
633 involvement_visitor v (other);
634 accept (&v);
635 return v.found_p ();
636 }
637
638 /* Extract SUBRANGE from this value, of type TYPE. */
639
640 const svalue *
641 svalue::extract_bit_range (tree type,
642 const bit_range &subrange,
643 region_model_manager *mgr) const
644 {
645 return mgr->get_or_create_bits_within (type, subrange, this);
646 }
647
648 /* Base implementation of svalue::maybe_fold_bits_within vfunc. */
649
650 const svalue *
651 svalue::maybe_fold_bits_within (tree,
652 const bit_range &,
653 region_model_manager *) const
654 {
655 /* By default, don't fold. */
656 return NULL;
657 }
658
659 /* Base implementation of svalue::all_zeroes_p.
660 Return true if this value is known to be all zeroes. */
661
662 bool
663 svalue::all_zeroes_p () const
664 {
665 return false;
666 }
667
668 /* If this svalue is a pointer, attempt to determine the base region it points
669 to. Return NULL on any problems. */
670
671 const region *
672 svalue::maybe_get_deref_base_region () const
673 {
674 const svalue *iter = this;
675 while (1)
676 {
677 switch (iter->get_kind ())
678 {
679 default:
680 return NULL;
681
682 case SK_REGION:
683 {
684 const region_svalue *region_sval
685 = as_a <const region_svalue *> (iter);
686 return region_sval->get_pointee ()->get_base_region ();
687 }
688
689 case SK_BINOP:
690 {
691 const binop_svalue *binop_sval
692 = as_a <const binop_svalue *> (iter);
693 switch (binop_sval->get_op ())
694 {
695 case POINTER_PLUS_EXPR:
696 /* If we have a symbolic value expressing pointer arithmetic,
697 use the LHS. */
698 iter = binop_sval->get_arg0 ();
699 continue;
700
701 default:
702 return NULL;
703 }
704 return NULL;
705 }
706 }
707 }
708 }
709
710 /* class region_svalue : public svalue. */
711
712 /* Implementation of svalue::dump_to_pp vfunc for region_svalue. */
713
714 void
715 region_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
716 {
717 if (simple)
718 {
719 pp_string (pp, "&");
720 m_reg->dump_to_pp (pp, simple);
721 }
722 else
723 {
724 pp_string (pp, "region_svalue(");
725 if (get_type ())
726 {
727 print_quoted_type (pp, get_type ());
728 pp_string (pp, ", ");
729 }
730 m_reg->dump_to_pp (pp, simple);
731 pp_string (pp, ")");
732 }
733 }
734
735 /* Implementation of svalue::accept vfunc for region_svalue. */
736
737 void
738 region_svalue::accept (visitor *v) const
739 {
740 m_reg->accept (v);
741 v->visit_region_svalue (this);
742 }
743
744 /* Implementation of svalue::implicitly_live_p vfunc for region_svalue. */
745
746 bool
747 region_svalue::implicitly_live_p (const svalue_set *,
748 const region_model *model) const
749 {
750 /* Pointers into clusters that have escaped should be treated as live. */
751 const region *base_reg = get_pointee ()->get_base_region ();
752 const store *store = model->get_store ();
753 if (const binding_cluster *c = store->get_cluster (base_reg))
754 if (c->escaped_p ())
755 return true;
756
757 return false;
758 }
759
760 /* Evaluate the condition LHS OP RHS.
761 Subroutine of region_model::eval_condition for when we have a pair of
762 pointers. */
763
764 tristate
765 region_svalue::eval_condition (const region_svalue *lhs,
766 enum tree_code op,
767 const region_svalue *rhs)
768 {
769 /* See if they point to the same region. */
770 const region *lhs_reg = lhs->get_pointee ();
771 const region *rhs_reg = rhs->get_pointee ();
772 bool ptr_equality = lhs_reg == rhs_reg;
773 switch (op)
774 {
775 default:
776 gcc_unreachable ();
777
778 case EQ_EXPR:
779 if (ptr_equality)
780 return tristate::TS_TRUE;
781 else
782 return tristate::TS_FALSE;
783 break;
784
785 case NE_EXPR:
786 if (ptr_equality)
787 return tristate::TS_FALSE;
788 else
789 return tristate::TS_TRUE;
790 break;
791
792 case GE_EXPR:
793 case LE_EXPR:
794 if (ptr_equality)
795 return tristate::TS_TRUE;
796 break;
797
798 case GT_EXPR:
799 case LT_EXPR:
800 if (ptr_equality)
801 return tristate::TS_FALSE;
802 break;
803 }
804
805 return tristate::TS_UNKNOWN;
806 }
807
808 /* class constant_svalue : public svalue. */
809
810 /* Implementation of svalue::dump_to_pp vfunc for constant_svalue. */
811
812 void
813 constant_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
814 {
815 if (simple)
816 {
817 pp_string (pp, "(");
818 dump_tree (pp, get_type ());
819 pp_string (pp, ")");
820 dump_tree (pp, m_cst_expr);
821 }
822 else
823 {
824 pp_string (pp, "constant_svalue(");
825 if (get_type ())
826 {
827 print_quoted_type (pp, get_type ());
828 pp_string (pp, ", ");
829 }
830 dump_tree (pp, m_cst_expr);
831 pp_string (pp, ")");
832 }
833 }
834
835 /* Implementation of svalue::accept vfunc for constant_svalue. */
836
837 void
838 constant_svalue::accept (visitor *v) const
839 {
840 v->visit_constant_svalue (this);
841 }
842
843 /* Implementation of svalue::implicitly_live_p vfunc for constant_svalue.
844 Constants are implicitly live. */
845
846 bool
847 constant_svalue::implicitly_live_p (const svalue_set *,
848 const region_model *) const
849 {
850 return true;
851 }
852
853 /* Evaluate the condition LHS OP RHS.
854 Subroutine of region_model::eval_condition for when we have a pair of
855 constants. */
856
857 tristate
858 constant_svalue::eval_condition (const constant_svalue *lhs,
859 enum tree_code op,
860 const constant_svalue *rhs)
861 {
862 tree lhs_const = lhs->get_constant ();
863 tree rhs_const = rhs->get_constant ();
864
865 gcc_assert (CONSTANT_CLASS_P (lhs_const));
866 gcc_assert (CONSTANT_CLASS_P (rhs_const));
867
868 /* Check for comparable types. */
869 if (types_compatible_p (TREE_TYPE (lhs_const), TREE_TYPE (rhs_const)))
870 {
871 tree comparison
872 = fold_binary (op, boolean_type_node, lhs_const, rhs_const);
873 if (comparison == boolean_true_node)
874 return tristate (tristate::TS_TRUE);
875 if (comparison == boolean_false_node)
876 return tristate (tristate::TS_FALSE);
877 }
878 return tristate::TS_UNKNOWN;
879 }
880
881 /* Implementation of svalue::maybe_fold_bits_within vfunc
882 for constant_svalue. */
883
884 const svalue *
885 constant_svalue::maybe_fold_bits_within (tree type,
886 const bit_range &bits,
887 region_model_manager *mgr) const
888 {
889 /* Bits within an all-zero value are also all zero. */
890 if (zerop (m_cst_expr))
891 {
892 if (type)
893 return mgr->get_or_create_cast (type, this);
894 else
895 return this;
896 }
897
898 /* Handle the case of extracting a single bit. */
899 if (bits.m_size_in_bits == 1
900 && TREE_CODE (m_cst_expr) == INTEGER_CST
901 && type
902 && INTEGRAL_TYPE_P (type)
903 && tree_fits_uhwi_p (m_cst_expr))
904 {
905 unsigned HOST_WIDE_INT bit = bits.m_start_bit_offset.to_uhwi ();
906 unsigned HOST_WIDE_INT mask = (1 << bit);
907 unsigned HOST_WIDE_INT val_as_hwi = tree_to_uhwi (m_cst_expr);
908 unsigned HOST_WIDE_INT masked_val = val_as_hwi & mask;
909 int result = masked_val ? 1 : 0;
910 return mgr->get_or_create_int_cst (type, result);
911 }
912
913 /* Otherwise, don't fold. */
914 return NULL;
915 }
916
917 /* Implementation of svalue::all_zeroes_p for constant_svalue. */
918
919 bool
920 constant_svalue::all_zeroes_p () const
921 {
922 return zerop (m_cst_expr);
923 }
924
925 /* class unknown_svalue : public svalue. */
926
927 /* Implementation of svalue::dump_to_pp vfunc for unknown_svalue. */
928
929 void
930 unknown_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
931 {
932 if (simple)
933 {
934 pp_string (pp, "UNKNOWN(");
935 if (get_type ())
936 dump_tree (pp, get_type ());
937 pp_character (pp, ')');
938 }
939 else
940 {
941 pp_string (pp, "unknown_svalue(");
942 if (get_type ())
943 dump_tree (pp, get_type ());
944 pp_character (pp, ')');
945 }
946 }
947
948 /* Implementation of svalue::accept vfunc for unknown_svalue. */
949
950 void
951 unknown_svalue::accept (visitor *v) const
952 {
953 v->visit_unknown_svalue (this);
954 }
955
956 /* Implementation of svalue::maybe_fold_bits_within vfunc
957 for unknown_svalue. */
958
959 const svalue *
960 unknown_svalue::maybe_fold_bits_within (tree type,
961 const bit_range &,
962 region_model_manager *mgr) const
963 {
964 /* Bits within an unknown_svalue are themselves unknown. */
965 return mgr->get_or_create_unknown_svalue (type);
966 }
967
968 /* Get a string for KIND for use in debug dumps. */
969
970 const char *
971 poison_kind_to_str (enum poison_kind kind)
972 {
973 switch (kind)
974 {
975 default:
976 gcc_unreachable ();
977 case POISON_KIND_UNINIT:
978 return "uninit";
979 case POISON_KIND_FREED:
980 return "freed";
981 case POISON_KIND_DELETED:
982 return "deleted";
983 case POISON_KIND_POPPED_STACK:
984 return "popped stack";
985 }
986 }
987
988 /* class poisoned_svalue : public svalue. */
989
990 /* Implementation of svalue::dump_to_pp vfunc for poisoned_svalue. */
991
992 void
993 poisoned_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
994 {
995 if (simple)
996 {
997 pp_string (pp, "POISONED(");
998 print_quoted_type (pp, get_type ());
999 pp_printf (pp, ", %s)", poison_kind_to_str (m_kind));
1000 }
1001 else
1002 {
1003 pp_string (pp, "poisoned_svalue(");
1004 print_quoted_type (pp, get_type ());
1005 pp_printf (pp, ", %s)", poison_kind_to_str (m_kind));
1006 }
1007 }
1008
1009 /* Implementation of svalue::accept vfunc for poisoned_svalue. */
1010
1011 void
1012 poisoned_svalue::accept (visitor *v) const
1013 {
1014 v->visit_poisoned_svalue (this);
1015 }
1016
1017 /* Implementation of svalue::maybe_fold_bits_within vfunc
1018 for poisoned_svalue. */
1019
1020 const svalue *
1021 poisoned_svalue::maybe_fold_bits_within (tree type,
1022 const bit_range &,
1023 region_model_manager *mgr) const
1024 {
1025 /* Bits within a poisoned value are also poisoned. */
1026 return mgr->get_or_create_poisoned_svalue (m_kind, type);
1027 }
1028
1029 /* class setjmp_svalue's implementation is in engine.cc, so that it can use
1030 the declaration of exploded_node. */
1031
1032 /* class initial_svalue : public svalue. */
1033
1034 /* Implementation of svalue::dump_to_pp vfunc for initial_svalue. */
1035
1036 void
1037 initial_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
1038 {
1039 if (simple)
1040 {
1041 pp_string (pp, "INIT_VAL(");
1042 m_reg->dump_to_pp (pp, simple);
1043 pp_string (pp, ")");
1044 }
1045 else
1046 {
1047 pp_string (pp, "initial_svalue(");
1048 if (get_type ())
1049 {
1050 print_quoted_type (pp, get_type ());
1051 pp_string (pp, ", ");
1052 }
1053 m_reg->dump_to_pp (pp, simple);
1054 pp_string (pp, ")");
1055 }
1056 }
1057
1058 /* Implementation of svalue::accept vfunc for initial_svalue. */
1059
1060 void
1061 initial_svalue::accept (visitor *v) const
1062 {
1063 m_reg->accept (v);
1064 v->visit_initial_svalue (this);
1065 }
1066
1067 /* Implementation of svalue::implicitly_live_p vfunc for initial_svalue. */
1068
1069 bool
1070 initial_svalue::implicitly_live_p (const svalue_set *,
1071 const region_model *model) const
1072 {
1073 /* This svalue may be implicitly live if the region still implicitly
1074 has its initial value and is reachable. */
1075
1076 /* It must be a region that exists; we don't want to consider
1077 INIT_VAL(R) as still being implicitly reachable if R is in
1078 a popped stack frame. */
1079 if (model->region_exists_p (m_reg))
1080 {
1081 const svalue *reg_sval = model->get_store_value (m_reg, NULL);
1082 if (reg_sval == this)
1083 return true;
1084 }
1085
1086 /* Assume that the initial values of params for the top level frame
1087 are still live, because (presumably) they're still
1088 live in the external caller. */
1089 if (initial_value_of_param_p ())
1090 if (const frame_region *frame_reg = m_reg->maybe_get_frame_region ())
1091 if (frame_reg->get_calling_frame () == NULL)
1092 return true;
1093
1094 return false;
1095 }
1096
1097 /* Return true if this is the initial value of a function parameter. */
1098
1099 bool
1100 initial_svalue::initial_value_of_param_p () const
1101 {
1102 if (tree reg_decl = m_reg->maybe_get_decl ())
1103 if (TREE_CODE (reg_decl) == SSA_NAME)
1104 {
1105 tree ssa_name = reg_decl;
1106 if (SSA_NAME_IS_DEFAULT_DEF (ssa_name)
1107 && SSA_NAME_VAR (ssa_name)
1108 && TREE_CODE (SSA_NAME_VAR (ssa_name)) == PARM_DECL)
1109 return true;
1110 }
1111 return false;
1112 }
1113
1114 /* class unaryop_svalue : public svalue. */
1115
1116 /* Implementation of svalue::dump_to_pp vfunc for unaryop_svalue. */
1117
1118 void
1119 unaryop_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
1120 {
1121 if (simple)
1122 {
1123 if (m_op == VIEW_CONVERT_EXPR || m_op == NOP_EXPR)
1124 {
1125 pp_string (pp, "CAST(");
1126 dump_tree (pp, get_type ());
1127 pp_string (pp, ", ");
1128 m_arg->dump_to_pp (pp, simple);
1129 pp_character (pp, ')');
1130 }
1131 else
1132 {
1133 pp_character (pp, '(');
1134 pp_string (pp, get_tree_code_name (m_op));
1135 //pp_string (pp, op_symbol_code (m_op));
1136 m_arg->dump_to_pp (pp, simple);
1137 pp_character (pp, ')');
1138 }
1139 }
1140 else
1141 {
1142 pp_string (pp, "unaryop_svalue (");
1143 pp_string (pp, get_tree_code_name (m_op));
1144 pp_string (pp, ", ");
1145 m_arg->dump_to_pp (pp, simple);
1146 pp_character (pp, ')');
1147 }
1148 }
1149
1150 /* Implementation of svalue::accept vfunc for unaryop_svalue. */
1151
1152 void
1153 unaryop_svalue::accept (visitor *v) const
1154 {
1155 m_arg->accept (v);
1156 v->visit_unaryop_svalue (this);
1157 }
1158
1159 /* Implementation of svalue::implicitly_live_p vfunc for unaryop_svalue. */
1160
1161 bool
1162 unaryop_svalue::implicitly_live_p (const svalue_set *live_svalues,
1163 const region_model *model) const
1164 {
1165 return get_arg ()->live_p (live_svalues, model);
1166 }
1167
1168 /* Implementation of svalue::maybe_fold_bits_within vfunc
1169 for unaryop_svalue. */
1170
1171 const svalue *
1172 unaryop_svalue::maybe_fold_bits_within (tree type,
1173 const bit_range &,
1174 region_model_manager *mgr) const
1175 {
1176 switch (m_op)
1177 {
1178 default:
1179 break;
1180 case NOP_EXPR:
1181 /* A cast of zero is zero. */
1182 if (tree cst = m_arg->maybe_get_constant ())
1183 if (zerop (cst))
1184 {
1185 if (type)
1186 return mgr->get_or_create_cast (type, this);
1187 else
1188 return this;
1189 }
1190 break;
1191 }
1192 /* Otherwise, don't fold. */
1193 return NULL;
1194 }
1195
1196 /* class binop_svalue : public svalue. */
1197
1198 /* Return whether OP be printed as an infix operator. */
1199
1200 static bool
1201 infix_p (enum tree_code op)
1202 {
1203 switch (op)
1204 {
1205 default:
1206 return true;
1207 case MAX_EXPR:
1208 case MIN_EXPR:
1209 return false;
1210 }
1211 }
1212
1213 /* Implementation of svalue::dump_to_pp vfunc for binop_svalue. */
1214
1215 void
1216 binop_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
1217 {
1218 if (simple)
1219 {
1220 if (infix_p (m_op))
1221 {
1222 /* Print "(A OP B)". */
1223 pp_character (pp, '(');
1224 m_arg0->dump_to_pp (pp, simple);
1225 pp_string (pp, op_symbol_code (m_op));
1226 m_arg1->dump_to_pp (pp, simple);
1227 pp_character (pp, ')');
1228 }
1229 else
1230 {
1231 /* Print "OP(A, B)". */
1232 pp_string (pp, op_symbol_code (m_op));
1233 pp_character (pp, '(');
1234 m_arg0->dump_to_pp (pp, simple);
1235 pp_string (pp, ", ");
1236 m_arg1->dump_to_pp (pp, simple);
1237 pp_character (pp, ')');
1238 }
1239 }
1240 else
1241 {
1242 pp_string (pp, "binop_svalue (");
1243 pp_string (pp, get_tree_code_name (m_op));
1244 pp_string (pp, ", ");
1245 m_arg0->dump_to_pp (pp, simple);
1246 pp_string (pp, ", ");
1247 m_arg1->dump_to_pp (pp, simple);
1248 pp_character (pp, ')');
1249 }
1250 }
1251
1252 /* Implementation of svalue::accept vfunc for binop_svalue. */
1253
1254 void
1255 binop_svalue::accept (visitor *v) const
1256 {
1257 m_arg0->accept (v);
1258 m_arg1->accept (v);
1259 v->visit_binop_svalue (this);
1260 }
1261
1262 /* Implementation of svalue::implicitly_live_p vfunc for binop_svalue. */
1263
1264 bool
1265 binop_svalue::implicitly_live_p (const svalue_set *live_svalues,
1266 const region_model *model) const
1267 {
1268 return (get_arg0 ()->live_p (live_svalues, model)
1269 && get_arg1 ()->live_p (live_svalues, model));
1270 }
1271
1272 /* class sub_svalue : public svalue. */
1273
1274 /* sub_svalue'c ctor. */
1275
1276 sub_svalue::sub_svalue (symbol::id_t id,
1277 tree type, const svalue *parent_svalue,
1278 const region *subregion)
1279 : svalue (complexity::from_pair (parent_svalue->get_complexity (),
1280 subregion->get_complexity ()),
1281 id,
1282 type),
1283 m_parent_svalue (parent_svalue), m_subregion (subregion)
1284 {
1285 gcc_assert (parent_svalue->can_have_associated_state_p ());
1286 }
1287
1288 /* Implementation of svalue::dump_to_pp vfunc for sub_svalue. */
1289
1290 void
1291 sub_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
1292 {
1293 if (simple)
1294 {
1295 pp_string (pp, "SUB(");
1296 m_parent_svalue->dump_to_pp (pp, simple);
1297 pp_string (pp, ", ");
1298 m_subregion->dump_to_pp (pp, simple);
1299 pp_character (pp, ')');
1300 }
1301 else
1302 {
1303 pp_string (pp, "sub_svalue (");
1304 pp_string (pp, ", ");
1305 m_parent_svalue->dump_to_pp (pp, simple);
1306 pp_string (pp, ", ");
1307 m_subregion->dump_to_pp (pp, simple);
1308 pp_character (pp, ')');
1309 }
1310 }
1311
1312 /* Implementation of svalue::accept vfunc for sub_svalue. */
1313
1314 void
1315 sub_svalue::accept (visitor *v) const
1316 {
1317 m_parent_svalue->accept (v);
1318 m_subregion->accept (v);
1319 v->visit_sub_svalue (this);
1320 }
1321
1322 /* Implementation of svalue::implicitly_live_p vfunc for sub_svalue. */
1323
1324 bool
1325 sub_svalue::implicitly_live_p (const svalue_set *live_svalues,
1326 const region_model *model) const
1327 {
1328 return get_parent ()->live_p (live_svalues, model);
1329 }
1330
1331 /* class repeated_svalue : public svalue. */
1332
1333 /* repeated_svalue'c ctor. */
1334
1335 repeated_svalue::repeated_svalue (symbol::id_t id,
1336 tree type,
1337 const svalue *outer_size,
1338 const svalue *inner_svalue)
1339 : svalue (complexity::from_pair (outer_size, inner_svalue), id, type),
1340 m_outer_size (outer_size),
1341 m_inner_svalue (inner_svalue)
1342 {
1343 gcc_assert (outer_size->can_have_associated_state_p ());
1344 gcc_assert (inner_svalue->can_have_associated_state_p ());
1345 }
1346
1347 /* Implementation of svalue::dump_to_pp vfunc for repeated_svalue. */
1348
1349 void
1350 repeated_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
1351 {
1352 if (simple)
1353 {
1354 pp_string (pp, "REPEATED(");
1355 if (get_type ())
1356 {
1357 print_quoted_type (pp, get_type ());
1358 pp_string (pp, ", ");
1359 }
1360 pp_string (pp, "outer_size: ");
1361 m_outer_size->dump_to_pp (pp, simple);
1362 pp_string (pp, ", inner_val: ");
1363 m_inner_svalue->dump_to_pp (pp, simple);
1364 pp_character (pp, ')');
1365 }
1366 else
1367 {
1368 pp_string (pp, "repeated_svalue (");
1369 if (get_type ())
1370 {
1371 print_quoted_type (pp, get_type ());
1372 pp_string (pp, ", ");
1373 }
1374 pp_string (pp, "outer_size: ");
1375 m_outer_size->dump_to_pp (pp, simple);
1376 pp_string (pp, ", inner_val: ");
1377 m_inner_svalue->dump_to_pp (pp, simple);
1378 pp_character (pp, ')');
1379 }
1380 }
1381
1382 /* Implementation of svalue::accept vfunc for repeated_svalue. */
1383
1384 void
1385 repeated_svalue::accept (visitor *v) const
1386 {
1387 m_inner_svalue->accept (v);
1388 v->visit_repeated_svalue (this);
1389 }
1390
1391 /* Implementation of svalue::all_zeroes_p for repeated_svalue. */
1392
1393 bool
1394 repeated_svalue::all_zeroes_p () const
1395 {
1396 return m_inner_svalue->all_zeroes_p ();
1397 }
1398
1399 /* Implementation of svalue::maybe_fold_bits_within vfunc
1400 for repeated_svalue. */
1401
1402 const svalue *
1403 repeated_svalue::maybe_fold_bits_within (tree type,
1404 const bit_range &bits,
1405 region_model_manager *mgr) const
1406 {
1407 const svalue *innermost_sval = m_inner_svalue;
1408 /* Fold
1409 BITS_WITHIN (range, REPEATED_SVALUE (ZERO))
1410 to:
1411 REPEATED_SVALUE (ZERO). */
1412 if (all_zeroes_p ())
1413 {
1414 byte_range bytes (0,0);
1415 if (bits.as_byte_range (&bytes))
1416 {
1417 const svalue *byte_size
1418 = mgr->get_or_create_int_cst (size_type_node,
1419 bytes.m_size_in_bytes.to_uhwi ());
1420 return mgr->get_or_create_repeated_svalue (type, byte_size,
1421 innermost_sval);
1422 }
1423 }
1424
1425 /* Fold:
1426 BITS_WITHIN (range, REPEATED_SVALUE (INNERMOST_SVALUE))
1427 to:
1428 BITS_WITHIN (range - offset, INNERMOST_SVALUE)
1429 if range is fully within one instance of INNERMOST_SVALUE. */
1430 if (tree innermost_type = innermost_sval->get_type ())
1431 {
1432 bit_size_t element_bit_size;
1433 if (int_size_in_bits (innermost_type, &element_bit_size)
1434 && element_bit_size > 0)
1435 {
1436 HOST_WIDE_INT start_idx
1437 = (bits.get_start_bit_offset ()
1438 / element_bit_size).to_shwi ();
1439 HOST_WIDE_INT last_idx
1440 = (bits.get_last_bit_offset ()
1441 / element_bit_size).to_shwi ();
1442 if (start_idx == last_idx)
1443 {
1444 bit_offset_t start_of_element
1445 = start_idx * element_bit_size;
1446 bit_range range_within_element
1447 (bits.m_start_bit_offset - start_of_element,
1448 bits.m_size_in_bits);
1449 return mgr->get_or_create_bits_within (type,
1450 range_within_element,
1451 innermost_sval);
1452 }
1453 }
1454 }
1455
1456 return NULL;
1457 }
1458
1459 /* class bits_within_svalue : public svalue. */
1460
1461 /* bits_within_svalue'c ctor. */
1462
1463 bits_within_svalue::bits_within_svalue (symbol::id_t id,
1464 tree type,
1465 const bit_range &bits,
1466 const svalue *inner_svalue)
1467 : svalue (complexity (inner_svalue), id, type),
1468 m_bits (bits),
1469 m_inner_svalue (inner_svalue)
1470 {
1471 gcc_assert (inner_svalue->can_have_associated_state_p ());
1472 }
1473
1474 /* Implementation of svalue::dump_to_pp vfunc for bits_within_svalue. */
1475
1476 void
1477 bits_within_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
1478 {
1479 if (simple)
1480 {
1481 pp_string (pp, "BITS_WITHIN(");
1482 if (get_type ())
1483 {
1484 print_quoted_type (pp, get_type ());
1485 pp_string (pp, ", ");
1486 }
1487 m_bits.dump_to_pp (pp);
1488 pp_string (pp, ", inner_val: ");
1489 m_inner_svalue->dump_to_pp (pp, simple);
1490 pp_character (pp, ')');
1491 }
1492 else
1493 {
1494 pp_string (pp, "bits_within_svalue (");
1495 if (get_type ())
1496 {
1497 print_quoted_type (pp, get_type ());
1498 pp_string (pp, ", ");
1499 }
1500 m_bits.dump_to_pp (pp);
1501 pp_string (pp, ", inner_val: ");
1502 m_inner_svalue->dump_to_pp (pp, simple);
1503 pp_character (pp, ')');
1504 }
1505 }
1506
1507 /* Implementation of svalue::maybe_fold_bits_within vfunc
1508 for bits_within_svalue. */
1509
1510 const svalue *
1511 bits_within_svalue::maybe_fold_bits_within (tree type,
1512 const bit_range &bits,
1513 region_model_manager *mgr) const
1514 {
1515 /* Fold:
1516 BITS_WITHIN (range1, BITS_WITHIN (range2, VAL))
1517 to:
1518 BITS_WITHIN (range1 in range 2, VAL). */
1519 bit_range offset_bits (m_bits.get_start_bit_offset ()
1520 + bits.m_start_bit_offset,
1521 bits.m_size_in_bits);
1522 return mgr->get_or_create_bits_within (type, offset_bits, m_inner_svalue);
1523 }
1524
1525 /* Implementation of svalue::accept vfunc for bits_within_svalue. */
1526
1527 void
1528 bits_within_svalue::accept (visitor *v) const
1529 {
1530 m_inner_svalue->accept (v);
1531 v->visit_bits_within_svalue (this);
1532 }
1533
1534 /* Implementation of svalue::implicitly_live_p vfunc for bits_within_svalue. */
1535
1536 bool
1537 bits_within_svalue::implicitly_live_p (const svalue_set *live_svalues,
1538 const region_model *model) const
1539 {
1540 return m_inner_svalue->live_p (live_svalues, model);
1541 }
1542
1543 /* class widening_svalue : public svalue. */
1544
1545 /* Implementation of svalue::dump_to_pp vfunc for widening_svalue. */
1546
1547 void
1548 widening_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
1549 {
1550 if (simple)
1551 {
1552 pp_string (pp, "WIDENING(");
1553 pp_character (pp, '{');
1554 m_point.print (pp, format (false));
1555 pp_string (pp, "}, ");
1556 m_base_sval->dump_to_pp (pp, simple);
1557 pp_string (pp, ", ");
1558 m_iter_sval->dump_to_pp (pp, simple);
1559 pp_character (pp, ')');
1560 }
1561 else
1562 {
1563 pp_string (pp, "widening_svalue (");
1564 pp_string (pp, ", ");
1565 pp_character (pp, '{');
1566 m_point.print (pp, format (false));
1567 pp_string (pp, "}, ");
1568 m_base_sval->dump_to_pp (pp, simple);
1569 pp_string (pp, ", ");
1570 m_iter_sval->dump_to_pp (pp, simple);
1571 pp_character (pp, ')');
1572 }
1573 }
1574
1575 /* Implementation of svalue::accept vfunc for widening_svalue. */
1576
1577 void
1578 widening_svalue::accept (visitor *v) const
1579 {
1580 m_base_sval->accept (v);
1581 m_iter_sval->accept (v);
1582 v->visit_widening_svalue (this);
1583 }
1584
1585 /* Attempt to determine in which direction this value is changing
1586 w.r.t. the initial value. */
1587
1588 enum widening_svalue::direction_t
1589 widening_svalue::get_direction () const
1590 {
1591 tree base_cst = m_base_sval->maybe_get_constant ();
1592 if (base_cst == NULL_TREE)
1593 return DIR_UNKNOWN;
1594 tree iter_cst = m_iter_sval->maybe_get_constant ();
1595 if (iter_cst == NULL_TREE)
1596 return DIR_UNKNOWN;
1597
1598 tree iter_gt_base = fold_binary (GT_EXPR, boolean_type_node,
1599 iter_cst, base_cst);
1600 if (iter_gt_base == boolean_true_node)
1601 return DIR_ASCENDING;
1602
1603 tree iter_lt_base = fold_binary (LT_EXPR, boolean_type_node,
1604 iter_cst, base_cst);
1605 if (iter_lt_base == boolean_true_node)
1606 return DIR_DESCENDING;
1607
1608 return DIR_UNKNOWN;
1609 }
1610
1611 /* Compare this value against constant RHS_CST. */
1612
1613 tristate
1614 widening_svalue::eval_condition_without_cm (enum tree_code op,
1615 tree rhs_cst) const
1616 {
1617 tree base_cst = m_base_sval->maybe_get_constant ();
1618 if (base_cst == NULL_TREE)
1619 return tristate::TS_UNKNOWN;
1620 tree iter_cst = m_iter_sval->maybe_get_constant ();
1621 if (iter_cst == NULL_TREE)
1622 return tristate::TS_UNKNOWN;
1623
1624 switch (get_direction ())
1625 {
1626 default:
1627 gcc_unreachable ();
1628 case DIR_ASCENDING:
1629 /* LHS is in [base_cst, +ve infinity), assuming no overflow. */
1630 switch (op)
1631 {
1632 case LE_EXPR:
1633 case LT_EXPR:
1634 {
1635 /* [BASE, +INF) OP RHS:
1636 This is either true or false at +ve ininity,
1637 It can be true for points X where X OP RHS, so we have either
1638 "false", or "unknown". */
1639 tree base_op_rhs = fold_binary (op, boolean_type_node,
1640 base_cst, rhs_cst);
1641 if (base_op_rhs == boolean_true_node)
1642 return tristate::TS_UNKNOWN;
1643 else
1644 return tristate::TS_FALSE;
1645 }
1646
1647 case GE_EXPR:
1648 case GT_EXPR:
1649 {
1650 /* [BASE, +INF) OP RHS:
1651 This is true at +ve infinity. It will be true everywhere
1652 in the range if BASE >= RHS. */
1653 tree base_op_rhs = fold_binary (op, boolean_type_node,
1654 base_cst, rhs_cst);
1655 if (base_op_rhs == boolean_true_node)
1656 return tristate::TS_TRUE;
1657 else
1658 return tristate::TS_UNKNOWN;
1659 }
1660
1661 case EQ_EXPR:
1662 {
1663 /* [BASE, +INF) == RHS:
1664 Could this be true at any point in the range? If so we
1665 have "unknown", otherwise we have "false". */
1666 tree base_le_rhs = fold_binary (LE_EXPR, boolean_type_node,
1667 base_cst, rhs_cst);
1668 if (base_le_rhs == boolean_true_node)
1669 return tristate::TS_UNKNOWN;
1670 else
1671 return tristate::TS_FALSE;
1672 }
1673
1674 case NE_EXPR:
1675 {
1676 /* [BASE, +INF) != RHS:
1677 Could we have equality at any point in the range? If so we
1678 have "unknown", otherwise we have "true". */
1679 tree base_le_rhs = fold_binary (LE_EXPR, boolean_type_node,
1680 base_cst, rhs_cst);
1681 if (base_le_rhs == boolean_true_node)
1682 return tristate::TS_UNKNOWN;
1683 else
1684 return tristate::TS_TRUE;
1685 }
1686
1687 default:
1688 return tristate::TS_UNKNOWN;
1689 }
1690
1691 case DIR_DESCENDING:
1692 /* LHS is in (-ve infinity, base_cst], assuming no overflow. */
1693 return tristate::TS_UNKNOWN;
1694
1695 case DIR_UNKNOWN:
1696 return tristate::TS_UNKNOWN;
1697 }
1698 }
1699
1700 /* class placeholder_svalue : public svalue. */
1701
1702 /* Implementation of svalue::dump_to_pp vfunc for placeholder_svalue. */
1703
1704 void
1705 placeholder_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
1706 {
1707 if (simple)
1708 pp_printf (pp, "PLACEHOLDER(%qs)", m_name);
1709 else
1710 pp_printf (pp, "placeholder_svalue (%qs)", m_name);
1711 }
1712
1713 /* Implementation of svalue::accept vfunc for placeholder_svalue. */
1714
1715 void
1716 placeholder_svalue::accept (visitor *v) const
1717 {
1718 v->visit_placeholder_svalue (this);
1719 }
1720
1721 /* class unmergeable_svalue : public svalue. */
1722
1723 /* Implementation of svalue::dump_to_pp vfunc for unmergeable_svalue. */
1724
1725 void
1726 unmergeable_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
1727 {
1728 if (simple)
1729 {
1730 pp_string (pp, "UNMERGEABLE(");
1731 m_arg->dump_to_pp (pp, simple);
1732 pp_character (pp, ')');
1733 }
1734 else
1735 {
1736 pp_string (pp, "unmergeable_svalue (");
1737 m_arg->dump_to_pp (pp, simple);
1738 pp_character (pp, ')');
1739 }
1740 }
1741
1742 /* Implementation of svalue::accept vfunc for unmergeable_svalue. */
1743
1744 void
1745 unmergeable_svalue::accept (visitor *v) const
1746 {
1747 m_arg->accept (v);
1748 v->visit_unmergeable_svalue (this);
1749 }
1750
1751 /* Implementation of svalue::implicitly_live_p vfunc for unmergeable_svalue. */
1752
1753 bool
1754 unmergeable_svalue::implicitly_live_p (const svalue_set *live_svalues,
1755 const region_model *model) const
1756 {
1757 return get_arg ()->live_p (live_svalues, model);
1758 }
1759
1760 /* class compound_svalue : public svalue. */
1761
1762 compound_svalue::compound_svalue (symbol::id_t id,
1763 tree type,
1764 const binding_map &map)
1765 : svalue (calc_complexity (map), id, type), m_map (map)
1766 {
1767 #if CHECKING_P
1768 for (iterator_t iter = begin (); iter != end (); ++iter)
1769 {
1770 /* All keys within the underlying binding_map are required to be concrete,
1771 not symbolic. */
1772 const binding_key *key = (*iter).first;
1773 gcc_assert (key->concrete_p ());
1774
1775 /* We don't nest compound svalues. */
1776 const svalue *sval = (*iter).second;
1777 gcc_assert (sval->get_kind () != SK_COMPOUND);
1778 }
1779 #endif
1780 }
1781
1782 /* Implementation of svalue::dump_to_pp vfunc for compound_svalue. */
1783
1784 void
1785 compound_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
1786 {
1787 if (simple)
1788 {
1789 pp_string (pp, "COMPOUND(");
1790 if (get_type ())
1791 {
1792 print_quoted_type (pp, get_type ());
1793 pp_string (pp, ", ");
1794 }
1795 pp_character (pp, '{');
1796 m_map.dump_to_pp (pp, simple, false);
1797 pp_string (pp, "})");
1798 }
1799 else
1800 {
1801 pp_string (pp, "compound_svalue (");
1802 if (get_type ())
1803 {
1804 print_quoted_type (pp, get_type ());
1805 pp_string (pp, ", ");
1806 }
1807 pp_character (pp, '{');
1808 m_map.dump_to_pp (pp, simple, false);
1809 pp_string (pp, "})");
1810 }
1811 }
1812
1813 /* Implementation of svalue::accept vfunc for compound_svalue. */
1814
1815 void
1816 compound_svalue::accept (visitor *v) const
1817 {
1818 for (binding_map::iterator_t iter = m_map.begin ();
1819 iter != m_map.end (); ++iter)
1820 {
1821 //(*iter).first.accept (v);
1822 (*iter).second->accept (v);
1823 }
1824 v->visit_compound_svalue (this);
1825 }
1826
1827 /* Calculate what the complexity of a compound_svalue instance for MAP
1828 will be, based on the svalues bound within MAP. */
1829
1830 complexity
1831 compound_svalue::calc_complexity (const binding_map &map)
1832 {
1833 unsigned num_child_nodes = 0;
1834 unsigned max_child_depth = 0;
1835 for (binding_map::iterator_t iter = map.begin ();
1836 iter != map.end (); ++iter)
1837 {
1838 const complexity &sval_c = (*iter).second->get_complexity ();
1839 num_child_nodes += sval_c.m_num_nodes;
1840 max_child_depth = MAX (max_child_depth, sval_c.m_max_depth);
1841 }
1842 return complexity (num_child_nodes + 1, max_child_depth + 1);
1843 }
1844
1845 /* Implementation of svalue::maybe_fold_bits_within vfunc
1846 for compound_svalue. */
1847
1848 const svalue *
1849 compound_svalue::maybe_fold_bits_within (tree type,
1850 const bit_range &bits,
1851 region_model_manager *mgr) const
1852 {
1853 binding_map result_map;
1854 for (auto iter : m_map)
1855 {
1856 const binding_key *key = iter.first;
1857 if (const concrete_binding *conc_key
1858 = key->dyn_cast_concrete_binding ())
1859 {
1860 /* Ignore concrete bindings outside BITS. */
1861 if (!conc_key->get_bit_range ().intersects_p (bits))
1862 continue;
1863
1864 const svalue *sval = iter.second;
1865 /* Get the position of conc_key relative to BITS. */
1866 bit_range result_location (conc_key->get_start_bit_offset ()
1867 - bits.get_start_bit_offset (),
1868 conc_key->get_size_in_bits ());
1869 /* If conc_key starts after BITS, trim off leading bits
1870 from the svalue and adjust binding location. */
1871 if (result_location.m_start_bit_offset < 0)
1872 {
1873 bit_size_t leading_bits_to_drop
1874 = -result_location.m_start_bit_offset;
1875 result_location = bit_range
1876 (0, result_location.m_size_in_bits - leading_bits_to_drop);
1877 bit_range bits_within_sval (leading_bits_to_drop,
1878 result_location.m_size_in_bits);
1879 /* Trim off leading bits from iter_sval. */
1880 sval = mgr->get_or_create_bits_within (NULL_TREE,
1881 bits_within_sval,
1882 sval);
1883 }
1884 /* If conc_key finishes after BITS, trim off trailing bits
1885 from the svalue and adjust binding location. */
1886 if (conc_key->get_next_bit_offset ()
1887 > bits.get_next_bit_offset ())
1888 {
1889 bit_size_t trailing_bits_to_drop
1890 = (conc_key->get_next_bit_offset ()
1891 - bits.get_next_bit_offset ());
1892 result_location = bit_range
1893 (result_location.m_start_bit_offset,
1894 result_location.m_size_in_bits - trailing_bits_to_drop);
1895 bit_range bits_within_sval (0,
1896 result_location.m_size_in_bits);
1897 /* Trim off leading bits from iter_sval. */
1898 sval = mgr->get_or_create_bits_within (NULL_TREE,
1899 bits_within_sval,
1900 sval);
1901 }
1902 const concrete_binding *offset_conc_key
1903 = mgr->get_store_manager ()->get_concrete_binding
1904 (result_location);
1905 result_map.put (offset_conc_key, sval);
1906 }
1907 else
1908 /* If we have any symbolic keys we can't get it as bits. */
1909 return NULL;
1910 }
1911 return mgr->get_or_create_compound_svalue (type, result_map);
1912 }
1913
1914 /* class conjured_svalue : public svalue. */
1915
1916 /* Implementation of svalue::dump_to_pp vfunc for conjured_svalue. */
1917
1918 void
1919 conjured_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
1920 {
1921 if (simple)
1922 {
1923 pp_string (pp, "CONJURED(");
1924 pp_gimple_stmt_1 (pp, m_stmt, 0, (dump_flags_t)0);
1925 pp_string (pp, ", ");
1926 m_id_reg->dump_to_pp (pp, simple);
1927 pp_character (pp, ')');
1928 }
1929 else
1930 {
1931 pp_string (pp, "conjured_svalue (");
1932 if (get_type ())
1933 {
1934 print_quoted_type (pp, get_type ());
1935 pp_string (pp, ", ");
1936 }
1937 pp_gimple_stmt_1 (pp, m_stmt, 0, (dump_flags_t)0);
1938 pp_string (pp, ", ");
1939 m_id_reg->dump_to_pp (pp, simple);
1940 pp_character (pp, ')');
1941 }
1942 }
1943
1944 /* Implementation of svalue::accept vfunc for conjured_svalue. */
1945
1946 void
1947 conjured_svalue::accept (visitor *v) const
1948 {
1949 m_id_reg->accept (v);
1950 v->visit_conjured_svalue (this);
1951 }
1952
1953 /* Return true iff this conjured_svalue is for the LHS of the
1954 stmt that conjured it. */
1955
1956 bool
1957 conjured_svalue::lhs_value_p () const
1958 {
1959 if (tree decl = m_id_reg->maybe_get_decl ())
1960 return decl == gimple_get_lhs (m_stmt);
1961 return false;
1962 }
1963
1964 /* class asm_output_svalue : public svalue. */
1965
1966 /* Implementation of svalue::dump_to_pp vfunc for asm_output_svalue. */
1967
1968 void
1969 asm_output_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
1970 {
1971 if (simple)
1972 {
1973 pp_printf (pp, "ASM_OUTPUT(%qs, %%%i, {",
1974 get_asm_string (),
1975 get_output_idx ());
1976 for (unsigned i = 0; i < m_num_inputs; i++)
1977 {
1978 if (i > 0)
1979 pp_string (pp, ", ");
1980 dump_input (pp, 0, m_input_arr[i], simple);
1981 }
1982 pp_string (pp, "})");
1983 }
1984 else
1985 {
1986 pp_printf (pp, "asm_output_svalue (%qs, %%%i, {",
1987 get_asm_string (),
1988 get_output_idx ());
1989 for (unsigned i = 0; i < m_num_inputs; i++)
1990 {
1991 if (i > 0)
1992 pp_string (pp, ", ");
1993 dump_input (pp, 0, m_input_arr[i], simple);
1994 }
1995 pp_string (pp, "})");
1996 }
1997 }
1998
1999 /* Subroutine of asm_output_svalue::dump_to_pp. */
2000
2001 void
2002 asm_output_svalue::dump_input (pretty_printer *pp,
2003 unsigned input_idx,
2004 const svalue *sval,
2005 bool simple) const
2006 {
2007 pp_printf (pp, "%%%i: ", input_idx_to_asm_idx (input_idx));
2008 sval->dump_to_pp (pp, simple);
2009 }
2010
2011 /* Convert INPUT_IDX from an index into the array of inputs
2012 into the index of all operands for the asm stmt. */
2013
2014 unsigned
2015 asm_output_svalue::input_idx_to_asm_idx (unsigned input_idx) const
2016 {
2017 return input_idx + m_num_outputs;
2018 }
2019
2020 /* Implementation of svalue::accept vfunc for asm_output_svalue. */
2021
2022 void
2023 asm_output_svalue::accept (visitor *v) const
2024 {
2025 for (unsigned i = 0; i < m_num_inputs; i++)
2026 m_input_arr[i]->accept (v);
2027 v->visit_asm_output_svalue (this);
2028 }
2029
2030 /* class const_fn_result_svalue : public svalue. */
2031
2032 /* Implementation of svalue::dump_to_pp vfunc for const_fn_result_svalue. */
2033
2034 void
2035 const_fn_result_svalue::dump_to_pp (pretty_printer *pp, bool simple) const
2036 {
2037 if (simple)
2038 {
2039 pp_printf (pp, "CONST_FN_RESULT(%qD, {", m_fndecl);
2040 for (unsigned i = 0; i < m_num_inputs; i++)
2041 {
2042 if (i > 0)
2043 pp_string (pp, ", ");
2044 dump_input (pp, i, m_input_arr[i], simple);
2045 }
2046 pp_string (pp, "})");
2047 }
2048 else
2049 {
2050 pp_printf (pp, "CONST_FN_RESULT(%qD, {", m_fndecl);
2051 for (unsigned i = 0; i < m_num_inputs; i++)
2052 {
2053 if (i > 0)
2054 pp_string (pp, ", ");
2055 dump_input (pp, i, m_input_arr[i], simple);
2056 }
2057 pp_string (pp, "})");
2058 }
2059 }
2060
2061 /* Subroutine of const_fn_result_svalue::dump_to_pp. */
2062
2063 void
2064 const_fn_result_svalue::dump_input (pretty_printer *pp,
2065 unsigned input_idx,
2066 const svalue *sval,
2067 bool simple) const
2068 {
2069 pp_printf (pp, "arg%i: ", input_idx);
2070 sval->dump_to_pp (pp, simple);
2071 }
2072
2073 /* Implementation of svalue::accept vfunc for const_fn_result_svalue. */
2074
2075 void
2076 const_fn_result_svalue::accept (visitor *v) const
2077 {
2078 for (unsigned i = 0; i < m_num_inputs; i++)
2079 m_input_arr[i]->accept (v);
2080 v->visit_const_fn_result_svalue (this);
2081 }
2082
2083 } // namespace ana
2084
2085 #endif /* #if ENABLE_ANALYZER */