GCC Middle and Back End API Reference
region-model.h
Go to the documentation of this file.
1/* Classes for modeling the state of memory.
2 Copyright (C) 2019-2024 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_REGION_MODEL_H
22#define GCC_ANALYZER_REGION_MODEL_H
23
24/* Implementation of the region-based ternary model described in:
25 "A Memory Model for Static Analysis of C Programs"
26 (Zhongxing Xu, Ted Kremenek, and Jian Zhang)
27 http://lcs.ios.ac.cn/~xuzb/canalyze/memmodel.pdf */
28
29#include "bitmap.h"
30#include "stringpool.h"
31#include "attribs.h" // for rdwr_map
32#include "selftest.h"
33#include "analyzer/svalue.h"
34#include "analyzer/region.h"
38#include "text-art/widget.h"
39#include "text-art/dump.h"
40
41using namespace ana;
42
43namespace inchash
44{
45 extern void add_path_var (path_var pv, hash &hstate);
46} // namespace inchash
47
48namespace ana {
49
50template <typename T>
52{
53 public:
54 one_way_id_map (int num_ids);
55 void put (T src, T dst);
56 T get_dst_for_src (T src) const;
57 void dump_to_pp (pretty_printer *pp) const;
58 void dump () const;
59 void update (T *) const;
60
61 private:
63 };
64
65/* class one_way_id_map. */
66
67/* one_way_id_map's ctor, which populates the map with dummy null values. */
68
69template <typename T>
70inline one_way_id_map<T>::one_way_id_map (int num_svalues)
71: m_src_to_dst (num_svalues)
72{
73 for (int i = 0; i < num_svalues; i++)
74 m_src_to_dst.quick_push (T::null ());
75}
76
77/* Record that SRC is to be mapped to DST. */
78
79template <typename T>
80inline void
82{
83 m_src_to_dst[src.as_int ()] = dst;
84}
85
86/* Get the new value for SRC within the map. */
87
88template <typename T>
89inline T
91{
92 if (src.null_p ())
93 return src;
94 return m_src_to_dst[src.as_int ()];
95}
96
97/* Dump this map to PP. */
98
99template <typename T>
100inline void
102{
103 pp_string (pp, "src to dst: {");
104 unsigned i;
105 T *dst;
106 FOR_EACH_VEC_ELT (m_src_to_dst, i, dst)
107 {
108 if (i > 0)
109 pp_string (pp, ", ");
110 T src (T::from_int (i));
111 src.print (pp);
112 pp_string (pp, " -> ");
113 dst->print (pp);
114 }
115 pp_string (pp, "}");
116 pp_newline (pp);
117}
118
119/* Dump this map to stderr. */
120
121template <typename T>
122DEBUG_FUNCTION inline void
124{
126 pp.set_output_stream (stderr);
127 dump_to_pp (&pp);
128 pp_flush (&pp);
129}
130
131/* Update *ID from the old value to its new value in this map. */
132
133template <typename T>
134inline void
136{
137 *id = get_dst_for_src (*id);
138}
139
140/* A mapping from region to svalue for use when tracking state. */
141
143{
144public:
146 typedef hash_map_t::iterator iterator;
147
152
153 bool operator== (const region_to_value_map &other) const;
154 bool operator!= (const region_to_value_map &other) const
155 {
156 return !(*this == other);
157 }
158
159 iterator begin () const { return m_hash_map.begin (); }
160 iterator end () const { return m_hash_map.end (); }
161
162 const svalue * const *get (const region *reg) const
163 {
164 return const_cast <hash_map_t &> (m_hash_map).get (reg);
165 }
166 void put (const region *reg, const svalue *sval)
167 {
168 m_hash_map.put (reg, sval);
169 }
170 void remove (const region *reg)
171 {
172 m_hash_map.remove (reg);
173 }
174
175 bool is_empty () const { return m_hash_map.is_empty (); }
176
177 void dump_to_pp (pretty_printer *pp, bool simple, bool multiline) const;
178 void dump (bool simple) const;
179
180 std::unique_ptr<json::object> to_json () const;
181
182 std::unique_ptr<text_art::tree_widget>
183 make_dump_widget (const text_art::dump_widget_info &dwi) const;
184
186 region_to_value_map *out) const;
187
188 void purge_state_involving (const svalue *sval);
189
190private:
192};
193
194/* Various operations delete information from a region_model.
195
196 This struct tracks how many of each kind of entity were purged (e.g.
197 for selftests, and for debugging). */
198
217
218/* A base class for visiting regions and svalues, with do-nothing
219 base implementations of the per-subclass vfuncs. */
220
222{
223public:
224 virtual void visit_region_svalue (const region_svalue *) {}
225 virtual void visit_constant_svalue (const constant_svalue *) {}
226 virtual void visit_unknown_svalue (const unknown_svalue *) {}
227 virtual void visit_poisoned_svalue (const poisoned_svalue *) {}
228 virtual void visit_setjmp_svalue (const setjmp_svalue *) {}
229 virtual void visit_initial_svalue (const initial_svalue *) {}
230 virtual void visit_unaryop_svalue (const unaryop_svalue *) {}
231 virtual void visit_binop_svalue (const binop_svalue *) {}
232 virtual void visit_sub_svalue (const sub_svalue *) {}
233 virtual void visit_repeated_svalue (const repeated_svalue *) {}
237 virtual void visit_widening_svalue (const widening_svalue *) {}
238 virtual void visit_compound_svalue (const compound_svalue *) {}
239 virtual void visit_conjured_svalue (const conjured_svalue *) {}
242
243 virtual void visit_region (const region *) {}
244};
245
246struct append_regions_cb_data;
247
248typedef void (*pop_frame_callback) (const region_model *model,
249 const region_model *prev_model,
250 const svalue *retval,
252
253/* A region_model encapsulates a representation of the state of memory, with
254 a tree of regions, along with their associated values.
255 The representation is graph-like because values can be pointers to
256 regions.
257 It also stores:
258 - a constraint_manager, capturing relationships between the values, and
259 - dynamic extents, mapping dynamically-allocated regions to svalues (their
260 capacities). */
261
263{
264 public:
266
271
272 bool operator== (const region_model &other) const;
273 bool operator!= (const region_model &other) const
274 {
275 return !(*this == other);
276 }
277
278 hashval_t hash () const;
279
280 void print (pretty_printer *pp) const;
281
282 void dump_to_pp (pretty_printer *pp, bool simple, bool multiline) const;
283 void dump (FILE *fp, bool simple, bool multiline) const;
284 void dump (bool simple) const;
285 void dump () const;
286
287 void debug () const;
288
289 std::unique_ptr<json::object> to_json () const;
290
291 std::unique_ptr<text_art::tree_widget>
292 make_dump_widget (const text_art::dump_widget_info &dwi) const;
293
294 void validate () const;
295
297 bool canonicalized_p () const;
298
299 void
300 on_stmt_pre (const gimple *stmt,
301 bool *out_unknown_side_effects,
303
304 void on_assignment (const gassign *stmt, region_model_context *ctxt);
305 const svalue *get_gassign_result (const gassign *assign,
307 void on_asm_stmt (const gasm *asm_stmt, region_model_context *ctxt);
308 bool on_call_pre (const gcall *stmt, region_model_context *ctxt);
309 void on_call_post (const gcall *stmt,
310 bool unknown_side_effects,
312
314
316
317 const svalue *maybe_get_copy_bounds (const region *src_reg,
318 const svalue *num_bytes_sval);
320 int retval,
321 bool unmergeable);
323 bool unmergeable);
325
329 const svalue *extra_sval,
330 const uncertainty_t *uncertainty);
331
332 void on_return (const greturn *stmt, region_model_context *ctxt);
333 void on_setjmp (const gcall *stmt, const exploded_node *enode,
335 void on_longjmp (const gcall *longjmp_call, const gcall *setjmp_call,
336 int setjmp_stack_depth, region_model_context *ctxt);
337
338 void update_for_phis (const supernode *snode,
339 const cfg_superedge *last_cfg_superedge,
341
342 void handle_phi (const gphi *phi, tree lhs, tree rhs,
343 const region_model &old_state,
344 hash_set<const svalue *> &svals_changing_meaning,
346
348 const gimple *last_stmt,
350 std::unique_ptr<rejected_constraint> *out);
351
352 void update_for_gcall (const gcall *call_stmt,
354 function *callee = NULL);
355
356 void update_for_return_gcall (const gcall *call_stmt,
358
359 const region *push_frame (const function &fun, const vec<const svalue *> *arg_sids,
363 void pop_frame (tree result_lvalue,
364 const svalue **out_result,
366 const gcall *call_stmt,
367 bool eval_return_svalue = true);
368 int get_stack_depth () const;
369 const frame_region *get_frame_at_index (int index) const;
370
375
376 const region *deref_rvalue (const svalue *ptr_sval, tree ptr_tree,
378 bool add_nonnull_constraint = true) const;
379
381 const region *reg,
382 const bit_range &bits,
383 region_model_context *ctxt) const;
384
385 void set_value (const region *lhs_reg, const svalue *rhs_sval,
387 void set_value (tree lhs, tree rhs, region_model_context *ctxt);
388 void clobber_region (const region *reg);
389 void purge_region (const region *reg);
390 void fill_region (const region *reg,
391 const svalue *sval,
393 void zero_fill_region (const region *reg,
395 void write_bytes (const region *dest_reg,
396 const svalue *num_bytes_sval,
397 const svalue *sval,
399 const svalue *read_bytes (const region *src_reg,
400 tree src_ptr_expr,
401 const svalue *num_bytes_sval,
402 region_model_context *ctxt) const;
403 void copy_bytes (const region *dest_reg,
404 const region *src_reg,
405 tree src_ptr_expr,
406 const svalue *num_bytes_sval,
408 void mark_region_as_unknown (const region *reg, uncertainty_t *uncertainty);
409
411 enum tree_code op,
412 const svalue *rhs) const;
414 const region_svalue *ptr) const;
416 const svalue *b) const;
417 tristate structural_equality (const svalue *a, const svalue *b) const;
419 enum tree_code op,
420 tree rhs,
421 region_model_context *ctxt) const;
422 bool add_constraint (tree lhs, enum tree_code op, tree rhs,
424 bool add_constraint (tree lhs, enum tree_code op, tree rhs,
426 std::unique_ptr<rejected_constraint> *out);
427
428 const region *
431 bool update_state_machine = false,
432 const call_details *cd = nullptr);
433
437
439 logger *logger = nullptr) const;
441 logger *logger = nullptr) const;
445 logger *logger) const;
449 logger *logger) const;
450
451 /* For selftests. */
456
457 store *get_store () { return &m_store; }
458 const store *get_store () const { return &m_store; }
459
460 const dynamic_extents_t &
462 {
463 return m_dynamic_extents;
464 }
465 const svalue *get_dynamic_extents (const region *reg) const;
466 void set_dynamic_extents (const region *reg,
467 const svalue *size_in_bytes,
469 void unset_dynamic_extents (const region *reg);
470
476
478 enum poison_kind pkind);
479
480 bool can_merge_with_p (const region_model &other_model,
481 const program_point &point,
482 region_model *out_model,
484 const program_state *state_a = NULL,
485 const program_state *state_b = NULL) const;
486
489
491 static void append_regions_cb (const region *base_reg,
492 struct append_regions_cb_data *data);
493
494 const svalue *get_store_value (const region *reg,
495 region_model_context *ctxt) const;
496 const svalue *get_store_bytes (const region *base_reg,
497 const byte_range &bytes,
498 region_model_context *ctxt) const;
500 tree expr,
501 const svalue **out_sval,
502 region_model_context *ctxt) const;
504 tree expr,
505 const svalue **out_sval,
506 region_model_context *ctxt) const;
507
508 bool region_exists_p (const region *reg) const;
509
510 void loop_replay_fixup (const region_model *dst_state);
511
512 const svalue *get_capacity (const region *reg) const;
513
515 const region_model &summary);
516
518 const svalue *copied_sval,
519 const region *src_reg,
521
522 void set_errno (const call_details &cd);
523
524 /* Implemented in sm-fd.cc */
526
527 /* Implemented in sm-malloc.cc */
529 const svalue *old_ptr_sval,
530 const svalue *new_ptr_sval);
531
532 /* Implemented in sm-malloc.cc. */
533 void
535 const svalue *new_ptr_sval);
536
537 /* Implemented in sm-taint.cc. */
538 void mark_as_tainted (const svalue *sval,
540
541 bool add_constraint (const svalue *lhs,
542 enum tree_code op,
543 const svalue *rhs,
545
546 const svalue *check_for_poison (const svalue *sval,
547 tree expr,
548 const region *src_region,
549 region_model_context *ctxt) const;
550
551 void check_region_for_write (const region *dest_reg,
552 const svalue *sval_hint,
553 region_model_context *ctxt) const;
554
555 const svalue *
557 unsigned idx) const;
558 const svalue *
560 unsigned idx,
561 bool include_terminator,
562 const svalue **out_sval) const;
563
565 get_builtin_kf (const gcall *call,
566 region_model_context *ctxt = NULL) const;
567
568 static void
570 {
571 pop_frame_callbacks.safe_push (callback);
572 }
573
574 static void
576 const region_model *prev_model,
577 const svalue *retval,
579 {
580 for (auto &callback : pop_frame_callbacks)
581 callback (model, prev_model, retval, ctxt);
582 }
583
584 bool called_from_main_p () const;
585
586private:
589
593 logger *logger) const;
597 logger *logger) const;
598
600 const call_details &cd) const;
602
603 bool add_constraints_from_binop (const svalue *outer_lhs,
604 enum tree_code outer_op,
605 const svalue *outer_rhs,
606 bool *out,
608
614 const gcond *cond_stmt,
616 std::unique_ptr<rejected_constraint> *out);
618 const gswitch *switch_stmt,
620 std::unique_ptr<rejected_constraint> *out);
622 const ggoto *goto_stmt,
626 std::unique_ptr<rejected_constraint> *out);
627
629 enum poison_kind pkind);
630
632 bool nonnull,
634
635 const svalue *get_initial_value_for_global (const region *reg) const;
636
638
640 const svalue *size_in_bytes,
641 region_model_context *ctxt) const;
643 region_model_context *ctxt) const;
644
646 enum access_direction dir,
647 region_model_context *ctxt) const;
648
649 void check_for_writable_region (const region* dest_reg,
650 region_model_context *ctxt) const;
651 bool check_region_access (const region *reg,
652 enum access_direction dir,
653 const svalue *sval_hint,
654 region_model_context *ctxt) const;
655 bool check_region_for_read (const region *src_reg,
656 region_model_context *ctxt) const;
657 void check_region_size (const region *lhs_reg, const svalue *rhs_sval,
658 region_model_context *ctxt) const;
659
660 /* Implemented in bounds-checking.cc */
661 bool check_symbolic_bounds (const region *base_reg,
662 const svalue *sym_byte_offset,
663 const svalue *num_bytes_sval,
664 const svalue *capacity,
665 enum access_direction dir,
666 const svalue *sval_hint,
667 region_model_context *ctxt) const;
668 bool check_region_bounds (const region *reg, enum access_direction dir,
669 const svalue *sval_hint,
670 region_model_context *ctxt) const;
671
672 void check_call_args (const call_details &cd) const;
674 tree format_attr) const;
676 tree callee_fndecl,
678 rdwr_map &rdwr_idx) const;
680 tree callee_fndecl,
682 rdwr_map &rdwr_idx);
684 tree callee_fndecl,
686 rdwr_map &rdwr_idx,
687 tree attr);
688 void check_function_attrs (const gcall *call,
689 tree callee_fndecl,
691
693 /* Storing this here to avoid passing it around everywhere. */
695
697
698 constraint_manager *m_constraints; // TODO: embed, rather than dynalloc?
699
701
702 /* Map from base region to size in bytes, for tracking the sizes of
703 dynamically-allocated regions.
704 This is part of the region_model rather than the region to allow for
705 memory regions to be resized (e.g. by realloc). */
707};
708
709/* Some region_model activity could lead to warnings (e.g. attempts to use an
710 uninitialized value). This abstract base class encapsulates an interface
711 for the region model to use when emitting such warnings.
712
713 Having this as an abstract base class allows us to support the various
714 operations needed by program_state in the analyzer within region_model,
715 whilst keeping them somewhat modularized. */
716
718{
719 public:
720 /* Hook for clients to store pending diagnostics.
721 Return true if the diagnostic was stored, or false if it was deleted.
722 Optionally provide a custom stmt_finder. */
723 virtual bool warn (std::unique_ptr<pending_diagnostic> d,
724 const stmt_finder *custom_finder = NULL) = 0;
725
726 /* Hook for clients to add a note to the last previously stored
727 pending diagnostic. */
728 virtual void add_note (std::unique_ptr<pending_note> pn) = 0;
729
730 /* Hook for clients to add an event to the last previously stored
731 pending diagnostic. */
732 virtual void add_event (std::unique_ptr<checker_event> event) = 0;
733
734 /* Hook for clients to be notified when an SVAL that was reachable
735 in a previous state is no longer live, so that clients can emit warnings
736 about leaks. */
737 virtual void on_svalue_leak (const svalue *sval) = 0;
738
739 /* Hook for clients to be notified when the set of explicitly live
740 svalues changes, so that they can purge state relating to dead
741 svalues. */
742 virtual void on_liveness_change (const svalue_set &live_svalues,
743 const region_model *model) = 0;
744
745 virtual logger *get_logger () = 0;
746
747 /* Hook for clients to be notified when the condition
748 "LHS OP RHS" is added to the region model.
749 This exists so that state machines can detect tests on edges,
750 and use them to trigger sm-state transitions (e.g. transitions due
751 to ptrs becoming known to be NULL or non-NULL, rather than just
752 "unchecked") */
753 virtual void on_condition (const svalue *lhs,
754 enum tree_code op,
755 const svalue *rhs) = 0;
756
757 /* Hook for clients to be notified when the condition that
758 SVAL is within RANGES is added to the region model.
759 Similar to on_condition, but for use when handling switch statements.
760 RANGES is non-empty. */
761 virtual void on_bounded_ranges (const svalue &sval,
762 const bounded_ranges &ranges) = 0;
763
764 /* Hook for clients to be notified when a frame is popped from the stack. */
765 virtual void on_pop_frame (const frame_region *) = 0;
766
767 /* Hooks for clients to be notified when an unknown change happens
768 to SVAL (in response to a call to an unknown function). */
769 virtual void on_unknown_change (const svalue *sval, bool is_mutable) = 0;
770
771 /* Hooks for clients to be notified when a phi node is handled,
772 where RHS is the pertinent argument. */
773 virtual void on_phi (const gphi *phi, tree rhs) = 0;
774
775 /* Hooks for clients to be notified when the region model doesn't
776 know how to handle the tree code of T at LOC. */
778 const dump_location_t &loc) = 0;
779
780 /* Hook for clients to be notified when a function_decl escapes. */
781 virtual void on_escaped_function (tree fndecl) = 0;
782
784
785 /* Hook for clients to purge state involving SVAL. */
786 virtual void purge_state_involving (const svalue *sval) = 0;
787
788 /* Hook for clients to split state with a non-standard path. */
789 virtual void bifurcate (std::unique_ptr<custom_edge_info> info) = 0;
790
791 /* Hook for clients to terminate the standard path. */
792 virtual void terminate_path () = 0;
793
794 virtual const extrinsic_state *get_ext_state () const = 0;
795
796 /* Hook for clients to access the a specific state machine in
797 any underlying program_state. */
798 virtual bool
799 get_state_map_by_name (const char *name,
800 sm_state_map **out_smap,
801 const state_machine **out_sm,
802 unsigned *out_sm_idx,
803 std::unique_ptr<sm_context> *out_sm_context) = 0;
804
805 /* Precanned ways for clients to access specific state machines. */
806 bool get_fd_map (sm_state_map **out_smap,
807 const state_machine **out_sm,
808 unsigned *out_sm_idx,
809 std::unique_ptr<sm_context> *out_sm_context)
810 {
811 return get_state_map_by_name ("file-descriptor", out_smap, out_sm,
812 out_sm_idx, out_sm_context);
813 }
814 bool get_malloc_map (sm_state_map **out_smap,
815 const state_machine **out_sm,
816 unsigned *out_sm_idx)
817 {
818 return get_state_map_by_name ("malloc", out_smap, out_sm, out_sm_idx, NULL);
819 }
820 bool get_taint_map (sm_state_map **out_smap,
821 const state_machine **out_sm,
822 unsigned *out_sm_idx)
823 {
824 return get_state_map_by_name ("taint", out_smap, out_sm, out_sm_idx, NULL);
825 }
826
827 bool possibly_tainted_p (const svalue *sval);
828
829 /* Get the current statement, if any. */
830 virtual const gimple *get_stmt () const = 0;
831
832 virtual const exploded_graph *get_eg () const = 0;
833
834 /* Hooks for detecting infinite loops. */
835 virtual void maybe_did_work () = 0;
836 virtual bool checking_for_infinite_loop_p () const = 0;
837 virtual void on_unusable_in_infinite_loop () = 0;
838};
839
840/* A "do nothing" subclass of region_model_context. */
841
843{
844public:
845 bool warn (std::unique_ptr<pending_diagnostic>,
846 const stmt_finder *) override { return false; }
847 void add_note (std::unique_ptr<pending_note>) override;
848 void add_event (std::unique_ptr<checker_event>) override;
849 void on_svalue_leak (const svalue *) override {}
851 const region_model *) override {}
852 logger *get_logger () override { return NULL; }
853 void on_condition (const svalue *lhs ATTRIBUTE_UNUSED,
854 enum tree_code op ATTRIBUTE_UNUSED,
855 const svalue *rhs ATTRIBUTE_UNUSED) override
856 {
857 }
859 const bounded_ranges &) override
860 {
861 }
862 void on_pop_frame (const frame_region *) override {}
863 void on_unknown_change (const svalue *sval ATTRIBUTE_UNUSED,
864 bool is_mutable ATTRIBUTE_UNUSED) override
865 {
866 }
867 void on_phi (const gphi *phi ATTRIBUTE_UNUSED,
868 tree rhs ATTRIBUTE_UNUSED) override
869 {
870 }
871 void on_unexpected_tree_code (tree, const dump_location_t &) override {}
872
873 void on_escaped_function (tree) override {}
874
875 uncertainty_t *get_uncertainty () override { return NULL; }
876
877 void purge_state_involving (const svalue *sval ATTRIBUTE_UNUSED) override {}
878
879 void bifurcate (std::unique_ptr<custom_edge_info> info) override;
880 void terminate_path () override;
881
882 const extrinsic_state *get_ext_state () const override { return NULL; }
883
884 bool get_state_map_by_name (const char *,
885 sm_state_map **,
886 const state_machine **,
887 unsigned *,
888 std::unique_ptr<sm_context> *) override
889 {
890 return false;
891 }
892
893 const gimple *get_stmt () const override { return NULL; }
894 const exploded_graph *get_eg () const override { return NULL; }
895 void maybe_did_work () override {}
896 bool checking_for_infinite_loop_p () const override { return false; }
898};
899
900/* A subclass of region_model_context for determining if operations fail
901 e.g. "can we generate a region for the lvalue of EXPR?". */
902
904{
905public:
907
909 final override
910 {
912 }
913
914 bool had_errors_p () const { return m_num_unexpected_codes > 0; }
915
916private:
918};
919
920/* Subclass of region_model_context that wraps another context, allowing
921 for extra code to be added to the various hooks. */
922
924{
925 public:
926 bool warn (std::unique_ptr<pending_diagnostic> d,
927 const stmt_finder *custom_finder) override
928 {
929 if (m_inner)
930 return m_inner->warn (std::move (d), custom_finder);
931 else
932 return false;
933 }
934
935 void add_note (std::unique_ptr<pending_note> pn) override
936 {
937 if (m_inner)
938 m_inner->add_note (std::move (pn));
939 }
940 void add_event (std::unique_ptr<checker_event> event) override;
941
942 void on_svalue_leak (const svalue *sval) override
943 {
944 if (m_inner)
945 m_inner->on_svalue_leak (sval);
946 }
947
948 void on_liveness_change (const svalue_set &live_svalues,
949 const region_model *model) override
950 {
951 if (m_inner)
952 m_inner->on_liveness_change (live_svalues, model);
953 }
954
955 logger *get_logger () override
956 {
957 if (m_inner)
958 return m_inner->get_logger ();
959 else
960 return nullptr;
961 }
962
963 void on_condition (const svalue *lhs,
964 enum tree_code op,
965 const svalue *rhs) override
966 {
967 if (m_inner)
968 m_inner->on_condition (lhs, op, rhs);
969 }
970
971 void on_bounded_ranges (const svalue &sval,
972 const bounded_ranges &ranges) override
973 {
974 if (m_inner)
975 m_inner->on_bounded_ranges (sval, ranges);
976 }
977
978 void on_pop_frame (const frame_region *frame_reg) override
979 {
980 if (m_inner)
981 m_inner->on_pop_frame (frame_reg);
982 }
983
984 void on_unknown_change (const svalue *sval, bool is_mutable) override
985 {
986 if (m_inner)
987 m_inner->on_unknown_change (sval, is_mutable);
988 }
989
990 void on_phi (const gphi *phi, tree rhs) override
991 {
992 if (m_inner)
993 m_inner->on_phi (phi, rhs);
994 }
995
997 const dump_location_t &loc) override
998 {
999 if (m_inner)
1001 }
1002
1003 void on_escaped_function (tree fndecl) override
1004 {
1005 if (m_inner)
1006 m_inner->on_escaped_function (fndecl);
1007 }
1008
1010 {
1011 if (m_inner)
1012 return m_inner->get_uncertainty ();
1013 else
1014 return nullptr;
1015 }
1016
1017 void purge_state_involving (const svalue *sval) override
1018 {
1019 if (m_inner)
1021 }
1022
1023 void bifurcate (std::unique_ptr<custom_edge_info> info) override
1024 {
1025 if (m_inner)
1026 m_inner->bifurcate (std::move (info));
1027 }
1028
1029 void terminate_path () override
1030 {
1031 if (m_inner)
1033 }
1034
1035 const extrinsic_state *get_ext_state () const override
1036 {
1037 if (m_inner)
1038 return m_inner->get_ext_state ();
1039 else
1040 return nullptr;
1041 }
1042
1043 bool get_state_map_by_name (const char *name,
1044 sm_state_map **out_smap,
1045 const state_machine **out_sm,
1046 unsigned *out_sm_idx,
1047 std::unique_ptr<sm_context> *out_sm_context)
1048 override
1049 {
1050 if (m_inner)
1051 return m_inner->get_state_map_by_name (name, out_smap, out_sm, out_sm_idx,
1052 out_sm_context);
1053 else
1054 return false;
1055 }
1056
1057 const gimple *get_stmt () const override
1058 {
1059 if (m_inner)
1060 return m_inner->get_stmt ();
1061 else
1062 return nullptr;
1063 }
1064
1065 const exploded_graph *get_eg () const override
1066 {
1067 if (m_inner)
1068 return m_inner->get_eg ();
1069 else
1070 return nullptr;
1071 }
1072
1073 void maybe_did_work () override
1074 {
1075 if (m_inner)
1077 }
1078
1079 bool checking_for_infinite_loop_p () const override
1080 {
1081 if (m_inner)
1083 return false;
1084 }
1086 {
1087 if (m_inner)
1089 }
1090
1091protected:
1093 : m_inner (inner)
1094 {
1095 }
1096
1098};
1099
1100/* Subclass of region_model_context_decorator with a hook for adding
1101 notes/events when saving diagnostics. */
1102
1104{
1105public:
1106 bool warn (std::unique_ptr<pending_diagnostic> d,
1107 const stmt_finder *custom_finder) override
1108 {
1109 if (m_inner)
1110 if (m_inner->warn (std::move (d), custom_finder))
1111 {
1112 add_annotations ();
1113 return true;
1114 }
1115 return false;
1116 }
1117
1118 /* Hook to add new event(s)/note(s) */
1119 virtual void add_annotations () = 0;
1120
1121protected:
1126};
1127
1128/* A bundle of data for use when attempting to merge two region_model
1129 instances to make a third. */
1130
1132{
1134 const region_model *model_b,
1135 const program_point &point,
1136 region_model *merged_model,
1138 const program_state *state_a,
1139 const program_state *state_b)
1140 : m_model_a (model_a), m_model_b (model_b),
1141 m_point (point),
1142 m_merged_model (merged_model),
1144 m_state_a (state_a), m_state_b (state_b)
1145 {
1146 }
1147
1148 void dump_to_pp (pretty_printer *pp, bool simple) const;
1149 void dump (FILE *fp, bool simple) const;
1150 void dump (bool simple) const;
1151
1153 {
1154 return m_model_a->get_manager ();
1155 }
1156
1157 bool mergeable_svalue_p (const svalue *) const;
1159 {
1160 return m_point.get_function_point ();
1161 }
1162
1163 void on_widening_reuse (const widening_svalue *widening_sval);
1164
1169
1173
1175};
1176
1177/* A record that can (optionally) be written out when
1178 region_model::add_constraint fails. */
1179
1181{
1182public:
1184 virtual void dump_to_pp (pretty_printer *pp) const = 0;
1185
1186 const region_model &get_model () const { return m_model; }
1187
1188protected:
1190 : m_model (model)
1191 {}
1192
1194};
1195
1197{
1198public:
1200 tree lhs, enum tree_code op, tree rhs)
1201 : rejected_constraint (model),
1202 m_lhs (lhs), m_op (op), m_rhs (rhs)
1203 {}
1204
1205 void dump_to_pp (pretty_printer *pp) const final override;
1206
1210};
1211
1213{
1214public:
1216 : rejected_constraint (model)
1217 {}
1218
1219 void dump_to_pp (pretty_printer *pp) const final override;
1220};
1221
1223{
1224public:
1226 tree expr, const bounded_ranges *ranges)
1227 : rejected_constraint (model),
1228 m_expr (expr), m_ranges (ranges)
1229 {}
1230
1231 void dump_to_pp (pretty_printer *pp) const final override;
1232
1233private:
1236};
1237
1238/* A bundle of state. */
1239
1241{
1242public:
1244 const supergraph *get_supergraph () { return m_sg; }
1250
1251 void log_stats (logger *logger) const;
1252
1253private:
1256};
1257
1258} // namespace ana
1259
1260extern void debug (const region_model &rmodel);
1261
1262namespace ana {
1263
1264#if CHECKING_P
1265
1266namespace selftest {
1267
1268using namespace ::selftest;
1269
1270/* An implementation of region_model_context for use in selftests, which
1271 stores any pending_diagnostic instances passed to it. */
1272
1273class test_region_model_context : public noop_region_model_context
1274{
1275public:
1276 bool warn (std::unique_ptr<pending_diagnostic> d,
1277 const stmt_finder *) final override
1278 {
1279 m_diagnostics.safe_push (d.release ());
1280 return true;
1281 }
1282
1283 unsigned get_num_diagnostics () const { return m_diagnostics.length (); }
1284
1285 void on_unexpected_tree_code (tree t, const dump_location_t &)
1286 final override
1287 {
1288 internal_error ("unhandled tree code: %qs",
1290 }
1291
1292private:
1293 /* Implicitly delete any diagnostics in the dtor. */
1295};
1296
1297/* Attempt to add the constraint (LHS OP RHS) to MODEL.
1298 Verify that MODEL remains satisfiable. */
1299
1300#define ADD_SAT_CONSTRAINT(MODEL, LHS, OP, RHS) \
1301 SELFTEST_BEGIN_STMT \
1302 bool sat = (MODEL).add_constraint (LHS, OP, RHS, NULL); \
1303 ASSERT_TRUE (sat); \
1304 SELFTEST_END_STMT
1305
1306/* Attempt to add the constraint (LHS OP RHS) to MODEL.
1307 Verify that the result is not satisfiable. */
1308
1309#define ADD_UNSAT_CONSTRAINT(MODEL, LHS, OP, RHS) \
1310 SELFTEST_BEGIN_STMT \
1311 bool sat = (MODEL).add_constraint (LHS, OP, RHS, NULL); \
1312 ASSERT_FALSE (sat); \
1313 SELFTEST_END_STMT
1314
1315/* Implementation detail of the ASSERT_CONDITION_* macros. */
1316
1317void assert_condition (const location &loc,
1318 region_model &model,
1319 const svalue *lhs, tree_code op, const svalue *rhs,
1320 tristate expected);
1321
1322void assert_condition (const location &loc,
1323 region_model &model,
1324 tree lhs, tree_code op, tree rhs,
1325 tristate expected);
1326
1327/* Assert that REGION_MODEL evaluates the condition "LHS OP RHS"
1328 as "true". */
1329
1330#define ASSERT_CONDITION_TRUE(REGION_MODEL, LHS, OP, RHS) \
1331 SELFTEST_BEGIN_STMT \
1332 assert_condition (SELFTEST_LOCATION, REGION_MODEL, LHS, OP, RHS, \
1333 tristate (tristate::TS_TRUE)); \
1334 SELFTEST_END_STMT
1335
1336/* Assert that REGION_MODEL evaluates the condition "LHS OP RHS"
1337 as "false". */
1338
1339#define ASSERT_CONDITION_FALSE(REGION_MODEL, LHS, OP, RHS) \
1340 SELFTEST_BEGIN_STMT \
1341 assert_condition (SELFTEST_LOCATION, REGION_MODEL, LHS, OP, RHS, \
1342 tristate (tristate::TS_FALSE)); \
1343 SELFTEST_END_STMT
1344
1345/* Assert that REGION_MODEL evaluates the condition "LHS OP RHS"
1346 as "unknown". */
1347
1348#define ASSERT_CONDITION_UNKNOWN(REGION_MODEL, LHS, OP, RHS) \
1349 SELFTEST_BEGIN_STMT \
1350 assert_condition (SELFTEST_LOCATION, REGION_MODEL, LHS, OP, RHS, \
1351 tristate (tristate::TS_UNKNOWN)); \
1352 SELFTEST_END_STMT
1353
1354} /* end of namespace selftest. */
1355
1356#endif /* #if CHECKING_P */
1357
1358} // namespace ana
1359
1360#endif /* GCC_ANALYZER_REGION_MODEL_H */
Definition region-model.h:1104
virtual void add_annotations()=0
annotating_context(region_model_context *inner)
Definition region-model.h:1122
bool warn(std::unique_ptr< pending_diagnostic > d, const stmt_finder *custom_finder) override
Definition region-model.h:1106
Definition svalue.h:1623
Definition svalue.h:786
Definition svalue.h:1070
Definition constraint-manager.h:181
Definition analyzer.h:298
Definition call-details.h:29
Definition call-summary.h:68
Definition supergraph.h:446
Definition supergraph.h:515
Definition svalue.h:1389
Definition svalue.h:1521
Definition svalue.h:1769
Definition svalue.h:299
Definition constraint-manager.h:425
Definition region-model.h:1241
known_function_manager * get_known_function_manager()
Definition region-model.h:1246
const supergraph * get_supergraph()
Definition region-model.h:1244
const supergraph * m_sg
Definition region-model.h:1254
region_model_manager * get_model_manager()
Definition region-model.h:1245
engine(const supergraph *sg=NULL, logger *logger=NULL)
void log_stats(logger *logger) const
region_model_manager m_mgr
Definition region-model.h:1255
Definition exploded-graph.h:791
Definition exploded-graph.h:203
Definition program-state.h:31
Definition region.h:319
Definition program-point.h:73
Definition svalue.h:645
Definition known-function-manager.h:41
Definition analyzer.h:278
Definition analyzer-logging.h:34
Definition region-model.h:843
bool get_state_map_by_name(const char *, sm_state_map **, const state_machine **, unsigned *, std::unique_ptr< sm_context > *) override
Definition region-model.h:884
bool checking_for_infinite_loop_p() const override
Definition region-model.h:896
bool warn(std::unique_ptr< pending_diagnostic >, const stmt_finder *) override
Definition region-model.h:845
void maybe_did_work() override
Definition region-model.h:895
uncertainty_t * get_uncertainty() override
Definition region-model.h:875
void on_unexpected_tree_code(tree, const dump_location_t &) override
Definition region-model.h:871
void on_unknown_change(const svalue *sval, bool is_mutable) override
Definition region-model.h:863
void on_pop_frame(const frame_region *) override
Definition region-model.h:862
void on_phi(const gphi *phi, tree rhs) override
Definition region-model.h:867
void on_condition(const svalue *lhs, enum tree_code op, const svalue *rhs) override
Definition region-model.h:853
void add_event(std::unique_ptr< checker_event >) override
void on_liveness_change(const svalue_set &, const region_model *) override
Definition region-model.h:850
logger * get_logger() override
Definition region-model.h:852
void on_escaped_function(tree) override
Definition region-model.h:873
const exploded_graph * get_eg() const override
Definition region-model.h:894
const gimple * get_stmt() const override
Definition region-model.h:893
void on_unusable_in_infinite_loop() override
Definition region-model.h:897
void on_svalue_leak(const svalue *) override
Definition region-model.h:849
void add_note(std::unique_ptr< pending_note >) override
void purge_state_involving(const svalue *sval) override
Definition region-model.h:877
const extrinsic_state * get_ext_state() const override
Definition region-model.h:882
void on_bounded_ranges(const svalue &, const bounded_ranges &) override
Definition region-model.h:858
void bifurcate(std::unique_ptr< custom_edge_info > info) override
Definition region-model.h:52
void put(T src, T dst)
Definition region-model.h:81
void dump() const
Definition region-model.h:123
T get_dst_for_src(T src) const
Definition region-model.h:90
void dump_to_pp(pretty_printer *pp) const
Definition region-model.h:101
auto_vec< T > m_src_to_dst
Definition region-model.h:62
void update(T *) const
Definition region-model.h:135
one_way_id_map(int num_ids)
Definition region-model.h:70
Definition analyzer.h:154
Definition svalue.h:1219
Definition svalue.h:445
Definition program-point.h:175
const function_point & get_function_point() const
Definition program-point.h:202
Definition program-state.h:209
Definition region-model.h:924
region_model_context * m_inner
Definition region-model.h:1097
const exploded_graph * get_eg() const override
Definition region-model.h:1065
void on_bounded_ranges(const svalue &sval, const bounded_ranges &ranges) override
Definition region-model.h:971
void on_phi(const gphi *phi, tree rhs) override
Definition region-model.h:990
void add_event(std::unique_ptr< checker_event > event) override
const extrinsic_state * get_ext_state() const override
Definition region-model.h:1035
void on_condition(const svalue *lhs, enum tree_code op, const svalue *rhs) override
Definition region-model.h:963
const gimple * get_stmt() const override
Definition region-model.h:1057
void maybe_did_work() override
Definition region-model.h:1073
void on_pop_frame(const frame_region *frame_reg) override
Definition region-model.h:978
uncertainty_t * get_uncertainty() override
Definition region-model.h:1009
void bifurcate(std::unique_ptr< custom_edge_info > info) override
Definition region-model.h:1023
void add_note(std::unique_ptr< pending_note > pn) override
Definition region-model.h:935
void on_svalue_leak(const svalue *sval) override
Definition region-model.h:942
bool checking_for_infinite_loop_p() const override
Definition region-model.h:1079
logger * get_logger() override
Definition region-model.h:955
region_model_context_decorator(region_model_context *inner)
Definition region-model.h:1092
void purge_state_involving(const svalue *sval) override
Definition region-model.h:1017
void on_liveness_change(const svalue_set &live_svalues, const region_model *model) override
Definition region-model.h:948
bool warn(std::unique_ptr< pending_diagnostic > d, const stmt_finder *custom_finder) override
Definition region-model.h:926
void on_unexpected_tree_code(tree t, const dump_location_t &loc) override
Definition region-model.h:996
void on_escaped_function(tree fndecl) override
Definition region-model.h:1003
void terminate_path() override
Definition region-model.h:1029
void on_unknown_change(const svalue *sval, bool is_mutable) override
Definition region-model.h:984
void on_unusable_in_infinite_loop() override
Definition region-model.h:1085
bool get_state_map_by_name(const char *name, sm_state_map **out_smap, const state_machine **out_sm, unsigned *out_sm_idx, std::unique_ptr< sm_context > *out_sm_context) override
Definition region-model.h:1043
Definition region-model.h:718
virtual void on_bounded_ranges(const svalue &sval, const bounded_ranges &ranges)=0
virtual void bifurcate(std::unique_ptr< custom_edge_info > info)=0
virtual void purge_state_involving(const svalue *sval)=0
virtual void on_escaped_function(tree fndecl)=0
virtual bool warn(std::unique_ptr< pending_diagnostic > d, const stmt_finder *custom_finder=NULL)=0
bool get_malloc_map(sm_state_map **out_smap, const state_machine **out_sm, unsigned *out_sm_idx)
Definition region-model.h:814
virtual void on_pop_frame(const frame_region *)=0
virtual void on_liveness_change(const svalue_set &live_svalues, const region_model *model)=0
bool get_fd_map(sm_state_map **out_smap, const state_machine **out_sm, unsigned *out_sm_idx, std::unique_ptr< sm_context > *out_sm_context)
Definition region-model.h:806
virtual void add_note(std::unique_ptr< pending_note > pn)=0
virtual logger * get_logger()=0
virtual const extrinsic_state * get_ext_state() const =0
bool possibly_tainted_p(const svalue *sval)
virtual void on_unexpected_tree_code(tree t, const dump_location_t &loc)=0
virtual void on_phi(const gphi *phi, tree rhs)=0
bool get_taint_map(sm_state_map **out_smap, const state_machine **out_sm, unsigned *out_sm_idx)
Definition region-model.h:820
virtual void on_svalue_leak(const svalue *sval)=0
virtual void on_condition(const svalue *lhs, enum tree_code op, const svalue *rhs)=0
virtual void on_unusable_in_infinite_loop()=0
virtual const exploded_graph * get_eg() const =0
virtual void on_unknown_change(const svalue *sval, bool is_mutable)=0
virtual const gimple * get_stmt() const =0
virtual uncertainty_t * get_uncertainty()=0
virtual bool checking_for_infinite_loop_p() const =0
virtual void terminate_path()=0
virtual bool get_state_map_by_name(const char *name, sm_state_map **out_smap, const state_machine **out_sm, unsigned *out_sm_idx, std::unique_ptr< sm_context > *out_sm_context)=0
virtual void add_event(std::unique_ptr< checker_event > event)=0
virtual void maybe_did_work()=0
Definition region-model-manager.h:32
bounded_ranges_manager * get_range_manager() const
Definition region-model-manager.h:151
known_function_manager * get_known_function_manager()
Definition region-model-manager.h:153
Definition region-model.h:263
path_var get_representative_path_var(const svalue *sval, svalue_set *visited, logger *logger) const
region_model(const region_model &other)
void impl_deallocation_call(const call_details &cd)
void update_for_phis(const supernode *snode, const cfg_superedge *last_cfg_superedge, region_model_context *ctxt)
void update_for_zero_return(const call_details &cd, bool unmergeable)
bool add_constraint(tree lhs, enum tree_code op, tree rhs, region_model_context *ctxt)
store * get_store()
Definition region-model.h:457
constraint_manager * get_constraints()
Definition region-model.h:452
void update_for_nonzero_return(const call_details &cd)
bool on_call_pre(const gcall *stmt, region_model_context *ctxt)
bool add_constraint(tree lhs, enum tree_code op, tree rhs, region_model_context *ctxt, std::unique_ptr< rejected_constraint > *out)
void dump(FILE *fp, bool simple, bool multiline) const
bool replay_call_summary(call_summary_replay &r, const region_model &summary)
void update_for_gcall(const gcall *call_stmt, region_model_context *ctxt, function *callee=NULL)
bool apply_constraints_for_gcond(const cfg_superedge &edge, const gcond *cond_stmt, region_model_context *ctxt, std::unique_ptr< rejected_constraint > *out)
bool apply_constraints_for_gswitch(const switch_cfg_superedge &edge, const gswitch *switch_stmt, region_model_context *ctxt, std::unique_ptr< rejected_constraint > *out)
void check_region_size(const region *lhs_reg, const svalue *rhs_sval, region_model_context *ctxt) const
void zero_fill_region(const region *reg, region_model_context *ctxt)
void on_asm_stmt(const gasm *asm_stmt, region_model_context *ctxt)
bool check_region_access(const region *reg, enum access_direction dir, const svalue *sval_hint, region_model_context *ctxt) const
bool can_merge_with_p(const region_model &other_model, const program_point &point, region_model *out_model, const extrinsic_state *ext_state=NULL, const program_state *state_a=NULL, const program_state *state_b=NULL) const
void check_one_function_attr_null_terminated_string_arg(const gcall *call, tree callee_fndecl, region_model_context *ctxt, rdwr_map &rdwr_idx, tree attr)
bounded_ranges_manager * get_range_manager() const
Definition region-model.h:472
void dump(bool simple) const
path_var get_representative_path_var_1(const svalue *sval, svalue_set *visited, logger *logger) const
static void append_regions_cb(const region *base_reg, struct append_regions_cb_data *data)
const region * deref_rvalue(const svalue *ptr_sval, tree ptr_tree, region_model_context *ctxt, bool add_nonnull_constraint=true) const
void debug() const
void on_realloc_with_move(const call_details &cd, const svalue *old_ptr_sval, const svalue *new_ptr_sval)
constraint_manager * m_constraints
Definition region-model.h:698
const svalue * check_for_null_terminated_string_arg(const call_details &cd, unsigned idx) const
void set_errno(const call_details &cd)
void set_dynamic_extents(const region *reg, const svalue *size_in_bytes, region_model_context *ctxt)
void update_for_return_superedge(const return_superedge &return_edge, region_model_context *ctxt)
void check_region_for_write(const region *dest_reg, const svalue *sval_hint, region_model_context *ctxt) const
const svalue * get_dynamic_extents(const region *reg) const
void clobber_region(const region *reg)
void dump_to_pp(pretty_printer *pp, bool simple, bool multiline) const
void transition_ptr_sval_non_null(region_model_context *ctxt, const svalue *new_ptr_sval)
const svalue * get_rvalue_1(path_var pv, region_model_context *ctxt) const
tristate eval_condition(const svalue *lhs, enum tree_code op, const svalue *rhs) const
const svalue * check_for_null_terminated_string_arg(const call_details &cd, unsigned idx, bool include_terminator, const svalue **out_sval) const
void mark_as_tainted(const svalue *sval, region_model_context *ctxt)
const svalue * get_capacity(const region *reg) const
bool add_constraint(const svalue *lhs, enum tree_code op, const svalue *rhs, region_model_context *ctxt)
void check_function_attrs(const gcall *call, tree callee_fndecl, region_model_context *ctxt)
void on_assignment(const gassign *stmt, region_model_context *ctxt)
tristate symbolic_greater_than(const binop_svalue *a, const svalue *b) const
region_model & operator=(const region_model &other)
const frame_region * get_frame_at_index(int index) const
store m_store
Definition region-model.h:696
void print(pretty_printer *pp) const
const region * create_region_for_alloca(const svalue *size_in_bytes, region_model_context *ctxt)
void purge_region(const region *reg)
void validate() const
bool operator!=(const region_model &other) const
Definition region-model.h:273
const svalue * get_store_value(const region *reg, region_model_context *ctxt) const
const region * get_region_for_poisoned_expr(tree expr) const
hashval_t hash() const
void get_regions_for_current_frame(auto_vec< const decl_region * > *out) const
std::unique_ptr< text_art::tree_widget > make_dump_widget(const text_art::dump_widget_info &dwi) const
const svalue * get_rvalue_for_bits(tree type, const region *reg, const bit_range &bits, region_model_context *ctxt) const
const svalue * get_initial_value_for_global(const region *reg) const
tristate compare_initial_and_pointer(const initial_svalue *init, const region_svalue *ptr) const
const function * get_current_function() const
const svalue * get_store_bytes(const region *base_reg, const byte_range &bytes, region_model_context *ctxt) const
static void register_pop_frame_callback(const pop_frame_callback &callback)
Definition region-model.h:569
bool apply_constraints_for_ggoto(const cfg_superedge &edge, const ggoto *goto_stmt, region_model_context *ctxt)
tree get_fndecl_for_call(const gcall *call, region_model_context *ctxt)
void loop_replay_fixup(const region_model *dst_state)
void check_dynamic_size_for_floats(const svalue *size_in_bytes, region_model_context *ctxt) const
bool operator==(const region_model &other) const
bool region_exists_p(const region *reg) const
tree get_representative_tree(const svalue *sval, logger *logger=nullptr) const
region_model(region_model_manager *mgr)
const svalue * maybe_get_copy_bounds(const region *src_reg, const svalue *num_bytes_sval)
tristate eval_condition(tree lhs, enum tree_code op, tree rhs, region_model_context *ctxt) const
const svalue * scan_for_null_terminator_1(const region *reg, tree expr, const svalue **out_sval, region_model_context *ctxt) const
void check_function_attr_null_terminated_string_arg(const gcall *call, tree callee_fndecl, region_model_context *ctxt, rdwr_map &rdwr_idx)
bool called_from_main_p() const
bool add_constraints_from_binop(const svalue *outer_lhs, enum tree_code outer_op, const svalue *outer_rhs, bool *out, region_model_context *ctxt)
void set_value(const region *lhs_reg, const svalue *rhs_sval, region_model_context *ctxt)
void on_return(const greturn *stmt, region_model_context *ctxt)
void get_reachable_svalues(svalue_set *out, const svalue *extra_sval, const uncertainty_t *uncertainty)
void update_for_call_superedge(const call_superedge &call_edge, region_model_context *ctxt)
bool apply_constraints_for_exception(const gimple *last_stmt, region_model_context *ctxt, std::unique_ptr< rejected_constraint > *out)
tristate structural_equality(const svalue *a, const svalue *b) const
void copy_bytes(const region *dest_reg, const region *src_reg, tree src_ptr_expr, const svalue *num_bytes_sval, region_model_context *ctxt)
const frame_region * get_current_frame() const
Definition region-model.h:361
void on_setjmp(const gcall *stmt, const exploded_node *enode, region_model_context *ctxt)
std::unique_ptr< json::object > to_json() const
region_model_manager *const m_mgr
Definition region-model.h:694
const frame_region * m_current_frame
Definition region-model.h:700
void dump() const
void check_region_for_taint(const region *reg, enum access_direction dir, region_model_context *ctxt) const
void on_top_level_param(tree param, bool nonnull, region_model_context *ctxt)
const builtin_known_function * get_builtin_kf(const gcall *call, region_model_context *ctxt=NULL) const
bool maybe_update_for_edge(const superedge &edge, const gimple *last_stmt, region_model_context *ctxt, std::unique_ptr< rejected_constraint > *out)
region_to_value_map dynamic_extents_t
Definition region-model.h:265
void mark_region_as_unknown(const region *reg, uncertainty_t *uncertainty)
void on_stmt_pre(const gimple *stmt, bool *out_unknown_side_effects, region_model_context *ctxt)
void check_call_format_attr(const call_details &cd, tree format_attr) const
void set_value(tree lhs, tree rhs, region_model_context *ctxt)
bool check_region_for_read(const region *src_reg, region_model_context *ctxt) const
void maybe_complain_about_infoleak(const region *dst_reg, const svalue *copied_sval, const region *src_reg, region_model_context *ctxt)
void handle_unrecognized_call(const gcall *call, region_model_context *ctxt)
region_model_manager * get_manager() const
Definition region-model.h:471
const known_function * get_known_function(tree fndecl, const call_details &cd) const
void handle_phi(const gphi *phi, tree lhs, tree rhs, const region_model &old_state, hash_set< const svalue * > &svals_changing_meaning, region_model_context *ctxt)
void on_call_post(const gcall *stmt, bool unknown_side_effects, region_model_context *ctxt)
void write_bytes(const region *dest_reg, const svalue *num_bytes_sval, const svalue *sval, region_model_context *ctxt)
void unset_dynamic_extents(const region *reg)
const region * push_frame(const function &fun, const vec< const svalue * > *arg_sids, region_model_context *ctxt)
void check_for_writable_region(const region *dest_reg, region_model_context *ctxt) const
const region * get_lvalue_1(path_var pv, region_model_context *ctxt) const
const known_function * get_known_function(enum internal_fn) const
path_var get_representative_path_var(const region *reg, svalue_set *visited, logger *logger) const
const region * get_lvalue(path_var pv, region_model_context *ctxt) const
void get_referenced_base_regions(auto_bitmap &out_ids) const
void update_for_int_cst_return(const call_details &cd, int retval, bool unmergeable)
const svalue * check_for_poison(const svalue *sval, tree expr, const region *src_region, region_model_context *ctxt) const
int get_stack_depth() const
bool check_region_bounds(const region *reg, enum access_direction dir, const svalue *sval_hint, region_model_context *ctxt) const
tree get_representative_tree(const region *reg, logger *logger=nullptr) const
void check_call_args(const call_details &cd) const
void fill_region(const region *reg, const svalue *sval, region_model_context *ctxt)
void check_dynamic_size_for_taint(enum memory_space mem_space, const svalue *size_in_bytes, region_model_context *ctxt) const
bool check_symbolic_bounds(const region *base_reg, const svalue *sym_byte_offset, const svalue *num_bytes_sval, const svalue *capacity, enum access_direction dir, const svalue *sval_hint, region_model_context *ctxt) const
void mark_as_valid_fd(const svalue *sval, region_model_context *ctxt)
void check_function_attr_access(const gcall *call, tree callee_fndecl, region_model_context *ctxt, rdwr_map &rdwr_idx) const
const svalue * get_rvalue(path_var pv, region_model_context *ctxt) const
path_var get_representative_path_var_1(const region *reg, svalue_set *visited, logger *logger) const
const store * get_store() const
Definition region-model.h:458
static void notify_on_pop_frame(const region_model *model, const region_model *prev_model, const svalue *retval, region_model_context *ctxt)
Definition region-model.h:575
dynamic_extents_t m_dynamic_extents
Definition region-model.h:706
static auto_vec< pop_frame_callback > pop_frame_callbacks
Definition region-model.h:692
int poison_any_pointers_to_descendents(const region *reg, enum poison_kind pkind)
const region * get_lvalue(tree expr, region_model_context *ctxt) const
const svalue * get_gassign_result(const gassign *assign, region_model_context *ctxt)
const svalue * read_bytes(const region *src_reg, tree src_ptr_expr, const svalue *num_bytes_sval, region_model_context *ctxt) const
void pop_frame(tree result_lvalue, const svalue **out_result, region_model_context *ctxt, const gcall *call_stmt, bool eval_return_svalue=true)
const svalue * scan_for_null_terminator(const region *reg, tree expr, const svalue **out_sval, region_model_context *ctxt) const
void update_for_return_gcall(const gcall *call_stmt, region_model_context *ctxt)
const region * get_or_create_region_for_heap_alloc(const svalue *size_in_bytes, region_model_context *ctxt, bool update_state_machine=false, const call_details *cd=nullptr)
const svalue * get_rvalue(tree expr, region_model_context *ctxt) const
bool canonicalized_p() const
void purge_state_involving(const svalue *sval, region_model_context *ctxt)
void on_longjmp(const gcall *longjmp_call, const gcall *setjmp_call, int setjmp_stack_depth, region_model_context *ctxt)
void unbind_region_and_descendents(const region *reg, enum poison_kind pkind)
const dynamic_extents_t & get_dynamic_extents() const
Definition region-model.h:461
Definition svalue.h:212
Definition region-model.h:143
void remove(const region *reg)
Definition region-model.h:170
iterator begin() const
Definition region-model.h:159
const svalue *const * get(const region *reg) const
Definition region-model.h:162
hash_map_t m_hash_map
Definition region-model.h:191
std::unique_ptr< text_art::tree_widget > make_dump_widget(const text_art::dump_widget_info &dwi) const
void purge_state_involving(const svalue *sval)
std::unique_ptr< json::object > to_json() const
bool operator==(const region_to_value_map &other) const
iterator end() const
Definition region-model.h:160
void put(const region *reg, const svalue *sval)
Definition region-model.h:166
bool is_empty() const
Definition region-model.h:175
region_to_value_map & operator=(const region_to_value_map &other)
region_to_value_map()
Definition region-model.h:148
void dump_to_pp(pretty_printer *pp, bool simple, bool multiline) const
hash_map_t::iterator iterator
Definition region-model.h:146
bool operator!=(const region_to_value_map &other) const
Definition region-model.h:154
void dump(bool simple) const
bool can_merge_with_p(const region_to_value_map &other, region_to_value_map *out) const
region_to_value_map(const region_to_value_map &other)
Definition region-model.h:149
hash_map< const region *, const svalue * > hash_map_t
Definition region-model.h:145
Definition region.h:126
Definition region-model.h:1181
virtual ~rejected_constraint()
Definition region-model.h:1183
virtual void dump_to_pp(pretty_printer *pp) const =0
rejected_constraint(const region_model &model)
Definition region-model.h:1189
const region_model & get_model() const
Definition region-model.h:1186
region_model m_model
Definition region-model.h:1193
Definition region-model.h:1213
void dump_to_pp(pretty_printer *pp) const final override
rejected_default_case(const region_model &model)
Definition region-model.h:1215
Definition region-model.h:1197
tree m_rhs
Definition region-model.h:1209
rejected_op_constraint(const region_model &model, tree lhs, enum tree_code op, tree rhs)
Definition region-model.h:1199
tree m_lhs
Definition region-model.h:1207
void dump_to_pp(pretty_printer *pp) const final override
enum tree_code m_op
Definition region-model.h:1208
Definition region-model.h:1223
void dump_to_pp(pretty_printer *pp) const final override
tree m_expr
Definition region-model.h:1234
const bounded_ranges * m_ranges
Definition region-model.h:1235
rejected_ranges_constraint(const region_model &model, tree expr, const bounded_ranges *ranges)
Definition region-model.h:1225
Definition svalue.h:974
Definition supergraph.h:482
Definition svalue.h:559
Definition program-state.h:77
Definition sm.h:40
Definition exploded-graph.h:1033
Definition store.h:736
Definition svalue.h:888
Definition supergraph.h:314
Definition supergraph.h:109
Definition supergraph.h:235
Definition svalue.h:92
Definition supergraph.h:557
Definition region-model.h:904
int m_num_unexpected_codes
Definition region-model.h:917
bool had_errors_p() const
Definition region-model.h:914
void on_unexpected_tree_code(tree, const dump_location_t &) final override
Definition region-model.h:908
tentative_region_model_context()
Definition region-model.h:906
Definition svalue.h:693
Definition store.h:161
Definition svalue.h:395
Definition svalue.h:1172
Definition region-model.h:222
virtual void visit_unknown_svalue(const unknown_svalue *)
Definition region-model.h:226
virtual void visit_poisoned_svalue(const poisoned_svalue *)
Definition region-model.h:227
virtual void visit_asm_output_svalue(const asm_output_svalue *)
Definition region-model.h:240
virtual void visit_unaryop_svalue(const unaryop_svalue *)
Definition region-model.h:230
virtual void visit_region_svalue(const region_svalue *)
Definition region-model.h:224
virtual void visit_initial_svalue(const initial_svalue *)
Definition region-model.h:229
virtual void visit_sub_svalue(const sub_svalue *)
Definition region-model.h:232
virtual void visit_setjmp_svalue(const setjmp_svalue *)
Definition region-model.h:228
virtual void visit_conjured_svalue(const conjured_svalue *)
Definition region-model.h:239
virtual void visit_placeholder_svalue(const placeholder_svalue *)
Definition region-model.h:236
virtual void visit_binop_svalue(const binop_svalue *)
Definition region-model.h:231
virtual void visit_const_fn_result_svalue(const const_fn_result_svalue *)
Definition region-model.h:241
virtual void visit_compound_svalue(const compound_svalue *)
Definition region-model.h:238
virtual void visit_unmergeable_svalue(const unmergeable_svalue *)
Definition region-model.h:235
virtual void visit_widening_svalue(const widening_svalue *)
Definition region-model.h:237
virtual void visit_bits_within_svalue(const bits_within_svalue *)
Definition region-model.h:234
virtual void visit_constant_svalue(const constant_svalue *)
Definition region-model.h:225
virtual void visit_region(const region *)
Definition region-model.h:243
virtual void visit_repeated_svalue(const repeated_svalue *)
Definition region-model.h:233
Definition svalue.h:1267
Definition bitmap.h:950
Definition vec.h:1802
Definition vec.h:1656
Definition genoutput.cc:150
Definition dumpfile.h:446
Definition genmatch.cc:1496
Definition ree.cc:583
Definition hash-map.h:40
bool is_empty() const
Definition hash-map.h:252
iterator begin() const
Definition hash-map.h:302
void remove(const Key &k)
Definition hash-map.h:218
iterator end() const
Definition hash-map.h:303
bool put(const Key &k, const Value &v)
Definition hash-map.h:168
Definition inchash.h:38
Definition pretty-print.h:241
void set_output_stream(FILE *outfile)
Definition pretty-print.h:274
Definition tristate.h:26
bool debug
Definition collect-utils.cc:34
class edge_def * edge
Definition coretypes.h:352
union tree_node * tree
Definition coretypes.h:97
void internal_error(const char *,...) ATTRIBUTE_GCC_DIAG(1
internal_fn
Definition genmatch.cc:1005
tree_code
Definition genmatch.cc:992
Definition access-diagram.h:30
access_direction
Definition analyzer.h:354
poison_kind
Definition svalue.h:425
void(* pop_frame_callback)(const region_model *model, const region_model *prev_model, const svalue *retval, region_model_context *ctxt)
Definition region-model.h:248
memory_space
Definition region.h:32
Definition fold-const.cc:4268
void add_path_var(path_var pv, hash &hstate)
Definition dump-context.h:31
poly_int< N, C > r
Definition poly-int.h:774
i
Definition poly-int.h:776
Ca const poly_int< N, Cb > & b
Definition poly-int.h:771
Ca & a
Definition poly-int.h:770
void pp_flush(pretty_printer *pp)
Definition pretty-print.cc:2349
void pp_newline(pretty_printer *pp)
Definition pretty-print.cc:2626
void pp_string(pretty_printer *pp, const char *str)
Definition pretty-print.cc:2653
Definition store.h:233
Definition constraint-manager.h:123
Definition store.h:309
Definition region-model.h:1132
const program_point & m_point
Definition region-model.h:1167
const program_state * m_state_a
Definition region-model.h:1171
const region_model * m_model_a
Definition region-model.h:1165
const extrinsic_state * m_ext_state
Definition region-model.h:1170
hash_set< const svalue * > m_svals_changing_meaning
Definition region-model.h:1174
void dump_to_pp(pretty_printer *pp, bool simple) const
model_merger(const region_model *model_a, const region_model *model_b, const program_point &point, region_model *merged_model, const extrinsic_state *ext_state, const program_state *state_a, const program_state *state_b)
Definition region-model.h:1133
const program_state * m_state_b
Definition region-model.h:1172
bool mergeable_svalue_p(const svalue *) const
void dump(bool simple) const
region_model_manager * get_manager() const
Definition region-model.h:1152
void on_widening_reuse(const widening_svalue *widening_sval)
region_model * m_merged_model
Definition region-model.h:1168
void dump(FILE *fp, bool simple) const
const function_point & get_function_point() const
Definition region-model.h:1158
const region_model * m_model_b
Definition region-model.h:1166
Definition region-model.h:200
int m_num_equiv_classes
Definition region-model.h:212
int m_num_bounded_ranges_constraints
Definition region-model.h:214
int m_num_client_items
Definition region-model.h:215
int m_num_svalues
Definition region-model.h:210
purge_stats()
Definition region-model.h:201
int m_num_constraints
Definition region-model.h:213
int m_num_regions
Definition region-model.h:211
Definition function.h:249
Definition gimple.h:546
Definition gimple.h:900
Definition gimple.h:349
Definition gimple.h:854
Definition gimple.h:873
Definition gimple.h:221
Definition gimple.h:458
Definition gimple.h:910
Definition gimple.h:891
Definition gengtype.h:252
Definition vec.h:450
#define NULL
Definition system.h:50
#define DEBUG_FUNCTION
Definition system.h:1236
static bitmap visited
Definition tree-ssa-dce.cc:577
static control_dependences * cd
Definition tree-ssa-dce.cc:104
const char * get_tree_code_name(enum tree_code code)
Definition tree.cc:12833
#define TREE_CODE(NODE)
Definition tree.h:324
tree size_in_bytes(const_tree t)
Definition tree.h:5131
#define FOR_EACH_VEC_ELT(V, I, P)
Definition vec.h:1884