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