@@ -219,7 +219,8 @@ class dfcct
219219 // / Adds the given symbol as parameter to the given code_typet.
220220 void add_parameter (const symbolt &symbol, code_typet &code_type);
221221
222- // / Adds a parameter to the given function
222+ // / Adds a parameter with given `base_name` and `type` to the given
223+ // / `function_id`. Both the symbol and the goto_function are updated.
223224 const symbolt &add_parameter (
224225 const irep_idt &function_id,
225226 const std::string &base_name,
@@ -245,66 +246,15 @@ class dfcct
245246 goto_programt &decl_init,
246247 goto_programt &dead);
247248
248- // / Wraps the given function_id
249- // / in a wrapper that checks the given contract_id against the function.
250- void wrap_with_contract_check (
251- const irep_idt &function_id,
252- const irep_idt &contract_id);
253-
254- // / Genrates the body of the wrapper function as follows:
255- // /
256- // / ```
257- // / static _Bool replace_wrapper_by_contract = 0;
258- // /
259- // / ret_t wrapper(params) {
260- // / if(replace_wrapper_by_contract) {
261- // / // replace call with contract
262- // / return contract::replace(params);
263- // / } else {
264- // / // check contract against wrapped function
265- // / replace_wrapper_by_contract = 1;
266- // / ret_t ret;
267- // / // declare history params ...
268- // / assume(requires);
269- // / ret = wrapped(params);
270- // / assert(ensures);
271- // / replace_wrapper_by_contract = 0;
272- // / return ret;
273- // / }
274- // / }
275- // / ```
276- // / \param wrapped_id name of the function that is to be wrapped
277- // / \param contract_id name of the symbol carrying the contract clauses
278- // / \param wrapper_id name to use for the wrapper function
279- void generate_contract_check_body (
280- const irep_idt &wrapped_id,
281- const irep_idt &wrapper_id,
282- const irep_idt &contract_id);
283-
284- // / Generates the body of the wrapper function as follows:
285- // / ```
286- // / ret_t wrapper(params) {
287- // / return contract::replace(params);
288- // / }
289- void wrap_with_contract_abstraction (
290- const irep_idt &function_id,
291- const irep_idt &contract_id);
292-
293- void generate_contract_abstraction_body (
294- const irep_idt &wrapped_id,
295- const irep_idt &wrapper_id,
296- const irep_idt &contract_id);
297-
298-
299249 // / Given a function to wrap `foo` and a new name `wrapped_foo`
300250 // /
301251 // / ```
302252 // / ret_t foo(x_t foo::x, y_t foo::y) { foo_body; }
303253 // / ```
304254 // /
305- // / This creates a new entry in the symbol_table for
306- // / `wrapped_foo` and moves the goto_function `foo_body` under
307- // / `wrapped_foo` in `function_map`.
255+ // / This method creates a new entry in the symbol_table for
256+ // / `wrapped_foo` and moves the body of the original function, `foo_body`,
257+ // / under `wrapped_foo` in `function_map`.
308258 // /
309259 // / The parameter symbols of `wrapped_foo` remain the same as in `foo`:
310260 // / ```
@@ -329,10 +279,101 @@ class dfcct
329279 const irep_idt &wrapped_function_id);
330280
331281
282+ // / Wraps the given function_id
283+ // / in a wrapper that checks the given contract_id against the function.
284+ // /
285+ // / ```
286+ // / static bool on_stack = false;
287+ // /
288+ // / ret_t foo(params) {
289+ // / IF on_stack GOTO replacement_label;
290+ // / <contract checking instructions>
291+ // / replacement_label;
292+ // / <contract replacement instructions>
293+ // / }
294+ // / ```
295+ void check_contract (
296+ const irep_idt &function_id,
297+ const irep_idt &contract_id);
298+
299+ // / Wraps the given function_id
300+ // / in a wrapper that models contract replacement.
301+ void replace_with_contract (
302+ const irep_idt &function_id,
303+ const irep_idt &contract_id);
304+
305+
306+ // / Adds instruction modeling contract checking, assuming
307+ // / `ret_t wrapper_id(params, __dfcc_set)` receives the instructions.
308+ // /
309+ // / \param wrapped_id name of the function that is to be wrapped
310+ // / \param contract_id name of the symbol carrying the contract clauses
311+ // / \param wrapper_id name to use for the wrapper function
312+ // / \param dest goto program where instructions are appended
313+ // /
314+ // / The generated instructions:
315+ // / ```
316+ // / DECL __dfcc_set_local: assignable_set_t;
317+ // / CALL assignable_set_create(
318+ // / &__dfcc_set_local, size_hint(contract_id), append_mode = false);
319+ // / CALL contract_id::assigns(params, &_dfcc_set_local);
320+ // / CALL contract_id::frees(params, &_dfcc_set_local);
321+ // / DECL __is_fresh_set: assignable_obj_set_t;
322+ // / CALL obj_set_create(&__is_fresh_set);
323+ // / ASSUME contract::pre(params);
324+ // / DECL hist = ...;
325+ // / CALL ret = wrapped_id(params, &__dfcc_set_local);
326+ // / ASSERT contract::post(params, hist, ret);
327+ // / SET_RETURN_VALUE ret;
328+ // / ```
329+ // /
330+ void add_contract_checking_instructions (
331+ const irep_idt &wrapped_id,
332+ const irep_idt &wrapper_id,
333+ const irep_idt &contract_id,
334+ goto_programt& dest);
335+
336+
337+ // / Adds instruction modeling contract replacement, assuming
338+ // / `ret_t wrapper(params, __dfcc_set)` receives the instructions.
339+ // /
340+ // / \param contract_id name of the symbol carrying the contract clauses
341+ // / \param wrapper_id name to use for the wrapper function
342+ // / \param dest goto program where instructions are appended
343+ // /
344+ // / The generated instructions:
345+ // / ```
346+ // / DECL __dfcc_set_local: assignable_set_t ;
347+ // / CALL assignable_set_create(
348+ // / &__dfcc_set_local, size_hint(contract_id), append_mode = true);
349+ // / CALL contract::assigns(params, &_dfcc_set_local);
350+ // / CALL contract::frees(params, &_dfcc_set_local);
351+ // / ASSERT check_assigns_clause_inclusion(__dfcc_set, &__dfcc_set_local);
352+ // / ASSERT check_frees_clause_inclusion(__dfcc_set, &__dfcc_set_local);
353+ // / DECL __is_fresh_set: assignable_obj_set_t;
354+ // / CALL obj_set_create(&__is_fresh_set);
355+ // / ASSERT contract::pre(params);
356+ // / DECL hist = ...; // snapshot history variables
357+ // / CALL contract::havoc(__dfcc_set_local);
358+ // / CALL ret = nondet();
359+ // / ASSUME contract::post(params, hist, ret);
360+ // / SET_RETURN_VALUE ret;
361+ // / ```
362+ void add_contract_replacement_instructions (
363+ const irep_idt &wrapper_id,
364+ const irep_idt &contract_id,
365+ goto_programt& dest);
366+
367+ // / Adds a global static `function_id::on_stack` for tracking
368+ // / recursive calls to `function_id`.
369+ symbol_exprt add_recursion_tracking_variable (const irep_idt &function_id);
370+
332371 // / Creates a new symbol in the `symbol_table` by cloning
333- // / the given `function_id` function.
372+ // / the given `function_id` function and transforming the
373+ // / function's name, parameter names, return type and source location
374+ // / using the given functions.
334375 // /
335- // / Also creates a new `goto_function` under the new name in
376+ // / Also creates a new `goto_function` under the transformed name in
336377 // / the `function_map` with new parameters and an empty body.
337378 // / Returns the new symbol.
338379 // /
0 commit comments