@@ -20,11 +20,14 @@ Author: Remi Delmas, delmarsd@amazon.com
2020#include < util/std_types.h>
2121
2222#include < goto-programs/goto_convert_functions.h>
23+ #include < goto-programs/goto_inline.h>
2324#include < goto-programs/goto_model.h>
2425
2526#include < ansi-c/c_expr.h>
2627#include < linking/static_lifetime_init.h>
2728
29+ #include " utils.h"
30+
2831dfcc_utilst::dfcc_utilst (goto_modelt &goto_model, messaget &log)
2932 : goto_model(goto_model), log(log), message_handler(log.get_message_handler())
3033{
@@ -48,7 +51,7 @@ const symbolt &dfcc_utilst::create_symbol(
4851 const irep_idt &module ,
4952 bool is_parameter)
5053{
51- log.debug () << " dfcc_utilst: create_symbol(" << prefix << " ::" << base_name
54+ log.debug () << " dfcc_utilst:: create_symbol(" << prefix << " ::" << base_name
5255 << " )" << messaget::eom;
5356
5457 symbolt &symbol = get_fresh_aux_symbol (
@@ -70,7 +73,7 @@ const symbolt &dfcc_utilst::create_static_symbol(
7073 const irep_idt &module ,
7174 const exprt &initial_value)
7275{
73- log.debug () << " dfcc_utilst: create_static_symbol(" << prefix
76+ log.debug () << " dfcc_utilst:: create_static_symbol(" << prefix
7477 << " ::" << base_name << " )" << messaget::eom;
7578
7679 symbolt &symbol = get_fresh_aux_symbol (
@@ -115,7 +118,7 @@ const symbolt &dfcc_utilst::add_parameter(
115118 const std::string &base_name,
116119 const typet &type)
117120{
118- log.debug () << " dfcc_utilst: add_parameter(" << function_id << " , "
121+ log.debug () << " dfcc_utilst:: add_parameter(" << function_id << " , "
119122 << base_name << " )" << messaget::eom;
120123
121124 symbolt &function_symbol = get_function_symbol (function_id);
@@ -144,14 +147,14 @@ const symbolt &dfcc_utilst::clone_and_rename_function(
144147 std::function<const typet(const typet &)> &trans_ret_type,
145148 std::function<const source_locationt(const source_locationt &)> &trans_loc)
146149{
147- log.debug () << " dfcc_utilst: clone_and_rename_function(" << function_id << " )"
150+ log.debug () << " dfcc_utilst:: clone_and_rename_function(" << function_id << " )"
148151 << messaget::eom;
149152 const symbolt &old_function_symbol = get_function_symbol (function_id);
150153 code_typet old_code_type = to_code_type (old_function_symbol.type );
151154
152155 irep_idt new_function_id = trans_fun (function_id);
153156
154- log.debug () << " dfcc_utilst: clone_and_rename_function: function "
157+ log.debug () << " dfcc_utilst:: clone_and_rename_function: function "
155158 << function_id << " ->" << new_function_id << messaget::eom;
156159
157160 code_typet::parameterst new_params;
@@ -180,7 +183,7 @@ const symbolt &dfcc_utilst::clone_and_rename_function(
180183
181184 if (!goto_model.symbol_table .add (new_function_symbol))
182185 {
183- log.error () << " dfcc_utilst: clone_and_rename_function: renamed function "
186+ log.error () << " dfcc_utilst:: clone_and_rename_function: renamed function "
184187 << function_id << " -> " << new_function_id << " already exists"
185188 << messaget::eom;
186189 exit (0 );
@@ -225,7 +228,7 @@ void dfcc_utilst::clone_parameters(
225228 new_params.push_back (new_param);
226229
227230 // build symbol
228- log.debug () << " dfcc_utilst: clone_parameters: param " << old_base_name
231+ log.debug () << " dfcc_utilst:: clone_parameters: param " << old_base_name
229232 << " ->" << new_param_id << messaget::eom;
230233 parameter_symbolt new_param_symbol;
231234 new_param_symbol.base_name = new_base_name;
@@ -237,7 +240,7 @@ void dfcc_utilst::clone_parameters(
237240 new_param_symbol.location = location;
238241 if (!goto_model.symbol_table .add (new_param_symbol))
239242 {
240- log.error () << " dfcc_utilst: clone_parameters: renamed parameter "
243+ log.error () << " dfcc_utilst:: clone_parameters: renamed parameter "
241244 << old_param.get_identifier () << " -> "
242245 << new_param.get_identifier () << " already exists"
243246 << messaget::eom;
@@ -248,12 +251,11 @@ void dfcc_utilst::clone_parameters(
248251
249252const symbolt &dfcc_utilst::clone_and_rename_function (
250253 const irep_idt &function_id,
251- const std::string &suffix ,
254+ const irep_idt &new_function_id ,
252255 optionalt<typet> new_return_type = {})
253256{
254257 std::function<const irep_idt (const irep_idt &)> trans_fun =
255- [&](const irep_idt &old_name)
256- { return id2string (old_name) + " ::" + suffix; };
258+ [&](const irep_idt &old_name) { return new_function_id; };
257259
258260 std::function<const irep_idt (const irep_idt &)> trans_param =
259261 [&](const irep_idt &old_name) { return old_name; };
@@ -279,7 +281,7 @@ void dfcc_utilst::wrap_function(
279281 auto old_function = goto_functions.function_map .find (function_id);
280282 INVARIANT (
281283 old_function != goto_functions.function_map .end (),
282- " dfcc_utilst: function to wrap " + id2string (function_id) +
284+ " dfcc_utilst::wrap_function: function to wrap " + id2string (function_id) +
283285 " must exist in the program" );
284286
285287 // Register the wrapped function under the new name
@@ -290,7 +292,8 @@ void dfcc_utilst::wrap_function(
290292 INVARIANT (
291293 goto_functions.function_map .find (wrapped_function_id) !=
292294 goto_functions.function_map .end (),
293- " dfcc_utilst: wrapped function " + id2string (wrapped_function_id) +
295+ " dfcc_utilst::wrap_function: wrapped function " +
296+ id2string (wrapped_function_id) +
294297 " shall exist in function_map at this point" );
295298
296299 // Remove previous entry
@@ -300,7 +303,8 @@ void dfcc_utilst::wrap_function(
300303 INVARIANT (
301304 goto_functions.function_map .find (function_id) ==
302305 goto_functions.function_map .end (),
303- " dfcc_utilst: the original function " + id2string (function_id) +
306+ " dfcc_utilst::wrap_function: the original function " +
307+ id2string (function_id) +
304308 " shall not exist in function_map anymore at this point" );
305309
306310 // Add new symbol for the wrapped function in the symbol table
@@ -316,8 +320,8 @@ void dfcc_utilst::wrap_function(
316320 const auto wrapped_found = symbol_table.insert (std::move (wrapped_sym));
317321 INVARIANT (
318322 wrapped_found.second ,
319- " dfcc_utilst: wrapped function symbol " + id2string (wrapped_function_id) +
320- " already exists in the symbol table" );
323+ " dfcc_utilst::wrap_function: wrapped function symbol " +
324+ id2string (wrapped_function_id) + " already exists in the symbol table" );
321325
322326 // Re-insert a symbol for `function_id` which is now the wrapper function
323327 symbolt wrapper_sym;
@@ -347,17 +351,17 @@ void dfcc_utilst::wrap_function(
347351 // Remove original symbol from the symbol_table
348352 if (!goto_model.symbol_table .remove (function_id))
349353 {
350- log.error () << " dfcc_utilst: could not remove " << function_id
351- << " from the symbol table" << messaget::eom;
354+ log.error () << " dfcc_utilst::wrap_function: could not remove "
355+ << function_id << " from the symbol table" << messaget::eom;
352356 exit (0 );
353357 }
354358
355359 // Insert update symbol in the symbol_table
356360 const auto wrapper_sym_found = symbol_table.insert (std::move (wrapper_sym));
357361 INVARIANT (
358362 wrapper_sym_found.second ,
359- " dfcc_utilst: could not insert symbol " + id2string (function_id) +
360- " in the symbol table" );
363+ " dfcc_utilst::wrap_function: could not insert symbol " +
364+ id2string (function_id) + " in the symbol table" );
361365
362366 // Insert wrapper function in the function_map
363367 goto_functiont &wrapper_fun = goto_functions.function_map [function_id];
@@ -372,14 +376,15 @@ const exprt dfcc_utilst::make_null_check_expr(const exprt &ptr)
372376
373377exprt dfcc_utilst::make_sizeof_expr (const exprt &expr)
374378{
375- log.debug () << " dfcc_utilst : make_sizeof_expr(" << format (expr) << " )"
379+ log.debug () << " dfcc_utilst:: make_sizeof_expr(" << format (expr) << " )"
376380 << messaget::eom;
377381 const auto &size =
378382 size_of_expr (expr.type (), namespacet (goto_model.symbol_table ));
379383
380384 PRECONDITION_WITH_DIAGNOSTICS (
381385 size.has_value (),
382- " dfcc_utilst: no definite size for lvalue target:\n " + expr.pretty ());
386+ " dfcc_utilst::make_sizeof_expr: no definite size for lvalue target:\n " +
387+ expr.pretty ());
383388
384389 return typecast_exprt::conditional_cast (size.value (), size_type ());
385390}
@@ -389,4 +394,32 @@ exprt dfcc_utilst::make_map_start_address(const exprt &expr)
389394 return typecast_exprt::conditional_cast (
390395 address_of_exprt (index_exprt (expr, from_integer (0 , c_index_type ()))),
391396 pointer_type (bool_typet ()));
392- }
397+ }
398+
399+ void dfcc_utilst::inline_and_check_loop_freeness (const irep_idt &function_id)
400+ {
401+ auto &goto_function = goto_model.goto_functions .function_map .at (function_id);
402+
403+ PRECONDITION_WITH_DIAGNOSTICS (
404+ goto_function.body_available (),
405+ " dfcc_utilst::inline_and_check_loop_freeness: function " +
406+ id2string (function_id) + " must have a body" );
407+
408+ inlining_decoratort decorated (log.get_message_handler ());
409+ namespacet ns{goto_model.symbol_table };
410+ goto_function_inline (
411+ goto_model.goto_functions , function_id, ns, log.get_message_handler ());
412+
413+ PRECONDITION_WITH_DIAGNOSTICS (
414+ decorated.get_recursive_function_warnings_count () == 0 ,
415+ " dfcc_utilst::inline_and_check_loop_freeness: function " +
416+ id2string (function_id) + " must not contain recursive function calls" );
417+
418+ PRECONDITION_WITH_DIAGNOSTICS (
419+ is_loop_free (goto_function.body , ns, log),
420+ " dfcc_utilst::inline_and_check_loop_freeness: function " +
421+ id2string (function_id) + " must not contain loops" );
422+
423+ // restore internal invariants
424+ goto_model.goto_functions .update ();
425+ }
0 commit comments