c++: new-expression is potentially constant in C++20
[official-gcc.git] / gcc / analyzer / analyzer.h
blobdcefc13a54681f71541fcd216c02abe34419e502
1 /* Utility functions for the analyzer.
2 Copyright (C) 2019-2022 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_ANALYZER_H
22 #define GCC_ANALYZER_ANALYZER_H
24 class graphviz_out;
26 namespace ana {
28 /* Forward decls of common types, with indentation to show inheritance. */
30 class supergraph;
31 class supernode;
32 class superedge;
33 class cfg_superedge;
34 class switch_cfg_superedge;
35 class callgraph_superedge;
36 class call_superedge;
37 class return_superedge;
39 class svalue;
40 class region_svalue;
41 class constant_svalue;
42 class unknown_svalue;
43 class poisoned_svalue;
44 class setjmp_svalue;
45 class initial_svalue;
46 class unaryop_svalue;
47 class binop_svalue;
48 class sub_svalue;
49 class repeated_svalue;
50 class bits_within_svalue;
51 class unmergeable_svalue;
52 class placeholder_svalue;
53 class widening_svalue;
54 class compound_svalue;
55 class conjured_svalue;
56 class asm_output_svalue;
57 class const_fn_result_svalue;
58 typedef hash_set<const svalue *> svalue_set;
59 class region;
60 class frame_region;
61 class function_region;
62 class label_region;
63 class decl_region;
64 class symbolic_region;
65 class element_region;
66 class offset_region;
67 class sized_region;
68 class cast_region;
69 class field_region;
70 class string_region;
71 class bit_range_region;
72 class var_arg_region;
73 class region_model_manager;
74 class conjured_purge;
75 struct model_merger;
76 class store_manager;
77 class store;
78 class region_model;
79 class region_model_context;
80 class impl_region_model_context;
81 class call_details;
82 class rejected_constraint;
83 class constraint_manager;
84 class equiv_class;
85 class reachable_regions;
86 class bounded_ranges;
87 class bounded_ranges_manager;
89 class pending_diagnostic;
90 class pending_note;
91 class state_change_event;
92 class checker_path;
93 class extrinsic_state;
94 class sm_state_map;
95 class stmt_finder;
96 class program_point;
97 class function_point;
98 class program_state;
99 class exploded_graph;
100 class exploded_node;
101 class exploded_edge;
102 class feasibility_problem;
103 class exploded_cluster;
104 class exploded_path;
105 class analysis_plan;
106 class state_purge_map;
107 class state_purge_per_ssa_name;
108 class state_purge_per_decl;
109 class state_change;
110 class rewind_info_t;
112 class engine;
113 class state_machine;
114 class logger;
115 class visitor;
117 /* Forward decls of functions. */
119 extern void dump_tree (pretty_printer *pp, tree t);
120 extern void dump_quoted_tree (pretty_printer *pp, tree t);
121 extern void print_quoted_type (pretty_printer *pp, tree t);
122 extern int readability_comparator (const void *p1, const void *p2);
123 extern int tree_cmp (const void *p1, const void *p2);
124 extern tree fixup_tree_for_diagnostic (tree);
125 extern tree get_diagnostic_tree_for_gassign (const gassign *);
127 /* A tree, extended with stack frame information for locals, so that
128 we can distinguish between different values of locals within a potentially
129 recursive callstack. */
131 class path_var
133 public:
134 path_var (tree t, int stack_depth)
135 : m_tree (t), m_stack_depth (stack_depth)
137 // TODO: ignore stack depth for globals and constants
140 bool operator== (const path_var &other) const
142 return (m_tree == other.m_tree
143 && m_stack_depth == other.m_stack_depth);
146 operator bool () const
148 return m_tree != NULL_TREE;
151 void dump (pretty_printer *pp) const;
153 tree m_tree;
154 int m_stack_depth; // or -1 for globals?
157 typedef offset_int bit_offset_t;
158 typedef offset_int bit_size_t;
159 typedef offset_int byte_offset_t;
160 typedef offset_int byte_size_t;
162 extern bool int_size_in_bits (const_tree type, bit_size_t *out);
164 extern tree get_field_at_bit_offset (tree record_type, bit_offset_t bit_offset);
166 /* The location of a region expressesd as an offset relative to a
167 base region. */
169 class region_offset
171 public:
172 static region_offset make_concrete (const region *base_region,
173 bit_offset_t offset)
175 return region_offset (base_region, offset, false);
177 static region_offset make_symbolic (const region *base_region)
179 return region_offset (base_region, 0, true);
182 const region *get_base_region () const { return m_base_region; }
184 bool symbolic_p () const { return m_is_symbolic; }
186 bit_offset_t get_bit_offset () const
188 gcc_assert (!symbolic_p ());
189 return m_offset;
192 bool operator== (const region_offset &other) const
194 return (m_base_region == other.m_base_region
195 && m_offset == other.m_offset
196 && m_is_symbolic == other.m_is_symbolic);
199 private:
200 region_offset (const region *base_region, bit_offset_t offset,
201 bool is_symbolic)
202 : m_base_region (base_region), m_offset (offset), m_is_symbolic (is_symbolic)
205 const region *m_base_region;
206 bit_offset_t m_offset;
207 bool m_is_symbolic;
210 extern location_t get_stmt_location (const gimple *stmt, function *fun);
212 extern bool compat_types_p (tree src_type, tree dst_type);
214 /* Passed by pointer to PLUGIN_ANALYZER_INIT callbacks. */
216 class plugin_analyzer_init_iface
218 public:
219 virtual void register_state_machine (state_machine *) = 0;
220 virtual logger *get_logger () const = 0;
223 /* An enum for describing the direction of an access to memory. */
225 enum access_direction
227 DIR_READ,
228 DIR_WRITE
231 /* Abstract base class for associating custom data with an
232 exploded_edge, for handling non-standard edges such as
233 rewinding from a longjmp, signal handlers, etc.
234 Also used when "bifurcating" state: splitting the execution
235 path in non-standard ways (e.g. for simulating the various
236 outcomes of "realloc"). */
238 class custom_edge_info
240 public:
241 virtual ~custom_edge_info () {}
243 /* Hook for making .dot label more readable. */
244 virtual void print (pretty_printer *pp) const = 0;
246 /* Hook for updating MODEL within exploded_path::feasible_p
247 and when handling bifurcation. */
248 virtual bool update_model (region_model *model,
249 const exploded_edge *eedge,
250 region_model_context *ctxt) const = 0;
252 virtual void add_events_to_path (checker_path *emission_path,
253 const exploded_edge &eedge) const = 0;
256 /* Abstract base class for splitting state.
258 Most of the state-management code in the analyzer involves
259 modifying state objects in-place, which assumes a single outcome.
261 This class provides an escape hatch to allow for multiple outcomes
262 for such updates e.g. for modelling multiple outcomes from function
263 calls, such as the various outcomes of "realloc". */
265 class path_context
267 public:
268 virtual ~path_context () {}
270 /* Hook for clients to split state with a non-standard path.
271 Take ownership of INFO. */
272 virtual void bifurcate (custom_edge_info *info) = 0;
274 /* Hook for clients to terminate the standard path. */
275 virtual void terminate_path () = 0;
277 /* Hook for clients to determine if the standard path has been
278 terminated. */
279 virtual bool terminate_path_p () const = 0;
282 } // namespace ana
284 extern bool is_special_named_call_p (const gcall *call, const char *funcname,
285 unsigned int num_args);
286 extern bool is_named_call_p (const_tree fndecl, const char *funcname);
287 extern bool is_named_call_p (const_tree fndecl, const char *funcname,
288 const gcall *call, unsigned int num_args);
289 extern bool is_std_named_call_p (const_tree fndecl, const char *funcname);
290 extern bool is_std_named_call_p (const_tree fndecl, const char *funcname,
291 const gcall *call, unsigned int num_args);
292 extern bool is_setjmp_call_p (const gcall *call);
293 extern bool is_longjmp_call_p (const gcall *call);
295 extern const char *get_user_facing_name (const gcall *call);
297 extern void register_analyzer_pass ();
299 extern label_text make_label_text (bool can_colorize, const char *fmt, ...);
300 extern label_text make_label_text_n (bool can_colorize, int n,
301 const char *singular_fmt,
302 const char *plural_fmt, ...);
304 extern bool fndecl_has_gimple_body_p (tree fndecl);
306 /* An RAII-style class for pushing/popping cfun within a scope.
307 Doing so ensures we get "In function " announcements
308 from the diagnostics subsystem. */
310 class auto_cfun
312 public:
313 auto_cfun (function *fun) { push_cfun (fun); }
314 ~auto_cfun () { pop_cfun (); }
317 /* A template for creating hash traits for a POD type. */
319 template <typename Type>
320 struct pod_hash_traits : typed_noop_remove<Type>
322 typedef Type value_type;
323 typedef Type compare_type;
324 static inline hashval_t hash (value_type);
325 static inline bool equal (const value_type &existing,
326 const value_type &candidate);
327 static inline void mark_deleted (Type &);
328 static inline void mark_empty (Type &);
329 static inline bool is_deleted (Type);
330 static inline bool is_empty (Type);
333 /* A hash traits class that uses member functions to implement
334 the various required ops. */
336 template <typename Type>
337 struct member_function_hash_traits : public typed_noop_remove<Type>
339 typedef Type value_type;
340 typedef Type compare_type;
341 static inline hashval_t hash (value_type v) { return v.hash (); }
342 static inline bool equal (const value_type &existing,
343 const value_type &candidate)
345 return existing == candidate;
347 static inline void mark_deleted (Type &t) { t.mark_deleted (); }
348 static inline void mark_empty (Type &t) { t.mark_empty (); }
349 static inline bool is_deleted (Type t) { return t.is_deleted (); }
350 static inline bool is_empty (Type t) { return t.is_empty (); }
353 /* A map from T::key_t to T* for use in consolidating instances of T.
354 Owns all instances of T.
355 T::key_t should have operator== and be hashable. */
357 template <typename T>
358 class consolidation_map
360 public:
361 typedef typename T::key_t key_t;
362 typedef T instance_t;
363 typedef hash_map<key_t, instance_t *> inner_map_t;
364 typedef typename inner_map_t::iterator iterator;
366 /* Delete all instances of T. */
368 ~consolidation_map ()
370 for (typename inner_map_t::iterator iter = m_inner_map.begin ();
371 iter != m_inner_map.end (); ++iter)
372 delete (*iter).second;
375 /* Get the instance of T for K if one exists, or NULL. */
377 T *get (const key_t &k) const
379 if (instance_t **slot = const_cast<inner_map_t &> (m_inner_map).get (k))
380 return *slot;
381 return NULL;
384 /* Take ownership of INSTANCE. */
386 void put (const key_t &k, T *instance)
388 m_inner_map.put (k, instance);
391 size_t elements () const { return m_inner_map.elements (); }
393 iterator begin () const { return m_inner_map.begin (); }
394 iterator end () const { return m_inner_map.end (); }
396 private:
397 inner_map_t m_inner_map;
400 /* Disable -Wformat-diag; we want to be able to use pp_printf
401 for logging/dumping without complying with the rules for diagnostics. */
402 #if __GNUC__ >= 10
403 #pragma GCC diagnostic ignored "-Wformat-diag"
404 #endif
406 #if !ENABLE_ANALYZER
407 extern void sorry_no_analyzer ();
408 #endif /* #if !ENABLE_ANALYZER */
410 #endif /* GCC_ANALYZER_ANALYZER_H */