@@ -16,10 +16,18 @@ Author: DiffBlue Limited.
16
16
#include < util/make_unique.h>
17
17
#include < util/message.h>
18
18
#include < langapi/language_util.h>
19
+ #include < util/string_utils.h>
19
20
21
+ // / Base class for replace_function_body implementations
20
22
class replace_function_bodiest
21
23
{
22
24
protected:
25
+ // / Produce a body for the passed function
26
+ // / At this point the body of function is always empty,
27
+ // / and all function parameters have identifiers
28
+ // / @param function whose body to generate
29
+ // / @param symbol_table of the current goto program
30
+ // / @param function_name Identifier of function
23
31
virtual void generate_function_body (
24
32
goto_functiont &function,
25
33
symbol_tablet &symbol_table,
@@ -28,6 +36,11 @@ class replace_function_bodiest
28
36
public:
29
37
virtual ~replace_function_bodiest () = default ;
30
38
39
+ // / Replace the function body with one based on the implementation
40
+ // / This will work the same whether or not the function already has a body
41
+ // / @param function whose body to replace
42
+ // / @param symbol_table of the current goto program
43
+ // / @param function_name Identifier of function
31
44
void replace_function_body (
32
45
goto_functiont &function,
33
46
symbol_tablet &symbol_table,
@@ -51,37 +64,29 @@ class replace_function_bodiest
51
64
int param_counter = 0 ;
52
65
for (auto ¶meter : function.type .parameters ())
53
66
{
54
- if (
55
- parameter.type ().id () == ID_pointer &&
56
- !is_constant_or_has_constant_components (parameter.type (), ns))
67
+ if (parameter.get_identifier ().empty ())
57
68
{
58
- if (parameter.get_identifier ().empty ())
59
- {
60
- const std::string param_base_name =
61
- parameter.get_base_name ().empty ()
62
- ? " __param$" + std::to_string (param_counter++)
63
- : id2string (parameter.get_base_name ());
64
- irep_idt new_param_identifier =
65
- id2string (function_name) + " ::" + param_base_name;
66
- parameter.set_base_name (param_base_name);
67
- parameter.set_identifier (new_param_identifier);
68
- parameter_symbolt new_param_sym;
69
- new_param_sym.name = new_param_identifier;
70
- new_param_sym.type = parameter.type ();
71
- new_param_sym.base_name = param_base_name;
72
- new_param_sym.is_parameter = true ;
73
- new_param_sym.mode = ID_C;
74
- const symbolt *function_symbol = symbol_table.lookup (function_name);
75
- new_param_sym.module = function_symbol->module ;
76
- new_param_sym.location = function_symbol->location ;
77
- symbol_table.add (new_param_sym);
78
- }
79
- auto function_symbol = *symbol_table.lookup (function_name);
80
- function_symbol.type = function.type ;
81
- symbol_table.remove (function_name);
82
- symbol_table.insert (function_symbol);
69
+ const std::string param_base_name =
70
+ parameter.get_base_name ().empty ()
71
+ ? " __param$" + std::to_string (param_counter++)
72
+ : id2string (parameter.get_base_name ());
73
+ irep_idt new_param_identifier =
74
+ id2string (function_name) + " ::" + param_base_name;
75
+ parameter.set_base_name (param_base_name);
76
+ parameter.set_identifier (new_param_identifier);
77
+ parameter_symbolt new_param_sym;
78
+ new_param_sym.name = new_param_identifier;
79
+ new_param_sym.type = parameter.type ();
80
+ new_param_sym.base_name = param_base_name;
81
+ new_param_sym.mode = ID_C;
82
+ auto &function_symbol = symbol_table.lookup_ref (function_name);
83
+ new_param_sym.module = function_symbol.module ;
84
+ new_param_sym.location = function_symbol.location ;
85
+ symbol_table.add (new_param_sym);
83
86
}
84
87
}
88
+ auto &function_symbol = symbol_table.get_writeable_ref (function_name);
89
+ function_symbol.type = function.type ;
85
90
}
86
91
};
87
92
@@ -184,7 +189,8 @@ class havoc_replace_function_bodiest : public replace_function_bodiest
184
189
{
185
190
if (
186
191
parameter.type ().id () == ID_pointer &&
187
- !parameter.type ().subtype ().get_bool (ID_C_constant) &&
192
+ !is_constant_or_has_constant_components (
193
+ parameter.type ().subtype (), ns) &&
188
194
std::regex_match (
189
195
id2string (parameter.get_base_name ()), parameters_to_havoc))
190
196
{
@@ -222,44 +228,20 @@ class havoc_replace_function_bodiest : public replace_function_bodiest
222
228
std::regex parameters_to_havoc;
223
229
};
224
230
225
- static std::vector<std::string>
226
- tokenize (const std::string &base, char separator)
231
+ class replace_function_bodies_errort : public std ::runtime_error
227
232
{
228
- std::vector<std::string> tokens;
229
- tokens.push_back (" " );
230
- for (char c : base)
233
+ public:
234
+ replace_function_bodies_errort (
235
+ const std::string &file,
236
+ int line,
237
+ const std::string &reason)
238
+ : runtime_error(file + " :" + std::to_string(line) + " : " + reason)
231
239
{
232
- if (c == separator)
233
- {
234
- tokens.push_back (" " );
235
- }
236
- else
237
- {
238
- tokens.back ().push_back (c);
239
- }
240
240
}
241
- return tokens;
242
- }
243
-
244
- static void write_to_stream (std::ostream &out)
245
- {
246
- }
247
-
248
- template <typename T, typename ... Ts>
249
- void write_to_stream (std::ostream &out, const T &arg, const Ts &... args)
250
- {
251
- out << arg;
252
- write_to_stream (out, args...);
253
- }
241
+ };
254
242
255
- template <typename ... Ts>
256
- std::string replace_function_body_parse_error (const Ts &... args)
257
- {
258
- std::ostringstream out;
259
- write_to_stream (
260
- out, " parse error for --replace-function-body-options: " , args...);
261
- return out.str ();
262
- }
243
+ #define REPLACE_FUNCTION_BODIES_ERROR (reason ) \
244
+ replace_function_bodies_errort (__FILE__, __LINE__, (reason))
263
245
264
246
std::unique_ptr<replace_function_bodiest> replace_function_body_options_factory(
265
247
const std::string &options,
@@ -292,17 +274,18 @@ std::unique_ptr<replace_function_bodiest> replace_function_body_options_factory(
292
274
return util_make_unique<empty_replace_function_bodiest>();
293
275
}
294
276
295
- const std::vector<std::string> tokens = tokenize (options, ' ,' );
296
- if (!tokens .empty () && tokens [0 ] == " havoc" )
277
+ const std::vector<std::string> option_components = split_string (options, ' ,' );
278
+ if (!option_components .empty () && option_components [0 ] == " havoc" )
297
279
{
298
280
std::regex globals_regex;
299
281
std::regex params_regex;
300
- for (std::size_t i = 1 ; i < tokens .size (); ++i)
282
+ for (std::size_t i = 1 ; i < option_components .size (); ++i)
301
283
{
302
- const std::vector<std::string> key_value_pair = tokenize (tokens[i], ' :' );
284
+ const std::vector<std::string> key_value_pair =
285
+ split_string (option_components[i], ' :' );
303
286
if (key_value_pair.size () != 2 )
304
287
{
305
- throw replace_function_body_parse_error (
288
+ throw REPLACE_FUNCTION_BODIES_ERROR (
306
289
" Expected key_value_pair of form argument:value" );
307
290
}
308
291
if (key_value_pair[0 ] == " globals" )
@@ -315,8 +298,8 @@ std::unique_ptr<replace_function_bodiest> replace_function_body_options_factory(
315
298
}
316
299
else
317
300
{
318
- throw replace_function_body_parse_error (
319
- " Unknown option \" " , key_value_pair[0 ], " \" " );
301
+ throw REPLACE_FUNCTION_BODIES_ERROR (
302
+ " Unknown option \" " + key_value_pair[0 ] + " \" " );
320
303
}
321
304
}
322
305
std::vector<irep_idt> globals_to_havoc;
@@ -333,7 +316,7 @@ std::unique_ptr<replace_function_bodiest> replace_function_body_options_factory(
333
316
return util_make_unique<havoc_replace_function_bodiest>(
334
317
globals_to_havoc, params_regex);
335
318
}
336
- throw replace_function_body_parse_error (" Can't parse \" " , options, " \" " );
319
+ throw REPLACE_FUNCTION_BODIES_ERROR (" Can't parse \" " + options + " \" " );
337
320
}
338
321
339
322
void replace_function_bodies (
0 commit comments