d: Add test for PR d/108167 to the testsuite [PR108167]
[official-gcc.git] / gcc / analyzer / program-point.h
blobd1f8480fa8c3d27d6fdb71e04d126e4789b220ff
1 /* Classes for representing locations within the program.
2 Copyright (C) 2019-2023 Free Software Foundation, Inc.
3 Contributed by David Malcolm <dmalcolm@redhat.com>.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
10 any later version.
12 GCC is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
21 #ifndef GCC_ANALYZER_PROGRAM_POINT_H
22 #define GCC_ANALYZER_PROGRAM_POINT_H
24 #include "pretty-print.h"
25 #include "analyzer/call-string.h"
27 namespace ana {
29 class exploded_graph;
31 /* An enum for distinguishing the various kinds of program_point. */
33 enum point_kind {
34 /* A "fake" node which has edges to all entrypoints. */
35 PK_ORIGIN,
37 PK_BEFORE_SUPERNODE,
38 PK_BEFORE_STMT,
39 PK_AFTER_SUPERNODE,
41 /* Special values used for hash_map: */
42 PK_EMPTY,
43 PK_DELETED,
45 NUM_POINT_KINDS
48 extern const char *point_kind_to_string (enum point_kind pk);
50 class format
52 public:
53 format (bool newlines) : m_newlines (newlines) {}
55 void spacer (pretty_printer *pp) const
57 if (m_newlines)
58 pp_newline (pp);
59 else
60 pp_space (pp);
63 bool m_newlines;
66 /* A class for representing a location within the program, without
67 interprocedural information.
69 This represents a fine-grained location within the supergraph (or
70 within one of its nodes). */
72 class function_point
74 public:
75 function_point (const supernode *supernode,
76 const superedge *from_edge,
77 unsigned stmt_idx,
78 enum point_kind kind);
80 void print (pretty_printer *pp, const format &f) const;
81 void print_source_line (pretty_printer *pp) const;
82 void dump () const;
84 hashval_t hash () const;
85 bool operator== (const function_point &other) const
87 return (m_supernode == other.m_supernode
88 && m_from_edge == other.m_from_edge
89 && m_stmt_idx == other.m_stmt_idx
90 && m_kind == other.m_kind);
93 /* Accessors. */
95 const supernode *get_supernode () const { return m_supernode; }
96 function *get_function () const;
97 const gimple *get_stmt () const;
98 location_t get_location () const;
99 enum point_kind get_kind () const { return m_kind; }
100 const superedge *get_from_edge () const
102 return m_from_edge;
104 unsigned get_stmt_idx () const
106 gcc_assert (m_kind == PK_BEFORE_STMT);
107 return m_stmt_idx;
110 bool final_stmt_p () const;
112 /* Factory functions for making various kinds of program_point. */
114 static function_point from_function_entry (const supergraph &sg,
115 function *fun);
117 static function_point before_supernode (const supernode *supernode,
118 const superedge *from_edge);
120 static function_point before_stmt (const supernode *supernode,
121 unsigned stmt_idx)
123 return function_point (supernode, NULL, stmt_idx, PK_BEFORE_STMT);
126 static function_point after_supernode (const supernode *supernode)
128 return function_point (supernode, NULL, 0, PK_AFTER_SUPERNODE);
131 /* Support for hash_map. */
133 static function_point empty ()
135 return function_point (NULL, NULL, 0, PK_EMPTY);
137 static function_point deleted ()
139 return function_point (NULL, NULL, 0, PK_DELETED);
142 static int cmp_within_supernode_1 (const function_point &point_a,
143 const function_point &point_b);
144 static int cmp_within_supernode (const function_point &point_a,
145 const function_point &point_b);
146 static int cmp (const function_point &point_a,
147 const function_point &point_b);
148 static int cmp_ptr (const void *p1, const void *p2);
150 /* For before_stmt, go to next stmt. */
151 void next_stmt ();
153 function_point get_next () const;
155 private:
156 const supernode *m_supernode;
158 /* For PK_BEFORE_SUPERNODE, and only for CFG edges. */
159 const superedge *m_from_edge;
161 /* Only for PK_BEFORE_STMT. */
162 unsigned m_stmt_idx;
164 enum point_kind m_kind;
167 /* A class for representing a location within the program, including
168 interprocedural information.
170 This represents a fine-grained location within the supergraph (or
171 within one of its nodes), along with a call string giving the
172 interprocedural context. */
174 class program_point
176 public:
177 program_point (const function_point &fn_point,
178 const call_string &call_string)
179 : m_function_point (fn_point),
180 m_call_string (&call_string)
184 void print (pretty_printer *pp, const format &f) const;
185 void dump () const;
187 json::object *to_json () const;
189 hashval_t hash () const;
190 bool operator== (const program_point &other) const
192 return (m_function_point == other.m_function_point
193 && m_call_string == other.m_call_string);
195 bool operator!= (const program_point &other) const
197 return !(*this == other);
200 /* Accessors. */
202 const function_point &get_function_point () const { return m_function_point; }
203 const call_string &get_call_string () const { return *m_call_string; }
205 const supernode *get_supernode () const
207 return m_function_point.get_supernode ();
209 function *get_function () const
211 return m_function_point.get_function ();
213 function *get_function_at_depth (unsigned depth) const;
214 tree get_fndecl () const
216 gcc_assert (get_kind () != PK_ORIGIN);
217 return get_function ()->decl;
219 const gimple *get_stmt () const
221 return m_function_point.get_stmt ();
223 location_t get_location () const
225 return m_function_point.get_location ();
227 enum point_kind get_kind () const
229 return m_function_point.get_kind ();
231 const superedge *get_from_edge () const
233 return m_function_point.get_from_edge ();
235 unsigned get_stmt_idx () const
237 return m_function_point.get_stmt_idx ();
240 /* Get the number of frames we expect at this program point.
241 This will be one more than the length of the call_string
242 (which stores the parent callsites), apart from the origin
243 node, which doesn't have any frames. */
244 int get_stack_depth () const
246 if (get_kind () == PK_ORIGIN)
247 return 0;
248 return get_call_string ().length () + 1;
251 /* Factory functions for making various kinds of program_point. */
252 static program_point origin (const region_model_manager &mgr);
253 static program_point from_function_entry (const region_model_manager &mgr,
254 const supergraph &sg,
255 function *fun);
257 static program_point before_supernode (const supernode *supernode,
258 const superedge *from_edge,
259 const call_string &call_string)
261 return program_point (function_point::before_supernode (supernode,
262 from_edge),
263 call_string);
266 static program_point before_stmt (const supernode *supernode,
267 unsigned stmt_idx,
268 const call_string &call_string)
270 return program_point (function_point::before_stmt (supernode, stmt_idx),
271 call_string);
274 static program_point after_supernode (const supernode *supernode,
275 const call_string &call_string)
277 return program_point (function_point::after_supernode (supernode),
278 call_string);
281 /* Support for hash_map. */
283 static program_point empty ()
285 return program_point (function_point::empty ());
287 static program_point deleted ()
289 return program_point (function_point::deleted ());
292 bool on_edge (exploded_graph &eg, const superedge *succ);
293 void push_to_call_stack (const supernode *caller, const supernode *callee);
294 void pop_from_call_stack ();
295 void validate () const;
297 /* For before_stmt, go to next stmt. */
298 void next_stmt () { m_function_point.next_stmt (); }
300 program_point get_next () const;
302 private:
303 program_point (const function_point &fn_point)
304 : m_function_point (fn_point),
305 m_call_string (NULL)
309 function_point m_function_point;
310 const call_string *m_call_string;
313 } // namespace ana
315 #endif /* GCC_ANALYZER_PROGRAM_POINT_H */