cprover
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
30 id2string(pure_contract_symbol.name) + "::assigns"),
32 id2string(pure_contract_symbol.name) + "::assigns::havoc"),
42 ns(goto_model.symbol_table)
43{
44 gen_spec_assigns_function();
45
46 spec_functions.generate_havoc_function(
50
51 spec_functions.to_spec_assigns_function(
53
55
56 spec_functions.to_spec_frees_function(
58
61
64}
65
68 const irep_idt &spec_function_id)
69{
70 std::set<irep_idt> function_pointer_contracts;
71 instrument.instrument_function(
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
107void dfcc_contract_functionst::gen_spec_assigns_function()
108{
109 const auto &spec_function_symbol = dfcc_utilst::clone_and_rename_function(
113 empty_typet());
114
115 const auto &spec_function_id = spec_function_symbol.name;
116
117 auto &spec_code_type = to_code_type(spec_function_symbol.type);
118
119 exprt::operandst lambda_parameters;
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 =
136 goto_model.goto_functions.function_map.at(spec_function_id);
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;
148 contract_clauses_codegen.gen_spec_assigns_instructions(
149 spec_function_symbol.mode, targets, body);
150 body.add(goto_programt::make_end_function(spec_function_symbol.location));
151
152 goto_model.goto_functions.update();
153}
154
156{
157 // fetch pure contract symbol
158 const auto &code_with_contract =
160
161 auto &spec_function_symbol = dfcc_utilst::clone_and_rename_function(
165 empty_typet());
166
167 const auto &spec_function_id = spec_function_symbol.name;
168
169 auto &spec_code_type = to_code_type(spec_function_symbol.type);
170
171 exprt::operandst lambda_parameters;
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 =
190 goto_model.goto_functions.function_map.at(spec_function_id);
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;
202 contract_clauses_codegen.gen_spec_frees_instructions(
203 spec_function_symbol.mode, targets, body);
204 body.add(goto_programt::make_end_function(spec_function_symbol.location));
205
206 goto_model.goto_functions.update();
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
const typet & return_type() const
Definition std_types.h:689
Translates assigns and frees clauses of a function contract or loop contract into GOTO programs that ...
void gen_spec_frees_function()
Translates the contract's assigns clause to a GOTO function that uses the assignable,...
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.
const irep_idt spec_frees_function_id
Identifier of the contract::frees function.
dfcc_spec_functionst & spec_functions
const irep_idt & language_mode
Language mode of the contract symbol.
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 ...
Class interface to library types and functions defined in cprover_contracts.c.
This class rewrites GOTO functions that use the built-ins:
The empty type.
Definition std_types.h:51
Base class for all expressions.
Definition expr.h:57
std::vector< exprt > operandst
Definition expr.h:59
source_locationt & add_source_location()
Definition expr.h:241
A goto function, consisting of function body (see body) and parameter identifiers (see parameter_iden...
goto_programt body
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.
const irep_idt & id() const
Definition irep.h:388
exprt application(const operandst &arguments) const
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
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.
dstringt irep_idt