CBMC
Loading...
Searching...
No Matches
dfcc_contract_functions.cpp
Go to the documentation of this file.
1/*******************************************************************\
2
3Module: Dynamic frame condition checking for function contracts
4
5Author: Remi Delmas, delmasrd@amazon.com
6Date: August 2022
7
8\*******************************************************************/
10
12#include <util/symbol.h>
13
15#include "dfcc_instrument.h"
16#include "dfcc_spec_functions.h"
17#include "dfcc_utils.h"
18
20 const symbolt &pure_contract_symbol,
21 goto_modelt &goto_model,
22 message_handlert &message_handler,
23 dfcc_libraryt &library,
24 dfcc_spec_functionst &spec_functions,
25 dfcc_contract_clauses_codegent &contract_clauses_codegen,
26 dfcc_instrumentt &instrument)
27 : pure_contract_symbol(pure_contract_symbol),
28 code_with_contract(to_code_with_contract_type(pure_contract_symbol.type)),
29 spec_assigns_function_id(
30 id2string(pure_contract_symbol.name) + "::assigns"),
31 spec_assigns_havoc_function_id(
32 id2string(pure_contract_symbol.name) + "::assigns::havoc"),
33 spec_frees_function_id(id2string(pure_contract_symbol.name) + "::frees"),
34 language_mode(pure_contract_symbol.mode),
35 goto_model(goto_model),
36 message_handler(message_handler),
37 log(message_handler),
38 library(library),
39 spec_functions(spec_functions),
40 contract_clauses_codegen(contract_clauses_codegen),
41 instrument(instrument),
42 ns(goto_model.symbol_table)
43{
45
50
53
55
58
61
64}
65
69{
70 std::set<irep_idt> function_pointer_contracts;
72 spec_function_id, loop_contract_configt{false}, function_pointer_contracts);
73
75 function_pointer_contracts.empty(),
76 id2string(spec_function_id) + " shall not contain calls to " CPROVER_PREFIX
77 "obeys_contract");
78}
79
80const symbolt &
85
86const symbolt &
91
96
98{
100}
101
103{
104 return nof_frees_targets;
105}
106
108{
113 empty_typet());
114
115 const auto &spec_function_id = spec_function_symbol.name;
116
118
120
121 if(code_with_contract.return_type().id() != ID_empty)
122 {
123 // use a dummy symbol for __CPROVER_return_value
124 // which does occur in the assigns clause anyway
125 lambda_parameters.push_back(
126 symbol_exprt("dummy_return_value", code_with_contract.return_type()));
127 }
128
129 for(const auto &param_id : spec_code_type.parameter_identifiers())
130 {
131 lambda_parameters.push_back(ns.lookup(param_id).symbol_expr());
132 }
133
134 // fetch the goto_function to add instructions to
135 goto_functiont &goto_function =
137
138 exprt::operandst targets;
139
140 for(const exprt &target : code_with_contract.c_assigns())
141 {
142 auto new_target = to_lambda_expr(target).application(lambda_parameters);
143 new_target.add_source_location() = target.source_location();
144 targets.push_back(new_target);
145 }
146
147 goto_programt &body = goto_function.body;
149 spec_function_symbol.mode, targets, body);
151
153}
154
156{
157 // fetch pure contract symbol
158 const auto &code_with_contract =
160
165 empty_typet());
166
167 const auto &spec_function_id = spec_function_symbol.name;
168
170
172
173 if(code_with_contract.return_type().id() != ID_empty)
174 {
175 // use a dummy symbol for __CPROVER_return_value
176 // which does occur in the assigns clause anyway
177 symbolt dummy;
178 dummy.name = "dummy_return_value";
179 dummy.type = code_with_contract.return_type();
180 lambda_parameters.push_back(dummy.symbol_expr());
181 }
182
183 for(const auto &param_id : spec_code_type.parameter_identifiers())
184 {
185 lambda_parameters.push_back(ns.lookup(param_id).symbol_expr());
186 }
187
188 // fetch the goto_function to add instructions to
189 goto_functiont &goto_function =
191
192 exprt::operandst targets;
193
194 for(const exprt &target : code_with_contract.c_frees())
195 {
196 auto new_target = to_lambda_expr(target).application(lambda_parameters);
197 new_target.add_source_location() = target.source_location();
198 targets.push_back(new_target);
199 }
200
201 goto_programt &body = goto_function.body;
203 spec_function_symbol.mode, targets, body);
205
207}
const code_with_contract_typet & to_code_with_contract_type(const typet &type)
Cast a typet to a code_with_contract_typet.
Definition c_types.h:467
ait supplies three of the four components needed: an abstract interpreter (in this case handling func...
Definition ai.h:562
Translates assigns and frees clauses of a function contract or loop contract into GOTO programs that ...
void gen_spec_assigns_instructions(const irep_idt &language_mode, const exprt::operandst &assigns_clause, goto_programt &dest)
Generates instructions encoding the assigns_clause targets and adds them to dest.
void gen_spec_frees_instructions(const irep_idt &language_mode, const exprt::operandst &frees_clause, goto_programt &dest)
Generates instructions encoding the frees_clause targets and adds them to dest.
void gen_spec_frees_function()
Translates the contract's frees clause to a GOTO function that uses the freeable built-in to express ...
const irep_idt spec_assigns_havoc_function_id
Identifier of the contract::c_assigns::havoc function.
const code_with_contract_typet & code_with_contract
The code_with_contract_type carrying the contract clauses.
const symbolt & get_spec_frees_function_symbol() const
Returns the contract::frees function symbol.
dfcc_contract_clauses_codegent & contract_clauses_codegen
const irep_idt spec_assigns_function_id
Identifier of the contract::c_assigns function.
void instrument_without_loop_contracts_check_no_pointer_contracts(const irep_idt &spec_function_id)
Instruments the given function without loop contracts and checks that no function pointer contracts w...
dfcc_contract_functionst(const symbolt &pure_contract_symbol, goto_modelt &goto_model, message_handlert &message_handler, dfcc_libraryt &library, dfcc_spec_functionst &spec_functions, dfcc_contract_clauses_codegent &contract_clauses_codegen, dfcc_instrumentt &instrument)
const symbolt & get_spec_assigns_function_symbol() const
Returns the contract::c_assigns function symbol.
const symbolt & pure_contract_symbol
The function symbol carrying the contract.
const std::size_t get_nof_assigns_targets() const
Returns the maximum number of targets in the assigns clause.
const symbolt & get_spec_assigns_havoc_function_symbol() const
Returns the contract::c_assigns::havoc function symbol.
void gen_spec_assigns_function()
Translates the contract's assigns clause to a GOTO function that uses the assignable,...
const irep_idt spec_frees_function_id
Identifier of the contract::frees function.
dfcc_spec_functionst & spec_functions
const std::size_t get_nof_frees_targets() const
Returns the maximum number of targets in the frees clause.
This class instruments GOTO functions or instruction sequences for frame condition checking and loop ...
void instrument_function(const irep_idt &function_id, const loop_contract_configt &loop_contract_config, std::set< irep_idt > &function_pointer_contracts)
Instruments a GOTO function by adding an extra write set parameter and instrumenting its body instruc...
Class interface to library types and functions defined in cprover_contracts.c.
This class rewrites GOTO functions that use the built-ins:
void to_spec_assigns_function(const irep_idt &function_id, std::size_t &nof_targets)
Transforms (in place) a function.
void generate_havoc_function(const irep_idt &function_id, const irep_idt &havoc_function_id, std::size_t &nof_targets)
Generates the havoc function for a function contract.
void to_spec_frees_function(const irep_idt &function_id, std::size_t &nof_targets)
Transforms (in place) a function.
dstringt has one field, an unsigned integer no which is an index into a static table of strings.
Definition dstring.h:38
The empty type.
Definition std_types.h:51
Base class for all expressions.
Definition expr.h:56
std::vector< exprt > operandst
Definition expr.h:58
function_mapt function_map
A goto function, consisting of function body (see body) and parameter identifiers (see parameter_iden...
goto_programt body
goto_functionst goto_functions
GOTO functions.
Definition goto_model.h:34
A generic container class for the GOTO intermediate representation of one function.
static instructiont make_end_function(const source_locationt &l=source_locationt::nil())
targett add(instructiont &&instruction)
Adds a given instruction at the end.
bool lookup(const irep_idt &name, const symbolt *&symbol) const override
See documentation for namespace_baset::lookup().
Expression to hold a symbol (variable)
Definition std_expr.h:131
Symbol table entry.
Definition symbol.h:28
class symbol_exprt symbol_expr() const
Produces a symbol_exprt for a symbol.
Definition symbol.cpp:121
typet type
Type of symbol.
Definition symbol.h:31
irep_idt name
The unique identifier.
Definition symbol.h:40
#define CPROVER_PREFIX
Translates assigns and frees clauses of a function contract or loop contract into goto programs that ...
Translates assigns and frees clauses of a function contract into goto functions that allow to build a...
Add instrumentation to a goto program to perform frame condition checks.
Translate functions that specify assignable and freeable targets declaratively into active functions ...
Dynamic frame condition checking utility functions.
const std::string & id2string(const irep_idt &d)
Definition irep.h:44
double log(double x)
Definition math.c:2449
API to expression classes for 'mathematical' expressions.
const lambda_exprt & to_lambda_expr(const exprt &expr)
Cast an exprt to a lambda_exprt.
#define INVARIANT(CONDITION, REASON)
This macro uses the wrapper function 'invariant_violated_string'.
Definition invariant.h:423
const code_typet & to_code_type(const typet &type)
Cast a typet to a code_typet.
Definition std_types.h:788
static const symbolt & clone_and_rename_function(goto_modelt &goto_model, const irep_idt &function_id, const irep_idt &new_function_id, std::optional< typet > new_return_type)
Creates a new function symbol and goto_function entry in the goto_functions_map by cloning the given ...
Loop contract configurations.
Symbol table entry.