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