Skip to content

Commit 582aa69

Browse files
authored
Merge pull request #8356 from qinheping/feature/use_loop_contract_config
[CONTRACTS] Use unified loop contract config
2 parents cbc5079 + a7afbe2 commit 582aa69

20 files changed

+157
-265
lines changed

src/goto-instrument/Makefile

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ SRC = accelerate/accelerate.cpp \
2121
contracts/dynamic-frames/dfcc_utils.cpp \
2222
contracts/dynamic-frames/dfcc_loop_nesting_graph.cpp \
2323
contracts/dynamic-frames/dfcc_contract_mode.cpp \
24-
contracts/dynamic-frames/dfcc_loop_contract_mode.cpp \
2524
contracts/dynamic-frames/dfcc_loop_tags.cpp \
2625
contracts/dynamic-frames/dfcc_check_loop_normal_form.cpp \
2726
contracts/dynamic-frames/dfcc_root_object.cpp \

src/goto-instrument/contracts/contracts.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1500,7 +1500,7 @@ void code_contractst::apply_loop_contracts(
15001500
nondet_static(goto_model, to_exclude_from_nondet_init);
15011501

15021502
// unwind all transformed loops twice.
1503-
if(unwind_transformed_loops)
1503+
if(loop_contract_config.unwind_transformed_loops)
15041504
{
15051505
unwindsett unwindset{goto_model};
15061506
unwindset.parse_unwindset(loop_names, log.get_message_handler());

src/goto-instrument/contracts/contracts.h

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ Date: February 2016
2222

2323
#include <goto-instrument/loop_utils.h>
2424

25+
#include "loop_contract_config.h"
26+
2527
#include <map>
2628
#include <set>
2729
#include <string>
@@ -55,12 +57,16 @@ class local_may_aliast;
5557
class code_contractst
5658
{
5759
public:
58-
code_contractst(goto_modelt &goto_model, messaget &log)
60+
code_contractst(
61+
goto_modelt &goto_model,
62+
messaget &log,
63+
const loop_contract_configt &loop_contract_config)
5964
: ns(goto_model.symbol_table),
6065
goto_model(goto_model),
6166
symbol_table(goto_model.symbol_table),
6267
goto_functions(goto_model.goto_functions),
63-
log(log)
68+
log(log),
69+
loop_contract_config(loop_contract_config)
6470
{
6571
}
6672

@@ -138,9 +144,6 @@ class code_contractst
138144

139145
namespacet ns;
140146

141-
// Unwind transformed loops after applying loop contracts or not.
142-
bool unwind_transformed_loops = true;
143-
144147
protected:
145148
goto_modelt &goto_model;
146149
symbol_tablet &symbol_table;
@@ -164,6 +167,9 @@ class code_contractst
164167
std::unordered_set<goto_programt::const_targett, const_target_hash>
165168
loop_havoc_set;
166169

170+
// Loop contract configuration
171+
loop_contract_configt loop_contract_config;
172+
167173
public:
168174
/// \brief Enforce contract of a single function
169175
void enforce_contract(const irep_idt &function);

src/goto-instrument/contracts/dynamic-frames/dfcc.cpp

Lines changed: 9 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -119,52 +119,25 @@ void dfcc(
119119
const std::optional<irep_idt> &to_check,
120120
const bool allow_recursive_calls,
121121
const std::set<irep_idt> &to_replace,
122-
const bool apply_loop_contracts,
123-
const bool unwind_transformed_loops,
122+
const loop_contract_configt loop_contract_config,
124123
const std::set<std::string> &to_exclude_from_nondet_static,
125124
message_handlert &message_handler)
126125
{
127126
std::map<irep_idt, irep_idt> to_replace_map;
128127
for(const auto &cli_flag : to_replace)
129128
to_replace_map.insert(parse_function_contract_pair(cli_flag));
130129

131-
dfcc(
130+
dfcct(
132131
options,
133132
goto_model,
134133
harness_id,
135134
to_check.has_value() ? parse_function_contract_pair(to_check.value())
136135
: std::optional<std::pair<irep_idt, irep_idt>>{},
137136
allow_recursive_calls,
138137
to_replace_map,
139-
apply_loop_contracts,
140-
unwind_transformed_loops,
141-
to_exclude_from_nondet_static,
142-
message_handler);
143-
}
144-
145-
void dfcc(
146-
const optionst &options,
147-
goto_modelt &goto_model,
148-
const irep_idt &harness_id,
149-
const std::optional<std::pair<irep_idt, irep_idt>> &to_check,
150-
const bool allow_recursive_calls,
151-
const std::map<irep_idt, irep_idt> &to_replace,
152-
const bool apply_loop_contracts,
153-
const bool unwind_transformed_loops,
154-
const std::set<std::string> &to_exclude_from_nondet_static,
155-
message_handlert &message_handler)
156-
{
157-
dfcct{
158-
options,
159-
goto_model,
160-
harness_id,
161-
to_check,
162-
allow_recursive_calls,
163-
to_replace,
164-
dfcc_loop_contract_mode_from_bools(
165-
apply_loop_contracts, unwind_transformed_loops),
138+
loop_contract_config,
166139
message_handler,
167-
to_exclude_from_nondet_static};
140+
to_exclude_from_nondet_static);
168141
}
169142

170143
dfcct::dfcct(
@@ -174,7 +147,7 @@ dfcct::dfcct(
174147
const std::optional<std::pair<irep_idt, irep_idt>> &to_check,
175148
const bool allow_recursive_calls,
176149
const std::map<irep_idt, irep_idt> &to_replace,
177-
const dfcc_loop_contract_modet loop_contract_mode,
150+
const loop_contract_configt loop_contract_config,
178151
message_handlert &message_handler,
179152
const std::set<std::string> &to_exclude_from_nondet_static)
180153
: options(options),
@@ -183,7 +156,7 @@ dfcct::dfcct(
183156
to_check(to_check),
184157
allow_recursive_calls(allow_recursive_calls),
185158
to_replace(to_replace),
186-
loop_contract_mode(loop_contract_mode),
159+
loop_contract_config(loop_contract_config),
187160
to_exclude_from_nondet_static(to_exclude_from_nondet_static),
188161
message_handler(message_handler),
189162
log(message_handler),
@@ -339,7 +312,7 @@ void dfcct::instrument_harness_function()
339312
<< messaget::eom;
340313

341314
instrument.instrument_harness_function(
342-
harness_id, loop_contract_mode, function_pointer_contracts);
315+
harness_id, loop_contract_config, function_pointer_contracts);
343316

344317
other_symbols.erase(harness_id);
345318
}
@@ -368,7 +341,7 @@ void dfcct::wrap_checked_function()
368341
<< contract_id << "' in CHECK mode" << messaget::eom;
369342

370343
swap_and_wrap.swap_and_wrap_check(
371-
loop_contract_mode,
344+
loop_contract_config,
372345
wrapper_id,
373346
contract_id,
374347
function_pointer_contracts,
@@ -486,7 +459,7 @@ void dfcct::instrument_other_functions()
486459
log.status() << "Instrumenting '" << function_id << "'" << messaget::eom;
487460

488461
instrument.instrument_function(
489-
function_id, loop_contract_mode, function_pointer_contracts);
462+
function_id, loop_contract_config, function_pointer_contracts);
490463
}
491464

492465
goto_model.goto_functions.update();

src/goto-instrument/contracts/dynamic-frames/dfcc.h

Lines changed: 5 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ Author: Remi Delmas, [email protected]
3838
#include "dfcc_instrument.h"
3939
#include "dfcc_library.h"
4040
#include "dfcc_lift_memory_predicates.h"
41-
#include "dfcc_loop_contract_mode.h"
4241
#include "dfcc_spec_functions.h"
4342
#include "dfcc_swap_and_wrap.h"
4443

@@ -96,9 +95,7 @@ class invalid_function_contract_pair_exceptiont : public cprover_exception_baset
9695
/// \param to_check function to check against its contract
9796
/// \param allow_recursive_calls Allow the checked function to be recursive
9897
/// \param to_replace set of functions to replace with their contract
99-
/// \param apply_loop_contracts apply loop contract transformations iff true
100-
/// \param unwind_transformed_loops unwind transformed loops after applying loop
101-
/// contracts.
98+
/// \param loop_contract_config configuration for applying loop contracts
10299
/// \param to_exclude_from_nondet_static set of symbols to exclude when havocing
103100
/// static program symbols.
104101
/// \param message_handler used for debug/warning/error messages
@@ -109,41 +106,7 @@ void dfcc(
109106
const std::optional<irep_idt> &to_check,
110107
const bool allow_recursive_calls,
111108
const std::set<irep_idt> &to_replace,
112-
const bool apply_loop_contracts,
113-
const bool unwind_transformed_loops,
114-
const std::set<std::string> &to_exclude_from_nondet_static,
115-
message_handlert &message_handler);
116-
117-
/// \ingroup dfcc-module
118-
/// \brief Applies function contracts and loop contracts transformation to GOTO
119-
/// model, using the dynamic frame condition checking approach.
120-
///
121-
/// Functions to check/replace are explicitly mapped to contracts.
122-
/// When checking function `foo` against contract `bar`, we require the
123-
/// actual contract symbol to exist as `contract::bar` in the symbol table.
124-
///
125-
/// \param options CLI options (used to lookup options for language config when
126-
/// re-defining the model's entry point)
127-
/// \param goto_model GOTO model to transform
128-
/// \param harness_id Proof harness name, must be the entry point of the model
129-
/// \param to_check (function,contract) pair for contract checking
130-
/// \param allow_recursive_calls Allow the checked function to be recursive
131-
/// \param to_replace Functions-to-contract mapping for replacement
132-
/// \param apply_loop_contracts Apply loop contract transformations iff true
133-
/// \param unwind_transformed_loops unwind transformed loops after applying loop
134-
/// contracts.
135-
/// \param to_exclude_from_nondet_static Set of symbols to exclude when havocing
136-
/// static program symbols.
137-
/// \param message_handler used for debug/warning/error messages
138-
void dfcc(
139-
const optionst &options,
140-
goto_modelt &goto_model,
141-
const irep_idt &harness_id,
142-
const std::optional<std::pair<irep_idt, irep_idt>> &to_check,
143-
const bool allow_recursive_calls,
144-
const std::map<irep_idt, irep_idt> &to_replace,
145-
const bool apply_loop_contracts,
146-
const bool unwind_transformed_loops,
109+
const loop_contract_configt loop_contract_config,
147110
const std::set<std::string> &to_exclude_from_nondet_static,
148111
message_handlert &message_handler);
149112

@@ -160,7 +123,7 @@ class dfcct
160123
/// \param to_check (function,contract) pair for contract checking
161124
/// \param allow_recursive_calls Allow the checked function to be recursive
162125
/// \param to_replace functions-to-contract mapping for replacement
163-
/// \param loop_contract_mode mode to use for loop contracts
126+
/// \param loop_contract_config configuration for applying loop contracts
164127
/// \param message_handler used for debug/warning/error messages
165128
/// \param to_exclude_from_nondet_static set of symbols to exclude when
166129
dfcct(
@@ -170,7 +133,7 @@ class dfcct
170133
const std::optional<std::pair<irep_idt, irep_idt>> &to_check,
171134
const bool allow_recursive_calls,
172135
const std::map<irep_idt, irep_idt> &to_replace,
173-
const dfcc_loop_contract_modet loop_contract_mode,
136+
const loop_contract_configt loop_contract_config,
174137
message_handlert &message_handler,
175138
const std::set<std::string> &to_exclude_from_nondet_static);
176139

@@ -207,7 +170,7 @@ class dfcct
207170
const std::optional<std::pair<irep_idt, irep_idt>> &to_check;
208171
const bool allow_recursive_calls;
209172
const std::map<irep_idt, irep_idt> &to_replace;
210-
const dfcc_loop_contract_modet loop_contract_mode;
173+
const loop_contract_configt loop_contract_config;
211174
const std::set<std::string> &to_exclude_from_nondet_static;
212175
message_handlert &message_handler;
213176
messaget log;

src/goto-instrument/contracts/dynamic-frames/dfcc_cfg_info.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -506,7 +506,7 @@ dfcc_cfg_infot::dfcc_cfg_infot(
506506
const irep_idt &function_id,
507507
goto_functiont &goto_function,
508508
const exprt &top_level_write_set,
509-
const dfcc_loop_contract_modet loop_contract_mode,
509+
const loop_contract_configt &loop_contract_config,
510510
symbol_table_baset &symbol_table,
511511
message_handlert &message_handler,
512512
dfcc_libraryt &library)
@@ -517,7 +517,7 @@ dfcc_cfg_infot::dfcc_cfg_infot(
517517
{
518518
dfcc_loop_nesting_grapht loop_nesting_graph;
519519
goto_programt &goto_program = goto_function.body;
520-
if(loop_contract_mode != dfcc_loop_contract_modet::NONE)
520+
if(loop_contract_config.apply_loop_contracts)
521521
{
522522
messaget log(message_handler);
523523
dfcc_check_loop_normal_form(goto_program, log);

src/goto-instrument/contracts/dynamic-frames/dfcc_cfg_info.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ Date: March 2023
2323

2424
#include <goto-programs/goto_program.h>
2525

26-
#include "dfcc_loop_contract_mode.h"
26+
#include <goto-instrument/contracts/loop_contract_config.h>
2727

2828
#include <map>
2929
#include <set>
@@ -238,7 +238,7 @@ class dfcc_cfg_infot
238238
const irep_idt &function_id,
239239
goto_functiont &goto_function,
240240
const exprt &top_level_write_set,
241-
const dfcc_loop_contract_modet loop_contract_mode,
241+
const loop_contract_configt &loop_contract_config,
242242
symbol_table_baset &symbol_table,
243243
message_handlert &message_handler,
244244
dfcc_libraryt &library);

src/goto-instrument/contracts/dynamic-frames/dfcc_contract_functions.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,9 +80,7 @@ void dfcc_contract_functionst::
8080
{
8181
std::set<irep_idt> function_pointer_contracts;
8282
instrument.instrument_function(
83-
spec_function_id,
84-
dfcc_loop_contract_modet::NONE,
85-
function_pointer_contracts);
83+
spec_function_id, loop_contract_configt{false}, function_pointer_contracts);
8684

8785
INVARIANT(
8886
function_pointer_contracts.empty(),

0 commit comments

Comments
 (0)