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-2025 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;
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/* Roughly equivalent to a struct __cxa_exception, except we store a std::vector
254 rather than a linked list. */
255
257{
258 exception_node (const svalue *exception_sval,
259 const svalue *typeinfo_sval,
260 const svalue *destructor_sval)
261 : m_exception_sval (exception_sval),
262 m_typeinfo_sval (typeinfo_sval),
263 m_destructor_sval (destructor_sval)
264 {
265 }
266
267 bool operator== (const exception_node &other) const;
268
269 void dump_to_pp (pretty_printer *pp, bool simple) const;
270 void dump (FILE *fp, bool simple) const;
271 void dump (bool simple) const;
272 void dump () const;
273
274 std::unique_ptr<json::object> to_json () const;
275
276 std::unique_ptr<text_art::tree_widget>
277 make_dump_widget (const text_art::dump_widget_info &dwi) const;
278
280
282
286};
287
288/* A region_model encapsulates a representation of the state of memory, with
289 a tree of regions, along with their associated values.
290 The representation is graph-like because values can be pointers to
291 regions.
292 It also stores:
293 - a constraint_manager, capturing relationships between the values, and
294 - dynamic extents, mapping dynamically-allocated regions to svalues (their
295 capacities). */
296
298{
299 public:
301
306
307 bool operator== (const region_model &other) const;
308 bool operator!= (const region_model &other) const
309 {
310 return !(*this == other);
311 }
312
313 hashval_t hash () const;
314
315 void print (pretty_printer *pp) const;
316
317 void dump_to_pp (pretty_printer *pp, bool simple, bool multiline) const;
318 void dump (FILE *fp, bool simple, bool multiline) const;
319 void dump (bool simple) const;
320 void dump () const;
321
322 void debug () const;
323
324 std::unique_ptr<json::object> to_json () const;
325
326 std::unique_ptr<text_art::tree_widget>
327 make_dump_widget (const text_art::dump_widget_info &dwi) const;
328
329 void validate () const;
330
332 bool canonicalized_p () const;
333
334 void
336 bool *out_unknown_side_effects,
338
340 const svalue *get_gassign_result (const gassign *assign,
342 void on_asm_stmt (const gasm *asm_stmt, region_model_context *ctxt);
344 void on_call_post (const gcall &stmt,
345 bool unknown_side_effects,
347
349
351
352 const svalue *maybe_get_copy_bounds (const region *src_reg,
353 const svalue *num_bytes_sval);
355 int retval,
356 bool unmergeable);
358 bool unmergeable);
360
364 const svalue *extra_sval,
365 const uncertainty_t *uncertainty);
366
368 void on_setjmp (const gcall &stmt, const exploded_node *enode,
370 void on_longjmp (const gcall &longjmp_call, const gcall &setjmp_call,
371 int setjmp_stack_depth, region_model_context *ctxt);
372
373 void update_for_phis (const supernode *snode,
374 const cfg_superedge *last_cfg_superedge,
376
377 void handle_phi (const gphi *phi, tree lhs, tree rhs,
378 const region_model &old_state,
379 hash_set<const svalue *> &svals_changing_meaning,
381
383 const gimple *last_stmt,
385 std::unique_ptr<rejected_constraint> *out);
386
387 void update_for_gcall (const gcall &call_stmt,
389 function *callee = NULL);
390
391 void update_for_return_gcall (const gcall &call_stmt,
393
394 const region *push_frame (const function &fun,
395 const gcall *call_stmt,
396 const vec<const svalue *> *arg_sids,
400 void pop_frame (tree result_lvalue,
401 const svalue **out_result,
403 const gcall *call_stmt,
404 bool eval_return_svalue = true);
405 int get_stack_depth () const;
406 const frame_region *get_frame_at_index (int index) const;
407
412
413 const region *deref_rvalue (const svalue *ptr_sval, tree ptr_tree,
415 bool add_nonnull_constraint = true) const;
416
418 const region *reg,
419 const bit_range &bits,
420 region_model_context *ctxt) const;
421
422 void set_value (const region *lhs_reg, const svalue *rhs_sval,
424 void set_value (tree lhs, tree rhs, region_model_context *ctxt);
425 void clobber_region (const region *reg);
426 void purge_region (const region *reg);
427 void fill_region (const region *reg,
428 const svalue *sval,
430 void zero_fill_region (const region *reg,
432 void write_bytes (const region *dest_reg,
433 const svalue *num_bytes_sval,
434 const svalue *sval,
436 const svalue *read_bytes (const region *src_reg,
437 tree src_ptr_expr,
438 const svalue *num_bytes_sval,
439 region_model_context *ctxt) const;
440 void copy_bytes (const region *dest_reg,
441 const region *src_reg,
442 tree src_ptr_expr,
443 const svalue *num_bytes_sval,
445 void mark_region_as_unknown (const region *reg, uncertainty_t *uncertainty);
446
448 enum tree_code op,
449 const svalue *rhs) const;
451 const region_svalue *ptr) const;
453 const svalue *b) const;
454 tristate structural_equality (const svalue *a, const svalue *b) const;
456 enum tree_code op,
457 tree rhs,
458 region_model_context *ctxt) const;
459 bool add_constraint (tree lhs, enum tree_code op, tree rhs,
461 bool add_constraint (tree lhs, enum tree_code op, tree rhs,
463 std::unique_ptr<rejected_constraint> *out);
464
465 const region *
468 bool update_state_machine = false,
469 const call_details *cd = nullptr);
470
474
476 logger *logger = nullptr) const;
478 logger *logger = nullptr) const;
482 logger *logger) const;
486 logger *logger) const;
487
488 /* For selftests. */
493
494 store *get_store () { return &m_store; }
495 const store *get_store () const { return &m_store; }
496
497 const dynamic_extents_t &
499 {
500 return m_dynamic_extents;
501 }
502 const svalue *get_dynamic_extents (const region *reg) const;
503 void set_dynamic_extents (const region *reg,
504 const svalue *size_in_bytes,
506 void unset_dynamic_extents (const region *reg);
507
510 {
511 return m_mgr->get_range_manager ();
512 }
513
515 enum poison_kind pkind);
516
517 bool can_merge_with_p (const region_model &other_model,
518 const program_point &point,
519 region_model *out_model,
521 const program_state *state_a = NULL,
522 const program_state *state_b = NULL) const;
523
526
528 static void append_regions_cb (const region *base_reg,
529 struct append_regions_cb_data *data);
530
531 const svalue *get_store_value (const region *reg,
532 region_model_context *ctxt) const;
533 const svalue *get_store_bytes (const region *base_reg,
534 const byte_range &bytes,
535 region_model_context *ctxt) const;
537 tree expr,
538 const svalue **out_sval,
539 region_model_context *ctxt) const;
541 tree expr,
542 const svalue **out_sval,
543 region_model_context *ctxt) const;
544
545 bool region_exists_p (const region *reg) const;
546
547 void loop_replay_fixup (const region_model *dst_state);
548
549 const svalue *get_capacity (const region *reg) const;
550
552 const region_model &summary);
553
555 const svalue *copied_sval,
556 const region *src_reg,
558
559 void set_errno (const call_details &cd);
560
561 /* Implemented in sm-fd.cc */
563
564 /* Implemented in sm-malloc.cc */
566 const svalue *old_ptr_sval,
567 const svalue *new_ptr_sval);
568
569 /* Implemented in sm-malloc.cc. */
570 void
572 const svalue *new_ptr_sval);
573
574 /* Implemented in sm-taint.cc. */
575 void mark_as_tainted (const svalue *sval,
577
578 bool add_constraint (const svalue *lhs,
579 enum tree_code op,
580 const svalue *rhs,
582
583 const svalue *check_for_poison (const svalue *sval,
584 tree expr,
585 const region *src_region,
586 region_model_context *ctxt) const;
587
588 void check_region_for_write (const region *dest_reg,
589 const svalue *sval_hint,
590 region_model_context *ctxt) const;
591
592 const svalue *
594 unsigned idx) const;
595 const svalue *
597 unsigned idx,
598 bool include_terminator,
599 const svalue **out_sval) const;
600
602 get_builtin_kf (const gcall &call,
603 region_model_context *ctxt = NULL) const;
604
605 static void
607 {
608 pop_frame_callbacks.safe_push (callback);
609 }
610
611 static void
613 const region_model *prev_model,
614 const svalue *retval,
616 {
617 for (auto &callback : pop_frame_callbacks)
618 callback (model, prev_model, retval, ctxt);
619 }
620
621 bool called_from_main_p () const;
622
624 {
625 m_thrown_exceptions_stack.push_back (node);
626 }
628 {
629 if (m_thrown_exceptions_stack.empty ())
630 return nullptr;
631 return &m_thrown_exceptions_stack.back ();
632 }
634 {
636 const exception_node retval = m_thrown_exceptions_stack.back ();
637 m_thrown_exceptions_stack.pop_back ();
638 return retval;
639 }
640
642 {
643 m_caught_exceptions_stack.push_back (node);
644 }
646 {
647 if (m_caught_exceptions_stack.empty ())
648 return nullptr;
649 return &m_caught_exceptions_stack.back ();
650 }
652 {
654 const exception_node retval = m_caught_exceptions_stack.back ();
655 m_caught_exceptions_stack.pop_back ();
656 return retval;
657 }
658
659 bool
663 tree exception_type,
664 std::unique_ptr<rejected_constraint> *out);
665
666 bool
670 tree exception_type,
671 std::unique_ptr<rejected_constraint> *out);
672
673private:
676
680 logger *logger) const;
684 logger *logger) const;
685
687 const call_details &cd) const;
689
690 bool add_constraints_from_binop (const svalue *outer_lhs,
691 enum tree_code outer_op,
692 const svalue *outer_rhs,
693 bool *out,
695
701 const gcond *cond_stmt,
703 std::unique_ptr<rejected_constraint> *out);
705 const gswitch *switch_stmt,
707 std::unique_ptr<rejected_constraint> *out);
709 const ggoto *goto_stmt,
711
712 bool
714 const geh_dispatch *eh_dispatch_stmt,
716 std::unique_ptr<rejected_constraint> *out);
717
719 enum poison_kind pkind);
720
722 bool nonnull,
724
725 const svalue *get_initial_value_for_global (const region *reg) const;
726
728
730 const svalue *size_in_bytes,
731 region_model_context *ctxt) const;
733 region_model_context *ctxt) const;
734
736 enum access_direction dir,
737 region_model_context *ctxt) const;
738
739 void check_for_writable_region (const region* dest_reg,
740 region_model_context *ctxt) const;
741 bool check_region_access (const region *reg,
742 enum access_direction dir,
743 const svalue *sval_hint,
744 region_model_context *ctxt) const;
745 bool check_region_for_read (const region *src_reg,
746 region_model_context *ctxt) const;
747 void check_region_size (const region *lhs_reg, const svalue *rhs_sval,
748 region_model_context *ctxt) const;
749
750 /* Implemented in bounds-checking.cc */
751 bool check_symbolic_bounds (const region *base_reg,
752 const svalue *sym_byte_offset,
753 const svalue *num_bytes_sval,
754 const svalue *capacity,
755 enum access_direction dir,
756 const svalue *sval_hint,
757 region_model_context *ctxt) const;
758 bool check_region_bounds (const region *reg, enum access_direction dir,
759 const svalue *sval_hint,
760 region_model_context *ctxt) const;
761
762 void check_call_args (const call_details &cd) const;
764 tree format_attr) const;
766 tree callee_fndecl,
768 rdwr_map &rdwr_idx) const;
770 tree callee_fndecl,
772 rdwr_map &rdwr_idx);
774 tree callee_fndecl,
776 rdwr_map &rdwr_idx,
777 tree attr);
778 void check_function_attrs (const gcall &call,
779 tree callee_fndecl,
781
783 tree fndecl,
785
787 /* Storing this here to avoid passing it around everywhere. */
789
791
792 constraint_manager *m_constraints; // TODO: embed, rather than dynalloc?
793
795
796 std::vector<exception_node> m_thrown_exceptions_stack;
797 std::vector<exception_node> m_caught_exceptions_stack;
798
799 /* Map from base region to size in bytes, for tracking the sizes of
800 dynamically-allocated regions.
801 This is part of the region_model rather than the region to allow for
802 memory regions to be resized (e.g. by realloc). */
804};
805
806/* Some region_model activity could lead to warnings (e.g. attempts to use an
807 uninitialized value). This abstract base class encapsulates an interface
808 for the region model to use when emitting such warnings.
809
810 Having this as an abstract base class allows us to support the various
811 operations needed by program_state in the analyzer within region_model,
812 whilst keeping them somewhat modularized. */
813
815{
816 public:
817 /* Hook for clients to store pending diagnostics.
818 Return true if the diagnostic was stored, or false if it was deleted.
819 Optionally provide a custom stmt_finder. */
820 virtual bool warn (std::unique_ptr<pending_diagnostic> d,
821 const stmt_finder *custom_finder = NULL) = 0;
822
823 /* Hook for clients to add a note to the last previously stored
824 pending diagnostic. */
825 virtual void add_note (std::unique_ptr<pending_note> pn) = 0;
826
827 /* Hook for clients to add an event to the last previously stored
828 pending diagnostic. */
829 virtual void add_event (std::unique_ptr<checker_event> event) = 0;
830
831 /* Hook for clients to be notified when an SVAL that was reachable
832 in a previous state is no longer live, so that clients can emit warnings
833 about leaks. */
834 virtual void on_svalue_leak (const svalue *sval) = 0;
835
836 /* Hook for clients to be notified when the set of explicitly live
837 svalues changes, so that they can purge state relating to dead
838 svalues. */
839 virtual void on_liveness_change (const svalue_set &live_svalues,
840 const region_model *model) = 0;
841
842 virtual logger *get_logger () = 0;
843
844 /* Hook for clients to be notified when the condition
845 "LHS OP RHS" is added to the region model.
846 This exists so that state machines can detect tests on edges,
847 and use them to trigger sm-state transitions (e.g. transitions due
848 to ptrs becoming known to be NULL or non-NULL, rather than just
849 "unchecked") */
850 virtual void on_condition (const svalue *lhs,
851 enum tree_code op,
852 const svalue *rhs) = 0;
853
854 /* Hook for clients to be notified when the condition that
855 SVAL is within RANGES is added to the region model.
856 Similar to on_condition, but for use when handling switch statements.
857 RANGES is non-empty. */
858 virtual void on_bounded_ranges (const svalue &sval,
859 const bounded_ranges &ranges) = 0;
860
861 /* Hook for clients to be notified when a frame is popped from the stack. */
862 virtual void on_pop_frame (const frame_region *) = 0;
863
864 /* Hooks for clients to be notified when an unknown change happens
865 to SVAL (in response to a call to an unknown function). */
866 virtual void on_unknown_change (const svalue *sval, bool is_mutable) = 0;
867
868 /* Hooks for clients to be notified when a phi node is handled,
869 where RHS is the pertinent argument. */
870 virtual void on_phi (const gphi *phi, tree rhs) = 0;
871
872 /* Hooks for clients to be notified when the region model doesn't
873 know how to handle the tree code of T at LOC. */
875 const dump_location_t &loc) = 0;
876
877 /* Hook for clients to be notified when a function_decl escapes. */
878 virtual void on_escaped_function (tree fndecl) = 0;
879
881
882 /* Hook for clients to purge state involving SVAL. */
883 virtual void purge_state_involving (const svalue *sval) = 0;
884
885 /* Hook for clients to split state with a non-standard path. */
886 virtual void bifurcate (std::unique_ptr<custom_edge_info> info) = 0;
887
888 /* Hook for clients to terminate the standard path. */
889 virtual void terminate_path () = 0;
890
891 virtual const extrinsic_state *get_ext_state () const = 0;
892
893 /* Hook for clients to access the a specific state machine in
894 any underlying program_state. */
895 virtual bool
896 get_state_map_by_name (const char *name,
897 sm_state_map **out_smap,
898 const state_machine **out_sm,
899 unsigned *out_sm_idx,
900 std::unique_ptr<sm_context> *out_sm_context) = 0;
901
902 /* Precanned ways for clients to access specific state machines. */
903 bool get_fd_map (sm_state_map **out_smap,
904 const state_machine **out_sm,
905 unsigned *out_sm_idx,
906 std::unique_ptr<sm_context> *out_sm_context)
907 {
908 return get_state_map_by_name ("file-descriptor", out_smap, out_sm,
909 out_sm_idx, out_sm_context);
910 }
911 bool get_malloc_map (sm_state_map **out_smap,
912 const state_machine **out_sm,
913 unsigned *out_sm_idx)
914 {
915 return get_state_map_by_name ("malloc", out_smap, out_sm, out_sm_idx, NULL);
916 }
917 bool get_taint_map (sm_state_map **out_smap,
918 const state_machine **out_sm,
919 unsigned *out_sm_idx)
920 {
921 return get_state_map_by_name ("taint", out_smap, out_sm, out_sm_idx, NULL);
922 }
923
924 bool possibly_tainted_p (const svalue *sval);
925
926 /* Get the current statement, if any. */
927 virtual const gimple *get_stmt () const = 0;
928
929 virtual const exploded_graph *get_eg () const = 0;
930
931 /* Hooks for detecting infinite loops. */
932 virtual void maybe_did_work () = 0;
933 virtual bool checking_for_infinite_loop_p () const = 0;
934 virtual void on_unusable_in_infinite_loop () = 0;
935};
936
937/* A "do nothing" subclass of region_model_context. */
938
940{
941public:
942 bool warn (std::unique_ptr<pending_diagnostic>,
943 const stmt_finder *) override { return false; }
944 void add_note (std::unique_ptr<pending_note>) override;
945 void add_event (std::unique_ptr<checker_event>) override;
946 void on_svalue_leak (const svalue *) override {}
948 const region_model *) override {}
949 logger *get_logger () override { return NULL; }
950 void on_condition (const svalue *lhs ATTRIBUTE_UNUSED,
951 enum tree_code op ATTRIBUTE_UNUSED,
952 const svalue *rhs ATTRIBUTE_UNUSED) override
953 {
954 }
956 const bounded_ranges &) override
957 {
958 }
959 void on_pop_frame (const frame_region *) override {}
960 void on_unknown_change (const svalue *sval ATTRIBUTE_UNUSED,
961 bool is_mutable ATTRIBUTE_UNUSED) override
962 {
963 }
964 void on_phi (const gphi *phi ATTRIBUTE_UNUSED,
965 tree rhs ATTRIBUTE_UNUSED) override
966 {
967 }
968 void on_unexpected_tree_code (tree, const dump_location_t &) override {}
969
970 void on_escaped_function (tree) override {}
971
972 uncertainty_t *get_uncertainty () override { return NULL; }
973
974 void purge_state_involving (const svalue *sval ATTRIBUTE_UNUSED) override {}
975
976 void bifurcate (std::unique_ptr<custom_edge_info> info) override;
977 void terminate_path () override;
978
979 const extrinsic_state *get_ext_state () const override { return NULL; }
980
981 bool get_state_map_by_name (const char *,
982 sm_state_map **,
983 const state_machine **,
984 unsigned *,
985 std::unique_ptr<sm_context> *) override
986 {
987 return false;
988 }
989
990 const gimple *get_stmt () const override { return NULL; }
991 const exploded_graph *get_eg () const override { return NULL; }
992 void maybe_did_work () override {}
993 bool checking_for_infinite_loop_p () const override { return false; }
995};
996
997/* A subclass of region_model_context for determining if operations fail
998 e.g. "can we generate a region for the lvalue of EXPR?". */
999
1001{
1002public:
1004
1006 final override
1007 {
1009 }
1010
1011 bool had_errors_p () const { return m_num_unexpected_codes > 0; }
1012
1013private:
1015};
1016
1017/* Subclass of region_model_context that wraps another context, allowing
1018 for extra code to be added to the various hooks. */
1019
1021{
1022 public:
1023 bool warn (std::unique_ptr<pending_diagnostic> d,
1024 const stmt_finder *custom_finder) override
1025 {
1026 if (m_inner)
1027 return m_inner->warn (std::move (d), custom_finder);
1028 else
1029 return false;
1030 }
1031
1032 void add_note (std::unique_ptr<pending_note> pn) override
1033 {
1034 if (m_inner)
1035 m_inner->add_note (std::move (pn));
1036 }
1037 void add_event (std::unique_ptr<checker_event> event) override;
1038
1039 void on_svalue_leak (const svalue *sval) override
1040 {
1041 if (m_inner)
1042 m_inner->on_svalue_leak (sval);
1043 }
1044
1045 void on_liveness_change (const svalue_set &live_svalues,
1046 const region_model *model) override
1047 {
1048 if (m_inner)
1049 m_inner->on_liveness_change (live_svalues, model);
1050 }
1051
1052 logger *get_logger () override
1053 {
1054 if (m_inner)
1055 return m_inner->get_logger ();
1056 else
1057 return nullptr;
1058 }
1059
1060 void on_condition (const svalue *lhs,
1061 enum tree_code op,
1062 const svalue *rhs) override
1063 {
1064 if (m_inner)
1065 m_inner->on_condition (lhs, op, rhs);
1066 }
1067
1068 void on_bounded_ranges (const svalue &sval,
1069 const bounded_ranges &ranges) override
1070 {
1071 if (m_inner)
1072 m_inner->on_bounded_ranges (sval, ranges);
1073 }
1074
1075 void on_pop_frame (const frame_region *frame_reg) override
1076 {
1077 if (m_inner)
1078 m_inner->on_pop_frame (frame_reg);
1079 }
1080
1081 void on_unknown_change (const svalue *sval, bool is_mutable) override
1082 {
1083 if (m_inner)
1084 m_inner->on_unknown_change (sval, is_mutable);
1085 }
1086
1087 void on_phi (const gphi *phi, tree rhs) override
1088 {
1089 if (m_inner)
1090 m_inner->on_phi (phi, rhs);
1091 }
1092
1094 const dump_location_t &loc) override
1095 {
1096 if (m_inner)
1097 m_inner->on_unexpected_tree_code (t, loc);
1098 }
1099
1100 void on_escaped_function (tree fndecl) override
1101 {
1102 if (m_inner)
1103 m_inner->on_escaped_function (fndecl);
1104 }
1105
1107 {
1108 if (m_inner)
1109 return m_inner->get_uncertainty ();
1110 else
1111 return nullptr;
1112 }
1113
1114 void purge_state_involving (const svalue *sval) override
1115 {
1116 if (m_inner)
1117 m_inner->purge_state_involving (sval);
1118 }
1119
1120 void bifurcate (std::unique_ptr<custom_edge_info> info) override
1121 {
1122 if (m_inner)
1123 m_inner->bifurcate (std::move (info));
1124 }
1125
1126 void terminate_path () override
1127 {
1128 if (m_inner)
1129 m_inner->terminate_path ();
1130 }
1131
1132 const extrinsic_state *get_ext_state () const override
1133 {
1134 if (m_inner)
1135 return m_inner->get_ext_state ();
1136 else
1137 return nullptr;
1138 }
1139
1140 bool get_state_map_by_name (const char *name,
1141 sm_state_map **out_smap,
1142 const state_machine **out_sm,
1143 unsigned *out_sm_idx,
1144 std::unique_ptr<sm_context> *out_sm_context)
1145 override
1146 {
1147 if (m_inner)
1148 return m_inner->get_state_map_by_name (name, out_smap, out_sm, out_sm_idx,
1149 out_sm_context);
1150 else
1151 return false;
1152 }
1153
1154 const gimple *get_stmt () const override
1155 {
1156 if (m_inner)
1157 return m_inner->get_stmt ();
1158 else
1159 return nullptr;
1160 }
1161
1162 const exploded_graph *get_eg () const override
1163 {
1164 if (m_inner)
1165 return m_inner->get_eg ();
1166 else
1167 return nullptr;
1168 }
1169
1170 void maybe_did_work () override
1171 {
1172 if (m_inner)
1173 m_inner->maybe_did_work ();
1174 }
1175
1176 bool checking_for_infinite_loop_p () const override
1177 {
1178 if (m_inner)
1179 return m_inner->checking_for_infinite_loop_p ();
1180 return false;
1181 }
1183 {
1184 if (m_inner)
1185 m_inner->on_unusable_in_infinite_loop ();
1186 }
1187
1188protected:
1190 : m_inner (inner)
1191 {
1192 }
1193
1195};
1196
1197/* Subclass of region_model_context_decorator with a hook for adding
1198 notes/events when saving diagnostics. */
1199
1201{
1202public:
1203 bool warn (std::unique_ptr<pending_diagnostic> d,
1204 const stmt_finder *custom_finder) override
1205 {
1206 if (m_inner)
1207 if (m_inner->warn (std::move (d), custom_finder))
1208 {
1209 add_annotations ();
1210 return true;
1211 }
1212 return false;
1213 }
1214
1215 /* Hook to add new event(s)/note(s) */
1216 virtual void add_annotations () = 0;
1217
1218protected:
1223};
1224
1225/* A bundle of data for use when attempting to merge two region_model
1226 instances to make a third. */
1227
1229{
1231 const region_model *model_b,
1232 const program_point &point,
1233 region_model *merged_model,
1235 const program_state *state_a,
1236 const program_state *state_b)
1237 : m_model_a (model_a), m_model_b (model_b),
1238 m_point (point),
1239 m_merged_model (merged_model),
1241 m_state_a (state_a), m_state_b (state_b)
1242 {
1243 }
1244
1245 void dump_to_pp (pretty_printer *pp, bool simple) const;
1246 void dump (FILE *fp, bool simple) const;
1247 void dump (bool simple) const;
1248
1250 {
1251 return m_model_a->get_manager ();
1252 }
1253
1254 bool mergeable_svalue_p (const svalue *) const;
1256 {
1257 return m_point.get_function_point ();
1258 }
1259
1260 void on_widening_reuse (const widening_svalue *widening_sval);
1261
1266
1270
1272};
1273
1274/* A record that can (optionally) be written out when
1275 region_model::add_constraint fails. */
1276
1278{
1279public:
1281 virtual void dump_to_pp (pretty_printer *pp) const = 0;
1282
1283 const region_model &get_model () const { return m_model; }
1284
1285protected:
1287 : m_model (model)
1288 {}
1289
1291};
1292
1294{
1295public:
1297 tree lhs, enum tree_code op, tree rhs)
1298 : rejected_constraint (model),
1299 m_lhs (lhs), m_op (op), m_rhs (rhs)
1300 {}
1301
1302 void dump_to_pp (pretty_printer *pp) const final override;
1303
1307};
1308
1310{
1311public:
1313 : rejected_constraint (model)
1314 {}
1315
1316 void dump_to_pp (pretty_printer *pp) const final override;
1317};
1318
1320{
1321public:
1323 tree expr, const bounded_ranges *ranges)
1324 : rejected_constraint (model),
1325 m_expr (expr), m_ranges (ranges)
1326 {}
1327
1328 void dump_to_pp (pretty_printer *pp) const final override;
1329
1330private:
1333};
1334
1335/* A bundle of state. */
1336
1338{
1339public:
1341 const supergraph *get_supergraph () { return m_sg; }
1344 {
1345 return m_mgr.get_known_function_manager ();
1346 }
1347
1348 void log_stats (logger *logger) const;
1349
1350private:
1353};
1354
1355} // namespace ana
1356
1357extern void debug (const region_model &rmodel);
1358
1359namespace ana {
1360
1361#if CHECKING_P
1362
1363namespace selftest {
1364
1365using namespace ::selftest;
1366
1367/* An implementation of region_model_context for use in selftests, which
1368 stores any pending_diagnostic instances passed to it. */
1369
1370class test_region_model_context : public noop_region_model_context
1371{
1372public:
1373 bool warn (std::unique_ptr<pending_diagnostic> d,
1374 const stmt_finder *) final override
1375 {
1376 m_diagnostics.safe_push (d.release ());
1377 return true;
1378 }
1379
1380 unsigned get_num_diagnostics () const { return m_diagnostics.length (); }
1381
1382 void on_unexpected_tree_code (tree t, const dump_location_t &)
1383 final override
1384 {
1385 internal_error ("unhandled tree code: %qs",
1387 }
1388
1389private:
1390 /* Implicitly delete any diagnostics in the dtor. */
1391 auto_delete_vec<pending_diagnostic> m_diagnostics;
1392};
1393
1394/* Attempt to add the constraint (LHS OP RHS) to MODEL.
1395 Verify that MODEL remains satisfiable. */
1396
1397#define ADD_SAT_CONSTRAINT(MODEL, LHS, OP, RHS) \
1398 SELFTEST_BEGIN_STMT \
1399 bool sat = (MODEL).add_constraint (LHS, OP, RHS, NULL); \
1400 ASSERT_TRUE (sat); \
1401 SELFTEST_END_STMT
1402
1403/* Attempt to add the constraint (LHS OP RHS) to MODEL.
1404 Verify that the result is not satisfiable. */
1405
1406#define ADD_UNSAT_CONSTRAINT(MODEL, LHS, OP, RHS) \
1407 SELFTEST_BEGIN_STMT \
1408 bool sat = (MODEL).add_constraint (LHS, OP, RHS, NULL); \
1409 ASSERT_FALSE (sat); \
1410 SELFTEST_END_STMT
1411
1412/* Implementation detail of the ASSERT_CONDITION_* macros. */
1413
1414void assert_condition (const location &loc,
1415 region_model &model,
1416 const svalue *lhs, tree_code op, const svalue *rhs,
1417 tristate expected);
1418
1419void assert_condition (const location &loc,
1420 region_model &model,
1421 tree lhs, tree_code op, tree rhs,
1422 tristate expected);
1423
1424/* Assert that REGION_MODEL evaluates the condition "LHS OP RHS"
1425 as "true". */
1426
1427#define ASSERT_CONDITION_TRUE(REGION_MODEL, LHS, OP, RHS) \
1428 SELFTEST_BEGIN_STMT \
1429 assert_condition (SELFTEST_LOCATION, REGION_MODEL, LHS, OP, RHS, \
1430 tristate (tristate::TS_TRUE)); \
1431 SELFTEST_END_STMT
1432
1433/* Assert that REGION_MODEL evaluates the condition "LHS OP RHS"
1434 as "false". */
1435
1436#define ASSERT_CONDITION_FALSE(REGION_MODEL, LHS, OP, RHS) \
1437 SELFTEST_BEGIN_STMT \
1438 assert_condition (SELFTEST_LOCATION, REGION_MODEL, LHS, OP, RHS, \
1439 tristate (tristate::TS_FALSE)); \
1440 SELFTEST_END_STMT
1441
1442/* Assert that REGION_MODEL evaluates the condition "LHS OP RHS"
1443 as "unknown". */
1444
1445#define ASSERT_CONDITION_UNKNOWN(REGION_MODEL, LHS, OP, RHS) \
1446 SELFTEST_BEGIN_STMT \
1447 assert_condition (SELFTEST_LOCATION, REGION_MODEL, LHS, OP, RHS, \
1448 tristate (tristate::TS_UNKNOWN)); \
1449 SELFTEST_END_STMT
1450
1451} /* end of namespace selftest. */
1452
1453#endif /* #if CHECKING_P */
1454
1455} // namespace ana
1456
1457#endif /* GCC_ANALYZER_REGION_MODEL_H */
hash_map< rdwr_access_hash, attr_access > rdwr_map
Definition attribs.h:402
virtual void add_annotations()=0
annotating_context(region_model_context *inner)
Definition region-model.h:1219
bool warn(std::unique_ptr< pending_diagnostic > d, const stmt_finder *custom_finder) override
Definition region-model.h:1203
Definition svalue.h:1626
Definition svalue.h:789
Definition svalue.h:1073
Definition constraint-manager.h:181
Definition common.h:313
Definition call-details.h:29
Definition call-summary.h:68
Definition supergraph.h:453
Definition supergraph.h:522
Definition svalue.h:1392
Definition svalue.h:1524
Definition svalue.h:1772
Definition svalue.h:301
Definition constraint-manager.h:425
Definition supergraph.h:715
Definition supergraph.h:610
Definition supergraph.h:665
known_function_manager * get_known_function_manager()
Definition region-model.h:1343
const supergraph * get_supergraph()
Definition region-model.h:1341
const supergraph * m_sg
Definition region-model.h:1351
region_model_manager * get_model_manager()
Definition region-model.h:1342
engine(const supergraph *sg=NULL, logger *logger=NULL)
void log_stats(logger *logger) const
region_model_manager m_mgr
Definition region-model.h:1352
Definition exploded-graph.h:804
Definition exploded-graph.h:203
Definition program-state.h:31
Definition region.h:319
Definition program-point.h:73
Definition svalue.h:648
Definition known-function-manager.h:41
Definition common.h:293
Definition analyzer-logging.h:34
Definition region-model.h:940
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:981
bool checking_for_infinite_loop_p() const override
Definition region-model.h:993
bool warn(std::unique_ptr< pending_diagnostic >, const stmt_finder *) override
Definition region-model.h:942
void maybe_did_work() override
Definition region-model.h:992
uncertainty_t * get_uncertainty() override
Definition region-model.h:972
void on_unexpected_tree_code(tree, const dump_location_t &) override
Definition region-model.h:968
void on_unknown_change(const svalue *sval, bool is_mutable) override
Definition region-model.h:960
void on_pop_frame(const frame_region *) override
Definition region-model.h:959
void on_phi(const gphi *phi, tree rhs) override
Definition region-model.h:964
void on_condition(const svalue *lhs, enum tree_code op, const svalue *rhs) override
Definition region-model.h:950
void add_event(std::unique_ptr< checker_event >) override
void on_liveness_change(const svalue_set &, const region_model *) override
Definition region-model.h:947
logger * get_logger() override
Definition region-model.h:949
void on_escaped_function(tree) override
Definition region-model.h:970
const exploded_graph * get_eg() const override
Definition region-model.h:991
const gimple * get_stmt() const override
Definition region-model.h:990
void on_unusable_in_infinite_loop() override
Definition region-model.h:994
void on_svalue_leak(const svalue *) override
Definition region-model.h:946
void add_note(std::unique_ptr< pending_note >) override
void purge_state_involving(const svalue *sval) override
Definition region-model.h:974
const extrinsic_state * get_ext_state() const override
Definition region-model.h:979
void on_bounded_ranges(const svalue &, const bounded_ranges &) override
Definition region-model.h:955
void bifurcate(std::unique_ptr< custom_edge_info > info) override
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 common.h:169
Definition svalue.h:1222
Definition svalue.h:447
Definition program-point.h:175
Definition program-state.h:221
Definition region-model-reachability.h:36
region_model_context * m_inner
Definition region-model.h:1194
const exploded_graph * get_eg() const override
Definition region-model.h:1162
void on_bounded_ranges(const svalue &sval, const bounded_ranges &ranges) override
Definition region-model.h:1068
void on_phi(const gphi *phi, tree rhs) override
Definition region-model.h:1087
void add_event(std::unique_ptr< checker_event > event) override
const extrinsic_state * get_ext_state() const override
Definition region-model.h:1132
void on_condition(const svalue *lhs, enum tree_code op, const svalue *rhs) override
Definition region-model.h:1060
const gimple * get_stmt() const override
Definition region-model.h:1154
void maybe_did_work() override
Definition region-model.h:1170
void on_pop_frame(const frame_region *frame_reg) override
Definition region-model.h:1075
uncertainty_t * get_uncertainty() override
Definition region-model.h:1106
void bifurcate(std::unique_ptr< custom_edge_info > info) override
Definition region-model.h:1120
void add_note(std::unique_ptr< pending_note > pn) override
Definition region-model.h:1032
void on_svalue_leak(const svalue *sval) override
Definition region-model.h:1039
bool checking_for_infinite_loop_p() const override
Definition region-model.h:1176
logger * get_logger() override
Definition region-model.h:1052
region_model_context_decorator(region_model_context *inner)
Definition region-model.h:1189
void purge_state_involving(const svalue *sval) override
Definition region-model.h:1114
void on_liveness_change(const svalue_set &live_svalues, const region_model *model) override
Definition region-model.h:1045
bool warn(std::unique_ptr< pending_diagnostic > d, const stmt_finder *custom_finder) override
Definition region-model.h:1023
void on_unexpected_tree_code(tree t, const dump_location_t &loc) override
Definition region-model.h:1093
void on_escaped_function(tree fndecl) override
Definition region-model.h:1100
void terminate_path() override
Definition region-model.h:1126
void on_unknown_change(const svalue *sval, bool is_mutable) override
Definition region-model.h:1081
void on_unusable_in_infinite_loop() override
Definition region-model.h:1182
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:1140
Definition region-model.h:815
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:911
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:903
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:917
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
Definition region-model.h:298
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)
const builtin_known_function * get_builtin_kf(const gcall &call, region_model_context *ctxt=NULL) const
store * get_store()
Definition region-model.h:494
constraint_manager * get_constraints()
Definition region-model.h:489
void update_for_nonzero_return(const call_details &cd)
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)
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 apply_constraints_for_eh_dispatch_allowed(const eh_dispatch_allowed_cfg_superedge &edge, region_model_context *ctxt, tree exception_type, std::unique_ptr< rejected_constraint > *out)
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 update_for_return_gcall(const gcall &call_stmt, region_model_context *ctxt)
bool apply_constraints_for_eh_dispatch(const eh_dispatch_cfg_superedge &edge, const geh_dispatch *eh_dispatch_stmt, region_model_context *ctxt, std::unique_ptr< rejected_constraint > *out)
void update_for_gcall(const gcall &call_stmt, region_model_context *ctxt, function *callee=NULL)
bounded_ranges_manager * get_range_manager() const
Definition region-model.h:509
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:792
const exception_node * get_current_thrown_exception() const
Definition region-model.h:627
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 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:790
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
const region * push_frame(const function &fun, const gcall *call_stmt, const vec< const svalue * > *arg_sids, region_model_context *ctxt)
bool operator!=(const region_model &other) const
Definition region-model.h:308
const svalue * get_store_value(const region *reg, region_model_context *ctxt) const
const region * get_region_for_poisoned_expr(tree expr) const
void push_caught_exception(const exception_node &node)
Definition region-model.h:641
hashval_t hash() const
void check_function_attrs(const gcall &call, tree callee_fndecl, region_model_context *ctxt)
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
std::vector< exception_node > m_caught_exceptions_stack
Definition region-model.h:797
tristate compare_initial_and_pointer(const initial_svalue *init, const region_svalue *ptr) const
exception_node pop_thrown_exception()
Definition region-model.h:633
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:606
bool apply_constraints_for_ggoto(const cfg_superedge &edge, const ggoto *goto_stmt, region_model_context *ctxt)
bool on_call_pre(const gcall &stmt, 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
tree get_fndecl_for_call(const gcall &call, region_model_context *ctxt)
bool region_exists_p(const region *reg) const
tree get_representative_tree(const svalue *sval, logger *logger=nullptr) const
void check_function_attr_access(const gcall &call, tree callee_fndecl, region_model_context *ctxt, rdwr_map &rdwr_idx) const
region_model(region_model_manager *mgr)
void handle_unrecognized_call(const gcall &call, region_model_context *ctxt)
void push_thrown_exception(const exception_node &node)
Definition region-model.h:623
const svalue * maybe_get_copy_bounds(const region *src_reg, const svalue *num_bytes_sval)
region_to_value_map dynamic_extents_t
Definition region-model.h:300
bool apply_constraints_for_eh_dispatch_try(const eh_dispatch_try_cfg_superedge &edge, region_model_context *ctxt, tree exception_type, std::unique_ptr< rejected_constraint > *out)
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
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 check_one_function_attr_null_terminated_string_arg(const gcall &call, tree callee_fndecl, region_model_context *ctxt, rdwr_map &rdwr_idx, tree attr)
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)
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:398
std::unique_ptr< json::object > to_json() const
region_model_manager *const m_mgr
Definition region-model.h:788
const frame_region * m_current_frame
Definition region-model.h:794
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)
bool maybe_update_for_edge(const superedge &edge, const gimple *last_stmt, region_model_context *ctxt, std::unique_ptr< rejected_constraint > *out)
void check_function_attr_null_terminated_string_arg(const gcall &call, tree callee_fndecl, region_model_context *ctxt, rdwr_map &rdwr_idx)
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 check_for_throw_inside_call(const gcall &call, tree fndecl, region_model_context *ctxt)
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)
region_model_manager * get_manager() const
Definition region-model.h:508
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)
const exception_node * get_current_caught_exception() const
Definition region-model.h:645
void write_bytes(const region *dest_reg, const svalue *num_bytes_sval, 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 unset_dynamic_extents(const region *reg)
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
std::vector< exception_node > m_thrown_exceptions_stack
Definition region-model.h:796
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 on_call_post(const gcall &stmt, bool unknown_side_effects, region_model_context *ctxt)
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)
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:495
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:612
dynamic_extents_t m_dynamic_extents
Definition region-model.h:803
static auto_vec< pop_frame_callback > pop_frame_callbacks
Definition region-model.h:786
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
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)
exception_node pop_caught_exception()
Definition region-model.h:651
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_setjmp(const gcall &stmt, const exploded_node *enode, 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:498
Definition svalue.h:214
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::iterator iterator
Definition region-model.h:146
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
hash_map< const region *, const svalue * > hash_map_t
Definition region-model.h:145
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
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
Definition region.h:126
virtual ~rejected_constraint()
Definition region-model.h:1280
virtual void dump_to_pp(pretty_printer *pp) const =0
rejected_constraint(const region_model &model)
Definition region-model.h:1286
const region_model & get_model() const
Definition region-model.h:1283
region_model m_model
Definition region-model.h:1290
void dump_to_pp(pretty_printer *pp) const final override
rejected_default_case(const region_model &model)
Definition region-model.h:1312
tree m_rhs
Definition region-model.h:1306
rejected_op_constraint(const region_model &model, tree lhs, enum tree_code op, tree rhs)
Definition region-model.h:1296
tree m_lhs
Definition region-model.h:1304
void dump_to_pp(pretty_printer *pp) const final override
enum tree_code m_op
Definition region-model.h:1305
void dump_to_pp(pretty_printer *pp) const final override
tree m_expr
Definition region-model.h:1331
const bounded_ranges * m_ranges
Definition region-model.h:1332
rejected_ranges_constraint(const region_model &model, tree expr, const bounded_ranges *ranges)
Definition region-model.h:1322
Definition svalue.h:977
Definition supergraph.h:489
Definition svalue.h:562
Definition program-state.h:89
Definition sm.h:40
Definition exploded-graph.h:1051
Definition store.h:736
Definition svalue.h:891
Definition supergraph.h:318
Definition supergraph.h:113
Definition supergraph.h:239
Definition svalue.h:92
Definition supergraph.h:564
int m_num_unexpected_codes
Definition region-model.h:1014
bool had_errors_p() const
Definition region-model.h:1011
void on_unexpected_tree_code(tree, const dump_location_t &) final override
Definition region-model.h:1005
tentative_region_model_context()
Definition region-model.h:1003
Definition svalue.h:696
Definition store.h:161
Definition svalue.h:397
Definition svalue.h:1175
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:1270
Definition bitmap.h:950
Definition vec.h:1667
Definition genoutput.cc:150
Definition dumpfile.h:446
Definition genmatch.cc:1506
Definition ree.cc:583
Definition hash-map.h:40
Definition hash-set.h:37
Definition inchash.h:38
Definition pretty-print.h:241
void set_output_stream(FILE *outfile)
Definition pretty-print.h:274
Definition tristate.h:26
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:1015
tree_code
Definition genmatch.cc:1002
Definition access-diagram.h:30
@ stmt
Definition checker-event.h:37
@ return_edge
Definition checker-event.h:45
@ debug
Definition checker-event.h:35
@ call_edge
Definition checker-event.h:44
access_direction
Definition common.h:369
poison_kind
Definition svalue.h:427
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
hash_set< const svalue * > svalue_set
Definition common.h:78
memory_space
Definition region.h:32
Definition fold-const.cc:4338
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:2348
void pp_newline(pretty_printer *pp)
Definition pretty-print.cc:2625
void pp_string(pretty_printer *pp, const char *str)
Definition pretty-print.cc:2652
Definition store.h:233
Definition constraint-manager.h:123
Definition store.h:309
Definition region-model.h:257
void dump() const
exception_node(const svalue *exception_sval, const svalue *typeinfo_sval, const svalue *destructor_sval)
Definition region-model.h:258
const svalue * m_exception_sval
Definition region-model.h:283
bool operator==(const exception_node &other) const
tree maybe_get_type() const
void dump(bool simple) const
const svalue * m_typeinfo_sval
Definition region-model.h:284
const svalue * m_destructor_sval
Definition region-model.h:285
void dump(FILE *fp, bool simple) const
std::unique_ptr< text_art::tree_widget > make_dump_widget(const text_art::dump_widget_info &dwi) const
void dump_to_pp(pretty_printer *pp, bool simple) const
std::unique_ptr< json::object > to_json() const
void add_to_reachable_regions(reachable_regions &) const
const program_point & m_point
Definition region-model.h:1264
const program_state * m_state_a
Definition region-model.h:1268
const region_model * m_model_a
Definition region-model.h:1262
const extrinsic_state * m_ext_state
Definition region-model.h:1267
hash_set< const svalue * > m_svals_changing_meaning
Definition region-model.h:1271
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:1230
const program_state * m_state_b
Definition region-model.h:1269
bool mergeable_svalue_p(const svalue *) const
void dump(bool simple) const
region_model_manager * get_manager() const
Definition region-model.h:1249
void on_widening_reuse(const widening_svalue *widening_sval)
region_model * m_merged_model
Definition region-model.h:1265
void dump(FILE *fp, bool simple) const
const function_point & get_function_point() const
Definition region-model.h:1255
const region_model * m_model_b
Definition region-model.h:1263
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:549
Definition gimple.h:904
Definition gimple.h:352
Definition gimple.h:858
Definition gimple.h:494
Definition gimple.h:877
Definition gimple.h:221
Definition gimple.h:461
Definition gimple.h:914
Definition gimple.h:895
Definition gengtype.h:252
Definition vec.h:450
#define NULL
Definition system.h:50
#define gcc_assert(EXPR)
Definition system.h:814
#define DEBUG_FUNCTION
Definition system.h:1236
static bitmap visited
Definition tree-ssa-dce.cc:640
static control_dependences * cd
Definition tree-ssa-dce.cc:104
const char * get_tree_code_name(enum tree_code code)
Definition tree.cc:12895
#define TREE_CODE(NODE)
Definition tree.h:324
tree size_in_bytes(const_tree t)
Definition tree.h:5169
#define FOR_EACH_VEC_ELT(V, I, P)
Definition vec.h:1895