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-2026 Free Software Foundation, Inc.
3 Contributed by David Malcolm <dmalcolm@redhat.com>.
4
5This file is part of GCC.
6
7GCC is free software; you can redistribute it and/or modify it
8under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 3, or (at your option)
10any later version.
11
12GCC is distributed in the hope that it will be useful, but
13WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with GCC; see the file COPYING3. If not see
19<http://www.gnu.org/licenses/>. */
20
21#ifndef GCC_ANALYZER_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"
39#include "text-art/widget.h"
40#include "text-art/dump.h"
41
42using namespace ana;
43
44namespace inchash
45{
46 extern void add_path_var (path_var pv, hash &hstate);
47} // namespace inchash
48
49namespace ana {
50
51template <typename T>
53{
54 public:
55 one_way_id_map (int num_ids);
56 void put (T src, T dst);
57 T get_dst_for_src (T src) const;
58 void dump_to_pp (pretty_printer *pp) const;
59 void dump () const;
60 void update (T *) const;
61
62 private:
64 };
65
66/* class one_way_id_map. */
67
68/* one_way_id_map's ctor, which populates the map with dummy null values. */
69
70template <typename T>
71inline one_way_id_map<T>::one_way_id_map (int num_svalues)
72: m_src_to_dst (num_svalues)
73{
74 for (int i = 0; i < num_svalues; i++)
75 m_src_to_dst.quick_push (T::null ());
76}
77
78/* Record that SRC is to be mapped to DST. */
79
80template <typename T>
81inline void
83{
84 m_src_to_dst[src.as_int ()] = dst;
85}
86
87/* Get the new value for SRC within the map. */
88
89template <typename T>
90inline T
92{
93 if (src.null_p ())
94 return src;
95 return m_src_to_dst[src.as_int ()];
96}
97
98/* Dump this map to PP. */
99
100template <typename T>
101inline void
103{
104 pp_string (pp, "src to dst: {");
105 unsigned i;
106 T *dst;
108 {
109 if (i > 0)
110 pp_string (pp, ", ");
111 T src (T::from_int (i));
112 src.print (pp);
113 pp_string (pp, " -> ");
114 dst->print (pp);
115 }
116 pp_string (pp, "}");
117 pp_newline (pp);
118}
119
120/* Dump this map to stderr. */
121
122template <typename T>
123DEBUG_FUNCTION inline void
125{
127 pp.set_output_stream (stderr);
128 dump_to_pp (&pp);
129 pp_flush (&pp);
130}
131
132/* Update *ID from the old value to its new value in this map. */
133
134template <typename T>
135inline void
137{
138 *id = get_dst_for_src (*id);
139}
140
141/* A mapping from region to svalue for use when tracking state. */
142
144{
145public:
147 typedef hash_map_t::iterator iterator;
148
153
154 bool operator== (const region_to_value_map &other) const;
155 bool operator!= (const region_to_value_map &other) const
156 {
157 return !(*this == other);
158 }
159
160 iterator begin () const { return m_hash_map.begin (); }
161 iterator end () const { return m_hash_map.end (); }
162
163 const svalue * const *get (const region *reg) const
164 {
165 return const_cast <hash_map_t &> (m_hash_map).get (reg);
166 }
167 void put (const region *reg, const svalue *sval)
168 {
169 m_hash_map.put (reg, sval);
170 }
171 void remove (const region *reg)
172 {
173 m_hash_map.remove (reg);
174 }
175
176 bool is_empty () const { return m_hash_map.is_empty (); }
177
178 void dump_to_pp (pretty_printer *pp, bool simple, bool multiline) const;
179 void dump (bool simple) const;
180
181 std::unique_ptr<json::object> to_json () const;
182
183 std::unique_ptr<text_art::tree_widget>
185
187 region_to_value_map *out) const;
188
189 void purge_state_involving (const svalue *sval);
190
191private:
193};
194
195/* Various operations delete information from a region_model.
196
197 This struct tracks how many of each kind of entity were purged (e.g.
198 for selftests, and for debugging). */
199
218
219/* A base class for visiting regions and svalues, with do-nothing
220 base implementations of the per-subclass vfuncs. */
221
223{
224public:
225 virtual void visit_region_svalue (const region_svalue *) {}
226 virtual void visit_constant_svalue (const constant_svalue *) {}
227 virtual void visit_unknown_svalue (const unknown_svalue *) {}
228 virtual void visit_poisoned_svalue (const poisoned_svalue *) {}
229 virtual void visit_setjmp_svalue (const setjmp_svalue *) {}
230 virtual void visit_initial_svalue (const initial_svalue *) {}
231 virtual void visit_unaryop_svalue (const unaryop_svalue *) {}
232 virtual void visit_binop_svalue (const binop_svalue *) {}
233 virtual void visit_sub_svalue (const sub_svalue *) {}
234 virtual void visit_repeated_svalue (const repeated_svalue *) {}
238 virtual void visit_widening_svalue (const widening_svalue *) {}
239 virtual void visit_compound_svalue (const compound_svalue *) {}
240 virtual void visit_conjured_svalue (const conjured_svalue *) {}
243
244 virtual void visit_region (const region *) {}
245};
246
247struct append_regions_cb_data;
248
249/* Roughly equivalent to a struct __cxa_exception, except we store a std::vector
250 rather than a linked list. */
251
253{
254 exception_node (const svalue *exception_sval,
255 const svalue *typeinfo_sval,
256 const svalue *destructor_sval)
257 : m_exception_sval (exception_sval),
258 m_typeinfo_sval (typeinfo_sval),
259 m_destructor_sval (destructor_sval)
260 {
261 }
262
263 bool operator== (const exception_node &other) const;
264
265 void dump_to_pp (pretty_printer *pp, bool simple) const;
266 void dump (FILE *fp, bool simple) const;
267 void dump (bool simple) const;
268 void dump () const;
269
270 std::unique_ptr<json::object> to_json () const;
271
272 std::unique_ptr<text_art::tree_widget>
274
276
278
282};
283
284/* A region_model encapsulates a representation of the state of memory, with
285 a tree of regions, along with their associated values.
286 The representation is graph-like because values can be pointers to
287 regions.
288 It also stores:
289 - a constraint_manager, capturing relationships between the values, and
290 - dynamic extents, mapping dynamically-allocated regions to svalues (their
291 capacities). */
292
294{
295 public:
297
302
303 bool operator== (const region_model &other) const;
304 bool operator!= (const region_model &other) const
305 {
306 return !(*this == other);
307 }
308
309 hashval_t hash () const;
310
311 void print (pretty_printer *pp) const;
312
313 void dump_to_pp (pretty_printer *pp, bool simple, bool multiline) const;
314 void dump (FILE *fp, bool simple, bool multiline) const;
315 void dump (bool simple) const;
316 void dump () const;
317
318 void debug () const;
319
320 std::unique_ptr<json::object> to_json () const;
321
322 std::unique_ptr<text_art::tree_widget>
324
325 void validate () const;
326
328 bool canonicalized_p () const;
329
330 void
332 bool *out_unknown_side_effects,
334
336 const svalue *get_gassign_result (const gassign *assign,
338 void on_asm_stmt (const gasm *asm_stmt, region_model_context *ctxt);
340 void on_call_post (const gcall &stmt,
341 bool unknown_side_effects,
343
345
347
348 const svalue *maybe_get_copy_bounds (const region *src_reg,
349 const svalue *num_bytes_sval);
351 int retval,
352 bool unmergeable);
354 bool unmergeable);
356 bool unmergeable);
358
362 const svalue *extra_sval,
363 const uncertainty_t *uncertainty);
364
366 void on_setjmp (const gcall &stmt,
367 const exploded_node &enode,
368 const superedge &sedge,
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_gcall (const gcall &call_stmt,
375 function *callee = nullptr);
376
377 void update_for_return_gcall (const gcall &call_stmt,
379
380 const region *push_frame (const function &fun,
381 const gcall *call_stmt,
382 const vec<const svalue *> *arg_sids,
386 void pop_frame (tree result_lvalue,
387 const svalue **out_result,
389 const gcall *call_stmt,
390 bool eval_return_svalue = true);
391 int get_stack_depth () const;
392 const frame_region *get_frame_at_index (int index) const;
393
398
399 const region *deref_rvalue (const svalue *ptr_sval, tree ptr_tree,
401 bool add_nonnull_constraint = true) const;
402
404 const region *reg,
405 const bit_range &bits,
406 region_model_context *ctxt) const;
407
408 void set_value (const region *lhs_reg, const svalue *rhs_sval,
410 void set_value (tree lhs, tree rhs, region_model_context *ctxt);
411 void clobber_region (const region *reg);
412 void purge_region (const region *reg);
413 void fill_region (const region *reg,
414 const svalue *sval,
416 void zero_fill_region (const region *reg,
418 void write_bytes (const region *dest_reg,
419 const svalue *num_bytes_sval,
420 const svalue *sval,
422 const svalue *read_bytes (const region *src_reg,
423 tree src_ptr_expr,
424 const svalue *num_bytes_sval,
425 region_model_context *ctxt) const;
426 void copy_bytes (const region *dest_reg,
427 const region *src_reg,
428 tree src_ptr_expr,
429 const svalue *num_bytes_sval,
431 void mark_region_as_unknown (const region *reg, uncertainty_t *uncertainty);
432
434 enum tree_code op,
435 const svalue *rhs) const;
437 const region_svalue *ptr) const;
439 const svalue *b) const;
440 tristate structural_equality (const svalue *a, const svalue *b) const;
442 enum tree_code op,
443 tree rhs,
444 region_model_context *ctxt) const;
445 bool add_constraint (tree lhs, enum tree_code op, tree rhs,
447 bool add_constraint (tree lhs, enum tree_code op, tree rhs,
449 std::unique_ptr<rejected_constraint> *out);
450
451 const region *
454 bool update_state_machine = false,
455 const call_details *cd = nullptr);
456
460
462 logger *logger = nullptr) const;
464 logger *logger = nullptr) const;
468 logger *logger) const;
472 logger *logger) const;
473
474 /* For selftests. */
479
480 store *get_store () { return &m_store; }
481 const store *get_store () const { return &m_store; }
482
483 const dynamic_extents_t &
485 {
486 return m_dynamic_extents;
487 }
488 const svalue *get_dynamic_extents (const region *reg) const;
489 void set_dynamic_extents (const region *reg,
490 const svalue *size_in_bytes,
492 void unset_dynamic_extents (const region *reg);
493
496 {
497 return m_mgr->get_range_manager ();
498 }
499
501 enum poison_kind pkind);
502
503 bool can_merge_with_p (const region_model &other_model,
504 const program_point &point,
505 region_model *out_model,
506 const extrinsic_state *ext_state = nullptr,
507 const program_state *state_a = nullptr,
508 const program_state *state_b = nullptr) const;
509
514
517 unsigned HOST_WIDE_INT *out = nullptr) const;
518
520 static void append_regions_cb (const region *base_reg,
521 struct append_regions_cb_data *data);
522
523 const svalue *get_store_value (const region *reg,
524 region_model_context *ctxt) const;
525 const svalue *get_store_bytes (const region *base_reg,
526 const byte_range &bytes,
527 region_model_context *ctxt) const;
529 tree expr,
530 const svalue **out_sval,
531 region_model_context *ctxt) const;
533 tree expr,
534 const svalue **out_sval,
535 region_model_context *ctxt) const;
536
537 bool region_exists_p (const region *reg) const;
538
539 void loop_replay_fixup (const region_model *dst_state);
540
541 const svalue *get_capacity (const region *reg) const;
542
544 const region_model &summary);
545
547 const svalue *copied_sval,
548 const region *src_reg,
550
551 void set_errno (const call_details &cd);
552
553 /* Implemented in sm-fd.cc */
555
556 /* Implemented in sm-malloc.cc */
558 const svalue *old_ptr_sval,
559 const svalue *new_ptr_sval);
560
561 /* Implemented in sm-malloc.cc. */
562 void
564 const svalue *new_ptr_sval);
565
566 /* Implemented in sm-taint.cc. */
567 void mark_as_tainted (const svalue *sval,
569
570 bool add_constraint (const svalue *lhs,
571 enum tree_code op,
572 const svalue *rhs,
574
575 const svalue *check_for_poison (const svalue *sval,
576 tree expr,
577 const region *src_region,
578 region_model_context *ctxt) const;
579
580 void check_region_for_write (const region *dest_reg,
581 const svalue *sval_hint,
582 region_model_context *ctxt) const;
583
584 const svalue *
586 unsigned idx) const;
587 const svalue *
589 unsigned idx,
590 bool include_terminator,
591 const svalue **out_sval) const;
592
594 get_builtin_kf (const gcall &call,
595 region_model_context *ctxt = nullptr) const;
596
597 bool called_from_main_p () const;
598
600 {
602 }
604 {
605 if (m_thrown_exceptions_stack.empty ())
606 return nullptr;
607 return &m_thrown_exceptions_stack.back ();
608 }
610 {
612 const exception_node retval = m_thrown_exceptions_stack.back ();
613 m_thrown_exceptions_stack.pop_back ();
614 return retval;
615 }
616
618 {
620 }
622 {
623 if (m_caught_exceptions_stack.empty ())
624 return nullptr;
625 return &m_caught_exceptions_stack.back ();
626 }
628 {
630 const exception_node retval = m_caught_exceptions_stack.back ();
631 m_caught_exceptions_stack.pop_back ();
632 return retval;
633 }
634
635private:
638
642 logger *logger) const;
646 logger *logger) const;
647
649 const call_details &cd) const;
651
652 bool add_constraints_from_binop (const svalue *outer_lhs,
653 enum tree_code outer_op,
654 const svalue *outer_rhs,
655 bool *out,
657
659 enum poison_kind pkind);
660
662 bool nonnull,
664
665 const svalue *get_initial_value_for_global (const region *reg) const;
666
668
670 const svalue *size_in_bytes,
671 region_model_context *ctxt) const;
673 region_model_context *ctxt) const;
674
676 enum access_direction dir,
677 region_model_context *ctxt) const;
678
679 void check_for_writable_region (const region* dest_reg,
680 region_model_context *ctxt) const;
681 bool check_region_access (const region *reg,
682 enum access_direction dir,
683 const svalue *sval_hint,
684 region_model_context *ctxt) const;
685 bool check_region_for_read (const region *src_reg,
686 region_model_context *ctxt) const;
687 void check_region_size (const region *lhs_reg, const svalue *rhs_sval,
688 region_model_context *ctxt) const;
689
690 /* Implemented in bounds-checking.cc */
691 bool check_symbolic_bounds (const region *base_reg,
692 const svalue *sym_byte_offset,
693 const svalue *num_bytes_sval,
694 const svalue *capacity,
695 enum access_direction dir,
696 const svalue *sval_hint,
697 region_model_context *ctxt) const;
698 bool check_region_bounds (const region *reg, enum access_direction dir,
699 const svalue *sval_hint,
700 region_model_context *ctxt) const;
701
702 void check_call_args (const call_details &cd) const;
704 tree format_attr) const;
706 tree callee_fndecl,
708 rdwr_map &rdwr_idx) const;
710 tree callee_fndecl,
712 rdwr_map &rdwr_idx);
714 tree callee_fndecl,
716 rdwr_map &rdwr_idx,
717 tree attr);
718 void check_function_attrs (const gcall &call,
719 tree callee_fndecl,
721
723 tree fndecl,
725
726 /* Storing this here to avoid passing it around everywhere. */
728
730
731 constraint_manager *m_constraints; // TODO: embed, rather than dynalloc?
732
734
735 std::vector<exception_node> m_thrown_exceptions_stack;
736 std::vector<exception_node> m_caught_exceptions_stack;
737
738 /* Map from base region to size in bytes, for tracking the sizes of
739 dynamically-allocated regions.
740 This is part of the region_model rather than the region to allow for
741 memory regions to be resized (e.g. by realloc). */
743};
744
745/* Some region_model activity could lead to warnings (e.g. attempts to use an
746 uninitialized value). This abstract base class encapsulates an interface
747 for the region model to use when emitting such warnings.
748
749 Having this as an abstract base class allows us to support the various
750 operations needed by program_state in the analyzer within region_model,
751 whilst keeping them somewhat modularized. */
752
754{
755 public:
756 bool
757 warn (std::unique_ptr<pending_diagnostic> d,
758 std::unique_ptr<pending_location::fixer_for_epath> ploc_fixer = nullptr);
759
760 /* Hook for determining where diagnostics are to currently be emitted. */
761 virtual pending_location
763
764 /* Hook for clients to store pending diagnostics.
765 Return true if the diagnostic was stored, or false if it was deleted. */
766 virtual bool
767 warn_at (std::unique_ptr<pending_diagnostic> d,
768 pending_location &&ploc) = 0;
769
770 /* Hook for clients to add a note to the last previously stored
771 pending diagnostic. */
772 virtual void add_note (std::unique_ptr<pending_note> pn) = 0;
773
774 /* Hook for clients to add an event to the last previously stored
775 pending diagnostic. */
776 virtual void add_event (std::unique_ptr<checker_event> event) = 0;
777
778 /* Hook for clients to be notified when an SVAL that was reachable
779 in a previous state is no longer live, so that clients can emit warnings
780 about leaks. */
781 virtual void on_svalue_leak (const svalue *sval) = 0;
782
783 /* Hook for clients to be notified when the set of explicitly live
784 svalues changes, so that they can purge state relating to dead
785 svalues. */
786 virtual void on_liveness_change (const svalue_set &live_svalues,
787 const region_model *model) = 0;
788
789 virtual logger *get_logger () = 0;
790
791 /* Hook for clients to be notified when the condition
792 "LHS OP RHS" is added to the region model.
793 This exists so that state machines can detect tests on edges,
794 and use them to trigger sm-state transitions (e.g. transitions due
795 to ptrs becoming known to be NULL or non-NULL, rather than just
796 "unchecked") */
797 virtual void on_condition (const svalue *lhs,
798 enum tree_code op,
799 const svalue *rhs) = 0;
800
801 /* Hook for clients to be notified when the condition that
802 SVAL is within RANGES is added to the region model.
803 Similar to on_condition, but for use when handling switch statements.
804 RANGES is non-empty. */
805 virtual void on_bounded_ranges (const svalue &sval,
806 const bounded_ranges &ranges) = 0;
807
808 /* Hook for clients to be notified when a frame is popped from the stack. */
809 virtual void on_pop_frame (const frame_region *) = 0;
810
811 /* Hooks for clients to be notified when an unknown change happens
812 to SVAL (in response to a call to an unknown function). */
813 virtual void on_unknown_change (const svalue *sval, bool is_mutable) = 0;
814
815 /* Hooks for clients to be notified when a phi node is handled,
816 where RHS is the pertinent argument. */
817 virtual void on_phi (const gphi *phi, tree rhs) = 0;
818
819 /* Hooks for clients to be notified when the region model doesn't
820 know how to handle the tree code of T at LOC. */
822 const dump_location_t &loc) = 0;
823
824 /* Hook for clients to be notified when a function_decl escapes. */
825 virtual void on_escaped_function (tree fndecl) = 0;
826
828
829 /* Hook for clients to purge state involving SVAL. */
830 virtual void purge_state_involving (const svalue *sval) = 0;
831
832 /* Hook for clients to split state with a non-standard path. */
833 virtual void bifurcate (std::unique_ptr<custom_edge_info> info) = 0;
834
835 /* Hook for clients to terminate the standard path. */
836 virtual void terminate_path () = 0;
837
838 virtual const extrinsic_state *get_ext_state () const = 0;
839
840 /* Hook for clients to access the a specific state machine in
841 any underlying program_state. */
842 virtual bool
843 get_state_map_by_name (const char *name,
844 sm_state_map **out_smap,
845 const state_machine **out_sm,
846 unsigned *out_sm_idx,
847 std::unique_ptr<sm_context> *out_sm_context) = 0;
848
849 /* Precanned ways for clients to access specific state machines. */
850 bool get_fd_map (sm_state_map **out_smap,
851 const state_machine **out_sm,
852 unsigned *out_sm_idx,
853 std::unique_ptr<sm_context> *out_sm_context)
854 {
855 return get_state_map_by_name ("file-descriptor", out_smap, out_sm,
856 out_sm_idx, out_sm_context);
857 }
858 bool get_malloc_map (sm_state_map **out_smap,
859 const state_machine **out_sm,
860 unsigned *out_sm_idx)
861 {
862 return get_state_map_by_name ("malloc", out_smap, out_sm, out_sm_idx,
863 nullptr);
864 }
865 bool get_taint_map (sm_state_map **out_smap,
866 const state_machine **out_sm,
867 unsigned *out_sm_idx)
868 {
869 return get_state_map_by_name ("taint", out_smap, out_sm, out_sm_idx,
870 nullptr);
871 }
872
873 bool possibly_tainted_p (const svalue *sval);
874
875 /* Get the current statement, if any. */
876 virtual const gimple *get_stmt () const = 0;
877
878 virtual const exploded_graph *get_eg () const = 0;
879
880 virtual const program_state *get_state () const = 0;
881
882 /* Hooks for detecting infinite loops. */
883 virtual void maybe_did_work () = 0;
884 virtual bool checking_for_infinite_loop_p () const = 0;
885 virtual void on_unusable_in_infinite_loop () = 0;
886};
887
888/* A "do nothing" subclass of region_model_context. */
889
891{
892public:
895 {
896 return pending_location ();
897 }
898 bool
899 warn_at (std::unique_ptr<pending_diagnostic>,
900 pending_location &&) override
901 {
902 return false;
903 }
904 void add_note (std::unique_ptr<pending_note>) override;
905 void add_event (std::unique_ptr<checker_event>) override;
906 void on_svalue_leak (const svalue *) override {}
908 const region_model *) override {}
909 logger *get_logger () override { return nullptr; }
910 void on_condition (const svalue *lhs ATTRIBUTE_UNUSED,
911 enum tree_code op ATTRIBUTE_UNUSED,
912 const svalue *rhs ATTRIBUTE_UNUSED) override
913 {
914 }
916 const bounded_ranges &) override
917 {
918 }
919 void on_pop_frame (const frame_region *) override {}
920 void on_unknown_change (const svalue *sval ATTRIBUTE_UNUSED,
921 bool is_mutable ATTRIBUTE_UNUSED) override
922 {
923 }
924 void on_phi (const gphi *phi ATTRIBUTE_UNUSED,
925 tree rhs ATTRIBUTE_UNUSED) override
926 {
927 }
928 void on_unexpected_tree_code (tree, const dump_location_t &) override {}
929
930 void on_escaped_function (tree) override {}
931
932 uncertainty_t *get_uncertainty () override { return nullptr; }
933
934 void purge_state_involving (const svalue *sval ATTRIBUTE_UNUSED) override {}
935
936 void bifurcate (std::unique_ptr<custom_edge_info> info) override;
937 void terminate_path () override;
938
939 const extrinsic_state *get_ext_state () const override { return nullptr; }
940
941 bool get_state_map_by_name (const char *,
942 sm_state_map **,
943 const state_machine **,
944 unsigned *,
945 std::unique_ptr<sm_context> *) override
946 {
947 return false;
948 }
949
950 const gimple *get_stmt () const override { return nullptr; }
951 const exploded_graph *get_eg () const override { return nullptr; }
952 const program_state *get_state () const override { return nullptr; }
953
954 void maybe_did_work () override {}
955 bool checking_for_infinite_loop_p () const override { return false; }
957};
958
959/* A subclass of region_model_context for determining if operations fail
960 e.g. "can we generate a region for the lvalue of EXPR?". */
961
963{
964public:
966
968 final override
969 {
971 }
972
973 bool had_errors_p () const { return m_num_unexpected_codes > 0; }
974
975private:
977};
978
979/* Subclass of region_model_context that wraps another context, allowing
980 for extra code to be added to the various hooks. */
981
983{
984 public:
987 {
988 if (m_inner)
989 return m_inner->get_pending_location_for_diag ();
990 else
991 return pending_location ();
992 }
993
994 bool
995 warn_at (std::unique_ptr<pending_diagnostic> d,
996 pending_location &&ploc) override
997 {
998 if (m_inner)
999 return m_inner->warn_at (std::move (d), std::move (ploc));
1000 else
1001 return false;
1002 }
1003
1004 void add_note (std::unique_ptr<pending_note> pn) override
1005 {
1006 if (m_inner)
1007 m_inner->add_note (std::move (pn));
1008 }
1009 void add_event (std::unique_ptr<checker_event> event) override;
1010
1011 void on_svalue_leak (const svalue *sval) override
1012 {
1013 if (m_inner)
1014 m_inner->on_svalue_leak (sval);
1015 }
1016
1017 void on_liveness_change (const svalue_set &live_svalues,
1018 const region_model *model) override
1019 {
1020 if (m_inner)
1021 m_inner->on_liveness_change (live_svalues, model);
1022 }
1023
1024 logger *get_logger () override
1025 {
1026 if (m_inner)
1027 return m_inner->get_logger ();
1028 else
1029 return nullptr;
1030 }
1031
1032 void on_condition (const svalue *lhs,
1033 enum tree_code op,
1034 const svalue *rhs) override
1035 {
1036 if (m_inner)
1037 m_inner->on_condition (lhs, op, rhs);
1038 }
1039
1040 void on_bounded_ranges (const svalue &sval,
1041 const bounded_ranges &ranges) override
1042 {
1043 if (m_inner)
1044 m_inner->on_bounded_ranges (sval, ranges);
1045 }
1046
1047 void on_pop_frame (const frame_region *frame_reg) override
1048 {
1049 if (m_inner)
1050 m_inner->on_pop_frame (frame_reg);
1051 }
1052
1053 void on_unknown_change (const svalue *sval, bool is_mutable) override
1054 {
1055 if (m_inner)
1056 m_inner->on_unknown_change (sval, is_mutable);
1057 }
1058
1059 void on_phi (const gphi *phi, tree rhs) override
1060 {
1061 if (m_inner)
1062 m_inner->on_phi (phi, rhs);
1063 }
1064
1066 const dump_location_t &loc) override
1067 {
1068 if (m_inner)
1069 m_inner->on_unexpected_tree_code (t, loc);
1070 }
1071
1072 void on_escaped_function (tree fndecl) override
1073 {
1074 if (m_inner)
1075 m_inner->on_escaped_function (fndecl);
1076 }
1077
1079 {
1080 if (m_inner)
1081 return m_inner->get_uncertainty ();
1082 else
1083 return nullptr;
1084 }
1085
1086 void purge_state_involving (const svalue *sval) override
1087 {
1088 if (m_inner)
1089 m_inner->purge_state_involving (sval);
1090 }
1091
1092 void bifurcate (std::unique_ptr<custom_edge_info> info) override
1093 {
1094 if (m_inner)
1095 m_inner->bifurcate (std::move (info));
1096 }
1097
1098 void terminate_path () override
1099 {
1100 if (m_inner)
1101 m_inner->terminate_path ();
1102 }
1103
1104 const extrinsic_state *get_ext_state () const override
1105 {
1106 if (m_inner)
1107 return m_inner->get_ext_state ();
1108 else
1109 return nullptr;
1110 }
1111
1112 bool get_state_map_by_name (const char *name,
1113 sm_state_map **out_smap,
1114 const state_machine **out_sm,
1115 unsigned *out_sm_idx,
1116 std::unique_ptr<sm_context> *out_sm_context)
1117 override
1118 {
1119 if (m_inner)
1120 return m_inner->get_state_map_by_name (name, out_smap, out_sm, out_sm_idx,
1121 out_sm_context);
1122 else
1123 return false;
1124 }
1125
1126 const gimple *get_stmt () const override
1127 {
1128 if (m_inner)
1129 return m_inner->get_stmt ();
1130 else
1131 return nullptr;
1132 }
1133
1134 const exploded_graph *get_eg () const override
1135 {
1136 if (m_inner)
1137 return m_inner->get_eg ();
1138 else
1139 return nullptr;
1140 }
1141
1142 const program_state *get_state () const override
1143 {
1144 if (m_inner)
1145 return m_inner->get_state ();
1146 else
1147 return nullptr;
1148 }
1149
1150 void maybe_did_work () override
1151 {
1152 if (m_inner)
1153 m_inner->maybe_did_work ();
1154 }
1155
1156 bool checking_for_infinite_loop_p () const override
1157 {
1158 if (m_inner)
1159 return m_inner->checking_for_infinite_loop_p ();
1160 return false;
1161 }
1163 {
1164 if (m_inner)
1165 m_inner->on_unusable_in_infinite_loop ();
1166 }
1167
1168protected:
1170 : m_inner (inner)
1171 {
1172 }
1173
1175};
1176
1177/* Subclass of region_model_context_decorator with a hook for adding
1178 notes/events when saving diagnostics. */
1179
1181{
1182public:
1183 bool
1184 warn_at (std::unique_ptr<pending_diagnostic> d,
1185 pending_location &&ploc) override
1186 {
1187 if (m_inner)
1188 if (m_inner->warn_at (std::move (d), std::move (ploc)))
1189 {
1190 add_annotations ();
1191 return true;
1192 }
1193 return false;
1194 }
1195
1196 /* Hook to add new event(s)/note(s) */
1197 virtual void add_annotations () = 0;
1198
1199protected:
1204};
1205
1206/* A bundle of data for use when attempting to merge two region_model
1207 instances to make a third. */
1208
1210{
1212 const region_model *model_b,
1213 const program_point &point,
1214 region_model *merged_model,
1216 const program_state *state_a,
1217 const program_state *state_b)
1218 : m_model_a (model_a), m_model_b (model_b),
1219 m_point (point),
1220 m_merged_model (merged_model),
1222 m_state_a (state_a), m_state_b (state_b)
1223 {
1224 }
1225
1226 void dump_to_pp (pretty_printer *pp, bool simple) const;
1227 void dump (FILE *fp, bool simple) const;
1228 void dump (bool simple) const;
1229
1231 {
1232 return m_model_a->get_manager ();
1233 }
1234
1235 bool mergeable_svalue_p (const svalue *) const;
1236
1237 const supernode *get_supernode () const
1238 {
1239 return m_point.get_supernode ();
1240 }
1241
1242 void on_widening_reuse (const widening_svalue *widening_sval);
1243
1248
1252
1254};
1255
1256/* A record that can (optionally) be written out when
1257 region_model::add_constraint fails. */
1258
1260{
1261public:
1263 virtual void dump_to_pp (pretty_printer *pp) const = 0;
1264
1265 const region_model &get_model () const { return m_model; }
1266
1267protected:
1269 : m_model (model)
1270 {}
1271
1273};
1274
1276{
1277public:
1279 const svalue *lhs, enum tree_code op, const svalue *rhs)
1280 : rejected_constraint (model),
1281 m_lhs (lhs), m_op (op), m_rhs (rhs)
1282 {}
1283
1284 void dump_to_pp (pretty_printer *pp) const final override;
1285
1289};
1290
1292{
1293public:
1295 : rejected_constraint (model)
1296 {}
1297
1298 void dump_to_pp (pretty_printer *pp) const final override;
1299};
1300
1302{
1303public:
1305 tree expr, const bounded_ranges *ranges)
1306 : rejected_constraint (model),
1307 m_expr (expr), m_ranges (ranges)
1308 {}
1309
1310 void dump_to_pp (pretty_printer *pp) const final override;
1311
1312private:
1315};
1316
1317/* A bundle of state. */
1318
1320{
1321public:
1323 const supergraph *sg = nullptr);
1324 const supergraph *get_supergraph () { return m_sg; }
1327 {
1328 return m_mgr.get_known_function_manager ();
1329 }
1330
1331 void log_stats (logger *logger) const;
1332
1333private:
1336};
1337
1338/* Factory functions for various diagnostics. */
1339
1340extern std::unique_ptr<pending_diagnostic>
1342 const region *src_region,
1343 tree check_expr);
1344
1345extern std::unique_ptr<pending_diagnostic>
1347 tree count_cst,
1348 const region *src_region);
1349
1350extern std::unique_ptr<pending_diagnostic>
1352 int operand_precision,
1353 tree count_cst,
1354 const region *src_region);
1355
1356extern std::unique_ptr<pending_diagnostic>
1358
1359extern std::unique_ptr<pending_diagnostic>
1361
1362} // namespace ana
1363
1364extern void debug (const region_model &rmodel);
1365
1366namespace ana {
1367
1368#if CHECKING_P
1369
1370namespace selftest {
1371
1372using namespace ::selftest;
1373
1374/* An implementation of region_model_context for use in selftests, which
1375 stores any pending_diagnostic instances passed to it. */
1376
1377class test_region_model_context : public noop_region_model_context
1378{
1379public:
1380 bool
1381 warn_at (std::unique_ptr<pending_diagnostic> d,
1382 pending_location &&) final override
1383 {
1384 m_diagnostics.safe_push (d.release ());
1385 return true;
1386 }
1387
1388 unsigned get_num_diagnostics () const { return m_diagnostics.length (); }
1389
1390 void on_unexpected_tree_code (tree t, const dump_location_t &)
1391 final override
1392 {
1393 internal_error ("unhandled tree code: %qs",
1395 }
1396
1397private:
1398 /* Implicitly delete any diagnostics in the dtor. */
1399 auto_delete_vec<pending_diagnostic> m_diagnostics;
1400};
1401
1402/* Attempt to add the constraint (LHS OP RHS) to MODEL.
1403 Verify that MODEL remains satisfiable. */
1404
1405#define ADD_SAT_CONSTRAINT(MODEL, LHS, OP, RHS) \
1406 SELFTEST_BEGIN_STMT \
1407 bool sat = (MODEL).add_constraint (LHS, OP, RHS, nullptr); \
1408 ASSERT_TRUE (sat); \
1409 SELFTEST_END_STMT
1410
1411/* Attempt to add the constraint (LHS OP RHS) to MODEL.
1412 Verify that the result is not satisfiable. */
1413
1414#define ADD_UNSAT_CONSTRAINT(MODEL, LHS, OP, RHS) \
1415 SELFTEST_BEGIN_STMT \
1416 bool sat = (MODEL).add_constraint (LHS, OP, RHS, nullptr); \
1417 ASSERT_FALSE (sat); \
1418 SELFTEST_END_STMT
1419
1420/* Implementation detail of the ASSERT_CONDITION_* macros. */
1421
1422void assert_condition (const location &loc,
1423 region_model &model,
1424 const svalue *lhs, tree_code op, const svalue *rhs,
1425 tristate expected);
1426
1427void assert_condition (const location &loc,
1428 region_model &model,
1429 tree lhs, tree_code op, tree rhs,
1430 tristate expected);
1431
1432/* Assert that REGION_MODEL evaluates the condition "LHS OP RHS"
1433 as "true". */
1434
1435#define ASSERT_CONDITION_TRUE(REGION_MODEL, LHS, OP, RHS) \
1436 SELFTEST_BEGIN_STMT \
1437 assert_condition (SELFTEST_LOCATION, REGION_MODEL, LHS, OP, RHS, \
1438 tristate (tristate::TS_TRUE)); \
1439 SELFTEST_END_STMT
1440
1441/* Assert that REGION_MODEL evaluates the condition "LHS OP RHS"
1442 as "false". */
1443
1444#define ASSERT_CONDITION_FALSE(REGION_MODEL, LHS, OP, RHS) \
1445 SELFTEST_BEGIN_STMT \
1446 assert_condition (SELFTEST_LOCATION, REGION_MODEL, LHS, OP, RHS, \
1447 tristate (tristate::TS_FALSE)); \
1448 SELFTEST_END_STMT
1449
1450/* Assert that REGION_MODEL evaluates the condition "LHS OP RHS"
1451 as "unknown". */
1452
1453#define ASSERT_CONDITION_UNKNOWN(REGION_MODEL, LHS, OP, RHS) \
1454 SELFTEST_BEGIN_STMT \
1455 assert_condition (SELFTEST_LOCATION, REGION_MODEL, LHS, OP, RHS, \
1456 tristate (tristate::TS_UNKNOWN)); \
1457 SELFTEST_END_STMT
1458
1459} /* end of namespace selftest. */
1460
1461#endif /* #if CHECKING_P */
1462
1463} // namespace ana
1464
1465#endif /* GCC_ANALYZER_REGION_MODEL_H */
hash_map< rdwr_access_hash, attr_access > rdwr_map
Definition attribs.h:402
bool warn_at(std::unique_ptr< pending_diagnostic > d, pending_location &&ploc) override
Definition region-model.h:1184
virtual void add_annotations()=0
annotating_context(region_model_context *inner)
Definition region-model.h:1200
Definition svalue.h:1655
Definition svalue.h:815
Definition svalue.h:1101
Definition constraint-manager.h:178
Definition common.h:343
Definition call-details.h:31
Definition call-summary.h:68
Definition svalue.h:1418
Definition svalue.h:1553
Definition svalue.h:1801
Definition svalue.h:317
Definition constraint-manager.h:410
known_function_manager * get_known_function_manager()
Definition region-model.h:1326
const supergraph * get_supergraph()
Definition region-model.h:1324
const supergraph * m_sg
Definition region-model.h:1335
region_model_manager * get_model_manager()
Definition region-model.h:1325
void log_stats(logger *logger) const
engine(region_model_manager &mgr, const supergraph *sg=nullptr)
region_model_manager & m_mgr
Definition region-model.h:1334
Definition exploded-graph.h:790
Definition exploded-graph.h:206
Definition program-state.h:34
Definition region.h:320
Definition svalue.h:672
Definition known-function-manager.h:41
Definition common.h:314
Definition analyzer-logging.h:36
Definition region-model.h:891
const program_state * get_state() const override
Definition region-model.h:952
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:941
bool checking_for_infinite_loop_p() const override
Definition region-model.h:955
void maybe_did_work() override
Definition region-model.h:954
uncertainty_t * get_uncertainty() override
Definition region-model.h:932
void on_unexpected_tree_code(tree, const dump_location_t &) override
Definition region-model.h:928
void on_unknown_change(const svalue *sval, bool is_mutable) override
Definition region-model.h:920
void on_pop_frame(const frame_region *) override
Definition region-model.h:919
void on_phi(const gphi *phi, tree rhs) override
Definition region-model.h:924
void on_condition(const svalue *lhs, enum tree_code op, const svalue *rhs) override
Definition region-model.h:910
void add_event(std::unique_ptr< checker_event >) override
void on_liveness_change(const svalue_set &, const region_model *) override
Definition region-model.h:907
logger * get_logger() override
Definition region-model.h:909
void on_escaped_function(tree) override
Definition region-model.h:930
const exploded_graph * get_eg() const override
Definition region-model.h:951
const gimple * get_stmt() const override
Definition region-model.h:950
pending_location get_pending_location_for_diag() const override
Definition region-model.h:894
void on_unusable_in_infinite_loop() override
Definition region-model.h:956
bool warn_at(std::unique_ptr< pending_diagnostic >, pending_location &&) override
Definition region-model.h:899
void on_svalue_leak(const svalue *) override
Definition region-model.h:906
void add_note(std::unique_ptr< pending_note >) override
void purge_state_involving(const svalue *sval) override
Definition region-model.h:934
const extrinsic_state * get_ext_state() const override
Definition region-model.h:939
void on_bounded_ranges(const svalue &, const bounded_ranges &) override
Definition region-model.h:915
void bifurcate(std::unique_ptr< custom_edge_info > info) override
void put(T src, T dst)
Definition region-model.h:82
void dump() const
Definition region-model.h:124
T get_dst_for_src(T src) const
Definition region-model.h:91
void dump_to_pp(pretty_printer *pp) const
Definition region-model.h:102
auto_vec< T > m_src_to_dst
Definition region-model.h:63
void update(T *) const
Definition region-model.h:136
one_way_id_map(int num_ids)
Definition region-model.h:71
Definition common.h:179
Definition svalue.h:1250
Definition svalue.h:467
Definition program-point.h:54
Definition program-state.h:224
Definition region-model-reachability.h:36
region_model_context * m_inner
Definition region-model.h:1174
const exploded_graph * get_eg() const override
Definition region-model.h:1134
void on_bounded_ranges(const svalue &sval, const bounded_ranges &ranges) override
Definition region-model.h:1040
void on_phi(const gphi *phi, tree rhs) override
Definition region-model.h:1059
void add_event(std::unique_ptr< checker_event > event) override
const extrinsic_state * get_ext_state() const override
Definition region-model.h:1104
void on_condition(const svalue *lhs, enum tree_code op, const svalue *rhs) override
Definition region-model.h:1032
const gimple * get_stmt() const override
Definition region-model.h:1126
void maybe_did_work() override
Definition region-model.h:1150
const program_state * get_state() const override
Definition region-model.h:1142
void on_pop_frame(const frame_region *frame_reg) override
Definition region-model.h:1047
uncertainty_t * get_uncertainty() override
Definition region-model.h:1078
void bifurcate(std::unique_ptr< custom_edge_info > info) override
Definition region-model.h:1092
void add_note(std::unique_ptr< pending_note > pn) override
Definition region-model.h:1004
void on_svalue_leak(const svalue *sval) override
Definition region-model.h:1011
pending_location get_pending_location_for_diag() const override
Definition region-model.h:986
bool checking_for_infinite_loop_p() const override
Definition region-model.h:1156
logger * get_logger() override
Definition region-model.h:1024
region_model_context_decorator(region_model_context *inner)
Definition region-model.h:1169
void purge_state_involving(const svalue *sval) override
Definition region-model.h:1086
void on_liveness_change(const svalue_set &live_svalues, const region_model *model) override
Definition region-model.h:1017
void on_unexpected_tree_code(tree t, const dump_location_t &loc) override
Definition region-model.h:1065
void on_escaped_function(tree fndecl) override
Definition region-model.h:1072
bool warn_at(std::unique_ptr< pending_diagnostic > d, pending_location &&ploc) override
Definition region-model.h:995
void terminate_path() override
Definition region-model.h:1098
void on_unknown_change(const svalue *sval, bool is_mutable) override
Definition region-model.h:1053
void on_unusable_in_infinite_loop() override
Definition region-model.h:1162
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:1112
Definition region-model.h:754
virtual void on_bounded_ranges(const svalue &sval, const bounded_ranges &ranges)=0
virtual bool warn_at(std::unique_ptr< pending_diagnostic > d, pending_location &&ploc)=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
bool get_malloc_map(sm_state_map **out_smap, const state_machine **out_sm, unsigned *out_sm_idx)
Definition region-model.h:858
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:850
virtual void add_note(std::unique_ptr< pending_note > pn)=0
virtual pending_location get_pending_location_for_diag() const =0
virtual logger * get_logger()=0
virtual const extrinsic_state * get_ext_state() const =0
bool possibly_tainted_p(const svalue *sval)
virtual const program_state * get_state() const =0
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:865
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
bool warn(std::unique_ptr< pending_diagnostic > d, std::unique_ptr< pending_location::fixer_for_epath > ploc_fixer=nullptr)
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:294
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_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:480
constraint_manager * get_constraints()
Definition region-model.h:475
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)
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
void update_for_return_gcall(const gcall &call_stmt, region_model_context *ctxt)
bounded_ranges_manager * get_range_manager() const
Definition region-model.h:495
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
const builtin_known_function * get_builtin_kf(const gcall &call, region_model_context *ctxt=nullptr) 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:731
const exception_node * get_current_thrown_exception() const
Definition region-model.h:603
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 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:729
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:304
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:617
void poison_any_pointers_to_descendents(const region *reg, enum poison_kind pkind)
void update_for_gcall(const gcall &call_stmt, region_model_context *ctxt, function *callee=nullptr)
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:736
tristate compare_initial_and_pointer(const initial_svalue *init, const region_svalue *ptr) const
exception_node pop_thrown_exception()
Definition region-model.h:609
const function * get_current_function() const
const svalue * get_store_bytes(const region *base_reg, const byte_range &bytes, 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=nullptr, const program_state *state_a=nullptr, const program_state *state_b=nullptr) const
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:599
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:296
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)
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:384
std::unique_ptr< json::object > to_json() const
region_model_manager *const m_mgr
Definition region-model.h:727
const frame_region * m_current_frame
Definition region-model.h:733
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)
tree get_fndecl_for_virtual_call(const_tree fn_ptr, region_model_context *ctxt)
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:494
const known_function * get_known_function(tree fndecl, const call_details &cd) const
const exception_node * get_current_caught_exception() const
Definition region-model.h:621
tree get_vtable_from_obj(tree obj, tree obj_type, region_model_manager *mgr, region_model_context *ctxt, unsigned HOST_WIDE_INT *out=nullptr) const
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 on_setjmp(const gcall &stmt, const exploded_node &enode, const superedge &sedge, region_model_context *ctxt)
void check_for_writable_region(const region *dest_reg, region_model_context *ctxt) const
void update_for_null_return(const call_details &cd, bool unmergeable)
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:735
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:481
dynamic_extents_t m_dynamic_extents
Definition region-model.h:742
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:627
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 unbind_region_and_descendents(const region *reg, enum poison_kind pkind)
const dynamic_extents_t & get_dynamic_extents() const
Definition region-model.h:484
Definition svalue.h:229
Definition region-model.h:144
void remove(const region *reg)
Definition region-model.h:171
iterator begin() const
Definition region-model.h:160
const svalue *const * get(const region *reg) const
Definition region-model.h:163
hash_map_t::iterator iterator
Definition region-model.h:147
hash_map_t m_hash_map
Definition region-model.h:192
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:146
bool operator==(const region_to_value_map &other) const
iterator end() const
Definition region-model.h:161
void put(const region *reg, const svalue *sval)
Definition region-model.h:167
bool is_empty() const
Definition region-model.h:176
region_to_value_map & operator=(const region_to_value_map &other)
region_to_value_map()
Definition region-model.h:149
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:155
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:150
Definition region.h:127
virtual ~rejected_constraint()
Definition region-model.h:1262
virtual void dump_to_pp(pretty_printer *pp) const =0
rejected_constraint(const region_model &model)
Definition region-model.h:1268
const region_model & get_model() const
Definition region-model.h:1265
region_model m_model
Definition region-model.h:1272
void dump_to_pp(pretty_printer *pp) const final override
rejected_default_case(const region_model &model)
Definition region-model.h:1294
const svalue * m_lhs
Definition region-model.h:1286
void dump_to_pp(pretty_printer *pp) const final override
enum tree_code m_op
Definition region-model.h:1287
rejected_op_constraint(const region_model &model, const svalue *lhs, enum tree_code op, const svalue *rhs)
Definition region-model.h:1278
const svalue * m_rhs
Definition region-model.h:1288
void dump_to_pp(pretty_printer *pp) const final override
tree m_expr
Definition region-model.h:1313
const bounded_ranges * m_ranges
Definition region-model.h:1314
rejected_ranges_constraint(const region_model &model, tree expr, const bounded_ranges *ranges)
Definition region-model.h:1304
Definition svalue.h:1005
Definition svalue.h:586
Definition program-state.h:92
Definition sm.h:43
Definition store.h:923
Definition svalue.h:919
Definition supergraph.h:281
Definition supergraph.h:105
Definition supergraph.h:224
Definition svalue.h:92
int m_num_unexpected_codes
Definition region-model.h:976
bool had_errors_p() const
Definition region-model.h:973
void on_unexpected_tree_code(tree, const dump_location_t &) final override
Definition region-model.h:967
tentative_region_model_context()
Definition region-model.h:965
Definition svalue.h:720
Definition store.h:162
Definition svalue.h:415
Definition svalue.h:1203
Definition region-model.h:223
virtual void visit_unknown_svalue(const unknown_svalue *)
Definition region-model.h:227
virtual void visit_poisoned_svalue(const poisoned_svalue *)
Definition region-model.h:228
virtual void visit_asm_output_svalue(const asm_output_svalue *)
Definition region-model.h:241
virtual void visit_unaryop_svalue(const unaryop_svalue *)
Definition region-model.h:231
virtual void visit_region_svalue(const region_svalue *)
Definition region-model.h:225
virtual void visit_initial_svalue(const initial_svalue *)
Definition region-model.h:230
virtual void visit_sub_svalue(const sub_svalue *)
Definition region-model.h:233
virtual void visit_setjmp_svalue(const setjmp_svalue *)
Definition region-model.h:229
virtual void visit_conjured_svalue(const conjured_svalue *)
Definition region-model.h:240
virtual void visit_placeholder_svalue(const placeholder_svalue *)
Definition region-model.h:237
virtual void visit_binop_svalue(const binop_svalue *)
Definition region-model.h:232
virtual void visit_const_fn_result_svalue(const const_fn_result_svalue *)
Definition region-model.h:242
virtual void visit_compound_svalue(const compound_svalue *)
Definition region-model.h:239
virtual void visit_unmergeable_svalue(const unmergeable_svalue *)
Definition region-model.h:236
virtual void visit_widening_svalue(const widening_svalue *)
Definition region-model.h:238
virtual void visit_bits_within_svalue(const bits_within_svalue *)
Definition region-model.h:235
virtual void visit_constant_svalue(const constant_svalue *)
Definition region-model.h:226
virtual void visit_region(const region *)
Definition region-model.h:244
virtual void visit_repeated_svalue(const repeated_svalue *)
Definition region-model.h:234
Definition svalue.h:1298
Definition bitmap.h:950
Definition vec.h:1667
Definition genoutput.cc:150
Definition dumpfile.h:446
Definition genmatch.cc:1507
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
bool debug
Definition collect-utils.cc:34
const union tree_node * const_tree
Definition coretypes.h:98
union tree_node * tree
Definition coretypes.h:97
void internal_error(const char *,...) ATTRIBUTE_GCC_DIAG(1
void final(rtx_insn *first, FILE *file, int optimize_p)
Definition final.cc:2003
internal_fn
Definition genmatch.cc:1015
tree_code
Definition genmatch.cc:1002
Definition access-diagram.h:30
std::unique_ptr< pending_diagnostic > make_write_to_const_diagnostic(const region *dest_reg, tree decl)
@ stmt
Definition checker-event.h:38
std::unique_ptr< pending_diagnostic > make_shift_count_negative_diagnostic(const gassign *assign, tree count_cst, const region *src_region)
access_direction
Definition common.h:388
std::unique_ptr< pending_diagnostic > make_poisoned_value_diagnostic(tree expr, enum poison_kind pkind, const region *src_region, tree check_expr)
std::unique_ptr< pending_diagnostic > make_write_to_string_literal_diagnostic(const region *reg)
poison_kind
Definition svalue.h:447
std::unique_ptr< pending_diagnostic > make_shift_count_overflow_diagnostic(const gassign *assign, int operand_precision, tree count_cst, const region *src_region)
hash_set< const svalue * > svalue_set
Definition common.h:76
memory_space
Definition region.h:33
Definition custom-sarif-properties/state-graphs.h:33
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:2462
void pp_newline(pretty_printer *pp)
Definition pretty-print.cc:2737
void pp_string(pretty_printer *pp, const char *str)
Definition pretty-print.cc:2764
Definition store.h:234
Definition constraint-manager.h:123
Definition store.h:328
Definition region-model.h:253
void dump() const
exception_node(const svalue *exception_sval, const svalue *typeinfo_sval, const svalue *destructor_sval)
Definition region-model.h:254
const svalue * m_exception_sval
Definition region-model.h:279
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:280
const svalue * m_destructor_sval
Definition region-model.h:281
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:1246
const program_state * m_state_a
Definition region-model.h:1250
const region_model * m_model_a
Definition region-model.h:1244
const extrinsic_state * m_ext_state
Definition region-model.h:1249
hash_set< const svalue * > m_svals_changing_meaning
Definition region-model.h:1253
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:1211
const program_state * m_state_b
Definition region-model.h:1251
const supernode * get_supernode() const
Definition region-model.h:1237
bool mergeable_svalue_p(const svalue *) const
void dump(bool simple) const
region_model_manager * get_manager() const
Definition region-model.h:1230
void on_widening_reuse(const widening_svalue *widening_sval)
region_model * m_merged_model
Definition region-model.h:1247
void dump(FILE *fp, bool simple) const
const region_model * m_model_b
Definition region-model.h:1245
Definition diagnostic-manager.h:35
int m_num_equiv_classes
Definition region-model.h:213
int m_num_bounded_ranges_constraints
Definition region-model.h:215
int m_num_client_items
Definition region-model.h:216
int m_num_svalues
Definition region-model.h:211
purge_stats()
Definition region-model.h:202
int m_num_constraints
Definition region-model.h:214
int m_num_regions
Definition region-model.h:212
Definition genautomata.cc:499
Definition function.h:249
Definition gimple.h:552
Definition gimple.h:910
Definition gimple.h:355
Definition gimple.h:224
Definition gimple.h:464
Definition gimple.h:920
Definition dump-widget-info.h:31
Definition gengtype.h:252
Definition vec.h:450
#define gcc_assert(EXPR)
Definition system.h:828
#define DEBUG_FUNCTION
Definition system.h:1200
static bitmap visited
Definition tree-ssa-dce.cc:664
static control_dependences * cd
Definition tree-ssa-dce.cc:105
const char * get_tree_code_name(enum tree_code code)
Definition tree.cc:13203
#define TREE_CODE(NODE)
Definition tree.h:325
tree size_in_bytes(const_tree t)
Definition tree.h:5327
#define FOR_EACH_VEC_ELT(V, I, P)
Definition vec.h:1895