CBMC
Loading...
Searching...
No Matches
dfcc_contract_handler.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\*******************************************************************/
9
11
13
16
18
19#include "dfcc_utils.h"
21
22std::map<irep_idt, dfcc_contract_functionst>
24
26 goto_modelt &goto_model,
27 message_handlert &message_handler,
28 dfcc_libraryt &library,
29 dfcc_instrumentt &instrument,
30 dfcc_lift_memory_predicatest &memory_predicates,
31 dfcc_spec_functionst &spec_functions,
32 dfcc_contract_clauses_codegent &contract_clauses_codegen)
33 : goto_model(goto_model),
34 message_handler(message_handler),
35 log(message_handler),
36 library(library),
37 instrument(instrument),
38 memory_predicates(memory_predicates),
39 spec_functions(spec_functions),
40 contract_clauses_codegen(contract_clauses_codegen),
41 ns(goto_model.symbol_table)
42{
43}
44
47{
49
50 // return existing value
52 return iter->second;
53
54 // insert new value
56 .insert(
62 library,
65 instrument)})
66 .first->second;
67}
68
69const std::size_t
74
97
99 const irep_idt &contract_id,
100 const std::optional<irep_idt> function_id_opt)
101{
102 auto pure_contract_id = "contract::" + id2string(contract_id);
103 const symbolt *pure_contract_symbol = nullptr;
104 if(!ns.lookup(pure_contract_id, pure_contract_symbol))
105 {
106 if(function_id_opt.has_value())
107 {
108 auto function_id = function_id_opt.value();
109 const auto &function_symbol =
112 function_id,
115 to_code_type(pure_contract_symbol->type));
116 }
117 return *pure_contract_symbol;
118 }
119 else
120 {
121 // The contract symbol might not have been created if the function had
122 // no contract or a contract with all empty clauses (which is equivalent).
123 // This is a soundness issue when using --replace-call-with-contract
124 // because we should not assume a trivial contract.
126 function_id_opt.has_value(),
127 "Contract '" + pure_contract_id +
128 "' not found, the identifier of an existing function must be provided "
129 "to derive a default contract");
130
131 // Produce a hard error instead of assuming a trivial contract
132 // to address soundness risk
134 "Function '" + id2string(*function_id_opt) +
135 "' does not have a contract. " +
136 "A contract must be explicitly provided. If you need a trivial " +
137 "contract, please add explicit " +
138 CPROVER_PREFIX "requires and " CPROVER_PREFIX
139 "ensures clauses to the function.");
140 }
141}
142
144 const irep_idt &contract_id,
148{
149 // can we turn a call to `contract` into a call to `pure_contract` ?
150 bool compatible =
152
153 if(!compatible)
154 {
155 std::ostringstream err_msg;
156 err_msg << "dfcc_contract_handlert: function '" << contract_id
157 << "' and the corresponding pure contract symbol '"
158 << pure_contract_id << "' have incompatible type signatures:\n";
159
160 err_msg << "- contract return type "
161 << from_type(ns, contract_id, contract_type.return_type()) << "\n";
162
163 for(const auto &param : contract_type.parameters())
164 {
165 err_msg << "- contract param type "
166 << from_type(ns, contract_id, param.type()) << "\n";
167 }
168
169 err_msg << "- pure contract return type "
171 << "\n";
172
173 for(const auto &param : pure_contract_type.parameters())
174 {
175 err_msg << "- pure contract param type "
176 << from_type(ns, pure_contract_id, param.type()) << "\n";
177 }
178
179 err_msg << "aborting."
180 << "\n";
182 err_msg.str(), contract_type.source_location());
183 }
184}
ait supplies three of the four components needed: an abstract interpreter (in this case handling func...
Definition ai.h:566
Base type of functions.
Definition std_types.h:583
Translates assigns and frees clauses of a function contract or loop contract into GOTO programs that ...
Generates GOTO functions modelling a contract assigns and frees clauses.
void check_signature_compat(const irep_idt &contract_id, const code_typet &contract_type, const irep_idt &pure_contract_id, const code_typet &pure_contract_type)
Throws an error if the type signatures are not compatible.
dfcc_spec_functionst & spec_functions
const symbolt & get_pure_contract_symbol(const irep_idt &contract_id, const std::optional< irep_idt > function_id_opt={})
Searches for a symbol named "contract::contract_id" in the symbol table.
static std::map< irep_idt, dfcc_contract_functionst > contract_cache
dfcc_lift_memory_predicatest & memory_predicates
message_handlert & message_handler
dfcc_contract_clauses_codegent & contract_clauses_codegen
const std::size_t get_assigns_clause_size(const irep_idt &contract_id)
Returns the size assigns clause of the given contract in number of targets.
void add_contract_instructions(const dfcc_contract_modet contract_mode, const irep_idt &wrapper_id, const irep_idt &wrapped_id, const irep_idt &contract_id, const symbolt &wrapper_write_set_symbol, goto_programt &dest, std::set< irep_idt > &function_pointer_contracts)
Adds instructions in dest modeling contract checking, assuming that ret_t wrapper_id(params) is the f...
dfcc_contract_handlert(goto_modelt &goto_model, message_handlert &message_handler, dfcc_libraryt &library, dfcc_instrumentt &instrument, dfcc_lift_memory_predicatest &memory_predicates, dfcc_spec_functionst &spec_functions, dfcc_contract_clauses_codegent &contract_clauses_codegen)
const dfcc_contract_functionst & get_contract_functions(const irep_idt &contract_id)
Returns the dfcc_contract_functionst object for the given contract from the cache,...
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:
Generates the body of a wrapper function from a contract specified using requires,...
void add_to_dest(goto_programt &dest, std::set< irep_idt > &dest_fp_contracts)
Adds the whole program to dest and the discovered function pointer contracts dest_fp_contracts.
dstringt has one field, an unsigned integer no which is an index into a static table of strings.
Definition dstring.h:38
symbol_tablet symbol_table
Symbol table.
Definition goto_model.h:31
A generic container class for the GOTO intermediate representation of one function.
Thrown when user-provided input cannot be processed.
Thrown when we can't handle something in an input source file.
bool lookup(const irep_idt &name, const symbolt *&symbol) const override
See documentation for namespace_baset::lookup().
Symbol table entry.
Definition symbol.h:28
typet type
Type of symbol.
Definition symbol.h:31
#define CPROVER_PREFIX
Specialisation of dfcc_contract_handlert for contracts.
dfcc_contract_modet
Enum type representing the contract checking and replacement modes.
Dynamic frame condition checking utility functions.
Generates the body of a wrapper function from a contract for contract checking or contract replacemen...
Symbol Table + CFG.
const std::string & id2string(const irep_idt &d)
Definition irep.h:44
std::string from_type(const namespacet &ns, const irep_idt &identifier, const typet &type)
double log(double x)
Definition math.c:2416
bool function_is_type_compatible(bool return_value_used, const code_typet &call_type, const code_typet &function_type, const namespacet &ns)
Returns true iff call_type can be converted to produce a function call of the same type as function_t...
Remove Indirect Function Calls.
#define PRECONDITION_WITH_DIAGNOSTICS(CONDITION,...)
Definition invariant.h:464
const code_typet & to_code_type(const typet &type)
Cast a typet to a code_typet.
Definition std_types.h:788
static symbolt & get_function_symbol(symbol_table_baset &, const irep_idt &function_id)
Returns the symbolt for function_id.