Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 89df5e9

Browse files
committedFeb 7, 2023
Add an option to not unwind tranformed loops after applying loop contracts
1 parent ee0d4f7 commit 89df5e9

File tree

7 files changed

+54
-4
lines changed

7 files changed

+54
-4
lines changed
 

‎doc/man/goto-instrument.1

+3
Original file line numberDiff line numberDiff line change
@@ -999,6 +999,9 @@ force aggressive slicer to preserve all direct paths
999999
\fB\-\-apply\-loop\-contracts\fR
10001000
check and use loop contracts when provided
10011001
.TP
1002+
\fB\-loop\-contracts\-no\-unwind\fR
1003+
do not unwind transformed loops
1004+
.TP
10021005
\fB\-\-replace\-call\-with\-contract\fR \fIfun\fR
10031006
replace calls to \fIfun\fR with \fIfun\fR's contract
10041007
.TP
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#include <assert.h>
2+
3+
int main()
4+
{
5+
int x = 0;
6+
7+
while(x < 10)
8+
__CPROVER_loop_invariant(0 <= x && x <= 10);
9+
{
10+
x++;
11+
}
12+
13+
assert(x == 10);
14+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
CORE
2+
main.c
3+
--apply-loop-contracts --loop-contracts-no-unwind _ --unwind 1 --unwinding-assertions
4+
^EXIT=10$
5+
^SIGNAL=0$
6+
\[main.unwind.\d+\] line \d+ unwinding assertion loop 0: FAILURE
7+
^VERIFICATION FAILED$
8+
--
9+
--
10+
Check that transformed loop will not be unwound with flag --loop-contracts-no-unwind.

‎src/goto-instrument/contracts/contracts.cpp

+7-4
Original file line numberDiff line numberDiff line change
@@ -1445,10 +1445,13 @@ void code_contractst::apply_loop_contracts(
14451445
nondet_static(goto_model, to_exclude_from_nondet_init);
14461446

14471447
// unwind all transformed loops twice.
1448-
unwindsett unwindset{goto_model};
1449-
unwindset.parse_unwindset(loop_names, log.get_message_handler());
1450-
goto_unwindt goto_unwind;
1451-
goto_unwind(goto_model, unwindset, goto_unwindt::unwind_strategyt::ASSUME);
1448+
if(unwind_transformed_loops)
1449+
{
1450+
unwindsett unwindset{goto_model};
1451+
unwindset.parse_unwindset(loop_names, log.get_message_handler());
1452+
goto_unwindt goto_unwind;
1453+
goto_unwind(goto_model, unwindset, goto_unwindt::unwind_strategyt::ASSUME);
1454+
}
14521455

14531456
remove_skip(goto_model);
14541457

‎src/goto-instrument/contracts/contracts.h

+8
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,11 @@ Date: February 2016
3535
" --apply-loop-contracts\n" \
3636
" check and use loop contracts when provided\n"
3737

38+
#define FLAG_LOOP_CONTRACTS_NO_UNWIND "loop-contracts-no-unwind"
39+
#define HELP_LOOP_CONTRACTS_NO_UNWIND \
40+
" --loop-contracts-no-unwind\n" \
41+
" do not unwind transformed loops\n"
42+
3843
#define FLAG_REPLACE_CALL "replace-call-with-contract"
3944
#define HELP_REPLACE_CALL \
4045
" --replace-call-with-contract <function>[/contract]\n" \
@@ -139,6 +144,9 @@ class code_contractst
139144

140145
namespacet ns;
141146

147+
// Unwind transformed loops after applying loop contracts or not.
148+
bool unwind_transformed_loops = true;
149+
142150
protected:
143151
goto_modelt &goto_model;
144152
symbol_tablet &symbol_table;

‎src/goto-instrument/goto_instrument_parse_options.cpp

+11
Original file line numberDiff line numberDiff line change
@@ -1237,7 +1237,17 @@ void goto_instrument_parse_optionst::instrument_goto_program()
12371237
contracts.enforce_contracts(to_enforce, to_exclude_from_nondet_static);
12381238

12391239
if(cmdline.isset(FLAG_LOOP_CONTRACTS))
1240+
{
1241+
if(cmdline.isset(FLAG_LOOP_CONTRACTS_NO_UNWIND))
1242+
{
1243+
contracts.unwind_transformed_loops = false;
1244+
log.warning() << "**** WARNING: transformed loops will not be unwound "
1245+
<< "after applying loop contracts. Remember to unwind "
1246+
<< "them at least twice to pass unwinding-assertions."
1247+
<< messaget::eom;
1248+
}
12401249
contracts.apply_loop_contracts(to_exclude_from_nondet_static);
1250+
}
12411251
}
12421252

12431253
if(cmdline.isset("value-set-fi-fp-removal"))
@@ -1966,6 +1976,7 @@ void goto_instrument_parse_optionst::help()
19661976
"Code contracts:\n"
19671977
HELP_DFCC
19681978
HELP_LOOP_CONTRACTS
1979+
HELP_LOOP_CONTRACTS_NO_UNWIND
19691980
HELP_REPLACE_CALL
19701981
HELP_ENFORCE_CONTRACT
19711982
HELP_ENFORCE_CONTRACT_REC

‎src/goto-instrument/goto_instrument_parse_options.h

+1
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ Author: Daniel Kroening, kroening@kroening.com
9797
"(horn)(skip-loops):(model-argc-argv):" \
9898
OPT_DFCC \
9999
"(" FLAG_LOOP_CONTRACTS ")" \
100+
"(" FLAG_LOOP_CONTRACTS_NO_UNWIND ")" \
100101
"(" FLAG_REPLACE_CALL "):" \
101102
"(" FLAG_ENFORCE_CONTRACT "):" \
102103
OPT_ENFORCE_CONTRACT_REC \

0 commit comments

Comments
 (0)
Please sign in to comment.