CBMC
instrument_preconditions.cpp
Go to the documentation of this file.
1 /*******************************************************************\
2 
3 Module: Move preconditions of a function
4  to the call-site of the function
5 
6 Author: Daniel Kroening
7 
8 Date: September 2017
9 
10 \*******************************************************************/
11 
13 
14 #include <util/replace_symbol.h>
15 
16 #include "goto_model.h"
17 
18 std::vector<goto_programt::const_targett> get_preconditions(
19  const symbol_exprt &function,
20  const goto_functionst &goto_functions)
21 {
22  const irep_idt &identifier=function.get_identifier();
23 
24  auto f_it=goto_functions.function_map.find(identifier);
25  if(f_it==goto_functions.function_map.end())
26  return {};
27 
28  const auto &body=f_it->second.body;
29 
30  std::vector<goto_programt::const_targett> result;
31 
32  for(auto i_it=body.instructions.begin();
33  i_it!=body.instructions.end();
34  i_it++)
35  {
36  if(i_it->is_location() ||
37  i_it->is_skip())
38  continue; // ignore
39 
40  if(
41  i_it->is_assert() &&
42  i_it->source_location().get_property_class() == ID_precondition)
43  {
44  result.push_back(i_it);
45  }
46  else
47  break; // preconditions must be at the front
48  }
49 
50  return result;
51 }
52 
54 {
55  for(auto &instruction : goto_program.instructions)
56  {
57  if(instruction.is_location() ||
58  instruction.is_skip())
59  continue; // ignore
60 
61  if(
62  instruction.is_assert() &&
63  instruction.source_location().get_property_class() == ID_precondition)
64  {
65  instruction = goto_programt::make_location(instruction.source_location());
66  }
67  else
68  break; // preconditions must be at the front
69  }
70 }
71 
73  const exprt &lhs,
74  const exprt &function,
75  const exprt::operandst &arguments,
76  const namespacet &ns)
77 {
78  PRECONDITION(function.id() == ID_symbol);
79  const symbolt &s = ns.lookup(to_symbol_expr(function));
80  const auto &code_type=to_code_type(s.type);
81  const auto &parameters=code_type.parameters();
82 
83  replace_symbolt result;
84  std::size_t count=0;
85  for(const auto &p : parameters)
86  {
87  if(!p.get_identifier().empty() && arguments.size() > count)
88  {
89  const exprt a =
90  typecast_exprt::conditional_cast(arguments[count], p.type());
91  result.insert(symbol_exprt(p.get_identifier(), p.type()), a);
92  }
93  count++;
94  }
95 
96  return result;
97 }
98 
100  const goto_modelt &goto_model,
101  goto_programt &goto_program)
102 {
103  const namespacet ns(goto_model.symbol_table);
104 
105  for(auto it=goto_program.instructions.begin();
106  it!=goto_program.instructions.end();
107  it++)
108  {
109  if(it->is_function_call())
110  {
111  // does the function we call have preconditions?
112  if(as_const(*it).call_function().id() == ID_symbol)
113  {
114  auto preconditions = get_preconditions(
115  to_symbol_expr(as_const(*it).call_function()),
116  goto_model.goto_functions);
117 
118  source_locationt source_location = it->source_location();
119 
121  as_const(*it).call_lhs(),
122  as_const(*it).call_function(),
123  as_const(*it).call_arguments(),
124  ns);
125 
126  // add before the call, with location of the call
127  for(const auto &p : preconditions)
128  {
129  goto_program.insert_before_swap(it);
130  exprt instance = p->condition();
131  r(instance);
132  *it = goto_programt::make_assertion(instance, source_location);
133  it->source_location_nonconst().set_property_class(
134  ID_precondition_instance);
135  it->source_location_nonconst().set_comment(
136  p->source_location().get_comment());
137  it++;
138  }
139  }
140  }
141  }
142 }
143 
145 {
146  // add at call site
147  for(auto &f_it : goto_model.goto_functions.function_map)
149  goto_model,
150  f_it.second.body);
151 
152  // now remove the preconditions
153  for(auto &f_it : goto_model.goto_functions.function_map)
154  remove_preconditions(f_it.second.body);
155  // The above may leave some locations uninitialized, this update is a
156  // sanity to check to ensure the goto model and functions are correct
157  // for later passes.
158  // Note that only the first loop is the one known to leave locations
159  // uninitialized.
160  goto_model.goto_functions.update();
161 }
162 
164 {
165  remove_preconditions(goto_function.body);
166 }
167 
169 {
170  for(auto &f_it : goto_model.goto_functions.function_map)
171  remove_preconditions(f_it.second);
172 }
dstringt
dstringt has one field, an unsigned integer no which is an index into a static table of strings.
Definition: dstring.h:36
goto_functiont::body
goto_programt body
Definition: goto_function.h:26
typecast_exprt::conditional_cast
static exprt conditional_cast(const exprt &expr, const typet &type)
Definition: std_expr.h:2025
symbolt::type
typet type
Type of symbol.
Definition: symbol.h:31
instrument_preconditions.h
replace_symbol.h
goto_model.h
exprt
Base class for all expressions.
Definition: expr.h:55
goto_modelt
Definition: goto_model.h:25
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
namespacet
A namespacet is essentially one or two symbol tables bound together, to allow for symbol lookups in t...
Definition: namespace.h:90
namespacet::lookup
bool lookup(const irep_idt &name, const symbolt *&symbol) const override
See documentation for namespace_baset::lookup().
Definition: namespace.cpp:138
to_code_type
const code_typet & to_code_type(const typet &type)
Cast a typet to a code_typet.
Definition: std_types.h:744
goto_programt::make_assertion
static instructiont make_assertion(const exprt &g, const source_locationt &l=source_locationt::nil())
Definition: goto_program.h:924
as_const
const T & as_const(T &value)
Return a reference to the same object but ensures the type is const.
Definition: as_const.h:14
get_preconditions
std::vector< goto_programt::const_targett > get_preconditions(const symbol_exprt &function, const goto_functionst &goto_functions)
Definition: instrument_preconditions.cpp:18
instrument_preconditions
void instrument_preconditions(const goto_modelt &goto_model, goto_programt &goto_program)
Definition: instrument_preconditions.cpp:99
PRECONDITION
#define PRECONDITION(CONDITION)
Definition: invariant.h:463
to_symbol_expr
const symbol_exprt & to_symbol_expr(const exprt &expr)
Cast an exprt to a symbol_exprt.
Definition: std_expr.h:222
goto_functiont
A goto function, consisting of function body (see body) and parameter identifiers (see parameter_iden...
Definition: goto_function.h:23
exprt::operandst
std::vector< exprt > operandst
Definition: expr.h:58
replace_symbolt::insert
void insert(const class symbol_exprt &old_expr, const exprt &new_expr)
Sets old_expr to be replaced by new_expr if we don't already have a replacement; otherwise does nothi...
Definition: replace_symbol.cpp:24
source_locationt
Definition: source_location.h:18
remove_preconditions
void remove_preconditions(goto_programt &goto_program)
Definition: instrument_preconditions.cpp:53
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
symbolt
Symbol table entry.
Definition: symbol.h:27
goto_functionst::update
void update()
Definition: goto_functions.h:83
goto_programt
A generic container class for the GOTO intermediate representation of one function.
Definition: goto_program.h:72
r
static int8_t r
Definition: irep_hash.h:60
goto_programt::insert_before_swap
void insert_before_swap(targett target)
Insertion that preserves jumps to "target".
Definition: goto_program.h:613
goto_modelt::symbol_table
symbol_tablet symbol_table
Symbol table.
Definition: goto_model.h:30
goto_programt::make_location
static instructiont make_location(const source_locationt &l)
Definition: goto_program.h:892
replace_symbolt
Replace a symbol expression by a given expression.
Definition: replace_symbol.h:27
actuals_replace_map
replace_symbolt actuals_replace_map(const exprt &lhs, const exprt &function, const exprt::operandst &arguments, const namespacet &ns)
Definition: instrument_preconditions.cpp:72