-
Notifications
You must be signed in to change notification settings - Fork 269
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Havoc to invalid for function contracts
- Loading branch information
Remi Delmas
committed
Jan 16, 2025
1 parent
958e5ab
commit 1405144
Showing
29 changed files
with
726 additions
and
61 deletions.
There are no files selected for viewing
16 changes: 16 additions & 0 deletions
16
regression/contracts-dfcc/test_pointer_equals_enforce_requires_disjunction_fail/main.c
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
void foo(int *x, int *y) | ||
// clang-format off | ||
__CPROVER_requires(__CPROVER_is_fresh(x, sizeof(int))) | ||
__CPROVER_requires(__CPROVER_pointer_equals(y, x) || 1) | ||
__CPROVER_assigns(*y) | ||
// clang-format on | ||
{ | ||
*y = 0; | ||
} | ||
|
||
void main() | ||
{ | ||
int *x; | ||
int *y; | ||
foo(x, y); | ||
} |
20 changes: 20 additions & 0 deletions
20
regression/contracts-dfcc/test_pointer_equals_enforce_requires_disjunction_fail/test.desc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
CORE dfcc-only | ||
main.c | ||
--dfcc main --enforce-contract foo | ||
^\[__CPROVER_contracts_car_set_insert.assertion.\d+\] line \d+ ptr NULL or writable up to size: FAILURE$ | ||
^\[__CPROVER_contracts_write_set_check_assignment.assertion.\d+\] line \d+ ptr NULL or writable up to size: FAILURE$ | ||
^\[foo.assigns.\d+\] line 8 Check that \*y is assignable: FAILURE$ | ||
^\[foo.pointer_dereference.\d+\] line 8 dereference failure: pointer NULL in \*y: FAILURE$ | ||
^\[foo.pointer_dereference.\d+\] line 8 dereference failure: pointer invalid in \*y: UNKNOWN$ | ||
^\[foo.pointer_dereference.\d+\] line 8 dereference failure: deallocated dynamic object in \*y: FAILURE$ | ||
^\[foo.pointer_dereference.\d+\] line 8 dereference failure: dead object in \*y: FAILURE$ | ||
^\[foo.pointer_dereference.\d+\] line 8 dereference failure: pointer outside object bounds in \*y: FAILURE$ | ||
^\[foo.pointer_dereference.\d+\] line 8 dereference failure: invalid integer address in \*y: UNKNOWN$ | ||
^EXIT=10$ | ||
^SIGNAL=0$ | ||
^VERIFICATION FAILED$ | ||
-- | ||
-- | ||
This test checks that when `__CPROVER_pointer_in_range_dfcc` is disjunctions, | ||
the program accepts models where `__CPROVER_pointer_in_range_dfcc` evaluates to | ||
false the target pointer of the predicate remains undefined. |
34 changes: 34 additions & 0 deletions
34
regression/contracts-dfcc/test_pointer_equals_enforce_requires_disjunction_pass/main.c
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
#include <stdlib.h> | ||
void foo(int *a, int *x, int *y) | ||
// clang-format off | ||
__CPROVER_requires(__CPROVER_is_fresh(a, sizeof(int))) | ||
__CPROVER_requires( | ||
(__CPROVER_pointer_equals(x,a) && y == NULL) || | ||
(x == NULL && __CPROVER_pointer_equals(y,a)) | ||
) | ||
__CPROVER_assigns(y == NULL: *x) | ||
__CPROVER_assigns(x == NULL: *y) | ||
// clang-format on | ||
{ | ||
if(y == NULL) | ||
{ | ||
assert(0); | ||
assert(__CPROVER_same_object(a, x)); | ||
*x = 0; | ||
} | ||
else | ||
{ | ||
assert(0); | ||
assert(x == NULL); | ||
assert(__CPROVER_same_object(a, y)); | ||
*y = 0; | ||
} | ||
} | ||
|
||
void main() | ||
{ | ||
int *a; | ||
int *x; | ||
int *y; | ||
foo(a, x, y); | ||
} |
32 changes: 32 additions & 0 deletions
32
regression/contracts-dfcc/test_pointer_equals_enforce_requires_disjunction_pass/test.desc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
CORE dfcc-only | ||
main.c | ||
--dfcc main --enforce-contract foo | ||
^\[foo.assertion.\d+\] line 15 assertion 0: FAILURE$ | ||
^\[foo.assertion.\d+\] line 16 assertion __CPROVER_POINTER_OBJECT\(\(.*\)a\) == __CPROVER_POINTER_OBJECT\(\(.*\)x\): SUCCESS$ | ||
^\[foo.assigns.\d+\] line 17 Check that \*x is assignable: SUCCESS$ | ||
^\[foo.pointer_dereference.\d+\] line 17 dereference failure: pointer NULL in \*x: SUCCESS$ | ||
^\[foo.pointer_dereference.\d+\] line 17 dereference failure: pointer invalid in \*x: SUCCESS$ | ||
^\[foo.pointer_dereference.\d+\] line 17 dereference failure: deallocated dynamic object in \*x: SUCCESS$ | ||
^\[foo.pointer_dereference.\d+\] line 17 dereference failure: dead object in \*x: SUCCESS$ | ||
^\[foo.pointer_dereference.\d+\] line 17 dereference failure: pointer outside object bounds in \*x: SUCCESS$ | ||
^\[foo.pointer_dereference.\d+\] line 17 dereference failure: invalid integer address in \*x: SUCCESS$ | ||
^\[foo.assertion.\d+\] line 21 assertion 0: FAILURE$ | ||
^\[foo.assertion.\d+\] line 22 assertion x == \(\(.*\)NULL\): SUCCESS$ | ||
^\[foo.assertion.\d+\] line 23 assertion __CPROVER_POINTER_OBJECT\(\(.*\)a\) == __CPROVER_POINTER_OBJECT\(\(.*\)y\): SUCCESS$ | ||
^\[foo.assigns.\d+\] line 24 Check that \*y is assignable: SUCCESS$ | ||
^\[foo.pointer_dereference.\d+\] line 24 dereference failure: pointer NULL in \*y: SUCCESS$ | ||
^\[foo.pointer_dereference.\d+\] line 24 dereference failure: pointer invalid in \*y: SUCCESS$ | ||
^\[foo.pointer_dereference.\d+\] line 24 dereference failure: deallocated dynamic object in \*y: SUCCESS$ | ||
^\[foo.pointer_dereference.\d+\] line 24 dereference failure: dead object in \*y: SUCCESS$ | ||
^\[foo.pointer_dereference.\d+\] line 24 dereference failure: pointer outside object bounds in \*y: SUCCESS$ | ||
^\[foo.pointer_dereference.\d+\] line 24 dereference failure: invalid integer address in \*y: SUCCESS$ | ||
^EXIT=10$ | ||
^SIGNAL=0$ | ||
^VERIFICATION FAILED$ | ||
-- | ||
-- | ||
Illustrates the behaviour of `__CPROVER_pointer_in_range_dfcc` under disjunctions in assume contexts. | ||
The precondition of `foo` describes a disjunction of cases, either `x` is in range of `a` and `y` is null, | ||
or `x` is null and `y` is in range of `a`. The function `foo` branches on `y == NULL`. | ||
The test suceeds if the two `assert(0)` in `foo` are falsifiable, which which shows | ||
that both cases of the disjunction expressed in the requires clause are reachable. |
28 changes: 28 additions & 0 deletions
28
regression/contracts-dfcc/test_pointer_equals_replace_ensures_disjunction_fail/main.c
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
|
||
typedef struct | ||
{ | ||
int *a; | ||
int *x; | ||
} ret_t; | ||
|
||
ret_t foo() | ||
// clang-format off | ||
__CPROVER_ensures(__CPROVER_is_fresh(__CPROVER_return_value.a, sizeof(int))) | ||
__CPROVER_ensures( | ||
__CPROVER_pointer_equals( | ||
__CPROVER_return_value.x, | ||
__CPROVER_return_value.a) || 1) | ||
// clang-format on | ||
; | ||
|
||
void bar() | ||
{ | ||
ret_t ret = foo(); | ||
int *x = ret.x; | ||
*x = 0; //expected to fail | ||
} | ||
|
||
void main() | ||
{ | ||
bar(); | ||
} |
17 changes: 17 additions & 0 deletions
17
regression/contracts-dfcc/test_pointer_equals_replace_ensures_disjunction_fail/test.desc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
CORE dfcc-only | ||
main.c | ||
--dfcc main --replace-call-with-contract foo | ||
^\[bar.pointer_dereference.\d+\] line 24 dereference failure: pointer NULL in \*x: FAILURE$ | ||
^\[bar.pointer_dereference.\d+\] line 24 dereference failure: pointer invalid in \*x: UNKNOWN$ | ||
^\[bar.pointer_dereference.\d+\] line 24 dereference failure: deallocated dynamic object in \*x: FAILURE$ | ||
^\[bar.pointer_dereference.\d+\] line 24 dereference failure: dead object in \*x: FAILURE$ | ||
^\[bar.pointer_dereference.\d+\] line 24 dereference failure: pointer outside object bounds in \*x: FAILURE$ | ||
^\[bar.pointer_dereference.\d+\] line 24 dereference failure: invalid integer address in \*x: UNKNOWN$ | ||
^EXIT=10$ | ||
^SIGNAL=0$ | ||
^VERIFICATION FAILED$ | ||
-- | ||
-- | ||
This test checks that when `__CPROVER_pointer_in_range_dfcc` is disjunctions, | ||
the program accepts models where `__CPROVER_pointer_in_range_dfcc` evaluates to | ||
false the target pointer remains undefined. |
49 changes: 49 additions & 0 deletions
49
regression/contracts-dfcc/test_pointer_equals_replace_ensures_disjunction_pass/main.c
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
#include <stdlib.h> | ||
typedef struct | ||
{ | ||
int *a; | ||
int *x; | ||
int *y; | ||
} ret_t; | ||
|
||
ret_t foo() | ||
// clang-format off | ||
__CPROVER_ensures(__CPROVER_is_fresh(__CPROVER_return_value.a, sizeof(int))) | ||
__CPROVER_ensures(( | ||
__CPROVER_pointer_equals( | ||
__CPROVER_return_value.x, | ||
__CPROVER_return_value.a) && | ||
__CPROVER_return_value.y == NULL | ||
) || ( | ||
__CPROVER_return_value.x == NULL && | ||
__CPROVER_pointer_equals( | ||
__CPROVER_return_value.y, | ||
__CPROVER_return_value.a))) | ||
// clang-format on | ||
; | ||
|
||
void bar() | ||
{ | ||
ret_t ret = foo(); | ||
int *a = ret.a; | ||
int *x = ret.x; | ||
int *y = ret.y; | ||
if(y == NULL) | ||
{ | ||
assert(0); | ||
assert(__CPROVER_same_object(x, a)); | ||
*x = 0; | ||
} | ||
else | ||
{ | ||
assert(0); | ||
assert(x == NULL); | ||
assert(__CPROVER_same_object(y, a)); | ||
*y = 0; | ||
} | ||
} | ||
|
||
void main() | ||
{ | ||
bar(); | ||
} |
32 changes: 32 additions & 0 deletions
32
regression/contracts-dfcc/test_pointer_equals_replace_ensures_disjunction_pass/test.desc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
CORE dfcc-only | ||
main.c | ||
--dfcc main --replace-call-with-contract foo | ||
^\[bar.assertion.\d+\] line 35 assertion 0: FAILURE$ | ||
^\[bar.assertion.\d+\] line 36 assertion __CPROVER_POINTER_OBJECT\(\(.*\)x\) == __CPROVER_POINTER_OBJECT\(\(.*\)a\): SUCCESS$ | ||
^\[bar.assigns.\d+\] line 37 Check that \*x is assignable: SUCCESS$ | ||
^\[bar.pointer_dereference.\d+\] line 37 dereference failure: pointer NULL in \*x: SUCCESS$ | ||
^\[bar.pointer_dereference.\d+\] line 37 dereference failure: pointer invalid in \*x: SUCCESS$ | ||
^\[bar.pointer_dereference.\d+\] line 37 dereference failure: deallocated dynamic object in \*x: SUCCESS$ | ||
^\[bar.pointer_dereference.\d+\] line 37 dereference failure: dead object in \*x: SUCCESS$ | ||
^\[bar.pointer_dereference.\d+\] line 37 dereference failure: pointer outside object bounds in \*x: SUCCESS$ | ||
^\[bar.pointer_dereference.\d+\] line 37 dereference failure: invalid integer address in \*x: SUCCESS$ | ||
^\[bar.assertion.\d+\] line 41 assertion 0: FAILURE$ | ||
^\[bar.assertion.\d+\] line 42 assertion x == \(\(.*\)NULL\): SUCCESS$ | ||
^\[bar.assertion.\d+\] line 43 assertion __CPROVER_POINTER_OBJECT\(\(.*\)y\) == __CPROVER_POINTER_OBJECT\(\(.*\)a\): SUCCESS$ | ||
^\[bar.assigns.\d+\] line 44 Check that \*y is assignable: SUCCESS$ | ||
^\[bar.pointer_dereference.\d+\] line 44 dereference failure: pointer NULL in \*y: SUCCESS$ | ||
^\[bar.pointer_dereference.\d+\] line 44 dereference failure: pointer invalid in \*y: SUCCESS$ | ||
^\[bar.pointer_dereference.\d+\] line 44 dereference failure: deallocated dynamic object in \*y: SUCCESS$ | ||
^\[bar.pointer_dereference.\d+\] line 44 dereference failure: dead object in \*y: SUCCESS$ | ||
^\[bar.pointer_dereference.\d+\] line 44 dereference failure: pointer outside object bounds in \*y: SUCCESS$ | ||
^\[bar.pointer_dereference.\d+\] line 44 dereference failure: invalid integer address in \*y: SUCCESS$ | ||
^EXIT=10$ | ||
^SIGNAL=0$ | ||
^VERIFICATION FAILED$ | ||
-- | ||
-- | ||
Illustrates the behaviour of `__CPROVER_pointer_in_range` under disjunctions in assume contexts. | ||
The postcondition of `foo` describes a disjunction of cases: either `x` is in range of `a` and `y` is null, | ||
or `x` is null and `y` is in range of `a`. The function `bar` branches on `y == NULL`. | ||
The test succeeds if the two `assert(0)` are falsifiable, which which shows that | ||
both cases of the disjunction expressed in the ensures clause of `foo` are reachable. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.