@@ -8,176 +8,14 @@ Author: Daniel Kroening, kroening@kroening.com
88
99#include " value_set_fi_fp_removal.h"
1010
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>
1711#include < util/message.h>
1812#include < util/namespace.h>
1913#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- }
17014
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>
17517
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>
18119
18220void value_set_fi_fp_removal (
18321 goto_modelt &goto_model,
@@ -210,7 +48,7 @@ void value_set_fi_fp_removal(
21048 const auto &pointer = to_dereference_expr (function).pointer ();
21149 auto addresses = value_sets.get_values (f.first , target, pointer);
21250
213- std::set <symbol_exprt> functions;
51+ std::unordered_set <symbol_exprt, irep_hash > functions;
21452
21553 for (const auto &address : addresses)
21654 {
@@ -230,8 +68,16 @@ void value_set_fi_fp_removal(
23068 << " function: " << f.get_identifier () << messaget::eom;
23169
23270 if (functions.size () > 0 )
71+ {
23372 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+ }
23581 }
23682 }
23783 }
0 commit comments