1 /* Utility functions for the analyzer.
2 Copyright (C) 2019-2020 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)
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
28 /* Forward decls of common types, with indentation to show inheritance. */
34 class switch_cfg_superedge
;
35 class callgraph_superedge
;
37 class return_superedge
;
41 class constant_svalue
;
43 class poisoned_svalue
;
49 class unmergeable_svalue
;
50 class placeholder_svalue
;
51 class widening_svalue
;
52 class compound_svalue
;
53 class conjured_svalue
;
54 typedef hash_set
<const svalue
*> svalue_set
;
57 class function_region
;
60 class symbolic_region
;
66 class region_model_manager
;
71 class region_model_context
;
72 class impl_region_model_context
;
74 struct rejected_constraint
;
75 class constraint_manager
;
78 class pending_diagnostic
;
79 class state_change_event
;
81 class extrinsic_state
;
90 class feasibility_problem
;
91 class exploded_cluster
;
94 class state_purge_map
;
95 class state_purge_per_ssa_name
;
104 /* Forward decls of functions. */
106 extern void dump_tree (pretty_printer
*pp
, tree t
);
107 extern void dump_quoted_tree (pretty_printer
*pp
, tree t
);
108 extern void print_quoted_type (pretty_printer
*pp
, tree t
);
109 extern int readability_comparator (const void *p1
, const void *p2
);
110 extern int tree_cmp (const void *p1
, const void *p2
);
112 /* A tree, extended with stack frame information for locals, so that
113 we can distinguish between different values of locals within a potentially
114 recursive callstack. */
119 path_var (tree t
, int stack_depth
)
120 : m_tree (t
), m_stack_depth (stack_depth
)
122 // TODO: ignore stack depth for globals and constants
125 bool operator== (const path_var
&other
) const
127 return (m_tree
== other
.m_tree
128 && m_stack_depth
== other
.m_stack_depth
);
131 operator bool () const
133 return m_tree
!= NULL_TREE
;
136 void dump (pretty_printer
*pp
) const;
139 int m_stack_depth
; // or -1 for globals?
142 typedef offset_int bit_offset_t
;
143 typedef offset_int bit_size_t
;
144 typedef offset_int byte_size_t
;
146 /* The location of a region expressesd as an offset relative to a
152 static region_offset
make_concrete (const region
*base_region
,
155 return region_offset (base_region
, offset
, false);
157 static region_offset
make_symbolic (const region
*base_region
)
159 return region_offset (base_region
, 0, true);
162 const region
*get_base_region () const { return m_base_region
; }
164 bool symbolic_p () const { return m_is_symbolic
; }
166 bit_offset_t
get_bit_offset () const
168 gcc_assert (!symbolic_p ());
172 bool operator== (const region_offset
&other
)
174 return (m_base_region
== other
.m_base_region
175 && m_offset
== other
.m_offset
176 && m_is_symbolic
== other
.m_is_symbolic
);
180 region_offset (const region
*base_region
, bit_offset_t offset
,
182 : m_base_region (base_region
), m_offset (offset
), m_is_symbolic (is_symbolic
)
185 const region
*m_base_region
;
186 bit_offset_t m_offset
;
190 extern location_t
get_stmt_location (const gimple
*stmt
, function
*fun
);
192 /* Passed by pointer to PLUGIN_ANALYZER_INIT callbacks. */
194 class plugin_analyzer_init_iface
197 virtual void register_state_machine (state_machine
*) = 0;
198 virtual logger
*get_logger () const = 0;
203 extern bool is_special_named_call_p (const gcall
*call
, const char *funcname
,
204 unsigned int num_args
);
205 extern bool is_named_call_p (tree fndecl
, const char *funcname
);
206 extern bool is_named_call_p (tree fndecl
, const char *funcname
,
207 const gcall
*call
, unsigned int num_args
);
208 extern bool is_std_named_call_p (tree fndecl
, const char *funcname
,
209 const gcall
*call
, unsigned int num_args
);
210 extern bool is_setjmp_call_p (const gcall
*call
);
211 extern bool is_longjmp_call_p (const gcall
*call
);
213 extern const char *get_user_facing_name (const gcall
*call
);
215 extern void register_analyzer_pass ();
217 extern label_text
make_label_text (bool can_colorize
, const char *fmt
, ...);
219 extern bool fndecl_has_gimple_body_p (tree fndecl
);
221 /* An RAII-style class for pushing/popping cfun within a scope.
222 Doing so ensures we get "In function " announcements
223 from the diagnostics subsystem. */
228 auto_cfun (function
*fun
) { push_cfun (fun
); }
229 ~auto_cfun () { pop_cfun (); }
232 /* A template for creating hash traits for a POD type. */
234 template <typename Type
>
235 struct pod_hash_traits
: typed_noop_remove
<Type
>
237 typedef Type value_type
;
238 typedef Type compare_type
;
239 static inline hashval_t
hash (value_type
);
240 static inline bool equal (const value_type
&existing
,
241 const value_type
&candidate
);
242 static inline void mark_deleted (Type
&);
243 static inline void mark_empty (Type
&);
244 static inline bool is_deleted (Type
);
245 static inline bool is_empty (Type
);
248 /* A hash traits class that uses member functions to implement
249 the various required ops. */
251 template <typename Type
>
252 struct member_function_hash_traits
: public typed_noop_remove
<Type
>
254 typedef Type value_type
;
255 typedef Type compare_type
;
256 static inline hashval_t
hash (value_type v
) { return v
.hash (); }
257 static inline bool equal (const value_type
&existing
,
258 const value_type
&candidate
)
260 return existing
== candidate
;
262 static inline void mark_deleted (Type
&t
) { t
.mark_deleted (); }
263 static inline void mark_empty (Type
&t
) { t
.mark_empty (); }
264 static inline bool is_deleted (Type t
) { return t
.is_deleted (); }
265 static inline bool is_empty (Type t
) { return t
.is_empty (); }
268 /* A map from T::key_t to T* for use in consolidating instances of T.
269 Owns all instances of T.
270 T::key_t should have operator== and be hashable. */
272 template <typename T
>
273 class consolidation_map
276 typedef typename
T::key_t key_t
;
277 typedef T instance_t
;
278 typedef hash_map
<key_t
, instance_t
*> inner_map_t
;
279 typedef typename
inner_map_t::iterator iterator
;
281 /* Delete all instances of T. */
283 ~consolidation_map ()
285 for (typename
inner_map_t::iterator iter
= m_inner_map
.begin ();
286 iter
!= m_inner_map
.end (); ++iter
)
287 delete (*iter
).second
;
290 /* Get the instance of T for K if one exists, or NULL. */
292 T
*get (const key_t
&k
) const
294 if (instance_t
**slot
= const_cast<inner_map_t
&> (m_inner_map
).get (k
))
299 /* Take ownership of INSTANCE. */
301 void put (const key_t
&k
, T
*instance
)
303 m_inner_map
.put (k
, instance
);
306 size_t elements () const { return m_inner_map
.elements (); }
308 iterator
begin () const { return m_inner_map
.begin (); }
309 iterator
end () const { return m_inner_map
.end (); }
312 inner_map_t m_inner_map
;
315 /* Disable -Wformat-diag; we want to be able to use pp_printf
316 for logging/dumping without complying with the rules for diagnostics. */
318 #pragma GCC diagnostic ignored "-Wformat-diag"
322 extern void sorry_no_analyzer ();
323 #endif /* #if !ENABLE_ANALYZER */
325 #endif /* GCC_ANALYZER_ANALYZER_H */