8
8
9
9
#include " value_set_fi_fp_removal.h"
10
10
11
- #include < goto-programs/goto_model.h>
12
-
13
- #include < pointer-analysis/value_set_analysis_fi.h>
14
-
15
- #include < util/c_types.h>
16
- #include < util/fresh_symbol.h>
17
11
#include < util/message.h>
18
12
#include < util/namespace.h>
19
13
#include < util/pointer_expr.h>
20
- #include < util/std_code.h>
21
-
22
- #ifdef USE_STD_STRING
23
- # include < util/dstring.h>
24
- #endif
25
-
26
- void fix_argument_types (
27
- code_function_callt &function_call,
28
- const namespacet &ns)
29
- {
30
- const code_typet &code_type =
31
- to_code_type (ns.follow (function_call.function ().type ()));
32
-
33
- const code_typet::parameterst &function_parameters = code_type.parameters ();
34
-
35
- code_function_callt::argumentst &call_arguments = function_call.arguments ();
36
-
37
- for (std::size_t i = 0 ; i < function_parameters.size (); i++)
38
- {
39
- // casting pointers might result in more arguments than function parameters
40
- if (i < call_arguments.size ())
41
- {
42
- call_arguments[i] = typecast_exprt::conditional_cast (
43
- call_arguments[i], function_parameters[i].type ());
44
- }
45
- }
46
- }
47
-
48
- void fix_return_type (
49
- code_function_callt &function_call,
50
- goto_programt &dest,
51
- goto_modelt &goto_model)
52
- {
53
- // are we returning anything at all?
54
- if (function_call.lhs ().is_nil ())
55
- return ;
56
-
57
- const namespacet ns (goto_model.symbol_table );
58
-
59
- const code_typet &code_type =
60
- to_code_type (ns.follow (function_call.function ().type ()));
61
-
62
- // type already ok?
63
- if (function_call.lhs ().type () == code_type.return_type ())
64
- return ;
65
-
66
- const symbolt &function_symbol =
67
- ns.lookup (to_symbol_expr (function_call.function ()).get_identifier ());
68
-
69
- symbolt &tmp_symbol = get_fresh_aux_symbol (
70
- code_type.return_type (),
71
- id2string (function_call.source_location ().get_function ()),
72
- " tmp_return_val_" + id2string (function_symbol.base_name ),
73
- function_call.source_location (),
74
- function_symbol.mode ,
75
- goto_model.symbol_table );
76
-
77
- const symbol_exprt tmp_symbol_expr = tmp_symbol.symbol_expr ();
78
-
79
- exprt old_lhs = function_call.lhs ();
80
- function_call.lhs () = tmp_symbol_expr;
81
-
82
- dest.add (goto_programt::make_assignment (
83
- code_assignt (old_lhs, typecast_exprt (tmp_symbol_expr, old_lhs.type ()))));
84
- }
85
-
86
- void remove_function_pointer (
87
- goto_programt &goto_program,
88
- goto_programt::targett target,
89
- const std::set<symbol_exprt> &functions,
90
- goto_modelt &goto_model)
91
- {
92
- const exprt &function = as_const (*target).call_function ();
93
- PRECONDITION (function.id () == ID_dereference);
94
-
95
- // this better have the right type
96
- code_typet call_type = to_code_type (function.type ());
97
-
98
- // refine the type in case the forward declaration was incomplete
99
- if (call_type.has_ellipsis () && call_type.parameters ().empty ())
100
- {
101
- call_type.remove_ellipsis ();
102
- for (const auto &argument : as_const (*target).call_arguments ())
103
- call_type.parameters ().push_back (code_typet::parametert (argument.type ()));
104
- }
105
-
106
- const exprt &pointer = to_dereference_expr (function).pointer ();
107
-
108
- // the final target is a skip
109
- goto_programt final_skip;
110
- goto_programt::targett t_final = final_skip.add (goto_programt::make_skip ());
111
-
112
- // build the calls and gotos
113
-
114
- goto_programt new_code_calls;
115
- goto_programt new_code_gotos;
116
-
117
- for (const auto &fun : functions)
118
- {
119
- // call function
120
- goto_programt::targett t1 =
121
- new_code_calls.add (goto_programt::make_function_call (
122
- as_const (*target).call_lhs (),
123
- fun,
124
- as_const (*target).call_arguments (),
125
- target->source_location ()));
126
-
127
- // the signature of the function might not match precisely
128
- const namespacet ns (goto_model.symbol_table );
129
- fix_argument_types (to_code_function_call (t1->code_nonconst ()), ns);
130
- fix_return_type (
131
- to_code_function_call (t1->code_nonconst ()), new_code_calls, goto_model);
132
-
133
- // goto final
134
- new_code_calls.add (goto_programt::make_goto (t_final, true_exprt ()));
135
-
136
- // goto to call
137
- address_of_exprt address_of (fun, pointer_type (fun.type ()));
138
-
139
- new_code_gotos.add (goto_programt::make_goto (
140
- t1,
141
- equal_exprt (
142
- pointer,
143
- typecast_exprt::conditional_cast (address_of, pointer.type ()))));
144
- }
145
-
146
- goto_programt::targett t =
147
- new_code_gotos.add (goto_programt::make_assertion (false_exprt ()));
148
- t->source_location_nonconst ().set_property_class (" pointer dereference" );
149
- t->source_location_nonconst ().set_comment (" invalid function pointer" );
150
-
151
- goto_programt new_code;
152
-
153
- // patch them all together
154
- new_code.destructive_append (new_code_gotos);
155
- new_code.destructive_append (new_code_calls);
156
- new_code.destructive_append (final_skip);
157
-
158
- // set locations
159
- for (auto &instruction : new_code.instructions )
160
- {
161
- irep_idt property_class =
162
- instruction.source_location ().get_property_class ();
163
- irep_idt comment = instruction.source_location ().get_comment ();
164
- instruction.source_location_nonconst () = target->source_location ();
165
- if (!property_class.empty ())
166
- instruction.source_location_nonconst ().set_property_class (property_class);
167
- if (!comment.empty ())
168
- instruction.source_location_nonconst ().set_comment (comment);
169
- }
170
14
171
- goto_programt::targett next_target = target;
172
- next_target++;
173
-
174
- goto_program.destructive_insert (next_target, new_code);
15
+ #include < goto-programs/goto_model.h>
16
+ #include < goto-programs/remove_function_pointers.h>
175
17
176
- // We preserve the original dereferencing to possibly catch
177
- // further pointer-related errors.
178
- *target = goto_programt::make_other (
179
- code_expressiont (function), function.source_location ());
180
- }
18
+ #include < pointer-analysis/value_set_analysis_fi.h>
181
19
182
20
void value_set_fi_fp_removal (
183
21
goto_modelt &goto_model,
@@ -210,7 +48,7 @@ void value_set_fi_fp_removal(
210
48
const auto &pointer = to_dereference_expr (function).pointer ();
211
49
auto addresses = value_sets.get_values (f.first , target, pointer);
212
50
213
- std::set <symbol_exprt> functions;
51
+ std::unordered_set <symbol_exprt, irep_hash > functions;
214
52
215
53
for (const auto &address : addresses)
216
54
{
@@ -230,8 +68,16 @@ void value_set_fi_fp_removal(
230
68
<< " function: " << f.get_identifier () << messaget::eom;
231
69
232
70
if (functions.size () > 0 )
71
+ {
233
72
remove_function_pointer (
234
- f.second .body , target, functions, goto_model);
73
+ message_handler,
74
+ goto_model.symbol_table ,
75
+ f.second .body ,
76
+ f.first ,
77
+ target,
78
+ functions,
79
+ true );
80
+ }
235
81
}
236
82
}
237
83
}
0 commit comments