GCC Middle and Back End API Reference
exploded-graph.h
Go to the documentation of this file.
1/* Classes for managing a directed graph of <point, state> pairs.
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_EXPLODED_GRAPH_H
22#define GCC_ANALYZER_EXPLODED_GRAPH_H
23
24#include "alloc-pool.h"
25#include "fibonacci_heap.h"
26#include "supergraph.h"
27#include "sbitmap.h"
28#include "shortest-paths.h"
29#include "analyzer/sm.h"
33
34namespace ana {
35
36/* Concrete implementation of region_model_context, wiring it up to the
37 rest of the analysis engine. */
38
40{
41 public:
43 exploded_node *enode_for_diag,
44
45 /* TODO: should we be getting the ECs from the
46 old state, rather than the new? */
47 const program_state *old_state,
48 program_state *new_state,
49 uncertainty_t *uncertainty,
50 path_context *path_ctxt,
51 const gimple *stmt = nullptr,
52 bool *out_could_have_done_work = nullptr);
53
56 uncertainty_t *uncertainty,
57 logger *logger = nullptr);
58
59 bool
60 warn_at (std::unique_ptr<pending_diagnostic> d,
61 pending_location &&ploc) final override;
62 void add_note (std::unique_ptr<pending_note> pn) final override;
63 void add_event (std::unique_ptr<checker_event> event) final override;
64 void on_svalue_leak (const svalue *) override;
65 void on_liveness_change (const svalue_set &live_svalues,
66 const region_model *model) final override;
67 logger *get_logger () final override
68 {
69 return m_logger.get_logger ();
70 }
71
73 const svalue *sval,
75
76 void on_condition (const svalue *lhs,
77 enum tree_code op,
78 const svalue *rhs) final override;
79
80 void on_bounded_ranges (const svalue &sval,
81 const bounded_ranges &ranges) final override;
82
83 void on_pop_frame (const frame_region *frame_reg) final override;
84
85 void on_unknown_change (const svalue *sval, bool is_mutable) final override;
86
87 void on_phi (const gphi *phi, tree rhs) final override;
88
90 const dump_location_t &loc) final override;
91
92 void on_escaped_function (tree fndecl) final override;
93
95
96 void purge_state_involving (const svalue *sval) final override;
97
98 void bifurcate (std::unique_ptr<custom_edge_info> info) final override;
99 void terminate_path () final override;
100 const extrinsic_state *get_ext_state () const final override
101 {
102 return &m_ext_state;
103 }
104 bool
105 get_state_map_by_name (const char *name,
106 sm_state_map **out_smap,
107 const state_machine **out_sm,
108 unsigned *out_sm_idx,
109 std::unique_ptr<sm_context> *out_sm_context) override;
110
111 const gimple *get_stmt () const override { return m_stmt; }
112 const exploded_graph *get_eg () const override { return m_eg; }
113
114 const program_state *get_state () const override { return m_new_state; }
115
116 void maybe_did_work () override;
117 bool checking_for_infinite_loop_p () const override { return false; }
119
122
133};
134
135/* A <program_point, program_state> pair, used internally by
136 exploded_node as its immutable data, and as a key for identifying
137 exploded_nodes we've already seen in the graph. */
138
140{
141public:
143 const program_state &state)
144 : m_point (point),
145 m_state (state),
146 m_hash (m_point.hash () ^ m_state.hash ())
147 {
148 /* We shouldn't be building point_and_states and thus exploded_nodes
149 for states that aren't valid. */
150 gcc_assert (state.m_valid);
151 }
152
153 point_and_state (const point_and_state &other) = default;
154
156 : m_point (other.m_point),
157 m_state (std::move (other.m_state)),
158 m_hash (other.m_hash)
159 {
160 }
161
162 hashval_t hash () const
163 {
164 return m_hash;
165 }
166 bool operator== (const point_and_state &other) const
167 {
168 return m_point == other.m_point && m_state == other.m_state;
169 }
170
171 const program_point &get_point () const { return m_point; }
172 const program_state &get_state () const { return m_state; }
173
175 {
176 m_state = state;
177 m_hash = m_point.hash () ^ m_state.hash ();
178 }
179
181 {
182 m_state = std::move (state);
183 m_hash = m_point.hash () ^ m_state.hash ();
184 }
185
186 void validate (const extrinsic_state &ext_state) const;
187
188private:
191 hashval_t m_hash;
192};
193
194/* A traits class for exploded graphs and their nodes and edges. */
195
197{
202 {
203 dump_args_t (const exploded_graph &eg) : m_eg (eg) {}
204
205 bool show_enode_details_p (const exploded_node &enode) const;
206
207 virtual void
209
211 };
212 typedef exploded_cluster cluster_t;
213};
214
215/* An exploded_node is a unique, immutable <point, state> pair within the
216 exploded_graph.
217 Each exploded_node has a unique index within the graph
218 (for ease of debugging). */
219
220class exploded_node : public dnode<eg_traits>
221{
222 public:
223 /* Has this enode had exploded_graph::process_node called on it?
224 This allows us to distinguish enodes that were merged during
225 worklist-handling, and thus never had process_node called on them
226 (in favor of processing the merged node). */
227 enum class status
228 {
229 /* Node is in the worklist. */
231
232 /* Node has had exploded_graph::process_node called on it. */
233 processed,
234
235 /* Node was excluded from worklist on creation.
236 e.g. for handling exception-unwinding. */
237 special,
238
239 /* Node was left unprocessed due to merger; it won't have had
240 exploded_graph::process_node called on it. */
241 merger,
242
243 /* Node was processed by maybe_process_run_of_enodes. */
244 bulk_merged
245 };
246 static const char * status_to_str (enum status s);
247
248 exploded_node (const point_and_state &ps, int index);
250
251 hashval_t hash () const { return m_ps.hash (); }
252
253 const char * get_dot_fillcolor () const;
254 void dump_dot (graphviz_out *gv, const dump_args_t &args)
255 const final override;
256 void dump_dot_id (pretty_printer *pp) const;
257
259 void dump (FILE *fp, const extrinsic_state &ext_state) const;
260 void dump (const extrinsic_state &ext_state) const;
261
264
265 std::unique_ptr<json::object> to_json (const extrinsic_state &ext_state) const;
266
268 const gcall &call,
269 program_state *new_state,
272 const gcall &call,
273 const program_point &after_throw_point,
274 program_state *new_state,
275 bool is_rethrow,
277
279
280 const program_point &get_point () const { return m_ps.get_point (); }
281 const supernode *get_supernode () const
282 {
283 return get_point ().get_supernode ();
284 }
285 location_t get_location () const
286 {
287 return get_point ().get_location ();
288 }
290 {
291 return get_point ().get_function ();
292 }
293 int get_stack_depth () const
294 {
295 return get_point ().get_stack_depth ();
296 }
297
298 const program_state &get_state () const { return m_ps.get_state (); }
299
300 const point_and_state *get_ps_key () const { return &m_ps; }
301 const program_point *get_point_key () const { return &m_ps.get_point (); }
302
303 void dump_succs_and_preds (FILE *outf) const;
304
305 enum status get_status () const { return m_status; }
306 void set_status (enum status s)
307 {
309 m_status = s;
310 }
311
313 {
314 m_saved_diagnostics.safe_push (sd);
315 }
316 unsigned get_num_diagnostics () const
317 {
318 return m_saved_diagnostics.length ();
319 }
320 const saved_diagnostic *get_saved_diagnostic (unsigned idx) const
321 {
322 return m_saved_diagnostics[idx];
323 }
324
325private:
327
328 /* The <program_point, program_state> pair. This is const, as it
329 is immutable once the exploded_node has been created. */
331
333
334 /* The saved_diagnostics at this enode, borrowed from the
335 diagnostic_manager. */
336 auto_vec <const saved_diagnostic *> m_saved_diagnostics;
337
338public:
339 /* The index of this exploded_node. */
340 const int m_index;
341};
342
343/* An edge within the exploded graph.
344 Some exploded_edges have an underlying superedge; others don't. */
345
346class exploded_edge : public dedge<eg_traits>
347{
348 public:
350 const superedge *sedge, bool could_do_work,
351 std::unique_ptr<custom_edge_info> custom_info);
352 void dump_dot (graphviz_out *gv, const dump_args_t &args)
353 const final override;
355
356 std::unique_ptr<json::object> to_json () const;
357
358 //private:
359 const superedge *const m_sedge;
360
361 /* nullptr for most edges; will be non-NULL for special cases
362 such as an unwind from a longjmp to a setjmp, or when
363 a signal is delivered to a signal-handler. */
364 std::unique_ptr<custom_edge_info> m_custom_info;
365
366 bool could_do_work_p () const { return m_could_do_work_p; }
367
368 const gimple *maybe_get_stmt () const;
369 const operation *maybe_get_op () const;
370
371private:
373
374 /* For -Wanalyzer-infinite-loop.
375 Set to true during processing if any of the activity along
376 this edge is "externally-visible work" (and thus ruling this
377 out as being part of an infinite loop.
378
379 For example, given:
380
381 while (1)
382 do_something ();
383
384 although it is an infinite loop, presumably the point of the
385 program is the loop body, and thus reporting this as an infinite
386 loop is likely to be unhelpful to the user. */
388};
389
390/* Extra data for an exploded_edge that represents an interprocedural
391 call. */
392
394{
395public:
397 function &callee_fun)
398 : m_op (op),
399 m_callee_fun (callee_fun)
400 {}
401
402 void print (pretty_printer *pp) const final override;
403
404 void get_dot_attrs (const char *&out_style,
405 const char *&out_color) const final override;
406
408 const exploded_edge *eedge,
409 region_model_context *ctxt) const final override;
410
412 const exploded_edge *eedge,
413 region_model_context *ctxt) const final override;
414
415 void add_events_to_path (checker_path *emission_path,
416 const exploded_edge &eedge,
418 const state_transition *state_trans) const final override;
419
420 bool
421 try_to_rewind_data_flow (rewind_context &) const final override;
422
423 const gcall &get_gcall () const;
424
425private:
428};
429
430/* Extra data for an exploded_edge that represents an interprocedural
431 return. */
432
434{
435public:
436 interprocedural_return (const gcall &call_stmt)
437 : m_call_stmt (call_stmt)
438 {}
439
440 void print (pretty_printer *pp) const final override;
441
442 void get_dot_attrs (const char *&out_style,
443 const char *&out_color) const final override;
444
446 const exploded_edge *eedge,
447 region_model_context *ctxt) const final override;
448
450 const exploded_edge *eedge,
451 region_model_context *ctxt) const final override;
452
453 void add_events_to_path (checker_path *emission_path,
454 const exploded_edge &eedge,
456 const state_transition *state_trans) const final override;
457
458 bool
459 try_to_rewind_data_flow (rewind_context &) const final override;
460
461private:
463};
464
465/* Extra data for an exploded_edge that represents a rewind from a
466 longjmp to a setjmp (or from a siglongjmp to a sigsetjmp). */
467
469{
470public:
472 const gcall &longjmp_call)
474 m_longjmp_call (longjmp_call)
475 {}
476
477 void print (pretty_printer *pp) const final override
478 {
479 pp_string (pp, "rewind");
480 }
481
483 const exploded_edge *eedge,
484 region_model_context *ctxt) const final override;
485
486 void add_events_to_path (checker_path *emission_path,
487 const exploded_edge &eedge,
489 const state_transition *state_trans) const final override;
490
493 {
494 return get_enode_origin ()->get_point ();
495 }
496
499 {
500 const program_point &origin_point = get_enode_origin ()->get_point ();
502 origin_point.get_call_string ());
503 }
504
505 const gcall &get_setjmp_call () const
506 {
508 }
509
510 const gcall &get_longjmp_call () const
511 {
512 return m_longjmp_call;
513 }
514
516 {
518 }
519
520private:
523};
524
525/* Statistics about aspects of an exploded_graph. */
526
527struct stats
528{
529 stats (int num_supernodes);
530 void log (logger *logger) const;
531 void dump (FILE *out) const;
532
533 int get_total_enodes () const;
534
539};
540
541/* Traits class for ensuring uniqueness of point_and_state data within
542 an exploded_graph. */
543
545{
546 typedef const point_and_state *key_type;
549
550 static inline hashval_t hash (const key_type &k)
551 {
552 gcc_assert (k != nullptr);
553 gcc_assert (k != reinterpret_cast<key_type> (1));
554 return k->hash ();
555 }
556 static inline bool equal_keys (const key_type &k1, const key_type &k2)
557 {
558 gcc_assert (k1 != nullptr);
559 gcc_assert (k2 != nullptr);
560 gcc_assert (k1 != reinterpret_cast<key_type> (1));
561 gcc_assert (k2 != reinterpret_cast<key_type> (1));
562 if (k1 && k2)
563 return *k1 == *k2;
564 else
565 /* Otherwise they must both be non-NULL. */
566 return k1 == k2;
567 }
568 template <typename T>
569 static inline void remove (T &)
570 {
571 /* empty; the nodes are handled elsewhere. */
572 }
573 template <typename T>
574 static inline void mark_deleted (T &entry)
575 {
576 entry.m_key = reinterpret_cast<key_type> (1);
577 }
578 template <typename T>
579 static inline void mark_empty (T &entry)
580 {
581 entry.m_key = nullptr;
582 }
583 template <typename T>
584 static inline bool is_deleted (const T &entry)
585 {
586 return entry.m_key == reinterpret_cast<key_type> (1);
587 }
588 template <typename T>
589 static inline bool is_empty (const T &entry)
590 {
591 return entry.m_key == nullptr;
592 }
593 static const bool empty_zero_p = false;
594};
595
596/* Per-program_point data for an exploded_graph. */
597
599{
601 : m_key (key), m_excess_enodes (0)
602 {}
603
606 /* The number of attempts to create an enode for this point
607 after exceeding --param=analyzer-max-enodes-per-program-point. */
609};
610
611/* Traits class for storing per-program_point data within
612 an exploded_graph. */
613
615{
616 typedef const program_point *key_type;
619
620 static inline hashval_t hash (const key_type &k)
621 {
622 gcc_assert (k != nullptr);
623 gcc_assert (k != reinterpret_cast<key_type> (1));
624 return k->hash ();
625 }
626 static inline bool equal_keys (const key_type &k1, const key_type &k2)
627 {
628 gcc_assert (k1 != nullptr);
629 gcc_assert (k2 != nullptr);
630 gcc_assert (k1 != reinterpret_cast<key_type> (1));
631 gcc_assert (k2 != reinterpret_cast<key_type> (1));
632 if (k1 && k2)
633 return *k1 == *k2;
634 else
635 /* Otherwise they must both be non-NULL. */
636 return k1 == k2;
637 }
638 template <typename T>
639 static inline void remove (T &)
640 {
641 /* empty; the nodes are handled elsewhere. */
642 }
643 template <typename T>
644 static inline void mark_deleted (T &entry)
645 {
646 entry.m_key = reinterpret_cast<key_type> (1);
647 }
648 template <typename T>
649 static inline void mark_empty (T &entry)
650 {
651 entry.m_key = nullptr;
652 }
653 template <typename T>
654 static inline bool is_deleted (const T &entry)
655 {
656 return entry.m_key == reinterpret_cast<key_type> (1);
657 }
658 template <typename T>
659 static inline bool is_empty (const T &entry)
660 {
661 return entry.m_key == nullptr;
662 }
663 static const bool empty_zero_p = false;
664};
665
666/* Data about a particular call_string within an exploded_graph. */
667
669{
670 per_call_string_data (const call_string &key, int num_supernodes)
671 : m_key (key), m_stats (num_supernodes)
672 {}
673
676};
677
678/* Data about a particular function within an exploded_graph. */
679
689
690/* The strongly connected components of a supergraph.
691 In particular, this allows us to compute a partial ordering
692 of supernodes. */
693
695{
696public:
698
699 int get_scc_id (int node_index) const
700 {
701 return m_per_node[node_index].m_lowlink;
702 }
703
704 void dump () const;
705
706 std::unique_ptr<json::array> to_json () const;
707
708private:
710 {
712 : m_id (-1), m_lowlink (-1), m_on_stack (false)
713 {}
714
715 int m_id;
718 };
719
720 void strong_connect (unsigned index, logger *logger);
721
725};
726
727/* The worklist of exploded_node instances that have been added to
728 an exploded_graph, but that haven't yet been processed to find
729 their successors (or warnings).
730
731 The enodes are stored in a priority queue, ordered by a topological
732 sort of the SCCs in the supergraph, so that enodes for the same
733 program_point should appear at the front of the queue together.
734 This allows for state-merging at CFG join-points, so that
735 sufficiently-similar enodes can be merged into one. */
736
738{
739public:
740 worklist (const exploded_graph &eg, const analysis_plan &plan);
741 unsigned length () const;
744 void add_node (exploded_node *enode);
745 int get_scc_id (const supernode &snode) const
746 {
747 return m_scc.get_scc_id (snode.m_id);
748 }
749
750 std::unique_ptr<json::object> to_json () const;
751
752private:
753 class key_t
754 {
755 public:
756 key_t (const worklist &w, exploded_node *enode)
757 : m_worklist (w), m_enode (enode)
758 {}
759
760 bool operator< (const key_t &other) const
761 {
762 return cmp (*this, other) < 0;
763 }
764
765 bool operator== (const key_t &other) const
766 {
767 return cmp (*this, other) == 0;
768 }
769
770 bool operator> (const key_t &other) const
771 {
772 return !(*this == other || *this < other);
773 }
774
775 private:
776 static int cmp (const key_t &ka, const key_t &kb);
777
778 int get_scc_id (const exploded_node *enode) const
779 {
780 const supernode *snode = enode->get_supernode ();
781 if (snode == nullptr)
782 return 0;
783 return m_worklist.m_scc.get_scc_id (snode->m_id);
784 }
785
788 };
789
790 /* The order is important here: m_scc needs to stick around
791 until after m_queue has finished being cleaned up (the dtor
792 calls the ordering fns). */
795
796 /* Priority queue, backed by a fibonacci_heap. */
799};
800
801/* An exploded_graph is a directed graph of unique <point, state> pairs.
802 It also has a worklist of nodes that are waiting for their successors
803 to be added to the graph. */
804
805class exploded_graph : public digraph<eg_traits>
806{
807public:
808 typedef hash_map <const call_string *,
810
813 const state_purge_map *purge_map,
814 const analysis_plan &plan,
815 int verbosity);
817
818 logger *get_logger () const { return m_logger.get_logger (); }
819
820 const supergraph &get_supergraph () const { return m_sg; }
821 const extrinsic_state &get_ext_state () const { return m_ext_state; }
822 engine *get_engine () const { return m_ext_state.get_engine (); }
823 const state_purge_map *get_purge_map () const { return m_purge_map; }
824 const analysis_plan &get_analysis_plan () const { return m_plan; }
825
826 exploded_node *get_origin () const { return m_origin; }
827
829
834
836 const program_state &state,
837 exploded_node *enode_for_diag,
838 bool add_to_worklist = true);
840 const superedge *sedge, bool could_do_work,
841 std::unique_ptr<custom_edge_info> custom = nullptr);
842
847
850
854
856 const exploded_node *enode,
857 const supernode *node, const gimple *stmt,
860
866 {
868 }
869
872 void log_stats () const;
873 void dump_stats (FILE *) const;
874 void dump_exploded_nodes () const;
875
876 std::unique_ptr<json::object> to_json () const;
877
879
882
883 int get_scc_id (const supernode &node) const
884 {
885 return m_worklist.get_scc_id (node);
886 }
887
889
891 const gimple *stmt,
893
894 /* In infinite-loop.cc */
895 void detect_infinite_loops ();
896
897 /* In infinite-recursion.cc */
900 exploded_node *enode) const;
901
902private:
904
906
908
910
911 /* Map from point/state to exploded node.
912 To avoid duplication we store point_and_state
913 *pointers* as keys, rather than point_and_state, using the
914 instance from within the exploded_node, with a custom hasher. */
915 typedef hash_map <const point_and_state *, exploded_node *,
918
919 /* Map from program_point to per-program_point data. */
923
925
927
929
931
933
936
938
939 /* Stats. */
944
946
947 /* Functions with a top-level enode, to make add_function_entry
948 be idempotent, for use in handling callbacks. */
950};
951
952/* A reason why a particular exploded_path is infeasible. */
953
955{
956public:
957 feasibility_problem (unsigned eedge_idx,
958 const exploded_edge &eedge,
959 std::unique_ptr<rejected_constraint> rc)
960 : m_eedge_idx (eedge_idx), m_eedge (eedge),
961 m_rc (std::move (rc))
962 {}
963
964 void dump_to_pp (pretty_printer *pp) const;
965
966 unsigned m_eedge_idx;
968 std::unique_ptr<rejected_constraint> m_rc;
969};
970
971/* A class for capturing the state of a node when checking a path
972 through the exploded_graph for feasibility. */
973
975{
976public:
978 const supergraph &sg);
980 const supergraph &sg);
982
984
986 const exploded_edge *eedge,
988 std::unique_ptr<rejected_constraint> *out_rc);
989
991 const region_model &get_model () const { return m_model; }
994
995 void dump_to_pp (pretty_printer *pp, bool simple, bool multiline) const;
996
997private:
1000};
1001
1002// TODO: split the above up?
1003
1004} // namespace ana
1005
1006#endif /* GCC_ANALYZER_EXPLODED_GRAPH_H */
Definition analysis-plan.h:35
Definition ops.h:433
Definition call-string.h:41
Definition checker-path.h:32
Definition common.h:439
Definition diagnostic-manager.h:161
Definition region-model.h:1320
Definition exploded-graph.h:347
std::unique_ptr< json::object > to_json() const
const operation * maybe_get_op() const
void dump_dot_label(pretty_printer *pp) const
bool m_could_do_work_p
Definition exploded-graph.h:387
exploded_edge(exploded_node *src, exploded_node *dest, const superedge *sedge, bool could_do_work, std::unique_ptr< custom_edge_info > custom_info)
std::unique_ptr< custom_edge_info > m_custom_info
Definition exploded-graph.h:364
void dump_dot(graphviz_out *gv, const dump_args_t &args) const final override
bool could_do_work_p() const
Definition exploded-graph.h:366
DISABLE_COPY_AND_ASSIGN(exploded_edge)
const gimple * maybe_get_stmt() const
const superedge *const m_sedge
Definition exploded-graph.h:359
Definition exploded-graph.h:806
hash_map< const point_and_state *, exploded_node *, eg_hash_map_traits > map_t
Definition exploded-graph.h:916
void log_stats() const
stats * get_global_stats()
Definition exploded-graph.h:870
const call_string_data_map_t * get_per_call_string_data() const
Definition exploded-graph.h:880
const state_purge_map * get_purge_map() const
Definition exploded-graph.h:823
const extrinsic_state & m_ext_state
Definition exploded-graph.h:928
void detect_infinite_recursion(exploded_node *enode)
Definition infinite-recursion.cc:585
call_string_data_map_t m_per_call_string_data
Definition exploded-graph.h:945
stats m_functionless_stats
Definition exploded-graph.h:943
exploded_node * find_previous_entry_to(function *top_of_stack_fun, exploded_node *enode) const
Definition infinite-recursion.cc:328
function_stat_map_t m_per_function_stats
Definition exploded-graph.h:942
exploded_edge * add_edge(exploded_node *src, exploded_node *dest, const superedge *sedge, bool could_do_work, std::unique_ptr< custom_edge_info > custom=nullptr)
void detect_infinite_loops()
Definition infinite-loop.cc:555
void process_node(exploded_node *node)
engine * get_engine() const
Definition exploded-graph.h:822
point_map_t m_per_point_data
Definition exploded-graph.h:922
diagnostic_manager & get_diagnostic_manager()
Definition exploded-graph.h:861
exploded_node * add_function_entry(const function &fun)
per_function_data * get_per_function_data(function *) const
log_user m_logger
Definition exploded-graph.h:909
bool maybe_process_run_of_enodes(exploded_node *node)
const supergraph & get_supergraph() const
Definition exploded-graph.h:820
const analysis_plan & get_analysis_plan() const
Definition exploded-graph.h:824
map_t m_point_and_state_to_node
Definition exploded-graph.h:917
const supergraph & m_sg
Definition exploded-graph.h:907
exploded_graph(const supergraph &sg, logger *logger, const extrinsic_state &ext_state, const state_purge_map *purge_map, const analysis_plan &plan, int verbosity)
diagnostic_manager m_diagnostic_manager
Definition exploded-graph.h:937
hash_map< function *, per_function_data * > per_function_data_t
Definition exploded-graph.h:934
void build_initial_worklist()
per_call_string_data * get_or_create_per_call_string_data(const call_string &)
const diagnostic_manager & get_diagnostic_manager() const
Definition exploded-graph.h:865
per_program_point_data * get_per_program_point_data(const program_point &) const
logger * get_logger() const
Definition exploded-graph.h:818
exploded_node * m_origin
Definition exploded-graph.h:926
per_function_data * get_or_create_per_function_data(function *)
void on_escaped_function(tree fndecl)
void dump_exploded_nodes() const
hash_map< const call_string *, per_call_string_data * > call_string_data_map_t
Definition exploded-graph.h:809
hash_set< function * > m_functions_with_enodes
Definition exploded-graph.h:949
stats * get_or_create_function_stats(function *fn)
void print_bar_charts(pretty_printer *pp) const
stats m_global_stats
Definition exploded-graph.h:940
ordered_hash_map< function *, stats * > function_stat_map_t
Definition exploded-graph.h:941
const extrinsic_state & get_ext_state() const
Definition exploded-graph.h:821
worklist m_worklist
Definition exploded-graph.h:924
void dump_stats(FILE *) const
int get_scc_id(const supernode &node) const
Definition exploded-graph.h:883
hash_map< const program_point *, per_program_point_data *, eg_point_hash_map_traits > point_map_t
Definition exploded-graph.h:921
std::unique_ptr< json::object > to_json() const
void save_diagnostic(const state_machine &sm, const exploded_node *enode, const supernode *node, const gimple *stmt, tree var, state_machine::state_t state, pending_diagnostic *d)
const state_purge_map *const m_purge_map
Definition exploded-graph.h:930
const analysis_plan & m_plan
Definition exploded-graph.h:932
void unwind_from_exception(exploded_node &enode, const gimple *stmt, region_model_context *ctxt)
exploded_node * get_or_create_node(const program_point &point, const program_state &state, exploded_node *enode_for_diag, bool add_to_worklist=true)
per_program_point_data * get_or_create_per_program_point_data(const program_point &)
per_function_data_t m_per_function_data
Definition exploded-graph.h:935
exploded_node * get_origin() const
Definition exploded-graph.h:826
exploded_node * get_node_by_index(int idx) const
DISABLE_COPY_AND_ASSIGN(exploded_graph)
Definition exploded-graph.h:221
DISABLE_COPY_AND_ASSIGN(exploded_node)
const point_and_state * get_ps_key() const
Definition exploded-graph.h:300
void dump(const extrinsic_state &ext_state) const
status
Definition exploded-graph.h:228
@ worklist
Definition exploded-graph.h:230
function * get_function() const
Definition exploded-graph.h:289
void dump_to_pp(pretty_printer *pp, const extrinsic_state &ext_state) const
location_t get_location() const
Definition exploded-graph.h:285
unsigned get_num_diagnostics() const
Definition exploded-graph.h:316
void dump_saved_diagnostics(pretty_printer *pp) const
void dump_dot(graphviz_out *gv, const dump_args_t &args) const final override
void on_throw(exploded_graph &eg, const gcall &call, const program_point &after_throw_point, program_state *new_state, bool is_rethrow, region_model_context *ctxt)
std::unique_ptr< json::object > to_json(const extrinsic_state &ext_state) const
void add_diagnostic(const saved_diagnostic *sd)
Definition exploded-graph.h:312
void dump_processed_stmts(pretty_printer *pp) const
const point_and_state m_ps
Definition exploded-graph.h:330
const char * get_dot_fillcolor() const
void dump_dot_id(pretty_printer *pp) const
const program_state & get_state() const
Definition exploded-graph.h:298
static const char * status_to_str(enum status s)
void dump_succs_and_preds(FILE *outf) const
const int m_index
Definition exploded-graph.h:340
const program_point * get_point_key() const
Definition exploded-graph.h:301
enum status get_status() const
Definition exploded-graph.h:305
void set_status(enum status s)
Definition exploded-graph.h:306
int get_stack_depth() const
Definition exploded-graph.h:293
void on_longjmp(exploded_graph &eg, const gcall &call, program_state *new_state, region_model_context *ctxt)
exploded_node(const point_and_state &ps, int index)
const program_point & get_point() const
Definition exploded-graph.h:280
void dump(FILE *fp, const extrinsic_state &ext_state) const
exploded_node(point_and_state &&ps, int index)
auto_vec< const saved_diagnostic * > m_saved_diagnostics
Definition exploded-graph.h:336
const supernode * get_supernode() const
Definition exploded-graph.h:281
void detect_leaks(exploded_graph &eg)
hashval_t hash() const
Definition exploded-graph.h:251
enum status m_status
Definition exploded-graph.h:332
const saved_diagnostic * get_saved_diagnostic(unsigned idx) const
Definition exploded-graph.h:320
Definition program-state.h:34
engine * get_engine() const
Definition program-state.h:75
feasibility_problem(unsigned eedge_idx, const exploded_edge &eedge, std::unique_ptr< rejected_constraint > rc)
Definition exploded-graph.h:957
const exploded_edge & m_eedge
Definition exploded-graph.h:967
void dump_to_pp(pretty_printer *pp) const
unsigned m_eedge_idx
Definition exploded-graph.h:966
std::unique_ptr< rejected_constraint > m_rc
Definition exploded-graph.h:968
bool maybe_update_for_edge(logger *logger, const exploded_edge *eedge, region_model_context *ctxt, std::unique_ptr< rejected_constraint > *out_rc)
auto_sbitmap & get_snodes_visited()
Definition exploded-graph.h:992
feasibility_state(const region_model &model, const supergraph &sg)
auto_sbitmap m_snodes_visited
Definition exploded-graph.h:999
feasibility_state(region_model_manager *manager, const supergraph &sg)
void dump_to_pp(pretty_printer *pp, bool simple, bool multiline) const
region_model & get_model()
Definition exploded-graph.h:990
feasibility_state(const feasibility_state &other)
region_model m_model
Definition exploded-graph.h:998
const region_model & get_model() const
Definition exploded-graph.h:991
feasibility_state & operator=(const feasibility_state &other)
const auto_sbitmap & get_snodes_visited() const
Definition exploded-graph.h:993
Definition region.h:320
void on_condition(const svalue *lhs, enum tree_code op, const svalue *rhs) final override
void on_unknown_change(const svalue *sval, bool is_mutable) final override
void terminate_path() final override
impl_region_model_context(exploded_graph &eg, exploded_node *enode_for_diag, const program_state *old_state, program_state *new_state, uncertainty_t *uncertainty, path_context *path_ctxt, const gimple *stmt=nullptr, bool *out_could_have_done_work=nullptr)
exploded_graph * m_eg
Definition exploded-graph.h:123
const extrinsic_state & m_ext_state
Definition exploded-graph.h:129
logger * get_logger() final override
Definition exploded-graph.h:67
void on_svalue_leak(const svalue *) override
void on_pop_frame(const frame_region *frame_reg) final override
void on_liveness_change(const svalue_set &live_svalues, const region_model *model) final override
void add_note(std::unique_ptr< pending_note > pn) final override
bool * m_out_could_have_done_work
Definition exploded-graph.h:132
bool warn_at(std::unique_ptr< pending_diagnostic > d, pending_location &&ploc) final override
void on_state_leak(const state_machine &sm, const svalue *sval, state_machine::state_t state)
impl_region_model_context(program_state *state, const extrinsic_state &ext_state, uncertainty_t *uncertainty, logger *logger=nullptr)
void add_event(std::unique_ptr< checker_event > event) final override
pending_location get_pending_location_for_diag() const override
program_state * m_new_state
Definition exploded-graph.h:127
log_user m_logger
Definition exploded-graph.h:124
const program_state * m_old_state
Definition exploded-graph.h:126
void on_unusable_in_infinite_loop() override
Definition exploded-graph.h:118
const program_state * get_state() const override
Definition exploded-graph.h:114
void on_phi(const gphi *phi, tree rhs) final override
void on_unexpected_tree_code(tree t, const dump_location_t &loc) final override
void on_escaped_function(tree fndecl) final override
void bifurcate(std::unique_ptr< custom_edge_info > info) final override
path_context * m_path_ctxt
Definition exploded-graph.h:131
void purge_state_involving(const svalue *sval) final override
void on_bounded_ranges(const svalue &sval, const bounded_ranges &ranges) final override
uncertainty_t * get_uncertainty() final override
const gimple * m_stmt
Definition exploded-graph.h:128
uncertainty_t * m_uncertainty
Definition exploded-graph.h:130
const gimple * get_stmt() const override
Definition exploded-graph.h:111
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
bool checking_for_infinite_loop_p() const override
Definition exploded-graph.h:117
const extrinsic_state * get_ext_state() const final override
Definition exploded-graph.h:100
const exploded_graph * get_eg() const override
Definition exploded-graph.h:112
exploded_node * m_enode_for_diag
Definition exploded-graph.h:125
interprocedural_call(const call_and_return_op &op, function &callee_fun)
Definition exploded-graph.h:396
void get_dot_attrs(const char *&out_style, const char *&out_color) const final override
bool update_model(region_model *model, const exploded_edge *eedge, region_model_context *ctxt) const final override
const gcall & get_gcall() const
void add_events_to_path(checker_path *emission_path, const exploded_edge &eedge, pending_diagnostic &pd, const state_transition *state_trans) const final override
const call_and_return_op & m_op
Definition exploded-graph.h:426
bool update_state(program_state *state, const exploded_edge *eedge, region_model_context *ctxt) const final override
bool try_to_rewind_data_flow(rewind_context &) const final override
function & m_callee_fun
Definition exploded-graph.h:427
void print(pretty_printer *pp) const final override
const gcall & m_call_stmt
Definition exploded-graph.h:462
void print(pretty_printer *pp) const final override
bool try_to_rewind_data_flow(rewind_context &) const final override
interprocedural_return(const gcall &call_stmt)
Definition exploded-graph.h:436
bool update_model(region_model *model, const exploded_edge *eedge, region_model_context *ctxt) const final override
bool update_state(program_state *state, const exploded_edge *eedge, region_model_context *ctxt) const final override
void get_dot_attrs(const char *&out_style, const char *&out_color) const final override
void add_events_to_path(checker_path *emission_path, const exploded_edge &eedge, pending_diagnostic &pd, const state_transition *state_trans) const final override
Definition analyzer-logging.h:193
logger * get_logger() const
Definition analyzer-logging.h:198
Definition analyzer-logging.h:36
Definition ops.h:113
Definition common.h:489
Definition pending-diagnostic.h:258
Definition exploded-graph.h:140
hashval_t m_hash
Definition exploded-graph.h:191
bool operator==(const point_and_state &other) const
Definition exploded-graph.h:166
void validate(const extrinsic_state &ext_state) const
const program_state & get_state() const
Definition exploded-graph.h:172
void set_state(program_state &&state)
Definition exploded-graph.h:180
program_state m_state
Definition exploded-graph.h:190
program_point m_point
Definition exploded-graph.h:189
point_and_state(const program_point &point, const program_state &state)
Definition exploded-graph.h:142
point_and_state(point_and_state &&other)
Definition exploded-graph.h:155
const program_point & get_point() const
Definition exploded-graph.h:171
hashval_t hash() const
Definition exploded-graph.h:162
void set_state(const program_state &state)
Definition exploded-graph.h:174
point_and_state(const point_and_state &other)=default
Definition program-point.h:54
location_t get_location() const
Definition program-point.h:98
function * get_function() const
Definition program-point.h:88
program_point(const supernode *snode, const call_string &call_string)
Definition program-point.h:56
const supernode * get_supernode() const
Definition program-point.h:82
int get_stack_depth() const
Definition program-point.h:107
const call_string & get_call_string() const
Definition program-point.h:86
hashval_t hash() const
Definition program-state.h:224
hashval_t hash() const
Definition region-model.h:754
Definition region-model-manager.h:32
Definition region-model.h:294
setjmp_record m_setjmp_record
Definition exploded-graph.h:521
program_point get_point_before_setjmp() const
Definition exploded-graph.h:492
bool update_model(region_model *model, const exploded_edge *eedge, region_model_context *ctxt) const final override
void add_events_to_path(checker_path *emission_path, const exploded_edge &eedge, pending_diagnostic &pd, const state_transition *state_trans) const final override
const gcall & get_setjmp_call() const
Definition exploded-graph.h:505
void print(pretty_printer *pp) const final override
Definition exploded-graph.h:477
const exploded_node * get_enode_origin() const
Definition exploded-graph.h:515
const gcall & m_longjmp_call
Definition exploded-graph.h:522
program_point get_point_after_setjmp() const
Definition exploded-graph.h:498
rewind_info_t(const setjmp_record &setjmp_record, const gcall &longjmp_call)
Definition exploded-graph.h:471
const gcall & get_longjmp_call() const
Definition exploded-graph.h:510
Definition diagnostic-manager.h:79
Definition program-state.h:92
Definition sm.h:43
const state_machine::state * state_t
Definition sm.h:63
Definition state-purge.h:31
Definition state-transition.h:31
Definition exploded-graph.h:695
void strong_connect(unsigned index, logger *logger)
int get_scc_id(int node_index) const
Definition exploded-graph.h:699
auto_vec< per_node_data > m_per_node
Definition exploded-graph.h:724
const supergraph & m_sg
Definition exploded-graph.h:722
strongly_connected_components(const supergraph &sg, logger *logger)
auto_vec< unsigned > m_stack
Definition exploded-graph.h:723
std::unique_ptr< json::array > to_json() const
Definition supergraph.h:281
Definition supergraph.h:105
Definition supergraph.h:224
int m_id
Definition supergraph.h:268
Definition svalue.h:92
Definition store.h:162
bool operator<(const key_t &other) const
Definition exploded-graph.h:760
const worklist & m_worklist
Definition exploded-graph.h:786
bool operator==(const key_t &other) const
Definition exploded-graph.h:765
exploded_node * m_enode
Definition exploded-graph.h:787
bool operator>(const key_t &other) const
Definition exploded-graph.h:770
static int cmp(const key_t &ka, const key_t &kb)
int get_scc_id(const exploded_node *enode) const
Definition exploded-graph.h:778
key_t(const worklist &w, exploded_node *enode)
Definition exploded-graph.h:756
Definition exploded-graph.h:738
std::unique_ptr< json::object > to_json() const
void add_node(exploded_node *enode)
strongly_connected_components m_scc
Definition exploded-graph.h:793
worklist(const exploded_graph &eg, const analysis_plan &plan)
queue_t m_queue
Definition exploded-graph.h:798
exploded_node * take_next()
fibonacci_heap< key_t, exploded_node > queue_t
Definition exploded-graph.h:797
exploded_node * peek_next()
const analysis_plan & m_plan
Definition exploded-graph.h:794
int get_scc_id(const supernode &snode) const
Definition exploded-graph.h:745
unsigned length() const
Definition sbitmap.h:303
Definition vec.h:1667
node_t * m_dest
Definition digraph.h:112
dedge(node_t *src, node_t *dest)
Definition digraph.h:93
eg_traits::dump_args_t dump_args_t
Definition digraph.h:91
digraph()
Definition digraph.h:128
Definition digraph.h:43
eg_traits::dump_args_t dump_args_t
Definition digraph.h:46
Definition dumpfile.h:446
Definition ree.cc:583
Definition fibonacci_heap.h:143
Definition graphviz.h:388
Definition hash-map.h:40
Definition hash-set.h:37
Definition ordered-hash-map.h:35
Definition pretty-print.h:241
union tree_node * tree
Definition coretypes.h:97
void final(rtx_insn *first, FILE *file, int optimize_p)
Definition final.cc:2001
tree_code
Definition genmatch.cc:1011
Definition access-diagram.h:30
hash_set< const svalue * > svalue_set
Definition common.h:76
Definition custom-sarif-properties/state-graphs.h:33
void pp_string(pretty_printer *pp, const char *str)
Definition pretty-print.cc:2764
Definition constraint-manager.h:123
Definition exploded-graph.h:545
static bool equal_keys(const key_type &k1, const key_type &k2)
Definition exploded-graph.h:556
static void mark_empty(T &entry)
Definition exploded-graph.h:579
static void mark_deleted(T &entry)
Definition exploded-graph.h:574
static bool is_deleted(const T &entry)
Definition exploded-graph.h:584
static const bool empty_zero_p
Definition exploded-graph.h:593
exploded_node * compare_type
Definition exploded-graph.h:548
const point_and_state * key_type
Definition exploded-graph.h:546
exploded_node * value_type
Definition exploded-graph.h:547
static void remove(T &)
Definition exploded-graph.h:569
static hashval_t hash(const key_type &k)
Definition exploded-graph.h:550
static bool is_empty(const T &entry)
Definition exploded-graph.h:589
Definition exploded-graph.h:615
static bool is_deleted(const T &entry)
Definition exploded-graph.h:654
static const bool empty_zero_p
Definition exploded-graph.h:663
static void mark_empty(T &entry)
Definition exploded-graph.h:649
static hashval_t hash(const key_type &k)
Definition exploded-graph.h:620
const program_point * key_type
Definition exploded-graph.h:616
per_program_point_data * value_type
Definition exploded-graph.h:617
per_program_point_data * compare_type
Definition exploded-graph.h:618
static void mark_deleted(T &entry)
Definition exploded-graph.h:644
static bool is_empty(const T &entry)
Definition exploded-graph.h:659
static bool equal_keys(const key_type &k1, const key_type &k2)
Definition exploded-graph.h:626
static void remove(T &)
Definition exploded-graph.h:639
bool show_enode_details_p(const exploded_node &enode) const
const exploded_graph & m_eg
Definition exploded-graph.h:210
virtual void dump_extra_info(const exploded_node *, pretty_printer *) const
Definition exploded-graph.h:208
dump_args_t(const exploded_graph &eg)
Definition exploded-graph.h:203
Definition exploded-graph.h:197
exploded_graph graph_t
Definition exploded-graph.h:200
exploded_edge edge_t
Definition exploded-graph.h:199
exploded_node node_t
Definition exploded-graph.h:198
exploded_cluster cluster_t
Definition exploded-graph.h:212
Definition diagnostic-manager.h:35
Definition exploded-graph.h:669
stats m_stats
Definition exploded-graph.h:675
const call_string & m_key
Definition exploded-graph.h:674
per_call_string_data(const call_string &key, int num_supernodes)
Definition exploded-graph.h:670
Definition exploded-graph.h:681
per_function_data()
Definition exploded-graph.h:682
auto_vec< call_summary * > m_summaries
Definition exploded-graph.h:687
void add_call_summary(exploded_node *node)
Definition exploded-graph.h:599
const program_point m_key
Definition exploded-graph.h:604
int m_excess_enodes
Definition exploded-graph.h:608
per_program_point_data(const program_point &key)
Definition exploded-graph.h:600
auto_vec< exploded_node * > m_enodes
Definition exploded-graph.h:605
Definition ops.h:78
Definition svalue.h:551
const exploded_node * m_enode
Definition svalue.h:575
const gcall * m_setjmp_call
Definition svalue.h:577
const superedge * m_sedge
Definition svalue.h:576
Definition exploded-graph.h:528
void log(logger *logger) const
void dump(FILE *out) const
int m_num_nodes
Definition exploded-graph.h:535
int m_num_supernodes
Definition exploded-graph.h:538
int m_node_reuse_after_merge_count
Definition exploded-graph.h:537
stats(int num_supernodes)
int get_total_enodes() const
int m_node_reuse_count
Definition exploded-graph.h:536
per_node_data()
Definition exploded-graph.h:711
bool m_on_stack
Definition exploded-graph.h:717
int m_id
Definition exploded-graph.h:715
int m_lowlink
Definition exploded-graph.h:716
Definition function.h:249
Definition gimple.h:355
Definition gimple.h:224
Definition gimple.h:464
Definition ira-emit.cc:158
Definition gengtype.h:377
Definition genautomata.cc:669
#define gcc_assert(EXPR)
Definition system.h:772
#define false
Definition system.h:846