1 | /* Helper class for handling a call with specific arguments. |
2 | Copyright (C) 2019-2024 Free Software Foundation, Inc. |
3 | Contributed by David Malcolm <dmalcolm@redhat.com>. |
4 | |
5 | This file is part of GCC. |
6 | |
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. |
11 | |
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. |
16 | |
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/>. */ |
20 | |
21 | #ifndef GCC_ANALYZER_CALL_DETAILS_H |
22 | #define GCC_ANALYZER_CALL_DETAILS_H |
23 | |
24 | namespace ana { |
25 | |
26 | /* Helper class for handling calls to functions with known behavior. */ |
27 | |
28 | class call_details |
29 | { |
30 | public: |
31 | call_details (const gcall *call, region_model *model, |
32 | region_model_context *ctxt); |
33 | call_details (const call_details &cd, region_model_context *ctxt); |
34 | |
35 | region_model *get_model () const { return m_model; } |
36 | region_model_manager *get_manager () const; |
37 | region_model_context *get_ctxt () const { return m_ctxt; } |
38 | logger *get_logger () const; |
39 | |
40 | uncertainty_t *get_uncertainty () const; |
41 | tree get_lhs_type () const { return m_lhs_type; } |
42 | const region *get_lhs_region () const { return m_lhs_region; } |
43 | |
44 | bool maybe_set_lhs (const svalue *result) const; |
45 | void set_any_lhs_with_defaults () const; |
46 | |
47 | unsigned num_args () const; |
48 | bool arg_is_pointer_p (unsigned idx) const |
49 | { |
50 | return POINTER_TYPE_P (get_arg_type (idx)); |
51 | } |
52 | bool arg_is_size_p (unsigned idx) const; |
53 | bool arg_is_integral_p (unsigned idx) const |
54 | { |
55 | return INTEGRAL_TYPE_P (get_arg_type (idx)); |
56 | } |
57 | |
58 | const gcall *get_call_stmt () const { return m_call; } |
59 | location_t get_location () const; |
60 | |
61 | tree get_arg_tree (unsigned idx) const; |
62 | tree get_arg_type (unsigned idx) const; |
63 | const svalue *get_arg_svalue (unsigned idx) const; |
64 | const region *deref_ptr_arg (unsigned idx) const; |
65 | const char *get_arg_string_literal (unsigned idx) const; |
66 | |
67 | tree get_fndecl_for_call () const; |
68 | |
69 | void dump_to_pp (pretty_printer *pp, bool simple) const; |
70 | void dump (bool simple) const; |
71 | |
72 | const svalue *get_or_create_conjured_svalue (const region *) const; |
73 | |
74 | tree lookup_function_attribute (const char *attr_name) const; |
75 | |
76 | void |
77 | check_for_null_terminated_string_arg (unsigned arg_idx) const; |
78 | const svalue * |
79 | check_for_null_terminated_string_arg (unsigned arg_idx, |
80 | bool include_terminator, |
81 | const svalue **out_sval) const; |
82 | |
83 | void |
84 | complain_about_overlap (unsigned arg_idx_a, |
85 | unsigned arg_idx_b, |
86 | const svalue *num_bytes_read_sval) const; |
87 | |
88 | private: |
89 | const gcall *m_call; |
90 | region_model *m_model; |
91 | region_model_context *m_ctxt; |
92 | tree m_lhs_type; |
93 | const region *m_lhs_region; |
94 | }; |
95 | |
96 | /* A bundle of information about a problematic argument at a callsite |
97 | for use by pending_diagnostic subclasses for reporting and |
98 | for deduplication. */ |
99 | |
100 | struct call_arg_details |
101 | { |
102 | public: |
103 | call_arg_details (const call_details &cd, unsigned arg_idx) |
104 | : m_call (cd.get_call_stmt ()), |
105 | m_called_fndecl (cd.get_fndecl_for_call ()), |
106 | m_arg_idx (arg_idx), |
107 | m_arg_expr (cd.get_arg_tree (idx: arg_idx)) |
108 | { |
109 | } |
110 | |
111 | bool operator== (const call_arg_details &other) const |
112 | { |
113 | return (m_call == other.m_call |
114 | && m_called_fndecl == other.m_called_fndecl |
115 | && m_arg_idx == other.m_arg_idx |
116 | && pending_diagnostic::same_tree_p (t1: m_arg_expr, t2: other.m_arg_expr)); |
117 | } |
118 | |
119 | const gcall *m_call; |
120 | tree m_called_fndecl; |
121 | unsigned m_arg_idx; // 0-based |
122 | tree m_arg_expr; |
123 | }; |
124 | |
125 | } // namespace ana |
126 | |
127 | #endif /* GCC_ANALYZER_CALL_DETAILS_H */ |
128 | |