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-2025 Free Software Foundation, Inc.
3 Contributed by David Malcolm <dmalcolm@redhat.com>.
4
5This file is part of GCC.
6
7GCC is free software; you can redistribute it and/or modify it
8under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 3, or (at your option)
10any later version.
11
12GCC is distributed in the hope that it will be useful, but
13WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with GCC; see the file COPYING3. If not see
19<http://www.gnu.org/licenses/>. */
20
21#ifndef GCC_ANALYZER_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"
32
33namespace ana {
34
35/* Concrete implementation of region_model_context, wiring it up to the
36 rest of the analysis engine. */
37
39{
40 public:
42 exploded_node *enode_for_diag,
43
44 /* TODO: should we be getting the ECs from the
45 old state, rather than the new? */
46 const program_state *old_state,
47 program_state *new_state,
48 uncertainty_t *uncertainty,
49 path_context *path_ctxt,
50
51 const gimple *stmt,
53
54 bool *out_could_have_done_work = nullptr);
55
58 uncertainty_t *uncertainty,
59 logger *logger = NULL);
60
61 bool warn (std::unique_ptr<pending_diagnostic> d,
62 const stmt_finder *custom_finder = NULL) final override;
63 void add_note (std::unique_ptr<pending_note> pn) final override;
64 void add_event (std::unique_ptr<checker_event> event) final override;
65 void on_svalue_leak (const svalue *) override;
66 void on_liveness_change (const svalue_set &live_svalues,
67 const region_model *model) final override;
68 logger *get_logger () final override
69 {
70 return m_logger.get_logger ();
71 }
72
74 const svalue *sval,
76
77 void on_condition (const svalue *lhs,
78 enum tree_code op,
79 const svalue *rhs) final override;
80
81 void on_bounded_ranges (const svalue &sval,
82 const bounded_ranges &ranges) final override;
83
84 void on_pop_frame (const frame_region *frame_reg) final override;
85
86 void on_unknown_change (const svalue *sval, bool is_mutable) final override;
87
88 void on_phi (const gphi *phi, tree rhs) final override;
89
91 const dump_location_t &loc) final override;
92
93 void on_escaped_function (tree fndecl) final override;
94
96
97 void purge_state_involving (const svalue *sval) final override;
98
99 void bifurcate (std::unique_ptr<custom_edge_info> info) final override;
100 void terminate_path () final override;
101 const extrinsic_state *get_ext_state () const final override
102 {
103 return &m_ext_state;
104 }
105 bool
106 get_state_map_by_name (const char *name,
107 sm_state_map **out_smap,
108 const state_machine **out_sm,
109 unsigned *out_sm_idx,
110 std::unique_ptr<sm_context> *out_sm_context) override;
111
112 const gimple *get_stmt () const override { return m_stmt; }
113 const exploded_graph *get_eg () const override { return m_eg; }
114
115 void maybe_did_work () override;
116 bool checking_for_infinite_loop_p () const override { return false; }
118
130};
131
132/* A <program_point, program_state> pair, used internally by
133 exploded_node as its immutable data, and as a key for identifying
134 exploded_nodes we've already seen in the graph. */
135
137{
138public:
140 const program_state &state)
141 : m_point (point),
142 m_state (state),
143 m_hash (m_point.hash () ^ m_state.hash ())
144 {
145 /* We shouldn't be building point_and_states and thus exploded_nodes
146 for states that aren't valid. */
147 gcc_assert (state.m_valid);
148 }
149
150 hashval_t hash () const
151 {
152 return m_hash;
153 }
154 bool operator== (const point_and_state &other) const
155 {
156 return m_point == other.m_point && m_state == other.m_state;
157 }
158
159 const program_point &get_point () const { return m_point; }
160 const program_state &get_state () const { return m_state; }
161
163 {
164 m_state = state;
165 m_hash = m_point.hash () ^ m_state.hash ();
166 }
167
168 void validate (const extrinsic_state &ext_state) const;
169
170private:
173 hashval_t m_hash;
174};
175
176/* A traits class for exploded graphs and their nodes and edges. */
177
179{
184 {
185 dump_args_t (const exploded_graph &eg) : m_eg (eg) {}
186
187 bool show_enode_details_p (const exploded_node &enode) const;
188
189 virtual void
191
193 };
194 typedef exploded_cluster cluster_t;
195};
196
197/* An exploded_node is a unique, immutable <point, state> pair within the
198 exploded_graph.
199 Each exploded_node has a unique index within the graph
200 (for ease of debugging). */
201
202class exploded_node : public dnode<eg_traits>
203{
204 public:
205 /* Has this enode had exploded_graph::process_node called on it?
206 This allows us to distinguish enodes that were merged during
207 worklist-handling, and thus never had process_node called on them
208 (in favor of processing the merged node). */
209 enum class status
210 {
211 /* Node is in the worklist. */
213
214 /* Node has had exploded_graph::process_node called on it. */
216
217 /* Node was excluded from worklist on creation.
218 e.g. for handling exception-unwinding. */
220
221 /* Node was left unprocessed due to merger; it won't have had
222 exploded_graph::process_node called on it. */
224
225 /* Node was processed by maybe_process_run_of_before_supernode_enodes. */
227 };
228 static const char * status_to_str (enum status s);
229
230 exploded_node (const point_and_state &ps, int index);
231
232 hashval_t hash () const { return m_ps.hash (); }
233
234 const char * get_dot_fillcolor () const;
235 void dump_dot (graphviz_out *gv, const dump_args_t &args)
236 const final override;
237 void dump_dot_id (pretty_printer *pp) const;
238
240 void dump (FILE *fp, const extrinsic_state &ext_state) const;
241 void dump (const extrinsic_state &ext_state) const;
242
245
246 std::unique_ptr<json::object> to_json (const extrinsic_state &ext_state) const;
247
248 /* The result of on_stmt. */
250 {
253
255 {
256 return on_stmt_flags (true);
257 }
258
259 /* Should we stop analyzing this path (on_stmt may have already
260 added nodes/edges, e.g. when handling longjmp). */
262
263 private:
267 };
268
270 const supernode *snode,
271 const gimple *stmt,
273 uncertainty_t *uncertainty,
274 bool *out_could_have_done_work,
275 path_context *path_ctxt);
277 const gimple *stmt,
279 bool *out_terminate_path,
280 bool *out_unknown_side_effects,
284 bool unknown_side_effects,
286
288 const supernode *snode,
289 const gcall &call_stmt,
291 path_context *path_ctxt,
292 const function &called_fn,
293 per_function_data &called_fn_data,
296 const supernode *snode,
297 const gcall &call_stmt,
299 path_context *path_ctxt,
300 const function &called_fn,
301 call_summary &summary,
303
305 const superedge *succ,
306 program_point *next_point,
307 program_state *next_state,
308 uncertainty_t *uncertainty);
310 const gcall &call,
311 program_state *new_state,
314 const gcall &call,
315 program_state *new_state,
316 bool is_rethrow,
319 const gresx &resx,
320 program_state *new_state,
322
324
325 const program_point &get_point () const { return m_ps.get_point (); }
326 const supernode *get_supernode () const
327 {
328 return get_point ().get_supernode ();
329 }
331 {
332 return get_point ().get_function ();
333 }
334 int get_stack_depth () const
335 {
336 return get_point ().get_stack_depth ();
337 }
338 const gimple *get_stmt () const { return get_point ().get_stmt (); }
339 const gimple *get_processed_stmt (unsigned idx) const;
340
341 const program_state &get_state () const { return m_ps.get_state (); }
342
343 const point_and_state *get_ps_key () const { return &m_ps; }
344 const program_point *get_point_key () const { return &m_ps.get_point (); }
345
346 void dump_succs_and_preds (FILE *outf) const;
347
348 enum status get_status () const { return m_status; }
349 void set_status (enum status s)
350 {
352 m_status = s;
353 }
354
356 {
357 m_saved_diagnostics.safe_push (sd);
358 }
359 unsigned get_num_diagnostics () const
360 {
361 return m_saved_diagnostics.length ();
362 }
363 const saved_diagnostic *get_saved_diagnostic (unsigned idx) const
364 {
365 return m_saved_diagnostics[idx];
366 }
367
368private:
370
371 /* The <program_point, program_state> pair. This is const, as it
372 is immutable once the exploded_node has been created. */
374
376
377 /* The saved_diagnostics at this enode, borrowed from the
378 diagnostic_manager. */
379 auto_vec <const saved_diagnostic *> m_saved_diagnostics;
380
381public:
382 /* The index of this exploded_node. */
383 const int m_index;
384
385 /* The number of stmts that were processed when process_node was
386 called on this enode. */
388};
389
390/* An edge within the exploded graph.
391 Some exploded_edges have an underlying superedge; others don't. */
392
393class exploded_edge : public dedge<eg_traits>
394{
395 public:
397 const superedge *sedge, bool could_do_work,
398 std::unique_ptr<custom_edge_info> custom_info);
399 void dump_dot (graphviz_out *gv, const dump_args_t &args)
400 const final override;
402
403 std::unique_ptr<json::object> to_json () const;
404
405 //private:
406 const superedge *const m_sedge;
407
408 /* NULL for most edges; will be non-NULL for special cases
409 such as an unwind from a longjmp to a setjmp, or when
410 a signal is delivered to a signal-handler. */
411 std::unique_ptr<custom_edge_info> m_custom_info;
412
413 bool could_do_work_p () const { return m_could_do_work_p; }
414
415private:
417
418 /* For -Wanalyzer-infinite-loop.
419 Set to true during processing if any of the activity along
420 this edge is "externally-visible work" (and thus ruling this
421 out as being part of an infinite loop.
422
423 For example, given:
424
425 while (1)
426 do_something ();
427
428 although it is an infinite loop, presumably the point of the
429 program is the loop body, and thus reporting this as an infinite
430 loop is likely to be unhelpful to the user. */
432};
433
434/* Extra data for an exploded_edge that represents dynamic call info ( calls
435 that doesn't have an underlying superedge representing the call ). */
436
438{
439public:
440 dynamic_call_info_t (const gcall &dynamic_call,
441 const bool is_returning_call = false)
442 : m_dynamic_call (dynamic_call),
443 m_is_returning_call (is_returning_call)
444 {}
445
446 void print (pretty_printer *pp) const final override
447 {
449 pp_string (pp, "dynamic_return");
450 else
451 pp_string (pp, "dynamic_call");
452 }
453
455 const exploded_edge *eedge,
456 region_model_context *ctxt) const final override;
457
458 void add_events_to_path (checker_path *emission_path,
459 const exploded_edge &eedge) const final override;
460private:
463};
464
465
466/* Extra data for an exploded_edge that represents a rewind from a
467 longjmp to a setjmp (or from a siglongjmp to a sigsetjmp). */
468
470{
471public:
473 const gcall &longjmp_call)
475 m_longjmp_call (longjmp_call)
476 {}
477
478 void print (pretty_printer *pp) const final override
479 {
480 pp_string (pp, "rewind");
481 }
482
484 const exploded_edge *eedge,
485 region_model_context *ctxt) const final override;
486
487 void add_events_to_path (checker_path *emission_path,
488 const exploded_edge &eedge) const final override;
489
491 {
492 const program_point &origin_point = get_enode_origin ()->get_point ();
493
494 /* "origin_point" ought to be before the call to "setjmp". */
495 gcc_assert (origin_point.get_kind () == PK_BEFORE_STMT);
496
497 /* TODO: assert that it's the final stmt in its supernode. */
498
499 return origin_point;
500 }
501
502 const gcall &get_setjmp_call () const
503 {
504 return *m_setjmp_record.m_setjmp_call;
505 }
506
507 const gcall &get_longjmp_call () const
508 {
509 return m_longjmp_call;
510 }
511
513 {
514 return m_setjmp_record.m_enode;
515 }
516
517private:
520};
521
522/* Statistics about aspects of an exploded_graph. */
523
524struct stats
525{
526 stats (int num_supernodes);
527 void log (logger *logger) const;
528 void dump (FILE *out) const;
529
530 int get_total_enodes () const;
531
536};
537
538/* Traits class for ensuring uniqueness of point_and_state data within
539 an exploded_graph. */
540
542{
543 typedef const point_and_state *key_type;
546
547 static inline hashval_t hash (const key_type &k)
548 {
549 gcc_assert (k != NULL);
550 gcc_assert (k != reinterpret_cast<key_type> (1));
551 return k->hash ();
552 }
553 static inline bool equal_keys (const key_type &k1, const key_type &k2)
554 {
555 gcc_assert (k1 != NULL);
556 gcc_assert (k2 != NULL);
557 gcc_assert (k1 != reinterpret_cast<key_type> (1));
558 gcc_assert (k2 != reinterpret_cast<key_type> (1));
559 if (k1 && k2)
560 return *k1 == *k2;
561 else
562 /* Otherwise they must both be non-NULL. */
563 return k1 == k2;
564 }
565 template <typename T>
566 static inline void remove (T &)
567 {
568 /* empty; the nodes are handled elsewhere. */
569 }
570 template <typename T>
571 static inline void mark_deleted (T &entry)
572 {
573 entry.m_key = reinterpret_cast<key_type> (1);
574 }
575 template <typename T>
576 static inline void mark_empty (T &entry)
577 {
578 entry.m_key = NULL;
579 }
580 template <typename T>
581 static inline bool is_deleted (const T &entry)
582 {
583 return entry.m_key == reinterpret_cast<key_type> (1);
584 }
585 template <typename T>
586 static inline bool is_empty (const T &entry)
587 {
588 return entry.m_key == NULL;
589 }
590 static const bool empty_zero_p = false;
591};
592
593/* Per-program_point data for an exploded_graph. */
594
596{
598 : m_key (key), m_excess_enodes (0)
599 {}
600
603 /* The number of attempts to create an enode for this point
604 after exceeding --param=analyzer-max-enodes-per-program-point. */
606};
607
608/* Traits class for storing per-program_point data within
609 an exploded_graph. */
610
612{
613 typedef const program_point *key_type;
616
617 static inline hashval_t hash (const key_type &k)
618 {
619 gcc_assert (k != NULL);
620 gcc_assert (k != reinterpret_cast<key_type> (1));
621 return k->hash ();
622 }
623 static inline bool equal_keys (const key_type &k1, const key_type &k2)
624 {
625 gcc_assert (k1 != NULL);
626 gcc_assert (k2 != NULL);
627 gcc_assert (k1 != reinterpret_cast<key_type> (1));
628 gcc_assert (k2 != reinterpret_cast<key_type> (1));
629 if (k1 && k2)
630 return *k1 == *k2;
631 else
632 /* Otherwise they must both be non-NULL. */
633 return k1 == k2;
634 }
635 template <typename T>
636 static inline void remove (T &)
637 {
638 /* empty; the nodes are handled elsewhere. */
639 }
640 template <typename T>
641 static inline void mark_deleted (T &entry)
642 {
643 entry.m_key = reinterpret_cast<key_type> (1);
644 }
645 template <typename T>
646 static inline void mark_empty (T &entry)
647 {
648 entry.m_key = NULL;
649 }
650 template <typename T>
651 static inline bool is_deleted (const T &entry)
652 {
653 return entry.m_key == reinterpret_cast<key_type> (1);
654 }
655 template <typename T>
656 static inline bool is_empty (const T &entry)
657 {
658 return entry.m_key == NULL;
659 }
660 static const bool empty_zero_p = false;
661};
662
663/* Data about a particular call_string within an exploded_graph. */
664
666{
667 per_call_string_data (const call_string &key, int num_supernodes)
668 : m_key (key), m_stats (num_supernodes)
669 {}
670
673};
674
675/* Data about a particular function within an exploded_graph. */
676
686
687
688/* The strongly connected components of a supergraph.
689 In particular, this allows us to compute a partial ordering
690 of supernodes. */
691
693{
694public:
696
697 int get_scc_id (int node_index) const
698 {
699 return m_per_node[node_index].m_lowlink;
700 }
701
702 void dump () const;
703
704 std::unique_ptr<json::array> to_json () const;
705
706private:
708 {
710 : m_index (-1), m_lowlink (-1), m_on_stack (false)
711 {}
712
716 };
717
718 void strong_connect (unsigned index);
719
723};
724
725/* The worklist of exploded_node instances that have been added to
726 an exploded_graph, but that haven't yet been processed to find
727 their successors (or warnings).
728
729 The enodes are stored in a priority queue, ordered by a topological
730 sort of the SCCs in the supergraph, so that enodes for the same
731 program_point should appear at the front of the queue together.
732 This allows for state-merging at CFG join-points, so that
733 sufficiently-similar enodes can be merged into one. */
734
736{
737public:
738 worklist (const exploded_graph &eg, const analysis_plan &plan);
739 unsigned length () const;
742 void add_node (exploded_node *enode);
743 int get_scc_id (const supernode &snode) const
744 {
745 return m_scc.get_scc_id (snode.m_index);
746 }
747
748 std::unique_ptr<json::object> to_json () const;
749
750private:
751 class key_t
752 {
753 public:
754 key_t (const worklist &w, exploded_node *enode)
755 : m_worklist (w), m_enode (enode)
756 {}
757
758 bool operator< (const key_t &other) const
759 {
760 return cmp (*this, other) < 0;
761 }
762
763 bool operator== (const key_t &other) const
764 {
765 return cmp (*this, other) == 0;
766 }
767
768 bool operator> (const key_t &other) const
769 {
770 return !(*this == other || *this < other);
771 }
772
773 private:
774 static int cmp (const key_t &ka, const key_t &kb);
775
776 int get_scc_id (const exploded_node *enode) const
777 {
778 const supernode *snode = enode->get_supernode ();
779 if (snode == NULL)
780 return 0;
781 return m_worklist.m_scc.get_scc_id (snode->m_index);
782 }
783
786 };
787
788 /* The order is important here: m_scc needs to stick around
789 until after m_queue has finished being cleaned up (the dtor
790 calls the ordering fns). */
793
794 /* Priority queue, backed by a fibonacci_heap. */
797};
798
799/* An exploded_graph is a directed graph of unique <point, state> pairs.
800 It also has a worklist of nodes that are waiting for their successors
801 to be added to the graph. */
802
803class exploded_graph : public digraph<eg_traits>
804{
805public:
806 typedef hash_map <const call_string *,
808
811 const state_purge_map *purge_map,
812 const analysis_plan &plan,
813 int verbosity);
815
816 logger *get_logger () const { return m_logger.get_logger (); }
817
818 const supergraph &get_supergraph () const { return m_sg; }
819 const extrinsic_state &get_ext_state () const { return m_ext_state; }
820 engine *get_engine () const { return m_ext_state.get_engine (); }
821 const state_purge_map *get_purge_map () const { return m_purge_map; }
822 const analysis_plan &get_analysis_plan () const { return m_plan; }
823
824 exploded_node *get_origin () const { return m_origin; }
825
827
832
834 tree fn_decl,
835 exploded_node *node,
836 program_state next_state,
837 program_point &next_point,
838 uncertainty_t *uncertainty,
839 logger *logger);
840
842 const program_state &state,
843 exploded_node *enode_for_diag,
844 bool add_to_worklist = true);
846 const superedge *sedge, bool could_do_work,
847 std::unique_ptr<custom_edge_info> custom = NULL);
848
853
856
860
862 const exploded_node *enode,
863 const supernode *node, const gimple *stmt,
864 stmt_finder *finder,
867
873 {
875 }
876
879 void log_stats () const;
880 void dump_stats (FILE *) const;
881 void dump_states_for_supernode (FILE *, const supernode *snode) const;
882 void dump_exploded_nodes () const;
883
884 std::unique_ptr<json::object> to_json () const;
885
887
890
891 int get_scc_id (const supernode &node) const
892 {
893 return m_worklist.get_scc_id (node);
894 }
895
897
899 const gimple *stmt,
901
902 /* In infinite-loop.cc */
903 void detect_infinite_loops ();
904
905 /* In infinite-recursion.cc */
908 exploded_node *enode) const;
909
910private:
912
914
916
918
919 /* Map from point/state to exploded node.
920 To avoid duplication we store point_and_state
921 *pointers* as keys, rather than point_and_state, using the
922 instance from within the exploded_node, with a custom hasher. */
923 typedef hash_map <const point_and_state *, exploded_node *,
926
927 /* Map from program_point to per-program_point data. */
931
933
935
937
939
941
944
946
947 /* Stats. */
952
954
956
957 /* Functions with a top-level enode, to make add_function_entry
958 be idempotent, for use in handling callbacks. */
960};
961
962/* A path within an exploded_graph: a sequence of edges. */
963
965{
966public:
969
970 unsigned length () const { return m_edges.length (); }
971
972 bool find_stmt_backwards (const gimple *search_stmt,
973 int *out_idx) const;
974
976
978 const extrinsic_state *ext_state) const;
979 void dump (FILE *fp, const extrinsic_state *ext_state) const;
980 void dump (const extrinsic_state *ext_state = NULL) const;
981 void dump_to_file (const char *filename,
982 const extrinsic_state &ext_state) const;
983
984 bool feasible_p (logger *logger, std::unique_ptr<feasibility_problem> *out,
985 engine *eng, const exploded_graph *eg) const;
986
988};
989
990/* A reason why a particular exploded_path is infeasible. */
991
993{
994public:
995 feasibility_problem (unsigned eedge_idx,
996 const exploded_edge &eedge,
997 const gimple *last_stmt,
998 std::unique_ptr<rejected_constraint> rc)
999 : m_eedge_idx (eedge_idx), m_eedge (eedge),
1000 m_last_stmt (last_stmt), m_rc (std::move (rc))
1001 {}
1002
1003 void dump_to_pp (pretty_printer *pp) const;
1004
1005 unsigned m_eedge_idx;
1008 std::unique_ptr<rejected_constraint> m_rc;
1009};
1010
1011/* A class for capturing the state of a node when checking a path
1012 through the exploded_graph for feasibility. */
1013
1015{
1016public:
1018 const supergraph &sg);
1020 const supergraph &sg);
1022
1024
1026 const exploded_edge *eedge,
1028 std::unique_ptr<rejected_constraint> *out_rc);
1030
1031 const region_model &get_model () const { return m_model; }
1033
1034 void dump_to_pp (pretty_printer *pp, bool simple, bool multiline) const;
1035
1036private:
1039};
1040
1041/* Finding the shortest exploded_path within an exploded_graph. */
1042
1044
1045/* Abstract base class for use when passing NULL as the stmt for
1046 a possible warning, allowing the choice of stmt to be deferred
1047 until after we have an emission path (and know we're emitting a
1048 warning). */
1049
1051{
1052public:
1053 virtual ~stmt_finder () {}
1054 virtual std::unique_ptr<stmt_finder> clone () const = 0;
1055 virtual const gimple *find_stmt (const exploded_path &epath) = 0;
1057};
1058
1059// TODO: split the above up?
1060
1061} // namespace ana
1062
1063#endif /* GCC_ANALYZER_EXPLODED_GRAPH_H */
Definition analysis-plan.h:35
Definition call-string.h:48
Definition call-summary.h:34
Definition checker-path.h:32
Definition common.h:382
Definition diagnostic-manager.h:154
void print(pretty_printer *pp) const final override
Definition exploded-graph.h:446
const bool m_is_returning_call
Definition exploded-graph.h:462
bool update_model(region_model *model, const exploded_edge *eedge, region_model_context *ctxt) const final override
dynamic_call_info_t(const gcall &dynamic_call, const bool is_returning_call=false)
Definition exploded-graph.h:440
void add_events_to_path(checker_path *emission_path, const exploded_edge &eedge) const final override
const gcall & m_dynamic_call
Definition exploded-graph.h:461
Definition region-model.h:1338
Definition exploded-graph.h:394
std::unique_ptr< json::object > to_json() const
void dump_dot_label(pretty_printer *pp) const
bool m_could_do_work_p
Definition exploded-graph.h:431
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:411
void dump_dot(graphviz_out *gv, const dump_args_t &args) const final override
bool could_do_work_p() const
Definition exploded-graph.h:413
DISABLE_COPY_AND_ASSIGN(exploded_edge)
const superedge *const m_sedge
Definition exploded-graph.h:406
Definition exploded-graph.h:804
hash_map< const point_and_state *, exploded_node *, eg_hash_map_traits > map_t
Definition exploded-graph.h:924
void log_stats() const
stats * get_global_stats()
Definition exploded-graph.h:877
const call_string_data_map_t * get_per_call_string_data() const
Definition exploded-graph.h:888
const state_purge_map * get_purge_map() const
Definition exploded-graph.h:821
const extrinsic_state & m_ext_state
Definition exploded-graph.h:936
void detect_infinite_recursion(exploded_node *enode)
Definition infinite-recursion.cc:582
call_string_data_map_t m_per_call_string_data
Definition exploded-graph.h:953
stats m_functionless_stats
Definition exploded-graph.h:951
exploded_node * find_previous_entry_to(function *top_of_stack_fun, exploded_node *enode) const
Definition infinite-recursion.cc:325
auto_vec< int > m_PK_AFTER_SUPERNODE_per_snode
Definition exploded-graph.h:955
function_stat_map_t m_per_function_stats
Definition exploded-graph.h:950
void detect_infinite_loops()
Definition infinite-loop.cc:535
void process_node(exploded_node *node)
engine * get_engine() const
Definition exploded-graph.h:820
point_map_t m_per_point_data
Definition exploded-graph.h:930
diagnostic_manager & get_diagnostic_manager()
Definition exploded-graph.h:868
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:917
exploded_edge * add_edge(exploded_node *src, exploded_node *dest, const superedge *sedge, bool could_do_work, std::unique_ptr< custom_edge_info > custom=NULL)
const supergraph & get_supergraph() const
Definition exploded-graph.h:818
const analysis_plan & get_analysis_plan() const
Definition exploded-graph.h:822
map_t m_point_and_state_to_node
Definition exploded-graph.h:925
const supergraph & m_sg
Definition exploded-graph.h:915
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:945
hash_map< function *, per_function_data * > per_function_data_t
Definition exploded-graph.h:942
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:872
per_program_point_data * get_per_program_point_data(const program_point &) const
logger * get_logger() const
Definition exploded-graph.h:816
exploded_node * m_origin
Definition exploded-graph.h:934
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:807
hash_set< function * > m_functions_with_enodes
Definition exploded-graph.h:959
stats * get_or_create_function_stats(function *fn)
void print_bar_charts(pretty_printer *pp) const
void dump_states_for_supernode(FILE *, const supernode *snode) const
bool maybe_create_dynamic_call(const gcall &call, tree fn_decl, exploded_node *node, program_state next_state, program_point &next_point, uncertainty_t *uncertainty, logger *logger)
stats m_global_stats
Definition exploded-graph.h:948
ordered_hash_map< function *, stats * > function_stat_map_t
Definition exploded-graph.h:949
const extrinsic_state & get_ext_state() const
Definition exploded-graph.h:819
worklist m_worklist
Definition exploded-graph.h:932
void dump_stats(FILE *) const
int get_scc_id(const supernode &node) const
Definition exploded-graph.h:891
hash_map< const program_point *, per_program_point_data *, eg_point_hash_map_traits > point_map_t
Definition exploded-graph.h:929
std::unique_ptr< json::object > to_json() const
const state_purge_map *const m_purge_map
Definition exploded-graph.h:938
const analysis_plan & m_plan
Definition exploded-graph.h:940
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:943
exploded_node * get_origin() const
Definition exploded-graph.h:824
void save_diagnostic(const state_machine &sm, const exploded_node *enode, const supernode *node, const gimple *stmt, stmt_finder *finder, tree var, state_machine::state_t state, pending_diagnostic *d)
bool maybe_process_run_of_before_supernode_enodes(exploded_node *node)
exploded_node * get_node_by_index(int idx) const
DISABLE_COPY_AND_ASSIGN(exploded_graph)
Definition exploded-graph.h:203
DISABLE_COPY_AND_ASSIGN(exploded_node)
const point_and_state * get_ps_key() const
Definition exploded-graph.h:343
void on_stmt_post(const gimple *stmt, program_state *state, bool unknown_side_effects, region_model_context *ctxt)
void dump(const extrinsic_state &ext_state) const
unsigned m_num_processed_stmts
Definition exploded-graph.h:387
status
Definition exploded-graph.h:210
@ special
Definition exploded-graph.h:219
@ bulk_merged
Definition exploded-graph.h:226
@ worklist
Definition exploded-graph.h:212
@ merger
Definition exploded-graph.h:223
@ processed
Definition exploded-graph.h:215
function * get_function() const
Definition exploded-graph.h:330
void dump_to_pp(pretty_printer *pp, const extrinsic_state &ext_state) const
bool on_edge(exploded_graph &eg, const superedge *succ, program_point *next_point, program_state *next_state, uncertainty_t *uncertainty)
unsigned get_num_diagnostics() const
Definition exploded-graph.h:359
void dump_saved_diagnostics(pretty_printer *pp) const
void dump_dot(graphviz_out *gv, const dump_args_t &args) const final override
void on_stmt_pre(exploded_graph &eg, const gimple *stmt, program_state *state, bool *out_terminate_path, bool *out_unknown_side_effects, region_model_context *ctxt)
std::unique_ptr< json::object > to_json(const extrinsic_state &ext_state) const
const gimple * get_stmt() const
Definition exploded-graph.h:338
void add_diagnostic(const saved_diagnostic *sd)
Definition exploded-graph.h:355
void dump_processed_stmts(pretty_printer *pp) const
const point_and_state m_ps
Definition exploded-graph.h:373
void on_resx(exploded_graph &eg, const gresx &resx, program_state *new_state, region_model_context *ctxt)
const char * get_dot_fillcolor() const
void dump_dot_id(pretty_printer *pp) const
const program_state & get_state() const
Definition exploded-graph.h:341
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:383
const gimple * get_processed_stmt(unsigned idx) const
void replay_call_summary(exploded_graph &eg, const supernode *snode, const gcall &call_stmt, program_state *state, path_context *path_ctxt, const function &called_fn, call_summary &summary, region_model_context *ctxt)
const program_point * get_point_key() const
Definition exploded-graph.h:344
enum status get_status() const
Definition exploded-graph.h:348
void set_status(enum status s)
Definition exploded-graph.h:349
int get_stack_depth() const
Definition exploded-graph.h:334
void on_longjmp(exploded_graph &eg, const gcall &call, program_state *new_state, region_model_context *ctxt)
on_stmt_flags on_stmt(exploded_graph &eg, const supernode *snode, const gimple *stmt, program_state *state, uncertainty_t *uncertainty, bool *out_could_have_done_work, path_context *path_ctxt)
exploded_node(const point_and_state &ps, int index)
const program_point & get_point() const
Definition exploded-graph.h:325
void dump(FILE *fp, const extrinsic_state &ext_state) const
auto_vec< const saved_diagnostic * > m_saved_diagnostics
Definition exploded-graph.h:379
const supernode * get_supernode() const
Definition exploded-graph.h:326
void detect_leaks(exploded_graph &eg)
hashval_t hash() const
Definition exploded-graph.h:232
on_stmt_flags replay_call_summaries(exploded_graph &eg, const supernode *snode, const gcall &call_stmt, program_state *state, path_context *path_ctxt, const function &called_fn, per_function_data &called_fn_data, region_model_context *ctxt)
enum status m_status
Definition exploded-graph.h:375
void on_throw(exploded_graph &eg, const gcall &call, program_state *new_state, bool is_rethrow, region_model_context *ctxt)
const saved_diagnostic * get_saved_diagnostic(unsigned idx) const
Definition exploded-graph.h:363
Definition exploded-graph.h:965
exploded_path()
Definition exploded-graph.h:967
unsigned length() const
Definition exploded-graph.h:970
exploded_node * get_final_enode() const
void dump(FILE *fp, const extrinsic_state *ext_state) const
void dump(const extrinsic_state *ext_state=NULL) const
bool find_stmt_backwards(const gimple *search_stmt, int *out_idx) const
bool feasible_p(logger *logger, std::unique_ptr< feasibility_problem > *out, engine *eng, const exploded_graph *eg) const
void dump_to_file(const char *filename, const extrinsic_state &ext_state) const
void dump_to_pp(pretty_printer *pp, const extrinsic_state *ext_state) const
auto_vec< const exploded_edge * > m_edges
Definition exploded-graph.h:987
exploded_path(const exploded_path &other)
Definition program-state.h:31
const exploded_edge & m_eedge
Definition exploded-graph.h:1006
void dump_to_pp(pretty_printer *pp) const
const gimple * m_last_stmt
Definition exploded-graph.h:1007
unsigned m_eedge_idx
Definition exploded-graph.h:1005
feasibility_problem(unsigned eedge_idx, const exploded_edge &eedge, const gimple *last_stmt, std::unique_ptr< rejected_constraint > rc)
Definition exploded-graph.h:995
std::unique_ptr< rejected_constraint > m_rc
Definition exploded-graph.h:1008
bool maybe_update_for_edge(logger *logger, const exploded_edge *eedge, region_model_context *ctxt, std::unique_ptr< rejected_constraint > *out_rc)
feasibility_state(const region_model &model, const supergraph &sg)
auto_sbitmap m_snodes_visited
Definition exploded-graph.h:1038
feasibility_state(region_model_manager *manager, const supergraph &sg)
void dump_to_pp(pretty_printer *pp, bool simple, bool multiline) const
feasibility_state(const feasibility_state &other)
region_model m_model
Definition exploded-graph.h:1037
const region_model & get_model() const
Definition exploded-graph.h:1031
feasibility_state & operator=(const feasibility_state &other)
const auto_sbitmap & get_snodes_visited() const
Definition exploded-graph.h:1032
void update_for_stmt(const gimple *stmt)
Definition region.h:319
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
exploded_graph * m_eg
Definition exploded-graph.h:119
const extrinsic_state & m_ext_state
Definition exploded-graph.h:126
logger * get_logger() final override
Definition exploded-graph.h:68
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:129
void on_state_leak(const state_machine &sm, const svalue *sval, state_machine::state_t state)
void add_event(std::unique_ptr< checker_event > event) final override
program_state * m_new_state
Definition exploded-graph.h:123
log_user m_logger
Definition exploded-graph.h:120
const program_state * m_old_state
Definition exploded-graph.h:122
void on_unusable_in_infinite_loop() override
Definition exploded-graph.h:117
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
stmt_finder * m_stmt_finder
Definition exploded-graph.h:125
path_context * m_path_ctxt
Definition exploded-graph.h:128
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
impl_region_model_context(program_state *state, const extrinsic_state &ext_state, uncertainty_t *uncertainty, logger *logger=NULL)
const gimple * m_stmt
Definition exploded-graph.h:124
uncertainty_t * m_uncertainty
Definition exploded-graph.h:127
const gimple * get_stmt() const override
Definition exploded-graph.h:112
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:116
const extrinsic_state * get_ext_state() const final override
Definition exploded-graph.h:101
const exploded_graph * get_eg() const override
Definition exploded-graph.h:113
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, stmt_finder *stmt_finder=NULL, bool *out_could_have_done_work=nullptr)
exploded_node * m_enode_for_diag
Definition exploded-graph.h:121
bool warn(std::unique_ptr< pending_diagnostic > d, const stmt_finder *custom_finder=NULL) final override
Definition analyzer-logging.h:147
Definition analyzer-logging.h:34
Definition common.h:420
Definition pending-diagnostic.h:190
Definition exploded-graph.h:137
hashval_t m_hash
Definition exploded-graph.h:173
bool operator==(const point_and_state &other) const
Definition exploded-graph.h:154
void validate(const extrinsic_state &ext_state) const
const program_state & get_state() const
Definition exploded-graph.h:160
program_state m_state
Definition exploded-graph.h:172
program_point m_point
Definition exploded-graph.h:171
point_and_state(const program_point &point, const program_state &state)
Definition exploded-graph.h:139
const program_point & get_point() const
Definition exploded-graph.h:159
hashval_t hash() const
Definition exploded-graph.h:150
void set_state(const program_state &state)
Definition exploded-graph.h:162
Definition program-point.h:175
function * get_function() const
Definition program-point.h:209
const supernode * get_supernode() const
Definition program-point.h:205
int get_stack_depth() const
Definition program-point.h:244
enum point_kind get_kind() const
Definition program-point.h:227
hashval_t hash() const
const gimple * get_stmt() const
Definition program-point.h:219
Definition program-state.h:221
Definition region-model.h:815
Definition region-model-manager.h:32
Definition region-model.h:298
setjmp_record m_setjmp_record
Definition exploded-graph.h:518
const program_point & get_setjmp_point() const
Definition exploded-graph.h:490
bool update_model(region_model *model, const exploded_edge *eedge, region_model_context *ctxt) const final override
const gcall & get_setjmp_call() const
Definition exploded-graph.h:502
void print(pretty_printer *pp) const final override
Definition exploded-graph.h:478
const exploded_node * get_enode_origin() const
Definition exploded-graph.h:512
const gcall & m_longjmp_call
Definition exploded-graph.h:519
void add_events_to_path(checker_path *emission_path, const exploded_edge &eedge) const final override
rewind_info_t(const setjmp_record &setjmp_record, const gcall &longjmp_call)
Definition exploded-graph.h:472
const gcall & get_longjmp_call() const
Definition exploded-graph.h:507
Definition diagnostic-manager.h:31
Definition program-state.h:89
Definition sm.h:40
const state_machine::state * state_t
Definition sm.h:60
Definition state-purge.h:78
Definition exploded-graph.h:1051
virtual void update_event_loc_info(event_loc_info &)=0
virtual ~stmt_finder()
Definition exploded-graph.h:1053
virtual const gimple * find_stmt(const exploded_path &epath)=0
virtual std::unique_ptr< stmt_finder > clone() const =0
Definition exploded-graph.h:693
void strong_connect(unsigned index)
int get_scc_id(int node_index) const
Definition exploded-graph.h:697
auto_vec< per_node_data > m_per_node
Definition exploded-graph.h:722
const supergraph & m_sg
Definition exploded-graph.h:720
strongly_connected_components(const supergraph &sg, logger *logger)
auto_vec< unsigned > m_stack
Definition exploded-graph.h:721
std::unique_ptr< json::array > to_json() const
Definition supergraph.h:318
Definition supergraph.h:113
Definition supergraph.h:239
const int m_index
Definition supergraph.h:311
Definition svalue.h:92
Definition store.h:161
bool operator<(const key_t &other) const
Definition exploded-graph.h:758
const worklist & m_worklist
Definition exploded-graph.h:784
bool operator==(const key_t &other) const
Definition exploded-graph.h:763
exploded_node * m_enode
Definition exploded-graph.h:785
bool operator>(const key_t &other) const
Definition exploded-graph.h:768
static int cmp(const key_t &ka, const key_t &kb)
int get_scc_id(const exploded_node *enode) const
Definition exploded-graph.h:776
key_t(const worklist &w, exploded_node *enode)
Definition exploded-graph.h:754
Definition exploded-graph.h:736
std::unique_ptr< json::object > to_json() const
void add_node(exploded_node *enode)
strongly_connected_components m_scc
Definition exploded-graph.h:791
worklist(const exploded_graph &eg, const analysis_plan &plan)
queue_t m_queue
Definition exploded-graph.h:796
exploded_node * take_next()
fibonacci_heap< key_t, exploded_node > queue_t
Definition exploded-graph.h:795
exploded_node * peek_next()
const analysis_plan & m_plan
Definition exploded-graph.h:792
int get_scc_id(const supernode &snode) const
Definition exploded-graph.h:743
unsigned length() const
Definition sbitmap.h:300
Definition vec.h:1667
dedge(node_t *src, node_t *dest)
Definition digraph.h:64
eg_traits::dump_args_t dump_args_t
Definition digraph.h:62
digraph()
Definition digraph.h:88
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:29
Definition hash-map.h:40
Definition hash-set.h:37
Definition ordered-hash-map.h:35
Definition pretty-print.h:241
Definition shortest-paths.h:49
union tree_node * tree
Definition coretypes.h:97
void final(rtx_insn *first, FILE *file, int optimize_p)
Definition final.cc:2008
tree_code
Definition genmatch.cc:1002
Definition access-diagram.h:30
@ stmt
Definition checker-event.h:37
@ custom
Definition checker-event.h:36
shortest_paths< eg_traits, exploded_path > shortest_exploded_paths
Definition exploded-graph.h:1043
@ NUM_POINT_KINDS
Definition program-point.h:45
@ PK_BEFORE_STMT
Definition program-point.h:38
hash_set< const svalue * > svalue_set
Definition common.h:78
void pp_string(pretty_printer *pp, const char *str)
Definition pretty-print.cc:2652
Definition constraint-manager.h:123
Definition exploded-graph.h:542
static bool equal_keys(const key_type &k1, const key_type &k2)
Definition exploded-graph.h:553
static void mark_empty(T &entry)
Definition exploded-graph.h:576
static void mark_deleted(T &entry)
Definition exploded-graph.h:571
static bool is_deleted(const T &entry)
Definition exploded-graph.h:581
static const bool empty_zero_p
Definition exploded-graph.h:590
exploded_node * compare_type
Definition exploded-graph.h:545
const point_and_state * key_type
Definition exploded-graph.h:543
exploded_node * value_type
Definition exploded-graph.h:544
static void remove(T &)
Definition exploded-graph.h:566
static hashval_t hash(const key_type &k)
Definition exploded-graph.h:547
static bool is_empty(const T &entry)
Definition exploded-graph.h:586
Definition exploded-graph.h:612
static bool is_deleted(const T &entry)
Definition exploded-graph.h:651
static const bool empty_zero_p
Definition exploded-graph.h:660
static void mark_empty(T &entry)
Definition exploded-graph.h:646
static hashval_t hash(const key_type &k)
Definition exploded-graph.h:617
const program_point * key_type
Definition exploded-graph.h:613
per_program_point_data * value_type
Definition exploded-graph.h:614
per_program_point_data * compare_type
Definition exploded-graph.h:615
static void mark_deleted(T &entry)
Definition exploded-graph.h:641
static bool is_empty(const T &entry)
Definition exploded-graph.h:656
static bool equal_keys(const key_type &k1, const key_type &k2)
Definition exploded-graph.h:623
static void remove(T &)
Definition exploded-graph.h:636
bool show_enode_details_p(const exploded_node &enode) const
const exploded_graph & m_eg
Definition exploded-graph.h:192
virtual void dump_extra_info(const exploded_node *, pretty_printer *) const
Definition exploded-graph.h:190
dump_args_t(const exploded_graph &eg)
Definition exploded-graph.h:185
Definition exploded-graph.h:179
exploded_graph graph_t
Definition exploded-graph.h:182
exploded_edge edge_t
Definition exploded-graph.h:181
exploded_node node_t
Definition exploded-graph.h:180
exploded_cluster cluster_t
Definition exploded-graph.h:194
Definition event-loc-info.h:29
Definition exploded-graph.h:250
static on_stmt_flags terminate_path()
Definition exploded-graph.h:254
on_stmt_flags()
Definition exploded-graph.h:251
bool m_terminate_path
Definition exploded-graph.h:261
on_stmt_flags(bool terminate_path)
Definition exploded-graph.h:264
Definition exploded-graph.h:666
stats m_stats
Definition exploded-graph.h:672
const call_string & m_key
Definition exploded-graph.h:671
per_call_string_data(const call_string &key, int num_supernodes)
Definition exploded-graph.h:667
Definition exploded-graph.h:678
per_function_data()
Definition exploded-graph.h:679
auto_vec< call_summary * > m_summaries
Definition exploded-graph.h:684
void add_call_summary(exploded_node *node)
Definition exploded-graph.h:596
const program_point m_key
Definition exploded-graph.h:601
int m_excess_enodes
Definition exploded-graph.h:605
per_program_point_data(const program_point &key)
Definition exploded-graph.h:597
auto_vec< exploded_node * > m_enodes
Definition exploded-graph.h:602
Definition svalue.h:531
Definition exploded-graph.h:525
void log(logger *logger) const
void dump(FILE *out) const
int m_num_supernodes
Definition exploded-graph.h:535
int m_node_reuse_after_merge_count
Definition exploded-graph.h:534
stats(int num_supernodes)
int get_total_enodes() const
int m_num_nodes[NUM_POINT_KINDS]
Definition exploded-graph.h:532
int m_node_reuse_count
Definition exploded-graph.h:533
per_node_data()
Definition exploded-graph.h:709
bool m_on_stack
Definition exploded-graph.h:715
int m_index
Definition exploded-graph.h:713
int m_lowlink
Definition exploded-graph.h:714
Definition function.h:249
Definition gimple.h:352
Definition gimple.h:221
Definition gimple.h:461
Definition gimple.h:488
Definition ira-emit.cc:158
Definition gengtype.h:377
Definition genautomata.cc:669
#define NULL
Definition system.h:50
#define gcc_assert(EXPR)
Definition system.h:814
#define false
Definition system.h:888
static void add_to_worklist(same_succ *same)
Definition tree-ssa-tail-merge.cc:714