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 class constraint_manager
;
77 class pending_diagnostic
;
78 class state_change_event
;
80 class extrinsic_state
;
89 class feasibility_problem
;
90 class exploded_cluster
;
93 class state_purge_map
;
94 class state_purge_per_ssa_name
;
100 /* Forward decls of functions. */
102 extern void dump_tree (pretty_printer
*pp
, tree t
);
103 extern void dump_quoted_tree (pretty_printer
*pp
, tree t
);
104 extern void print_quoted_type (pretty_printer
*pp
, tree t
);
105 extern int readability_comparator (const void *p1
, const void *p2
);
106 extern int tree_cmp (const void *p1
, const void *p2
);
108 /* A tree, extended with stack frame information for locals, so that
109 we can distinguish between different values of locals within a potentially
110 recursive callstack. */
115 path_var (tree t
, int stack_depth
)
116 : m_tree (t
), m_stack_depth (stack_depth
)
118 // TODO: ignore stack depth for globals and constants
121 bool operator== (const path_var
&other
) const
123 return (m_tree
== other
.m_tree
124 && m_stack_depth
== other
.m_stack_depth
);
127 operator bool () const
129 return m_tree
!= NULL_TREE
;
132 void dump (pretty_printer
*pp
) const;
135 int m_stack_depth
; // or -1 for globals?
138 typedef offset_int bit_offset_t
;
139 typedef offset_int bit_size_t
;
140 typedef offset_int byte_size_t
;
142 /* The location of a region expressesd as an offset relative to a
148 static region_offset
make_concrete (const region
*base_region
,
151 return region_offset (base_region
, offset
, false);
153 static region_offset
make_symbolic (const region
*base_region
)
155 return region_offset (base_region
, 0, true);
158 const region
*get_base_region () const { return m_base_region
; }
160 bool symbolic_p () const { return m_is_symbolic
; }
162 bit_offset_t
get_bit_offset () const
164 gcc_assert (!symbolic_p ());
168 bool operator== (const region_offset
&other
)
170 return (m_base_region
== other
.m_base_region
171 && m_offset
== other
.m_offset
172 && m_is_symbolic
== other
.m_is_symbolic
);
176 region_offset (const region
*base_region
, bit_offset_t offset
,
178 : m_base_region (base_region
), m_offset (offset
), m_is_symbolic (is_symbolic
)
181 const region
*m_base_region
;
182 bit_offset_t m_offset
;
186 extern location_t
get_stmt_location (const gimple
*stmt
, function
*fun
);
190 extern bool is_special_named_call_p (const gcall
*call
, const char *funcname
,
191 unsigned int num_args
);
192 extern bool is_named_call_p (tree fndecl
, const char *funcname
);
193 extern bool is_named_call_p (tree fndecl
, const char *funcname
,
194 const gcall
*call
, unsigned int num_args
);
195 extern bool is_std_named_call_p (tree fndecl
, const char *funcname
,
196 const gcall
*call
, unsigned int num_args
);
197 extern bool is_setjmp_call_p (const gcall
*call
);
198 extern bool is_longjmp_call_p (const gcall
*call
);
200 extern const char *get_user_facing_name (const gcall
*call
);
202 extern void register_analyzer_pass ();
204 extern label_text
make_label_text (bool can_colorize
, const char *fmt
, ...);
206 extern bool fndecl_has_gimple_body_p (tree fndecl
);
208 /* An RAII-style class for pushing/popping cfun within a scope.
209 Doing so ensures we get "In function " announcements
210 from the diagnostics subsystem. */
215 auto_cfun (function
*fun
) { push_cfun (fun
); }
216 ~auto_cfun () { pop_cfun (); }
219 /* A template for creating hash traits for a POD type. */
221 template <typename Type
>
222 struct pod_hash_traits
: typed_noop_remove
<Type
>
224 typedef Type value_type
;
225 typedef Type compare_type
;
226 static inline hashval_t
hash (value_type
);
227 static inline bool equal (const value_type
&existing
,
228 const value_type
&candidate
);
229 static inline void mark_deleted (Type
&);
230 static inline void mark_empty (Type
&);
231 static inline bool is_deleted (Type
);
232 static inline bool is_empty (Type
);
235 /* A hash traits class that uses member functions to implement
236 the various required ops. */
238 template <typename Type
>
239 struct member_function_hash_traits
: public typed_noop_remove
<Type
>
241 typedef Type value_type
;
242 typedef Type compare_type
;
243 static inline hashval_t
hash (value_type v
) { return v
.hash (); }
244 static inline bool equal (const value_type
&existing
,
245 const value_type
&candidate
)
247 return existing
== candidate
;
249 static inline void mark_deleted (Type
&t
) { t
.mark_deleted (); }
250 static inline void mark_empty (Type
&t
) { t
.mark_empty (); }
251 static inline bool is_deleted (Type t
) { return t
.is_deleted (); }
252 static inline bool is_empty (Type t
) { return t
.is_empty (); }
255 /* A map from T::key_t to T* for use in consolidating instances of T.
256 Owns all instances of T.
257 T::key_t should have operator== and be hashable. */
259 template <typename T
>
260 class consolidation_map
263 typedef typename
T::key_t key_t
;
264 typedef T instance_t
;
265 typedef hash_map
<key_t
, instance_t
*> inner_map_t
;
266 typedef typename
inner_map_t::iterator iterator
;
268 /* Delete all instances of T. */
270 ~consolidation_map ()
272 for (typename
inner_map_t::iterator iter
= m_inner_map
.begin ();
273 iter
!= m_inner_map
.end (); ++iter
)
274 delete (*iter
).second
;
277 /* Get the instance of T for K if one exists, or NULL. */
279 T
*get (const key_t
&k
) const
281 if (instance_t
**slot
= const_cast<inner_map_t
&> (m_inner_map
).get (k
))
286 /* Take ownership of INSTANCE. */
288 void put (const key_t
&k
, T
*instance
)
290 m_inner_map
.put (k
, instance
);
293 size_t elements () const { return m_inner_map
.elements (); }
295 iterator
begin () const { return m_inner_map
.begin (); }
296 iterator
end () const { return m_inner_map
.end (); }
299 inner_map_t m_inner_map
;
302 /* Disable -Wformat-diag; we want to be able to use pp_printf
303 for logging/dumping without complying with the rules for diagnostics. */
305 #pragma GCC diagnostic ignored "-Wformat-diag"
307 #endif /* GCC_ANALYZER_ANALYZER_H */