CBMC
replace_calls.cpp
Go to the documentation of this file.
1 /*******************************************************************\
2 
3 Module: Replace calls
4 
5 Author: Daniel Poetzl
6 
7 \*******************************************************************/
8 
13 
14 #include "replace_calls.h"
15 
16 #include <util/exception_utils.h>
17 #include <util/invariant.h>
18 #include <util/namespace.h>
19 #include <util/string_utils.h>
20 
23 
30  goto_modelt &goto_model,
31  const replacement_listt &replacement_list) const
32 {
33  replacement_mapt replacement_map = parse_replacement_list(replacement_list);
34  (*this)(goto_model, replacement_map);
35 }
36 
42  goto_modelt &goto_model,
43  const replacement_mapt &replacement_map) const
44 {
45  const namespacet ns(goto_model.symbol_table);
46  goto_functionst &goto_functions = goto_model.goto_functions;
47 
48  check_replacement_map(replacement_map, goto_functions, ns);
49 
50  for(auto &p : goto_functions.function_map)
51  {
52  goto_functionst::goto_functiont &goto_function = p.second;
53  goto_programt &goto_program = goto_function.body;
54 
55  (*this)(goto_program, goto_functions, ns, replacement_map);
56  }
57 }
58 
60  goto_programt &goto_program,
61  const goto_functionst &goto_functions,
62  const namespacet &ns,
63  const replacement_mapt &replacement_map) const
64 {
65  Forall_goto_program_instructions(it, goto_program)
66  {
67  goto_programt::instructiont &ins = *it;
68 
69  if(!ins.is_function_call())
70  continue;
71 
72  const exprt &function = ins.call_function();
73 
74  PRECONDITION(function.id() == ID_symbol);
75 
76  const symbol_exprt &se = to_symbol_expr(function);
77  const irep_idt &id = se.get_identifier();
78 
79  auto f_it1 = goto_functions.function_map.find(id);
80 
82  f_it1 != goto_functions.function_map.end(),
83  "Called functions need to be present");
84 
85  replacement_mapt::const_iterator r_it = replacement_map.find(id);
86 
87  if(r_it == replacement_map.end())
88  continue;
89 
90  const irep_idt &new_id = r_it->second;
91 
92  auto f_it2 = goto_functions.function_map.find(new_id);
93  PRECONDITION(f_it2 != goto_functions.function_map.end());
94 
95  // check that returns have not been removed
96  if(to_code_type(function.type()).return_type().id() != ID_empty)
97  {
98  goto_programt::const_targett next_it = std::next(it);
99  if(next_it != goto_program.instructions.end() && next_it->is_assign())
100  {
101  const exprt &rhs = next_it->assign_rhs();
102 
103  INVARIANT(
104  rhs != return_value_symbol(id, ns),
105  "returns must not be removed before replacing calls");
106  }
107  }
108 
109  // Finally modify the call
110  ins.call_function().type() = ns.lookup(f_it2->first).type;
112  }
113 }
114 
116  const replacement_listt &replacement_list) const
117 {
118  replacement_mapt replacement_map;
119 
120  for(const std::string &s : replacement_list)
121  {
122  std::string original;
123  std::string replacement;
124 
125  split_string(s, ':', original, replacement, true);
126 
127  const auto r =
128  replacement_map.insert(std::make_pair(original, replacement));
129 
130  if(!r.second)
131  {
133  "conflicting replacement for function " + original, "--replace-calls");
134  }
135  }
136 
137  return replacement_map;
138 }
139 
141  const replacement_mapt &replacement_map,
142  const goto_functionst &goto_functions,
143  const namespacet &ns) const
144 {
145  for(const auto &p : replacement_map)
146  {
147  if(replacement_map.find(p.second) != replacement_map.end())
149  "function " + id2string(p.second) +
150  " cannot both be replaced and be a replacement",
151  "--replace-calls");
152 
153  auto it2 = goto_functions.function_map.find(p.second);
154 
155  if(it2 == goto_functions.function_map.end())
157  "replacement function " + id2string(p.second) + " needs to be present",
158  "--replace-calls");
159 
160  auto it1 = goto_functions.function_map.find(p.first);
161  if(it1 != goto_functions.function_map.end())
162  {
163  if(ns.lookup(it1->first).type != ns.lookup(it2->first).type)
165  "functions " + id2string(p.first) + " and " + id2string(p.second) +
166  " are not type-compatible",
167  "--replace-calls");
168  }
169  }
170 }
Forall_goto_program_instructions
#define Forall_goto_program_instructions(it, program)
Definition: goto_program.h:1234
exception_utils.h
dstringt
dstringt has one field, an unsigned integer no which is an index into a static table of strings.
Definition: dstring.h:36
replace_callst::replacement_listt
std::list< std::string > replacement_listt
Definition: replace_calls.h:29
string_utils.h
invariant.h
goto_model.h
exprt
Base class for all expressions.
Definition: expr.h:55
goto_modelt
Definition: goto_model.h:25
replace_calls.h
goto_functionst::function_map
function_mapt function_map
Definition: goto_functions.h:29
symbol_exprt
Expression to hold a symbol (variable)
Definition: std_expr.h:112
replace_callst::check_replacement_map
void check_replacement_map(const replacement_mapt &replacement_map, const goto_functionst &goto_functions, const namespacet &ns) const
Definition: replace_calls.cpp:140
namespace.h
replace_callst::parse_replacement_list
replacement_mapt parse_replacement_list(const replacement_listt &replacement_list) const
Definition: replace_calls.cpp:115
namespacet
A namespacet is essentially one or two symbol tables bound together, to allow for symbol lookups in t...
Definition: namespace.h:90
exprt::type
typet & type()
Return the type of the expression.
Definition: expr.h:84
namespacet::lookup
bool lookup(const irep_idt &name, const symbolt *&symbol) const override
See documentation for namespace_baset::lookup().
Definition: namespace.cpp:138
split_string
void split_string(const std::string &s, char delim, std::vector< std::string > &result, bool strip, bool remove_empty)
Definition: string_utils.cpp:39
to_code_type
const code_typet & to_code_type(const typet &type)
Cast a typet to a code_typet.
Definition: std_types.h:744
DATA_INVARIANT
#define DATA_INVARIANT(CONDITION, REASON)
This condition should be used to document that assumptions that are made on goto_functions,...
Definition: invariant.h:510
id2string
const std::string & id2string(const irep_idt &d)
Definition: irep.h:47
replace_callst::replacement_mapt
std::map< irep_idt, irep_idt > replacement_mapt
Definition: replace_calls.h:30
PRECONDITION
#define PRECONDITION(CONDITION)
Definition: invariant.h:463
symbol_exprt::get_identifier
const irep_idt & get_identifier() const
Definition: std_expr.h:142
to_symbol_expr
const symbol_exprt & to_symbol_expr(const exprt &expr)
Cast an exprt to a symbol_exprt.
Definition: std_expr.h:222
remove_returns.h
goto_functionst::goto_functiont
::goto_functiont goto_functiont
Definition: goto_functions.h:27
goto_programt::instructions
instructionst instructions
The list of instructions in the goto program.
Definition: goto_program.h:592
goto_functionst
A collection of goto functions.
Definition: goto_functions.h:24
goto_modelt::goto_functions
goto_functionst goto_functions
GOTO functions.
Definition: goto_model.h:33
replace_callst::operator()
void operator()(goto_modelt &goto_model, const replacement_listt &replacement_list) const
Replace function calls with calls to other functions.
Definition: replace_calls.cpp:29
goto_programt
A generic container class for the GOTO intermediate representation of one function.
Definition: goto_program.h:72
return_value_symbol
symbol_exprt return_value_symbol(const irep_idt &identifier, const namespacet &ns)
produces the symbol that is used to store the return value of the function with the given identifier
Definition: remove_returns.cpp:409
goto_programt::const_targett
instructionst::const_iterator const_targett
Definition: goto_program.h:587
r
static int8_t r
Definition: irep_hash.h:60
goto_programt::instructiont::is_function_call
bool is_function_call() const
Definition: goto_program.h:466
invalid_command_line_argument_exceptiont
Thrown when users pass incorrect command line arguments, for example passing no files to analysis or ...
Definition: exception_utils.h:50
goto_programt::instructiont
This class represents an instruction in the GOTO intermediate representation.
Definition: goto_program.h:180
goto_modelt::symbol_table
symbol_tablet symbol_table
Symbol table.
Definition: goto_model.h:30
goto_programt::instructiont::call_function
const exprt & call_function() const
Get the function that is called for FUNCTION_CALL.
Definition: goto_program.h:279
symbol_exprt::set_identifier
void set_identifier(const irep_idt &identifier)
Definition: std_expr.h:137
validation_modet::INVARIANT
@ INVARIANT