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
;
101 /* Forward decls of functions. */
103 extern void dump_tree (pretty_printer
*pp
, tree t
);
104 extern void dump_quoted_tree (pretty_printer
*pp
, tree t
);
105 extern void print_quoted_type (pretty_printer
*pp
, tree t
);
106 extern int readability_comparator (const void *p1
, const void *p2
);
107 extern int tree_cmp (const void *p1
, const void *p2
);
109 /* A tree, extended with stack frame information for locals, so that
110 we can distinguish between different values of locals within a potentially
111 recursive callstack. */
116 path_var (tree t
, int stack_depth
)
117 : m_tree (t
), m_stack_depth (stack_depth
)
119 // TODO: ignore stack depth for globals and constants
122 bool operator== (const path_var
&other
) const
124 return (m_tree
== other
.m_tree
125 && m_stack_depth
== other
.m_stack_depth
);
128 operator bool () const
130 return m_tree
!= NULL_TREE
;
133 void dump (pretty_printer
*pp
) const;
136 int m_stack_depth
; // or -1 for globals?
139 typedef offset_int bit_offset_t
;
140 typedef offset_int bit_size_t
;
141 typedef offset_int byte_size_t
;
143 /* The location of a region expressesd as an offset relative to a
149 static region_offset
make_concrete (const region
*base_region
,
152 return region_offset (base_region
, offset
, false);
154 static region_offset
make_symbolic (const region
*base_region
)
156 return region_offset (base_region
, 0, true);
159 const region
*get_base_region () const { return m_base_region
; }
161 bool symbolic_p () const { return m_is_symbolic
; }
163 bit_offset_t
get_bit_offset () const
165 gcc_assert (!symbolic_p ());
169 bool operator== (const region_offset
&other
)
171 return (m_base_region
== other
.m_base_region
172 && m_offset
== other
.m_offset
173 && m_is_symbolic
== other
.m_is_symbolic
);
177 region_offset (const region
*base_region
, bit_offset_t offset
,
179 : m_base_region (base_region
), m_offset (offset
), m_is_symbolic (is_symbolic
)
182 const region
*m_base_region
;
183 bit_offset_t m_offset
;
187 extern location_t
get_stmt_location (const gimple
*stmt
, function
*fun
);
191 extern bool is_special_named_call_p (const gcall
*call
, const char *funcname
,
192 unsigned int num_args
);
193 extern bool is_named_call_p (tree fndecl
, const char *funcname
);
194 extern bool is_named_call_p (tree fndecl
, const char *funcname
,
195 const gcall
*call
, unsigned int num_args
);
196 extern bool is_std_named_call_p (tree fndecl
, const char *funcname
,
197 const gcall
*call
, unsigned int num_args
);
198 extern bool is_setjmp_call_p (const gcall
*call
);
199 extern bool is_longjmp_call_p (const gcall
*call
);
201 extern const char *get_user_facing_name (const gcall
*call
);
203 extern void register_analyzer_pass ();
205 extern label_text
make_label_text (bool can_colorize
, const char *fmt
, ...);
207 extern bool fndecl_has_gimple_body_p (tree fndecl
);
209 /* An RAII-style class for pushing/popping cfun within a scope.
210 Doing so ensures we get "In function " announcements
211 from the diagnostics subsystem. */
216 auto_cfun (function
*fun
) { push_cfun (fun
); }
217 ~auto_cfun () { pop_cfun (); }
220 /* A template for creating hash traits for a POD type. */
222 template <typename Type
>
223 struct pod_hash_traits
: typed_noop_remove
<Type
>
225 typedef Type value_type
;
226 typedef Type compare_type
;
227 static inline hashval_t
hash (value_type
);
228 static inline bool equal (const value_type
&existing
,
229 const value_type
&candidate
);
230 static inline void mark_deleted (Type
&);
231 static inline void mark_empty (Type
&);
232 static inline bool is_deleted (Type
);
233 static inline bool is_empty (Type
);
236 /* A hash traits class that uses member functions to implement
237 the various required ops. */
239 template <typename Type
>
240 struct member_function_hash_traits
: public typed_noop_remove
<Type
>
242 typedef Type value_type
;
243 typedef Type compare_type
;
244 static inline hashval_t
hash (value_type v
) { return v
.hash (); }
245 static inline bool equal (const value_type
&existing
,
246 const value_type
&candidate
)
248 return existing
== candidate
;
250 static inline void mark_deleted (Type
&t
) { t
.mark_deleted (); }
251 static inline void mark_empty (Type
&t
) { t
.mark_empty (); }
252 static inline bool is_deleted (Type t
) { return t
.is_deleted (); }
253 static inline bool is_empty (Type t
) { return t
.is_empty (); }
256 /* A map from T::key_t to T* for use in consolidating instances of T.
257 Owns all instances of T.
258 T::key_t should have operator== and be hashable. */
260 template <typename T
>
261 class consolidation_map
264 typedef typename
T::key_t key_t
;
265 typedef T instance_t
;
266 typedef hash_map
<key_t
, instance_t
*> inner_map_t
;
267 typedef typename
inner_map_t::iterator iterator
;
269 /* Delete all instances of T. */
271 ~consolidation_map ()
273 for (typename
inner_map_t::iterator iter
= m_inner_map
.begin ();
274 iter
!= m_inner_map
.end (); ++iter
)
275 delete (*iter
).second
;
278 /* Get the instance of T for K if one exists, or NULL. */
280 T
*get (const key_t
&k
) const
282 if (instance_t
**slot
= const_cast<inner_map_t
&> (m_inner_map
).get (k
))
287 /* Take ownership of INSTANCE. */
289 void put (const key_t
&k
, T
*instance
)
291 m_inner_map
.put (k
, instance
);
294 size_t elements () const { return m_inner_map
.elements (); }
296 iterator
begin () const { return m_inner_map
.begin (); }
297 iterator
end () const { return m_inner_map
.end (); }
300 inner_map_t m_inner_map
;
303 /* Disable -Wformat-diag; we want to be able to use pp_printf
304 for logging/dumping without complying with the rules for diagnostics. */
306 #pragma GCC diagnostic ignored "-Wformat-diag"
309 #endif /* GCC_ANALYZER_ANALYZER_H */