aboutsummaryrefslogtreecommitdiff
path: root/gcc/analyzer/ana-state-to-diagnostic-state.h
blob: 3a5ccc1b4306b27984e0a0e8366134ab82e18a3f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
/* Creating diagnostic state graphs from ana::program_state.
   Copyright (C) 2025 Free Software Foundation, Inc.
   Contributed by David Malcolm <dmalcolm@redhat.com>.

This file is part of GCC.

GCC is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.

GCC is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */

#ifndef GCC_ANALYZER_ANA_STATE_TO_DIAGNOSTIC_STATE_H
#define GCC_ANALYZER_ANA_STATE_TO_DIAGNOSTIC_STATE_H

#include "diagnostics/state-graphs.h"
#include "tree-logical-location.h"

namespace ana {

class analyzer_state_graph : public diagnostics::digraphs::digraph
{
public:
  analyzer_state_graph (const program_state &state,
			const extrinsic_state &ext_state);
  diagnostics::state_graphs::state_node_ref
  get_or_create_state_node (const region &reg);

private:
  struct pending_edge
  {
    diagnostics::state_graphs::state_node_ref m_src_node;
    const region &m_dst_reg;
  };
  
  diagnostics::state_graphs::state_node_ref
  create_and_add_state_node (const region &reg);

  std::unique_ptr<diagnostics::digraphs::node>
  make_state_node (diagnostics::state_graphs::node_kind kind,
		   std::string id);

  std::unique_ptr<diagnostics::digraphs::node>
  make_memspace_state_node (const region &reg,
			    enum diagnostics::state_graphs::node_kind kind);

  std::unique_ptr<diagnostics::digraphs::node>
  create_state_node (const region &reg);

  /* Spatially sorted concrete bindings.  */
  typedef std::map<bit_range, const svalue *> concrete_bindings_t;

  void
  create_state_nodes_for_binding_cluster (const binding_cluster &cluster,
					  bool create_all);

  std::unique_ptr<diagnostics::digraphs::node>
  create_state_node_for_conc_bindings (const concrete_bindings_t &conc_bindings);

  // Try to get the bit_range of REG within its base region
  bool
  get_bit_range_within_base_region (const region &reg,
				    bit_range &out);

  void
  populate_state_node_for_typed_region (diagnostics::state_graphs::state_node_ref,
					const region &reg,
					const concrete_bindings_t &conc_bindings,
					bool create_all);

  void
  set_attr_for_dynamic_extents (const region &reg,
				diagnostics::state_graphs::state_node_ref);

  bool
  show_child_state_node_for_child_region_p (const region &reg,
					    const concrete_bindings_t &conc_bindings,
					    bool create_all);

  std::unique_ptr<diagnostics::digraphs::node>
  create_state_node_for_svalue (const svalue *sval);

  std::string make_node_id (const region &reg);
  std::string make_node_id (const char *prefix);

  tree_logical_location_manager m_logical_loc_mgr;
  const program_state &m_state;
  const extrinsic_state &m_ext_state;
  region_model_manager &m_mgr;
  std::map<const region *, diagnostics::digraphs::node *> m_region_to_state_node_map;
  std::map<const region *, tree> m_types_for_untyped_regions;
  unsigned m_next_id;
  std::vector<pending_edge> m_pending_edges;
};

} // namespace ana

#endif /* GCC_ANALYZER_ANA_STATE_TO_DIAGNOSTIC_STATE_H */