IBM Z: Fix usage of "f" constraint with long doubles
[official-gcc.git] / gcc / analyzer / region-model-impl-calls.cc
blobf83c12b5cb70d4bfb8a57276776b8d1e68b4f0be
1 /* Handling for the known behavior of various specific functions.
2 Copyright (C) 2020-2021 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 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "tree.h"
25 #include "function.h"
26 #include "basic-block.h"
27 #include "gimple.h"
28 #include "gimple-iterator.h"
29 #include "diagnostic-core.h"
30 #include "graphviz.h"
31 #include "options.h"
32 #include "cgraph.h"
33 #include "tree-dfa.h"
34 #include "stringpool.h"
35 #include "convert.h"
36 #include "target.h"
37 #include "fold-const.h"
38 #include "tree-pretty-print.h"
39 #include "diagnostic-color.h"
40 #include "diagnostic-metadata.h"
41 #include "tristate.h"
42 #include "bitmap.h"
43 #include "selftest.h"
44 #include "function.h"
45 #include "json.h"
46 #include "analyzer/analyzer.h"
47 #include "analyzer/analyzer-logging.h"
48 #include "ordered-hash-map.h"
49 #include "options.h"
50 #include "cgraph.h"
51 #include "cfg.h"
52 #include "digraph.h"
53 #include "analyzer/supergraph.h"
54 #include "sbitmap.h"
55 #include "analyzer/call-string.h"
56 #include "analyzer/program-point.h"
57 #include "analyzer/store.h"
58 #include "analyzer/region-model.h"
59 #include "gimple-pretty-print.h"
61 #if ENABLE_ANALYZER
63 namespace ana {
65 /* class call_details. */
67 /* call_details's ctor. */
69 call_details::call_details (const gcall *call, region_model *model,
70 region_model_context *ctxt)
71 : m_call (call), m_model (model), m_ctxt (ctxt),
72 m_lhs_type (NULL_TREE), m_lhs_region (NULL)
74 m_lhs_type = NULL_TREE;
75 if (tree lhs = gimple_call_lhs (call))
77 m_lhs_region = model->get_lvalue (lhs, ctxt);
78 m_lhs_type = TREE_TYPE (lhs);
82 /* If the callsite has a left-hand-side region, set it to RESULT
83 and return true.
84 Otherwise do nothing and return false. */
86 bool
87 call_details::maybe_set_lhs (const svalue *result) const
89 gcc_assert (result);
90 if (m_lhs_region)
92 m_model->set_value (m_lhs_region, result, m_ctxt);
93 return true;
95 else
96 return false;
99 /* Return the number of arguments used by the call statement. */
101 unsigned
102 call_details::num_args () const
104 return gimple_call_num_args (m_call);
107 /* Get argument IDX at the callsite as a tree. */
109 tree
110 call_details::get_arg_tree (unsigned idx) const
112 return gimple_call_arg (m_call, idx);
115 /* Get the type of argument IDX. */
117 tree
118 call_details::get_arg_type (unsigned idx) const
120 return TREE_TYPE (gimple_call_arg (m_call, idx));
123 /* Get argument IDX at the callsite as an svalue. */
125 const svalue *
126 call_details::get_arg_svalue (unsigned idx) const
128 tree arg = get_arg_tree (idx);
129 return m_model->get_rvalue (arg, m_ctxt);
132 /* Dump a multiline representation of this call to PP. */
134 void
135 call_details::dump_to_pp (pretty_printer *pp, bool simple) const
137 pp_string (pp, "gcall: ");
138 pp_gimple_stmt_1 (pp, m_call, 0 /* spc */, TDF_NONE /* flags */);
139 pp_newline (pp);
140 pp_string (pp, "return region: ");
141 if (m_lhs_region)
142 m_lhs_region->dump_to_pp (pp, simple);
143 else
144 pp_string (pp, "NULL");
145 pp_newline (pp);
146 for (unsigned i = 0; i < gimple_call_num_args (m_call); i++)
148 const svalue *arg_sval = get_arg_svalue (i);
149 pp_printf (pp, "arg %i: ", i);
150 arg_sval->dump_to_pp (pp, simple);
151 pp_newline (pp);
155 /* Dump a multiline representation of this call to stderr. */
157 DEBUG_FUNCTION void
158 call_details::dump (bool simple) const
160 pretty_printer pp;
161 pp_format_decoder (&pp) = default_tree_printer;
162 pp_show_color (&pp) = pp_show_color (global_dc->printer);
163 pp.buffer->stream = stderr;
164 dump_to_pp (&pp, simple);
165 pp_flush (&pp);
168 /* Implementations of specific functions. */
170 /* Handle the on_call_pre part of "alloca". */
172 bool
173 region_model::impl_call_alloca (const call_details &cd)
175 const svalue *size_sval = cd.get_arg_svalue (0);
176 const region *new_reg = create_region_for_alloca (size_sval);
177 const svalue *ptr_sval
178 = m_mgr->get_ptr_svalue (cd.get_lhs_type (), new_reg);
179 cd.maybe_set_lhs (ptr_sval);
180 return true;
183 /* Handle a call to "__analyzer_describe".
185 Emit a warning describing the 2nd argument (which can be of any
186 type), at the given verbosity level. This is for use when
187 debugging, and may be of use in DejaGnu tests. */
189 void
190 region_model::impl_call_analyzer_describe (const gcall *call,
191 region_model_context *ctxt)
193 tree t_verbosity = gimple_call_arg (call, 0);
194 tree t_val = gimple_call_arg (call, 1);
195 const svalue *sval = get_rvalue (t_val, ctxt);
196 bool simple = zerop (t_verbosity);
197 label_text desc = sval->get_desc (simple);
198 warning_at (call->location, 0, "svalue: %qs", desc.m_buffer);
201 /* Handle a call to "__analyzer_eval" by evaluating the input
202 and dumping as a dummy warning, so that test cases can use
203 dg-warning to validate the result (and so unexpected warnings will
204 lead to DejaGnu failures).
205 Broken out as a subroutine to make it easier to put a breakpoint on it
206 - though typically this doesn't help, as we have an SSA name as the arg,
207 and what's more interesting is usually the def stmt for that name. */
209 void
210 region_model::impl_call_analyzer_eval (const gcall *call,
211 region_model_context *ctxt)
213 tree t_arg = gimple_call_arg (call, 0);
214 tristate t = eval_condition (t_arg, NE_EXPR, integer_zero_node, ctxt);
215 warning_at (call->location, 0, "%s", t.as_string ());
218 /* Handle the on_call_pre part of "__builtin_expect" etc. */
220 bool
221 region_model::impl_call_builtin_expect (const call_details &cd)
223 /* __builtin_expect's return value is its initial argument. */
224 const svalue *sval = cd.get_arg_svalue (0);
225 cd.maybe_set_lhs (sval);
226 return false;
229 /* Handle the on_call_pre part of "calloc". */
231 bool
232 region_model::impl_call_calloc (const call_details &cd)
234 const svalue *nmemb_sval = cd.get_arg_svalue (0);
235 const svalue *size_sval = cd.get_arg_svalue (1);
236 /* TODO: check for overflow here? */
237 const svalue *prod_sval
238 = m_mgr->get_or_create_binop (size_type_node, MULT_EXPR,
239 nmemb_sval, size_sval);
240 const region *new_reg = create_region_for_heap_alloc (prod_sval);
241 zero_fill_region (new_reg);
242 if (cd.get_lhs_type ())
244 const svalue *ptr_sval
245 = m_mgr->get_ptr_svalue (cd.get_lhs_type (), new_reg);
246 cd.maybe_set_lhs (ptr_sval);
248 return true;
251 /* Handle the on_call_pre part of "error" and "error_at_line" from
252 GNU's non-standard <error.h>.
253 MIN_ARGS identifies the minimum number of expected arguments
254 to be consistent with such a call (3 and 5 respectively).
255 Return true if handling it as one of these functions.
256 Write true to *OUT_TERMINATE_PATH if this execution path should be
257 terminated (e.g. the function call terminates the process). */
259 bool
260 region_model::impl_call_error (const call_details &cd, unsigned min_args,
261 bool *out_terminate_path)
263 /* Bail if not enough args. */
264 if (cd.num_args () < min_args)
265 return false;
267 /* Initial argument ought to be of type "int". */
268 if (cd.get_arg_type (0) != integer_type_node)
269 return false;
271 /* The process exits if status != 0, so it only continues
272 for the case where status == 0.
273 Add that constraint, or terminate this analysis path. */
274 tree status = cd.get_arg_tree (0);
275 if (!add_constraint (status, EQ_EXPR, integer_zero_node, cd.get_ctxt ()))
276 *out_terminate_path = true;
278 return true;
281 /* Handle the on_call_post part of "free", after sm-handling.
283 If the ptr points to an underlying heap region, delete the region,
284 poisoning pointers to it and regions within it.
286 We delay this until after sm-state has been updated so that the
287 sm-handling can transition all of the various casts of the pointer
288 to a "freed" state *before* we delete the related region here.
290 This has to be done here so that the sm-handling can use the fact
291 that they point to the same region to establish that they are equal
292 (in region_model::eval_condition_without_cm), and thus transition
293 all pointers to the region to the "freed" state together, regardless
294 of casts. */
296 void
297 region_model::impl_call_free (const call_details &cd)
299 const svalue *ptr_sval = cd.get_arg_svalue (0);
300 if (const region_svalue *ptr_to_region_sval
301 = ptr_sval->dyn_cast_region_svalue ())
303 /* If the ptr points to an underlying heap region, delete it,
304 poisoning pointers. */
305 const region *freed_reg = ptr_to_region_sval->get_pointee ();
306 unbind_region_and_descendents (freed_reg, POISON_KIND_FREED);
310 /* Handle the on_call_pre part of "malloc". */
312 bool
313 region_model::impl_call_malloc (const call_details &cd)
315 const svalue *size_sval = cd.get_arg_svalue (0);
316 const region *new_reg = create_region_for_heap_alloc (size_sval);
317 if (cd.get_lhs_type ())
319 const svalue *ptr_sval
320 = m_mgr->get_ptr_svalue (cd.get_lhs_type (), new_reg);
321 cd.maybe_set_lhs (ptr_sval);
323 return true;
326 /* Handle the on_call_pre part of "memcpy" and "__builtin_memcpy". */
328 void
329 region_model::impl_call_memcpy (const call_details &cd)
331 const svalue *dest_sval = cd.get_arg_svalue (0);
332 const svalue *num_bytes_sval = cd.get_arg_svalue (2);
334 const region *dest_reg = deref_rvalue (dest_sval, cd.get_arg_tree (0),
335 cd.get_ctxt ());
337 cd.maybe_set_lhs (dest_sval);
339 if (tree num_bytes = num_bytes_sval->maybe_get_constant ())
341 /* "memcpy" of zero size is a no-op. */
342 if (zerop (num_bytes))
343 return;
346 check_for_writable_region (dest_reg, cd.get_ctxt ());
348 /* Otherwise, mark region's contents as unknown. */
349 mark_region_as_unknown (dest_reg);
352 /* Handle the on_call_pre part of "memset" and "__builtin_memset". */
354 bool
355 region_model::impl_call_memset (const call_details &cd)
357 const svalue *dest_sval = cd.get_arg_svalue (0);
358 const svalue *fill_value_sval = cd.get_arg_svalue (1);
359 const svalue *num_bytes_sval = cd.get_arg_svalue (2);
361 const region *dest_reg = deref_rvalue (dest_sval, cd.get_arg_tree (0),
362 cd.get_ctxt ());
364 if (tree num_bytes = num_bytes_sval->maybe_get_constant ())
366 /* "memset" of zero size is a no-op. */
367 if (zerop (num_bytes))
368 return true;
370 /* Set with known amount. */
371 byte_size_t reg_size;
372 if (dest_reg->get_byte_size (&reg_size))
374 /* Check for an exact size match. */
375 if (reg_size == wi::to_offset (num_bytes))
377 if (tree cst = fill_value_sval->maybe_get_constant ())
379 if (zerop (cst))
381 zero_fill_region (dest_reg);
382 return true;
389 check_for_writable_region (dest_reg, cd.get_ctxt ());
391 /* Otherwise, mark region's contents as unknown. */
392 mark_region_as_unknown (dest_reg);
393 return false;
396 /* Handle the on_call_pre part of "operator new". */
398 bool
399 region_model::impl_call_operator_new (const call_details &cd)
401 const svalue *size_sval = cd.get_arg_svalue (0);
402 const region *new_reg = create_region_for_heap_alloc (size_sval);
403 if (cd.get_lhs_type ())
405 const svalue *ptr_sval
406 = m_mgr->get_ptr_svalue (cd.get_lhs_type (), new_reg);
407 cd.maybe_set_lhs (ptr_sval);
409 return false;
412 /* Handle the on_call_pre part of "operator delete", which comes in
413 both sized and unsized variants (2 arguments and 1 argument
414 respectively). */
416 bool
417 region_model::impl_call_operator_delete (const call_details &cd)
419 const svalue *ptr_sval = cd.get_arg_svalue (0);
420 if (const region_svalue *ptr_to_region_sval
421 = ptr_sval->dyn_cast_region_svalue ())
423 /* If the ptr points to an underlying heap region, delete it,
424 poisoning pointers. */
425 const region *freed_reg = ptr_to_region_sval->get_pointee ();
426 unbind_region_and_descendents (freed_reg, POISON_KIND_FREED);
428 return false;
431 /* Handle the on_call_pre part of "realloc". */
433 void
434 region_model::impl_call_realloc (const call_details &)
436 /* Currently we don't support bifurcating state, so there's no good
437 way to implement realloc(3).
438 For now, malloc_state_machine::on_realloc_call has a minimal
439 implementation to suppress false positives. */
442 /* Handle the on_call_pre part of "strcpy" and "__builtin_strcpy_chk". */
444 void
445 region_model::impl_call_strcpy (const call_details &cd)
447 const svalue *dest_sval = cd.get_arg_svalue (0);
448 const region *dest_reg = deref_rvalue (dest_sval, cd.get_arg_tree (0),
449 cd.get_ctxt ());
451 cd.maybe_set_lhs (dest_sval);
453 check_for_writable_region (dest_reg, cd.get_ctxt ());
455 /* For now, just mark region's contents as unknown. */
456 mark_region_as_unknown (dest_reg);
459 /* Handle the on_call_pre part of "strlen".
460 Return true if the LHS is updated. */
462 bool
463 region_model::impl_call_strlen (const call_details &cd)
465 region_model_context *ctxt = cd.get_ctxt ();
466 const svalue *arg_sval = cd.get_arg_svalue (0);
467 const region *buf_reg = deref_rvalue (arg_sval, cd.get_arg_tree (0), ctxt);
468 if (const string_region *str_reg
469 = buf_reg->dyn_cast_string_region ())
471 tree str_cst = str_reg->get_string_cst ();
472 /* TREE_STRING_LENGTH is sizeof, not strlen. */
473 int sizeof_cst = TREE_STRING_LENGTH (str_cst);
474 int strlen_cst = sizeof_cst - 1;
475 if (cd.get_lhs_type ())
477 tree t_cst = build_int_cst (cd.get_lhs_type (), strlen_cst);
478 const svalue *result_sval
479 = m_mgr->get_or_create_constant_svalue (t_cst);
480 cd.maybe_set_lhs (result_sval);
481 return true;
484 /* Otherwise an unknown value. */
485 return true;
488 /* Handle calls to functions referenced by
489 __attribute__((malloc(FOO))). */
491 void
492 region_model::impl_deallocation_call (const call_details &cd)
494 impl_call_free (cd);
497 } // namespace ana
499 #endif /* #if ENABLE_ANALYZER */