Description
CBMC version: 5.69.1
Operating system: n/a
Problem description
Currently, the loop contract transformation will insert a backward jump (https://github.com/diffblue/cbmc/blob/develop/src/goto-instrument/contracts/contracts.cpp#L110) into the result goto program. So after applying loop contracts, there will be loops that execute only one iteration in the place of the original annotated loops, which require users to correctly specify the unwinding number of them: either not unwinding them, or unwind them for at least twice. It is an unnecessary usability pain point for users. So backward goto should be avoided during loop contract transformation.
Example
A smaller example to illustrate the problem.
int main()
{
int i;
for(i = 0; i < 1; i++)
__CPROVER_loop_invariant(1 > 1)
{
i++;
}
}
Note that the invariant 1 > 1
is invalid. So that a correct run of CBMC should report loop invariant doesn’t hold before entry of the loop.
Run goto-cc main.c
goto-instrument --apply-loop-contracts a.out b.out
to apply loop contracts and get the result goto program b.goto
. Then with command cbmc b.out
(or cbmc --unwind 2 b.out
) CBMC will correctly report the failure
[main.1] line 5 Check loop invariant before entry: FAILURE
However, running cbmc --unwind 1 b.out
will report no failure.
Running cbmc --unwind 1 --unwinding-assertions b.out
will report
[main.unwind.0] line 5 unwinding assertion loop 0: FAILURE