]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/analyzer/svalue.h
Update copyright years.
[thirdparty/gcc.git] / gcc / analyzer / svalue.h
CommitLineData
e9751143 1/* Symbolic values.
83ffe9cd 2 Copyright (C) 2019-2023 Free Software Foundation, Inc.
e9751143
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#ifndef GCC_ANALYZER_SVALUE_H
22#define GCC_ANALYZER_SVALUE_H
23
24#include "analyzer/complexity.h"
bfca9505
DM
25#include "analyzer/store.h"
26#include "analyzer/program-point.h"
e9751143
DM
27
28using namespace ana;
29
30namespace ana {
31
32/* An enum for discriminating between the different concrete subclasses
33 of svalue. */
34
35enum svalue_kind
36{
37 SK_REGION,
38 SK_CONSTANT,
39 SK_UNKNOWN,
40 SK_POISONED,
41 SK_SETJMP,
42 SK_INITIAL,
43 SK_UNARYOP,
44 SK_BINOP,
45 SK_SUB,
e61ffa20
DM
46 SK_REPEATED,
47 SK_BITS_WITHIN,
e9751143
DM
48 SK_UNMERGEABLE,
49 SK_PLACEHOLDER,
50 SK_WIDENING,
51 SK_COMPOUND,
ded2c2c0 52 SK_CONJURED,
aee1adf2
DM
53 SK_ASM_OUTPUT,
54 SK_CONST_FN_RESULT
e9751143
DM
55};
56
57/* svalue and its subclasses.
58
59 The class hierarchy looks like this (using indentation to show
60 inheritance, and with svalue_kinds shown for the concrete subclasses):
61
62 svalue
63 region_svalue (SK_REGION): a pointer to a region
64 constant_svalue (SK_CONSTANT): a constant
65 unknown_svalue (SK_UNKNOWN): an unknowable value
66 poisoned_svalue (SK_POISONED): a unusable value (undefined)
67 setjmp_svalue (SK_SETJMP): a setjmp/longjmp buffer
68 initial_svalue (SK_INITIAL): the initial value of a region
69 unaryop_svalue (SK_UNARYOP): unary operation on another svalue
70 binop_svalue (SK_BINOP): binary operation on two svalues
71 sub_svalue (SK_SUB): the result of accessing a subregion
e61ffa20
DM
72 repeated_svalue (SK_REPEATED): repeating an svalue to fill a larger region
73 bits_within_svalue (SK_BITS_WITHIN): a range of bits/bytes within a larger
74 svalue
e9751143
DM
75 unmergeable_svalue (SK_UNMERGEABLE): a value that is so interesting
76 from a control-flow perspective that it can inhibit state-merging
77 placeholder_svalue (SK_PLACEHOLDER): for use in selftests.
78 widening_svalue (SK_WIDENING): a merger of two svalues (possibly
79 in an iteration).
80 compound_svalue (SK_COMPOUND): a mapping of bit-ranges to svalues
ded2c2c0
DM
81 conjured_svalue (SK_CONJURED): a value arising from a stmt
82 asm_output_svalue (SK_ASM_OUTPUT): an output from a deterministic
aee1adf2
DM
83 asm stmt.
84 const_fn_result_svalue (SK_CONST_FN_RESULT): the return value from
85 a function with __attribute((const)) for given inputs. */
e9751143
DM
86
87/* An abstract base class representing a value held by a region of memory. */
88
89class svalue
90{
91public:
92 virtual ~svalue () {}
93
94 tree get_type () const { return m_type; }
95
96 virtual enum svalue_kind get_kind () const = 0;
97
98 void print (const region_model &model,
99 pretty_printer *pp) const;
100
101 virtual void dump_to_pp (pretty_printer *pp, bool simple) const = 0;
102 void dump (bool simple=true) const;
103 label_text get_desc (bool simple=true) const;
104
105 json::value *to_json () const;
106
107 virtual const region_svalue *
108 dyn_cast_region_svalue () const { return NULL; }
109 virtual const constant_svalue *
110 dyn_cast_constant_svalue () const { return NULL; }
111 virtual const poisoned_svalue *
112 dyn_cast_poisoned_svalue () const { return NULL; }
113 virtual const setjmp_svalue *
114 dyn_cast_setjmp_svalue () const { return NULL; }
115 virtual const initial_svalue *
116 dyn_cast_initial_svalue () const { return NULL; }
117 virtual const unaryop_svalue *
118 dyn_cast_unaryop_svalue () const { return NULL; }
119 virtual const binop_svalue *
120 dyn_cast_binop_svalue () const { return NULL; }
121 virtual const sub_svalue *
122 dyn_cast_sub_svalue () const { return NULL; }
e61ffa20
DM
123 virtual const repeated_svalue *
124 dyn_cast_repeated_svalue () const { return NULL; }
125 virtual const bits_within_svalue *
126 dyn_cast_bits_within_svalue () const { return NULL; }
e9751143
DM
127 virtual const unmergeable_svalue *
128 dyn_cast_unmergeable_svalue () const { return NULL; }
129 virtual const widening_svalue *
130 dyn_cast_widening_svalue () const { return NULL; }
131 virtual const compound_svalue *
132 dyn_cast_compound_svalue () const { return NULL; }
133 virtual const conjured_svalue *
134 dyn_cast_conjured_svalue () const { return NULL; }
ded2c2c0
DM
135 virtual const asm_output_svalue *
136 dyn_cast_asm_output_svalue () const { return NULL; }
aee1adf2
DM
137 virtual const const_fn_result_svalue *
138 dyn_cast_const_fn_result_svalue () const { return NULL; }
e9751143
DM
139
140 tree maybe_get_constant () const;
5932dd35 141 const region *maybe_get_region () const;
e9751143
DM
142 const svalue *maybe_undo_cast () const;
143 const svalue *unwrap_any_unmergeable () const;
144
145 const svalue *can_merge_p (const svalue *other,
146 region_model_manager *mgr,
147 model_merger *merger) const;
148
149 const complexity &get_complexity () const { return m_complexity; }
150
151 virtual void accept (visitor *v) const = 0;
152
e0139b2a 153 bool live_p (const svalue_set *live_svalues,
e9751143 154 const region_model *model) const;
e0139b2a 155 virtual bool implicitly_live_p (const svalue_set *live_svalues,
e9751143
DM
156 const region_model *model) const;
157
158 static int cmp_ptr (const svalue *, const svalue *);
159 static int cmp_ptr_ptr (const void *, const void *);
160
71fc4655
DM
161 bool involves_p (const svalue *other) const;
162
e61ffa20
DM
163 const svalue *
164 extract_bit_range (tree type,
165 const bit_range &subrange,
166 region_model_manager *mgr) const;
167
168 virtual const svalue *
169 maybe_fold_bits_within (tree type,
170 const bit_range &subrange,
171 region_model_manager *mgr) const;
172
48e8a7a6
DM
173 virtual bool all_zeroes_p () const;
174
a113b143
DM
175 /* Can this svalue be involved in constraints and sm-state?
176 Most can, but UNKNOWN and POISONED svalues are singletons
177 per-type and thus it's meaningless for them to "have state". */
178 virtual bool can_have_associated_state_p () const { return true; }
179
a358e4b6
DM
180 const region *maybe_get_deref_base_region () const;
181
e9751143
DM
182 protected:
183 svalue (complexity c, tree type)
184 : m_complexity (c), m_type (type)
185 {}
186
187 private:
188 complexity m_complexity;
189 tree m_type;
190};
191
192/* Concrete subclass of svalue representing a pointer value that points to
193 a known region */
194
195class region_svalue : public svalue
196{
197public:
198 /* A support class for uniquifying instances of region_svalue. */
199 struct key_t
200 {
201 key_t (tree type, const region *reg)
202 : m_type (type), m_reg (reg)
203 {}
204
205 hashval_t hash () const
206 {
207 inchash::hash hstate;
208 hstate.add_ptr (m_type);
209 hstate.add_ptr (m_reg);
210 return hstate.end ();
211 }
212
213 bool operator== (const key_t &other) const
214 {
215 return (m_type == other.m_type && m_reg == other.m_reg);
216 }
217
218 void mark_deleted () { m_type = reinterpret_cast<tree> (1); }
e61ffa20 219 void mark_empty () { m_type = reinterpret_cast<tree> (2); }
e9751143 220 bool is_deleted () const { return m_type == reinterpret_cast<tree> (1); }
e61ffa20 221 bool is_empty () const { return m_type == reinterpret_cast<tree> (2); }
e9751143
DM
222
223 tree m_type;
224 const region *m_reg;
225 };
226
227 region_svalue (tree type, const region *reg)
228 : svalue (complexity (reg), type),
229 m_reg (reg)
230 {
231 gcc_assert (m_reg != NULL);
232 }
233
ff171cb1 234 enum svalue_kind get_kind () const final override { return SK_REGION; }
e9751143 235 const region_svalue *
ff171cb1 236 dyn_cast_region_svalue () const final override { return this; }
e9751143 237
ff171cb1
DM
238 void dump_to_pp (pretty_printer *pp, bool simple) const final override;
239 void accept (visitor *v) const final override;
e0139b2a 240 bool implicitly_live_p (const svalue_set *,
ff171cb1 241 const region_model *) const final override;
e9751143
DM
242
243 const region * get_pointee () const { return m_reg; }
244
245 static tristate eval_condition (const region_svalue *lhs_ptr,
246 enum tree_code op,
247 const region_svalue *rhs_ptr);
248
249 private:
250 const region *m_reg;
251};
252
253} // namespace ana
254
255template <>
256template <>
257inline bool
258is_a_helper <const region_svalue *>::test (const svalue *sval)
259{
260 return sval->get_kind () == SK_REGION;
261}
262
263template <> struct default_hash_traits<region_svalue::key_t>
264: public member_function_hash_traits<region_svalue::key_t>
265{
e61ffa20 266 static const bool empty_zero_p = false;
e9751143
DM
267};
268
269namespace ana {
270
271/* Concrete subclass of svalue representing a specific constant value. */
272
273class constant_svalue : public svalue
274{
275public:
276 constant_svalue (tree cst_expr)
277 : svalue (complexity (1, 1), TREE_TYPE (cst_expr)), m_cst_expr (cst_expr)
278 {
279 gcc_assert (cst_expr);
280 gcc_assert (CONSTANT_CLASS_P (cst_expr));
281 }
282
ff171cb1 283 enum svalue_kind get_kind () const final override { return SK_CONSTANT; }
e9751143 284 const constant_svalue *
ff171cb1 285 dyn_cast_constant_svalue () const final override { return this; }
e9751143 286
ff171cb1
DM
287 void dump_to_pp (pretty_printer *pp, bool simple) const final override;
288 void accept (visitor *v) const final override;
e0139b2a 289 bool implicitly_live_p (const svalue_set *,
ff171cb1 290 const region_model *) const final override;
e9751143
DM
291
292 tree get_constant () const { return m_cst_expr; }
293 static tristate eval_condition (const constant_svalue *lhs,
294 enum tree_code op,
295 const constant_svalue *rhs);
296
e61ffa20
DM
297 const svalue *
298 maybe_fold_bits_within (tree type,
299 const bit_range &subrange,
ff171cb1 300 region_model_manager *mgr) const final override;
e61ffa20 301
ff171cb1 302 bool all_zeroes_p () const final override;
48e8a7a6 303
e9751143
DM
304 private:
305 tree m_cst_expr;
306};
307
308} // namespace ana
309
310template <>
311template <>
312inline bool
313is_a_helper <const constant_svalue *>::test (const svalue *sval)
314{
315 return sval->get_kind () == SK_CONSTANT;
316}
317
318namespace ana {
319
320/* Concrete subclass of svalue representing an unknowable value, the bottom
321 value when thinking of svalues as a lattice.
322 This is a singleton (w.r.t. its manager): there is a single unknown_svalue
323 per type. Self-comparisons of such instances yield "unknown". */
324
325class unknown_svalue : public svalue
326{
327public:
328 unknown_svalue (tree type)
329 : svalue (complexity (1, 1), type)
330 {}
331
ff171cb1 332 enum svalue_kind get_kind () const final override { return SK_UNKNOWN; }
e9751143 333
ff171cb1
DM
334 void dump_to_pp (pretty_printer *pp, bool simple) const final override;
335 void accept (visitor *v) const final override;
e61ffa20
DM
336
337 const svalue *
338 maybe_fold_bits_within (tree type,
339 const bit_range &subrange,
ff171cb1 340 region_model_manager *mgr) const final override;
a113b143
DM
341
342 /* Unknown values are singletons per-type, so can't have state. */
ff171cb1 343 bool can_have_associated_state_p () const final override { return false; }
e9751143
DM
344};
345
346/* An enum describing a particular kind of "poisoned" value. */
347
348enum poison_kind
349{
33255ad3
DM
350 /* For use to describe uninitialized memory. */
351 POISON_KIND_UNINIT,
352
e9751143
DM
353 /* For use to describe freed memory. */
354 POISON_KIND_FREED,
355
356 /* For use on pointers to regions within popped stack frames. */
357 POISON_KIND_POPPED_STACK
358};
359
360extern const char *poison_kind_to_str (enum poison_kind);
361
362/* Concrete subclass of svalue representing a value that should not
363 be used (e.g. uninitialized memory, freed memory). */
364
365class poisoned_svalue : public svalue
366{
367public:
368 /* A support class for uniquifying instances of poisoned_svalue. */
369 struct key_t
370 {
371 key_t (enum poison_kind kind, tree type)
372 : m_kind (kind), m_type (type)
373 {}
374
375 hashval_t hash () const
376 {
377 inchash::hash hstate;
378 hstate.add_int (m_kind);
379 hstate.add_ptr (m_type);
380 return hstate.end ();
381 }
382
383 bool operator== (const key_t &other) const
384 {
385 return (m_kind == other.m_kind && m_type == other.m_type);
386 }
387
388 void mark_deleted () { m_type = reinterpret_cast<tree> (1); }
e61ffa20 389 void mark_empty () { m_type = reinterpret_cast<tree> (2); }
e9751143 390 bool is_deleted () const { return m_type == reinterpret_cast<tree> (1); }
e61ffa20 391 bool is_empty () const { return m_type == reinterpret_cast<tree> (2); }
e9751143
DM
392
393 enum poison_kind m_kind;
394 tree m_type;
395 };
396
397 poisoned_svalue (enum poison_kind kind, tree type)
398 : svalue (complexity (1, 1), type), m_kind (kind) {}
399
ff171cb1 400 enum svalue_kind get_kind () const final override { return SK_POISONED; }
e9751143 401 const poisoned_svalue *
ff171cb1 402 dyn_cast_poisoned_svalue () const final override { return this; }
e9751143 403
ff171cb1
DM
404 void dump_to_pp (pretty_printer *pp, bool simple) const final override;
405 void accept (visitor *v) const final override;
e9751143 406
33255ad3
DM
407 const svalue *
408 maybe_fold_bits_within (tree type,
409 const bit_range &subrange,
ff171cb1 410 region_model_manager *mgr) const final override;
33255ad3 411
e9751143
DM
412 enum poison_kind get_poison_kind () const { return m_kind; }
413
a113b143 414 /* Poisoned svalues are singletons per-type, so can't have state. */
ff171cb1 415 bool can_have_associated_state_p () const final override { return false; }
a113b143 416
e9751143
DM
417 private:
418 enum poison_kind m_kind;
419};
420
421} // namespace ana
422
423template <>
424template <>
425inline bool
426is_a_helper <const poisoned_svalue *>::test (const svalue *sval)
427{
428 return sval->get_kind () == SK_POISONED;
429}
430
431template <> struct default_hash_traits<poisoned_svalue::key_t>
432: public member_function_hash_traits<poisoned_svalue::key_t>
433{
e61ffa20 434 static const bool empty_zero_p = false;
e9751143
DM
435};
436
437namespace ana {
438
439/* A bundle of information recording a setjmp/sigsetjmp call, corresponding
440 roughly to a jmp_buf. */
441
442struct setjmp_record
443{
444 setjmp_record (const exploded_node *enode,
445 const gcall *setjmp_call)
446 : m_enode (enode), m_setjmp_call (setjmp_call)
447 {
448 }
449
450 bool operator== (const setjmp_record &other) const
451 {
452 return (m_enode == other.m_enode
453 && m_setjmp_call == other.m_setjmp_call);
454 }
455
456 void add_to_hash (inchash::hash *hstate) const
457 {
458 hstate->add_ptr (m_enode);
459 hstate->add_ptr (m_setjmp_call);
460 }
461
462 static int cmp (const setjmp_record &rec1, const setjmp_record &rec2);
463
464 const exploded_node *m_enode;
465 const gcall *m_setjmp_call;
466};
467
468/* Concrete subclass of svalue representing buffers for setjmp/sigsetjmp,
469 so that longjmp/siglongjmp can potentially "return" to an entirely
470 different function. */
471
472class setjmp_svalue : public svalue
473{
474public:
475 /* A support class for uniquifying instances of poisoned_svalue. */
476 struct key_t
477 {
478 key_t (const setjmp_record &record, tree type)
479 : m_record (record), m_type (type)
480 {}
481
482 hashval_t hash () const
483 {
484 inchash::hash hstate;
485 m_record.add_to_hash (&hstate);
486 hstate.add_ptr (m_type);
487 return hstate.end ();
488 }
489
490 bool operator== (const key_t &other) const
491 {
492 return (m_record == other.m_record && m_type == other.m_type);
493 }
494
495 void mark_deleted () { m_type = reinterpret_cast<tree> (1); }
e61ffa20 496 void mark_empty () { m_type = reinterpret_cast<tree> (2); }
e9751143 497 bool is_deleted () const { return m_type == reinterpret_cast<tree> (1); }
e61ffa20 498 bool is_empty () const { return m_type == reinterpret_cast<tree> (2); }
e9751143
DM
499
500 setjmp_record m_record;
501 tree m_type;
502 };
503
504 setjmp_svalue (const setjmp_record &setjmp_record,
505 tree type)
506 : svalue (complexity (1, 1), type), m_setjmp_record (setjmp_record)
507 {}
508
ff171cb1 509 enum svalue_kind get_kind () const final override { return SK_SETJMP; }
e9751143 510 const setjmp_svalue *
ff171cb1 511 dyn_cast_setjmp_svalue () const final override { return this; }
e9751143 512
ff171cb1
DM
513 void dump_to_pp (pretty_printer *pp, bool simple) const final override;
514 void accept (visitor *v) const final override;
e9751143
DM
515
516 int get_enode_index () const;
517
518 const setjmp_record &get_setjmp_record () const { return m_setjmp_record; }
519
520 private:
521 setjmp_record m_setjmp_record;
522};
523
524} // namespace ana
525
526template <>
527template <>
528inline bool
529is_a_helper <const setjmp_svalue *>::test (const svalue *sval)
530{
531 return sval->get_kind () == SK_SETJMP;
532}
533
534template <> struct default_hash_traits<setjmp_svalue::key_t>
535: public member_function_hash_traits<setjmp_svalue::key_t>
536{
e61ffa20 537 static const bool empty_zero_p = false;
e9751143
DM
538};
539
540namespace ana {
541
542/* Concrete subclass of svalue representing the initial value of a
543 specific region.
544
545 This represents the initial value at the start of the analysis path,
546 as opposed to the first time the region is accessed during the path.
547 Hence as soon as we have a call to an unknown function, all previously
548 unmodelled globals become implicitly "unknown" rathen than "initial". */
549
550class initial_svalue : public svalue
551{
552public:
553 initial_svalue (tree type, const region *reg)
554 : svalue (complexity (reg), type), m_reg (reg)
555 {
556 gcc_assert (m_reg != NULL);
557 }
558
ff171cb1 559 enum svalue_kind get_kind () const final override { return SK_INITIAL; }
e9751143 560 const initial_svalue *
ff171cb1 561 dyn_cast_initial_svalue () const final override { return this; }
e9751143 562
ff171cb1
DM
563 void dump_to_pp (pretty_printer *pp, bool simple) const final override;
564 void accept (visitor *v) const final override;
e0139b2a 565 bool implicitly_live_p (const svalue_set *,
ff171cb1 566 const region_model *) const final override;
e9751143 567
e0139b2a
DM
568 bool initial_value_of_param_p () const;
569
e9751143
DM
570 const region *get_region () const { return m_reg; }
571
572 private:
573 const region *m_reg;
574};
575
576} // namespace ana
577
578template <>
579template <>
580inline bool
581is_a_helper <const initial_svalue *>::test (const svalue *sval)
582{
583 return sval->get_kind () == SK_INITIAL;
584}
585
586namespace ana {
587
588/* Concrete subclass of svalue representing a unary operation on
589 another svalues (e.g. a cast). */
590
591class unaryop_svalue : public svalue
592{
593public:
594 /* A support class for uniquifying instances of unaryop_svalue. */
595 struct key_t
596 {
597 key_t (tree type, enum tree_code op, const svalue *arg)
598 : m_type (type), m_op (op), m_arg (arg)
599 {}
600
601 hashval_t hash () const
602 {
603 inchash::hash hstate;
604 hstate.add_ptr (m_type);
605 hstate.add_int (m_op);
606 hstate.add_ptr (m_arg);
607 return hstate.end ();
608 }
609
610 bool operator== (const key_t &other) const
611 {
612 return (m_type == other.m_type
613 && m_op == other.m_op
614 && m_arg == other.m_arg);
615 }
616
617 void mark_deleted () { m_type = reinterpret_cast<tree> (1); }
e61ffa20 618 void mark_empty () { m_type = reinterpret_cast<tree> (2); }
e9751143 619 bool is_deleted () const { return m_type == reinterpret_cast<tree> (1); }
e61ffa20 620 bool is_empty () const { return m_type == reinterpret_cast<tree> (2); }
e9751143
DM
621
622 tree m_type;
623 enum tree_code m_op;
624 const svalue *m_arg;
625 };
626
627 unaryop_svalue (tree type, enum tree_code op, const svalue *arg)
628 : svalue (complexity (arg), type), m_op (op), m_arg (arg)
629 {
a113b143 630 gcc_assert (arg->can_have_associated_state_p ());
e9751143
DM
631 }
632
ff171cb1 633 enum svalue_kind get_kind () const final override { return SK_UNARYOP; }
e9751143 634 const unaryop_svalue *
ff171cb1 635 dyn_cast_unaryop_svalue () const final override { return this; }
e9751143 636
ff171cb1
DM
637 void dump_to_pp (pretty_printer *pp, bool simple) const final override;
638 void accept (visitor *v) const final override;
e0139b2a 639 bool implicitly_live_p (const svalue_set *,
ff171cb1 640 const region_model *) const final override;
e9751143
DM
641
642 enum tree_code get_op () const { return m_op; }
643 const svalue *get_arg () const { return m_arg; }
644
e61ffa20
DM
645 const svalue *
646 maybe_fold_bits_within (tree type,
647 const bit_range &subrange,
ff171cb1 648 region_model_manager *mgr) const final override;
e61ffa20 649
e9751143
DM
650 private:
651 enum tree_code m_op;
652 const svalue *m_arg;
653};
654
655} // namespace ana
656
657template <>
658template <>
659inline bool
660is_a_helper <const unaryop_svalue *>::test (const svalue *sval)
661{
662 return sval->get_kind () == SK_UNARYOP;
663}
664
665template <> struct default_hash_traits<unaryop_svalue::key_t>
666: public member_function_hash_traits<unaryop_svalue::key_t>
667{
e61ffa20 668 static const bool empty_zero_p = false;
e9751143
DM
669};
670
671namespace ana {
672
673/* Concrete subclass of svalue representing a binary operation of
674 two svalues. */
675
676class binop_svalue : public svalue
677{
678public:
679 /* A support class for uniquifying instances of binop_svalue. */
680 struct key_t
681 {
682 key_t (tree type, enum tree_code op,
683 const svalue *arg0, const svalue *arg1)
684 : m_type (type), m_op (op), m_arg0 (arg0), m_arg1 (arg1)
685 {}
686
687 hashval_t hash () const
688 {
689 inchash::hash hstate;
690 hstate.add_ptr (m_type);
691 hstate.add_int (m_op);
692 hstate.add_ptr (m_arg0);
693 hstate.add_ptr (m_arg1);
694 return hstate.end ();
695 }
696
697 bool operator== (const key_t &other) const
698 {
699 return (m_type == other.m_type
700 && m_op == other.m_op
701 && m_arg0 == other.m_arg0
702 && m_arg1 == other.m_arg1);
703 }
704
705 void mark_deleted () { m_type = reinterpret_cast<tree> (1); }
e61ffa20 706 void mark_empty () { m_type = reinterpret_cast<tree> (2); }
e9751143 707 bool is_deleted () const { return m_type == reinterpret_cast<tree> (1); }
e61ffa20 708 bool is_empty () const { return m_type == reinterpret_cast<tree> (2); }
e9751143
DM
709
710 tree m_type;
711 enum tree_code m_op;
712 const svalue *m_arg0;
713 const svalue *m_arg1;
714 };
715
716 binop_svalue (tree type, enum tree_code op,
717 const svalue *arg0, const svalue *arg1)
718 : svalue (complexity::from_pair (arg0->get_complexity (),
719 arg1->get_complexity ()),
720 type),
721 m_op (op), m_arg0 (arg0), m_arg1 (arg1)
722 {
a113b143
DM
723 gcc_assert (arg0->can_have_associated_state_p ());
724 gcc_assert (arg1->can_have_associated_state_p ());
e9751143
DM
725 }
726
ff171cb1
DM
727 enum svalue_kind get_kind () const final override { return SK_BINOP; }
728 const binop_svalue *dyn_cast_binop_svalue () const final override
e9751143
DM
729 {
730 return this;
731 }
732
ff171cb1
DM
733 void dump_to_pp (pretty_printer *pp, bool simple) const final override;
734 void accept (visitor *v) const final override;
e0139b2a 735 bool implicitly_live_p (const svalue_set *,
ff171cb1 736 const region_model *) const final override;
e9751143
DM
737
738 enum tree_code get_op () const { return m_op; }
739 const svalue *get_arg0 () const { return m_arg0; }
740 const svalue *get_arg1 () const { return m_arg1; }
741
742 private:
743 enum tree_code m_op;
744 const svalue *m_arg0;
745 const svalue *m_arg1;
746};
747
748} // namespace ana
749
750template <>
751template <>
752inline bool
753is_a_helper <const binop_svalue *>::test (const svalue *sval)
754{
755 return sval->get_kind () == SK_BINOP;
756}
757
758template <> struct default_hash_traits<binop_svalue::key_t>
759: public member_function_hash_traits<binop_svalue::key_t>
760{
e61ffa20 761 static const bool empty_zero_p = false;
e9751143
DM
762};
763
764namespace ana {
765
766/* Concrete subclass of svalue representing the result of accessing a subregion
767 of another svalue (the value of a component/field of a struct, or an element
768 from an array). */
769
770class sub_svalue : public svalue
771{
772public:
773 /* A support class for uniquifying instances of sub_svalue. */
774 struct key_t
775 {
776 key_t (tree type, const svalue *parent_svalue, const region *subregion)
777 : m_type (type), m_parent_svalue (parent_svalue), m_subregion (subregion)
778 {}
779
780 hashval_t hash () const
781 {
782 inchash::hash hstate;
783 hstate.add_ptr (m_type);
784 hstate.add_ptr (m_parent_svalue);
785 hstate.add_ptr (m_subregion);
786 return hstate.end ();
787 }
788
789 bool operator== (const key_t &other) const
790 {
791 return (m_type == other.m_type
792 && m_parent_svalue == other.m_parent_svalue
793 && m_subregion == other.m_subregion);
794 }
795
796 void mark_deleted () { m_type = reinterpret_cast<tree> (1); }
e61ffa20 797 void mark_empty () { m_type = reinterpret_cast<tree> (2); }
e9751143 798 bool is_deleted () const { return m_type == reinterpret_cast<tree> (1); }
e61ffa20 799 bool is_empty () const { return m_type == reinterpret_cast<tree> (2); }
e9751143
DM
800
801 tree m_type;
802 const svalue *m_parent_svalue;
803 const region *m_subregion;
804 };
805 sub_svalue (tree type, const svalue *parent_svalue,
806 const region *subregion);
807
ff171cb1
DM
808 enum svalue_kind get_kind () const final override { return SK_SUB; }
809 const sub_svalue *dyn_cast_sub_svalue () const final override
e9751143
DM
810 {
811 return this;
812 }
813
ff171cb1
DM
814 void dump_to_pp (pretty_printer *pp, bool simple) const final override;
815 void accept (visitor *v) const final override;
e0139b2a 816 bool implicitly_live_p (const svalue_set *,
ff171cb1 817 const region_model *) const final override;
e9751143
DM
818
819 const svalue *get_parent () const { return m_parent_svalue; }
820 const region *get_subregion () const { return m_subregion; }
821
822 private:
823 const svalue *m_parent_svalue;
824 const region *m_subregion;
825};
826
827} // namespace ana
828
829template <>
830template <>
831inline bool
832is_a_helper <const sub_svalue *>::test (const svalue *sval)
833{
834 return sval->get_kind () == SK_SUB;
835}
836
837template <> struct default_hash_traits<sub_svalue::key_t>
838: public member_function_hash_traits<sub_svalue::key_t>
839{
e61ffa20
DM
840 static const bool empty_zero_p = false;
841};
842
843namespace ana {
844
845/* Concrete subclass of svalue representing repeating an inner svalue
846 (possibly not a whole number of times) to fill a larger region of
847 type TYPE of size OUTER_SIZE bytes. */
848
849class repeated_svalue : public svalue
850{
851public:
852 /* A support class for uniquifying instances of repeated_svalue. */
853 struct key_t
854 {
855 key_t (tree type,
856 const svalue *outer_size,
857 const svalue *inner_svalue)
858 : m_type (type), m_outer_size (outer_size), m_inner_svalue (inner_svalue)
859 {}
860
861 hashval_t hash () const
862 {
863 inchash::hash hstate;
864 hstate.add_ptr (m_type);
865 hstate.add_ptr (m_outer_size);
866 hstate.add_ptr (m_inner_svalue);
867 return hstate.end ();
868 }
869
870 bool operator== (const key_t &other) const
871 {
872 return (m_type == other.m_type
873 && m_outer_size == other.m_outer_size
874 && m_inner_svalue == other.m_inner_svalue);
875 }
876
877 void mark_deleted () { m_type = reinterpret_cast<tree> (1); }
878 void mark_empty () { m_type = reinterpret_cast<tree> (2); }
879 bool is_deleted () const { return m_type == reinterpret_cast<tree> (1); }
880 bool is_empty () const { return m_type == reinterpret_cast<tree> (2); }
881
882 tree m_type;
883 const svalue *m_outer_size;
884 const svalue *m_inner_svalue;
885 };
886 repeated_svalue (tree type,
887 const svalue *outer_size,
888 const svalue *inner_svalue);
889
ff171cb1
DM
890 enum svalue_kind get_kind () const final override { return SK_REPEATED; }
891 const repeated_svalue *dyn_cast_repeated_svalue () const final override
e61ffa20
DM
892 {
893 return this;
894 }
895
ff171cb1
DM
896 void dump_to_pp (pretty_printer *pp, bool simple) const final override;
897 void accept (visitor *v) const final override;
e61ffa20
DM
898
899 const svalue *get_outer_size () const { return m_outer_size; }
900 const svalue *get_inner_svalue () const { return m_inner_svalue; }
901
ff171cb1 902 bool all_zeroes_p () const final override;
e61ffa20
DM
903
904 const svalue *
905 maybe_fold_bits_within (tree type,
906 const bit_range &subrange,
ff171cb1 907 region_model_manager *mgr) const final override;
e61ffa20
DM
908
909 private:
910 const svalue *m_outer_size;
911 const svalue *m_inner_svalue;
912};
913
914} // namespace ana
915
916template <>
917template <>
918inline bool
919is_a_helper <const repeated_svalue *>::test (const svalue *sval)
920{
921 return sval->get_kind () == SK_REPEATED;
922}
923
924template <> struct default_hash_traits<repeated_svalue::key_t>
925: public member_function_hash_traits<repeated_svalue::key_t>
926{
927 static const bool empty_zero_p = false;
928};
929
930namespace ana {
931
932/* A range of bits/bytes within another svalue
933 e.g. bytes 5-39 of INITIAL_SVALUE(R).
934 These can be generated for prefixes and suffixes when part of a binding
935 is clobbered, so that we don't lose too much information. */
936
937class bits_within_svalue : public svalue
938{
939public:
940 /* A support class for uniquifying instances of bits_within_svalue. */
941 struct key_t
942 {
943 key_t (tree type,
944 const bit_range &bits,
945 const svalue *inner_svalue)
946 : m_type (type), m_bits (bits), m_inner_svalue (inner_svalue)
947 {}
948
949 hashval_t hash () const
950 {
951 inchash::hash hstate;
952 hstate.add_ptr (m_type);
953 hstate.add_ptr (m_inner_svalue);
954 return hstate.end ();
955 }
956
957 bool operator== (const key_t &other) const
958 {
959 return (m_type == other.m_type
960 && m_bits == other.m_bits
961 && m_inner_svalue == other.m_inner_svalue);
962 }
963
964 void mark_deleted () { m_type = reinterpret_cast<tree> (1); }
965 void mark_empty () { m_type = reinterpret_cast<tree> (2); }
966 bool is_deleted () const { return m_type == reinterpret_cast<tree> (1); }
967 bool is_empty () const { return m_type == reinterpret_cast<tree> (2); }
968
969 tree m_type;
970 bit_range m_bits;
971 const svalue *m_inner_svalue;
972 };
973 bits_within_svalue (tree type,
974 const bit_range &bits,
975 const svalue *inner_svalue);
976
ff171cb1 977 enum svalue_kind get_kind () const final override { return SK_BITS_WITHIN; }
e61ffa20 978 const bits_within_svalue *
ff171cb1 979 dyn_cast_bits_within_svalue () const final override
e61ffa20
DM
980 {
981 return this;
982 }
983
ff171cb1
DM
984 void dump_to_pp (pretty_printer *pp, bool simple) const final override;
985 void accept (visitor *v) const final override;
e61ffa20 986 bool implicitly_live_p (const svalue_set *,
ff171cb1 987 const region_model *) const final override;
e61ffa20
DM
988
989 const bit_range &get_bits () const { return m_bits; }
990 const svalue *get_inner_svalue () const { return m_inner_svalue; }
991
992 const svalue *
993 maybe_fold_bits_within (tree type,
994 const bit_range &subrange,
ff171cb1 995 region_model_manager *mgr) const final override;
e61ffa20
DM
996
997 private:
998 const bit_range m_bits;
999 const svalue *m_inner_svalue;
1000};
1001
1002} // namespace ana
1003
1004template <>
1005template <>
1006inline bool
1007is_a_helper <const bits_within_svalue *>::test (const svalue *sval)
1008{
1009 return sval->get_kind () == SK_BITS_WITHIN;
1010}
1011
1012template <> struct default_hash_traits<bits_within_svalue::key_t>
1013: public member_function_hash_traits<bits_within_svalue::key_t>
1014{
1015 static const bool empty_zero_p = false;
e9751143
DM
1016};
1017
1018namespace ana {
1019
1020/* Concrete subclass of svalue: decorate another svalue,
1021 so that the resulting svalue can be identified as being
1022 "interesting to control flow".
1023 For example, consider the return value from setjmp. We
1024 don't want to merge states in which the result is 0 with
1025 those in which the result is non-zero. By using an
1026 unmergeable_svalue for the result, we can inhibit such merges
1027 and have separate exploded nodes for those states, keeping
1028 the first and second returns from setjmp distinct in the exploded
1029 graph. */
1030
1031class unmergeable_svalue : public svalue
1032{
1033public:
1034 unmergeable_svalue (const svalue *arg)
1035 : svalue (complexity (arg), arg->get_type ()), m_arg (arg)
1036 {
1037 }
1038
ff171cb1 1039 enum svalue_kind get_kind () const final override { return SK_UNMERGEABLE; }
e9751143 1040 const unmergeable_svalue *
ff171cb1 1041 dyn_cast_unmergeable_svalue () const final override { return this; }
e9751143 1042
ff171cb1
DM
1043 void dump_to_pp (pretty_printer *pp, bool simple) const final override;
1044 void accept (visitor *v) const final override;
e0139b2a 1045 bool implicitly_live_p (const svalue_set *,
ff171cb1 1046 const region_model *) const final override;
e9751143
DM
1047
1048 const svalue *get_arg () const { return m_arg; }
1049
1050 private:
1051 const svalue *m_arg;
1052};
1053
1054} // namespace ana
1055
1056template <>
1057template <>
1058inline bool
1059is_a_helper <const unmergeable_svalue *>::test (const svalue *sval)
1060{
1061 return sval->get_kind () == SK_UNMERGEABLE;
1062}
1063
1064namespace ana {
1065
1066/* Concrete subclass of svalue for use in selftests, where
1067 we want a specific but unknown svalue.
1068 Unlike other svalue subclasses these aren't managed by
1069 region_model_manager. */
1070
1071class placeholder_svalue : public svalue
1072{
1073public:
1074 placeholder_svalue (tree type, const char *name)
1075 : svalue (complexity (1, 1), type), m_name (name)
1076 {
1077 }
1078
ff171cb1 1079 enum svalue_kind get_kind () const final override { return SK_PLACEHOLDER; }
e9751143 1080
ff171cb1
DM
1081 void dump_to_pp (pretty_printer *pp, bool simple) const final override;
1082 void accept (visitor *v) const final override;
e9751143
DM
1083
1084 const char *get_name () const { return m_name; }
1085
1086 private:
1087 const char *m_name;
1088};
1089
1090} // namespace ana
1091
1092template <>
1093template <>
1094inline bool
c031ea27 1095is_a_helper <const placeholder_svalue *>::test (const svalue *sval)
e9751143
DM
1096{
1097 return sval->get_kind () == SK_PLACEHOLDER;
1098}
1099
1100namespace ana {
1101
1102/* Concrete subclass of svalue representing a "widening" seen when merging
1103 states, widening from a base value to {base value, iter value} and thus
1104 representing a possible fixed point in an iteration from the base to
1105 +ve infinity, or -ve infinity, and thus useful for representing a value
1106 within a loop.
1107 We also need to capture the program_point at which the merger happens,
1108 so that distinguish between different iterators, and thus handle
1109 nested loops. (currently we capture the function_point instead, for
1110 simplicity of hashing). */
1111
1112class widening_svalue : public svalue
1113{
1114public:
1115 /* A support class for uniquifying instances of widening_svalue. */
1116 struct key_t
1117 {
e6fe02d8 1118 key_t (tree type, const function_point &point,
e9751143 1119 const svalue *base_sval, const svalue *iter_sval)
e6fe02d8 1120 : m_type (type), m_point (point),
e9751143
DM
1121 m_base_sval (base_sval), m_iter_sval (iter_sval)
1122 {}
1123
1124 hashval_t hash () const
1125 {
1126 inchash::hash hstate;
1127 hstate.add_ptr (m_base_sval);
1128 hstate.add_ptr (m_iter_sval);
1129 return hstate.end ();
1130 }
1131
1132 bool operator== (const key_t &other) const
1133 {
1134 return (m_type == other.m_type
1135 && m_point == other.m_point
1136 && m_base_sval == other.m_base_sval
1137 && m_iter_sval == other.m_iter_sval);
1138 }
1139
1140 void mark_deleted () { m_type = reinterpret_cast<tree> (1); }
e61ffa20 1141 void mark_empty () { m_type = reinterpret_cast<tree> (2); }
e9751143 1142 bool is_deleted () const { return m_type == reinterpret_cast<tree> (1); }
e61ffa20 1143 bool is_empty () const { return m_type == reinterpret_cast<tree> (2); }
e9751143
DM
1144
1145 tree m_type;
1146 function_point m_point;
1147 const svalue *m_base_sval;
1148 const svalue *m_iter_sval;
1149 };
1150
1151 enum direction_t
1152 {
1153 DIR_ASCENDING,
1154 DIR_DESCENDING,
1155 DIR_UNKNOWN
1156 };
1157
e6fe02d8 1158 widening_svalue (tree type, const function_point &point,
e9751143
DM
1159 const svalue *base_sval, const svalue *iter_sval)
1160 : svalue (complexity::from_pair (base_sval->get_complexity (),
1161 iter_sval->get_complexity ()),
1162 type),
e6fe02d8 1163 m_point (point),
e9751143
DM
1164 m_base_sval (base_sval), m_iter_sval (iter_sval)
1165 {
a113b143
DM
1166 gcc_assert (base_sval->can_have_associated_state_p ());
1167 gcc_assert (iter_sval->can_have_associated_state_p ());
e9751143
DM
1168 }
1169
ff171cb1
DM
1170 enum svalue_kind get_kind () const final override { return SK_WIDENING; }
1171 const widening_svalue *dyn_cast_widening_svalue () const final override
e9751143
DM
1172 {
1173 return this;
1174 }
1175
ff171cb1
DM
1176 void dump_to_pp (pretty_printer *pp, bool simple) const final override;
1177 void accept (visitor *v) const final override;
e9751143
DM
1178
1179 const function_point &get_point () const { return m_point; }
1180 const svalue *get_base_svalue () const { return m_base_sval; }
1181 const svalue *get_iter_svalue () const { return m_iter_sval; }
1182
1183 enum direction_t get_direction () const;
1184
1185 tristate eval_condition_without_cm (enum tree_code op,
1186 tree rhs_cst) const;
1187
1188 private:
1189 function_point m_point;
1190 const svalue *m_base_sval;
1191 const svalue *m_iter_sval;
1192};
1193
1194} // namespace ana
1195
1196template <>
1197template <>
1198inline bool
c031ea27 1199is_a_helper <const widening_svalue *>::test (const svalue *sval)
e9751143
DM
1200{
1201 return sval->get_kind () == SK_WIDENING;
1202}
1203
1204template <> struct default_hash_traits<widening_svalue::key_t>
1205: public member_function_hash_traits<widening_svalue::key_t>
1206{
e61ffa20 1207 static const bool empty_zero_p = false;
e9751143
DM
1208};
1209
1210namespace ana {
1211
1212/* Concrete subclass of svalue representing a mapping of bit-ranges
1213 to svalues, analogous to a cluster within the store.
1214
1215 This is for use in places where we want to represent a store-like
1216 mapping, but are required to use an svalue, such as when handling
1217 compound assignments and compound return values.
1218
1219 All keys within the underlying binding_map are required to be concrete,
1220 not symbolic.
1221
1222 Instances of this class shouldn't be bound as-is into the store;
1223 instead they should be unpacked. Similarly, they should not be
1224 nested. */
1225
1226class compound_svalue : public svalue
1227{
1228public:
1229 typedef binding_map::iterator_t iterator_t;
1230
1231 /* A support class for uniquifying instances of compound_svalue.
1232 Note that to avoid copies, keys store pointers to binding_maps,
1233 rather than the maps themselves. */
1234 struct key_t
1235 {
1236 key_t (tree type, const binding_map *map_ptr)
1237 : m_type (type), m_map_ptr (map_ptr)
1238 {}
1239
1240 hashval_t hash () const
1241 {
1242 inchash::hash hstate;
1243 hstate.add_ptr (m_type);
1244 //hstate.add_ptr (m_map_ptr); // TODO
1245 return hstate.end ();
1246 }
1247
1248 bool operator== (const key_t &other) const
1249 {
1250 return (m_type == other.m_type
1251 && *m_map_ptr == *other.m_map_ptr);
1252 }
1253
1254 void mark_deleted () { m_type = reinterpret_cast<tree> (1); }
e61ffa20 1255 void mark_empty () { m_type = reinterpret_cast<tree> (2); }
e9751143 1256 bool is_deleted () const { return m_type == reinterpret_cast<tree> (1); }
e61ffa20 1257 bool is_empty () const { return m_type == reinterpret_cast<tree> (2); }
e9751143
DM
1258
1259 tree m_type;
1260 const binding_map *m_map_ptr;
1261 };
1262
1263 compound_svalue (tree type, const binding_map &map);
1264
ff171cb1
DM
1265 enum svalue_kind get_kind () const final override { return SK_COMPOUND; }
1266 const compound_svalue *dyn_cast_compound_svalue () const final override
e9751143
DM
1267 {
1268 return this;
1269 }
1270
ff171cb1
DM
1271 void dump_to_pp (pretty_printer *pp, bool simple) const final override;
1272 void accept (visitor *v) const final override;
e9751143
DM
1273
1274 const binding_map &get_map () const { return m_map; }
1275
1276 iterator_t begin () const { return m_map.begin (); }
1277 iterator_t end () const { return m_map.end (); }
1278
1279 struct key_t make_key () const
1280 {
1281 return key_t (get_type (), &m_map);
1282 }
1283
e61ffa20
DM
1284 const svalue *
1285 maybe_fold_bits_within (tree type,
1286 const bit_range &subrange,
ff171cb1 1287 region_model_manager *mgr) const final override;
e61ffa20 1288
e9751143
DM
1289 private:
1290 static complexity calc_complexity (const binding_map &map);
1291
1292 binding_map m_map;
1293};
1294
1295} // namespace ana
1296
1297template <>
1298template <>
1299inline bool
c031ea27 1300is_a_helper <const compound_svalue *>::test (const svalue *sval)
e9751143
DM
1301{
1302 return sval->get_kind () == SK_COMPOUND;
1303}
1304
1305template <> struct default_hash_traits<compound_svalue::key_t>
1306: public member_function_hash_traits<compound_svalue::key_t>
1307{
e61ffa20 1308 static const bool empty_zero_p = false;
e9751143
DM
1309};
1310
1311namespace ana {
1312
3734527d
DM
1313/* A bundle of state for purging information from a program_state about
1314 a conjured_svalue. We pass this whenever calling
1315 get_or_create_conjured_svalue, so that if the program_state already
1316 has information about this conjured_svalue on an execution path, we
1317 can purge that information, to avoid the analyzer confusing the two
1318 values as being the same. */
1319
1320class conjured_purge
1321{
1322public:
1323 conjured_purge (region_model *model, region_model_context *ctxt)
1324 : m_model (model), m_ctxt (ctxt)
1325 {
1326 }
1327 void purge (const conjured_svalue *sval) const;
1328
1329private:
1330 region_model *m_model;
1331 region_model_context *m_ctxt;
1332};
1333
e9751143
DM
1334/* A defined value arising from a statement, where we want to identify a
1335 particular unknown value, rather than resorting to the unknown_value
1336 singleton, so that the value can have sm-state.
1337
1338 Comparisons of variables that share the same conjured_svalue are known
1339 to be equal, even if we don't know what the value is.
1340
1341 For example, this is used for the values of regions that may have been
1342 touched when calling an unknown function.
1343
1344 The value captures a region as well as a stmt in order to avoid falsely
1345 aliasing the various values that could arise in one statement. For
1346 example, after:
1347 unknown_fn (&a, &b);
1348 we want values to clobber a and b with, but we don't want to use the
1349 same value, or it would falsely implicitly assume that a == b. */
1350
1351class conjured_svalue : public svalue
1352{
1353public:
e9751143
DM
1354 /* A support class for uniquifying instances of conjured_svalue. */
1355 struct key_t
1356 {
1357 key_t (tree type, const gimple *stmt, const region *id_reg)
1358 : m_type (type), m_stmt (stmt), m_id_reg (id_reg)
1359 {}
1360
1361 hashval_t hash () const
1362 {
1363 inchash::hash hstate;
1364 hstate.add_ptr (m_type);
1365 hstate.add_ptr (m_stmt);
1366 hstate.add_ptr (m_id_reg);
1367 return hstate.end ();
1368 }
1369
1370 bool operator== (const key_t &other) const
1371 {
1372 return (m_type == other.m_type
1373 && m_stmt == other.m_stmt
1374 && m_id_reg == other.m_id_reg);
1375 }
1376
1377 /* Use m_stmt to mark empty/deleted, as m_type can be NULL for
1378 legitimate instances. */
1379 void mark_deleted () { m_stmt = reinterpret_cast<const gimple *> (1); }
1380 void mark_empty () { m_stmt = NULL; }
1381 bool is_deleted () const
1382 {
1383 return m_stmt == reinterpret_cast<const gimple *> (1);
1384 }
1385 bool is_empty () const { return m_stmt == NULL; }
1386
1387 tree m_type;
1388 const gimple *m_stmt;
1389 const region *m_id_reg;
1390 };
1391
1392 conjured_svalue (tree type, const gimple *stmt, const region *id_reg)
1393 : svalue (complexity (id_reg), type),
1394 m_stmt (stmt), m_id_reg (id_reg)
1395 {
1396 gcc_assert (m_stmt != NULL);
1397 }
1398
ff171cb1
DM
1399 enum svalue_kind get_kind () const final override { return SK_CONJURED; }
1400 const conjured_svalue *dyn_cast_conjured_svalue () const final override
e9751143
DM
1401 {
1402 return this;
1403 }
1404
ff171cb1
DM
1405 void dump_to_pp (pretty_printer *pp, bool simple) const final override;
1406 void accept (visitor *v) const final override;
e9751143
DM
1407
1408 const gimple *get_stmt () const { return m_stmt; }
1409 const region *get_id_region () const { return m_id_reg; }
1410
1411 private:
1412 const gimple *m_stmt;
1413 const region *m_id_reg;
1414};
1415
1416} // namespace ana
1417
1418template <>
1419template <>
1420inline bool
c031ea27 1421is_a_helper <const conjured_svalue *>::test (const svalue *sval)
e9751143
DM
1422{
1423 return sval->get_kind () == SK_CONJURED;
1424}
1425
1426template <> struct default_hash_traits<conjured_svalue::key_t>
1427: public member_function_hash_traits<conjured_svalue::key_t>
1428{
1429 static const bool empty_zero_p = true;
1430};
1431
ded2c2c0
DM
1432namespace ana {
1433
1434/* An output from a deterministic asm stmt, where we want to identify a
1435 particular unknown value, rather than resorting to the unknown_value
1436 singleton.
1437
1438 Comparisons of variables that share the same asm_output_svalue are known
1439 to be equal, even if we don't know what the value is. */
1440
1441class asm_output_svalue : public svalue
1442{
1443public:
1444 /* Imposing an upper limit and using a (small) array allows key_t
1445 to avoid memory management. */
1446 static const unsigned MAX_INPUTS = 2;
1447
1448 /* A support class for uniquifying instances of asm_output_svalue. */
1449 struct key_t
1450 {
1451 key_t (tree type,
1452 const char *asm_string,
1453 unsigned output_idx,
1454 const vec<const svalue *> &inputs)
1455 : m_type (type), m_asm_string (asm_string), m_output_idx (output_idx),
1456 m_num_inputs (inputs.length ())
1457 {
1458 gcc_assert (inputs.length () <= MAX_INPUTS);
1459 for (unsigned i = 0; i < m_num_inputs; i++)
1460 m_input_arr[i] = inputs[i];
1461 }
1462
1463 hashval_t hash () const
1464 {
1465 inchash::hash hstate;
1466 hstate.add_ptr (m_type);
1467 /* We don't bother hashing m_asm_str. */
1468 hstate.add_int (m_output_idx);
1469 for (unsigned i = 0; i < m_num_inputs; i++)
1470 hstate.add_ptr (m_input_arr[i]);
1471 return hstate.end ();
1472 }
1473
1474 bool operator== (const key_t &other) const
1475 {
1476 if (!(m_type == other.m_type
1477 && 0 == (strcmp (m_asm_string, other.m_asm_string))
1478 && m_output_idx == other.m_output_idx
1479 && m_num_inputs == other.m_num_inputs))
1480 return false;
1481 for (unsigned i = 0; i < m_num_inputs; i++)
1482 if (m_input_arr[i] != other.m_input_arr[i])
1483 return false;
1484 return true;
1485 }
1486
1487 /* Use m_asm_string to mark empty/deleted, as m_type can be NULL for
1488 legitimate instances. */
1489 void mark_deleted () { m_asm_string = reinterpret_cast<const char *> (1); }
1490 void mark_empty () { m_asm_string = NULL; }
1491 bool is_deleted () const
1492 {
1493 return m_asm_string == reinterpret_cast<const char *> (1);
1494 }
1495 bool is_empty () const { return m_asm_string == NULL; }
1496
1497 tree m_type;
1498 const char *m_asm_string;
1499 unsigned m_output_idx;
1500 unsigned m_num_inputs;
1501 const svalue *m_input_arr[MAX_INPUTS];
1502 };
1503
1504 asm_output_svalue (tree type,
1505 const char *asm_string,
1506 unsigned output_idx,
1507 unsigned num_outputs,
1508 const vec<const svalue *> &inputs)
1509 : svalue (complexity::from_vec_svalue (inputs), type),
1510 m_asm_string (asm_string),
1511 m_output_idx (output_idx),
1512 m_num_outputs (num_outputs),
1513 m_num_inputs (inputs.length ())
1514 {
1515 gcc_assert (inputs.length () <= MAX_INPUTS);
1516 for (unsigned i = 0; i < m_num_inputs; i++)
1517 m_input_arr[i] = inputs[i];
1518 }
1519
ff171cb1 1520 enum svalue_kind get_kind () const final override { return SK_ASM_OUTPUT; }
ded2c2c0 1521 const asm_output_svalue *
ff171cb1 1522 dyn_cast_asm_output_svalue () const final override
ded2c2c0
DM
1523 {
1524 return this;
1525 }
1526
ff171cb1
DM
1527 void dump_to_pp (pretty_printer *pp, bool simple) const final override;
1528 void accept (visitor *v) const final override;
ded2c2c0
DM
1529
1530 const char *get_asm_string () const { return m_asm_string; }
1531 unsigned get_output_idx () const { return m_output_idx; }
bfca9505 1532 unsigned get_num_outputs () const { return m_num_outputs; }
ded2c2c0
DM
1533 unsigned get_num_inputs () const { return m_num_inputs; }
1534 const svalue *get_input (unsigned idx) const { return m_input_arr[idx]; }
1535
1536 private:
1537 void dump_input (pretty_printer *pp,
1538 unsigned input_idx,
1539 const svalue *sval,
1540 bool simple) const;
1541 unsigned input_idx_to_asm_idx (unsigned input_idx) const;
1542
1543 const char *m_asm_string;
1544 unsigned m_output_idx;
1545
1546 /* We capture this so that we can offset the input indices
1547 to match the %0, %1, %2 in the asm_string when dumping. */
1548 unsigned m_num_outputs;
1549
1550 unsigned m_num_inputs;
1551 const svalue *m_input_arr[MAX_INPUTS];
1552};
1553
1554} // namespace ana
1555
1556template <>
1557template <>
1558inline bool
1559is_a_helper <const asm_output_svalue *>::test (const svalue *sval)
1560{
1561 return sval->get_kind () == SK_ASM_OUTPUT;
1562}
1563
1564template <> struct default_hash_traits<asm_output_svalue::key_t>
1565: public member_function_hash_traits<asm_output_svalue::key_t>
1566{
1567 static const bool empty_zero_p = true;
1568};
aee1adf2
DM
1569
1570namespace ana {
1571
1572/* The return value from a function with __attribute((const)) for given
1573 inputs, provided that we don't have too many inputs, and all of them
1574 are deterministic.
1575
1576 Comparisons of variables that share the same const_fn_result_svalue are known
1577 to be equal, even if we don't know what the value is. */
1578
1579class const_fn_result_svalue : public svalue
1580{
1581public:
1582 /* Imposing an upper limit and using a (small) array allows key_t
1583 to avoid memory management. */
1584 static const unsigned MAX_INPUTS = 2;
1585
1586 /* A support class for uniquifying instances of const_fn_result_svalue. */
1587 struct key_t
1588 {
1589 key_t (tree type,
1590 tree fndecl,
1591 const vec<const svalue *> &inputs)
1592 : m_type (type), m_fndecl (fndecl),
1593 m_num_inputs (inputs.length ())
1594 {
1595 gcc_assert (inputs.length () <= MAX_INPUTS);
1596 for (unsigned i = 0; i < m_num_inputs; i++)
1597 m_input_arr[i] = inputs[i];
1598 }
1599
1600 hashval_t hash () const
1601 {
1602 inchash::hash hstate;
1603 hstate.add_ptr (m_type);
1604 hstate.add_ptr (m_fndecl);
1605 for (unsigned i = 0; i < m_num_inputs; i++)
1606 hstate.add_ptr (m_input_arr[i]);
1607 return hstate.end ();
1608 }
1609
1610 bool operator== (const key_t &other) const
1611 {
1612 if (!(m_type == other.m_type
1613 && m_fndecl == other.m_fndecl
1614 && m_num_inputs == other.m_num_inputs))
1615 return false;
1616 for (unsigned i = 0; i < m_num_inputs; i++)
1617 if (m_input_arr[i] != other.m_input_arr[i])
1618 return false;
1619 return true;
1620 }
1621
1622 /* Use m_fndecl to mark empty/deleted. */
1623 void mark_deleted () { m_fndecl = reinterpret_cast<tree> (1); }
1624 void mark_empty () { m_fndecl = NULL; }
1625 bool is_deleted () const
1626 {
1627 return m_fndecl == reinterpret_cast<tree> (1);
1628 }
1629 bool is_empty () const { return m_fndecl == NULL; }
1630
1631 tree m_type;
1632 tree m_fndecl;
1633 unsigned m_num_inputs;
1634 const svalue *m_input_arr[MAX_INPUTS];
1635 };
1636
1637 const_fn_result_svalue (tree type,
1638 tree fndecl,
1639 const vec<const svalue *> &inputs)
1640 : svalue (complexity::from_vec_svalue (inputs), type),
1641 m_fndecl (fndecl),
1642 m_num_inputs (inputs.length ())
1643 {
1644 gcc_assert (inputs.length () <= MAX_INPUTS);
1645 for (unsigned i = 0; i < m_num_inputs; i++)
1646 m_input_arr[i] = inputs[i];
1647 }
1648
ff171cb1 1649 enum svalue_kind get_kind () const final override
aee1adf2
DM
1650 {
1651 return SK_CONST_FN_RESULT;
1652 }
1653 const const_fn_result_svalue *
ff171cb1 1654 dyn_cast_const_fn_result_svalue () const final override
aee1adf2
DM
1655 {
1656 return this;
1657 }
1658
ff171cb1
DM
1659 void dump_to_pp (pretty_printer *pp, bool simple) const final override;
1660 void accept (visitor *v) const final override;
aee1adf2
DM
1661
1662 tree get_fndecl () const { return m_fndecl; }
1663 unsigned get_num_inputs () const { return m_num_inputs; }
1664 const svalue *get_input (unsigned idx) const { return m_input_arr[idx]; }
1665
1666 private:
1667 void dump_input (pretty_printer *pp,
1668 unsigned input_idx,
1669 const svalue *sval,
1670 bool simple) const;
1671
1672 tree m_fndecl;
1673 unsigned m_num_inputs;
1674 const svalue *m_input_arr[MAX_INPUTS];
1675};
1676
1677} // namespace ana
1678
1679template <>
1680template <>
1681inline bool
1682is_a_helper <const const_fn_result_svalue *>::test (const svalue *sval)
1683{
1684 return sval->get_kind () == SK_CONST_FN_RESULT;
1685}
1686
1687template <> struct default_hash_traits<const_fn_result_svalue::key_t>
1688: public member_function_hash_traits<const_fn_result_svalue::key_t>
1689{
1690 static const bool empty_zero_p = true;
1691};
1692
e9751143 1693#endif /* GCC_ANALYZER_SVALUE_H */