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