-
Notifications
You must be signed in to change notification settings - Fork 277
Add --expand-pointer-predicates to goto-instrument #4332
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
563ba56
7c5ae5a
2684caa
026a611
f53b62b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
int main() | ||
{ | ||
int *r; | ||
__CPROVER_points_to_valid_memory(r, "huh?"); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
CORE | ||
main.c | ||
--apply-code-contracts | ||
^EXIT=1$ | ||
^SIGNAL=0$ | ||
^main.c:\d+:\d+: error: size argument to points_to_valid_memory must be coercible to size_t$ | ||
^CONVERSION ERROR$ | ||
-- | ||
-- |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
int main() | ||
{ | ||
int *x; | ||
__CPROVER_assume(__CPROVER_points_to_valid_memory(x)); | ||
*x = 1; | ||
return 0; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
CORE | ||
main.c | ||
--pointer-check --expand-pointer-predicates | ||
^EXIT=0$ | ||
^SIGNAL=0$ | ||
^VERIFICATION SUCCESSFUL$ | ||
-- | ||
-- |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
int main() | ||
{ | ||
int *x; | ||
__CPROVER_assume(__CPROVER_points_to_valid_memory(x, sizeof(int))); | ||
*x = 1; | ||
return 0; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
CORE | ||
main.c | ||
--pointer-check --expand-pointer-predicates | ||
^EXIT=0$ | ||
^SIGNAL=0$ | ||
^VERIFICATION SUCCESSFUL$ | ||
-- | ||
-- |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
int main() | ||
{ | ||
int *x; | ||
__CPROVER_assume(__CPROVER_points_to_valid_memory(x, sizeof(int))); | ||
__CPROVER_assert( | ||
__CPROVER_points_to_valid_memory(x, sizeof(int)), "Assert matches assume"); | ||
return 0; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
CORE | ||
main.c | ||
--pointer-check --expand-pointer-predicates | ||
^EXIT=0$ | ||
^SIGNAL=0$ | ||
^VERIFICATION SUCCESSFUL$ | ||
-- | ||
-- |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
int main() | ||
{ | ||
int x; | ||
int *y = &x; | ||
__CPROVER_assert(__CPROVER_points_to_valid_memory(y), "Assert works on &"); | ||
return 0; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
CORE | ||
main.c | ||
--pointer-check --expand-pointer-predicates | ||
^EXIT=0$ | ||
^SIGNAL=0$ | ||
^VERIFICATION SUCCESSFUL$ | ||
-- | ||
-- |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
struct bar | ||
{ | ||
int w; | ||
int x; | ||
int y; | ||
int z; | ||
}; | ||
|
||
int main() | ||
{ | ||
struct bar s; | ||
s.z = 5; | ||
int *x_pointer = &(s.x); | ||
__CPROVER_assert( | ||
__CPROVER_points_to_valid_memory(x_pointer, 3 * sizeof(int)), | ||
"Variable length assert"); | ||
assert(x_pointer[2] == 5); | ||
return 0; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
CORE | ||
main.c | ||
--pointer-check --expand-pointer-predicates | ||
^\[main.assertion.1\] line \d+ Variable length assert: SUCCESS$ | ||
^\[main.assertion.2\] line \d+ assertion x_pointer\[\(signed long( long)? int\)2\] == 5: SUCCESS$ | ||
^EXIT=0$ | ||
^SIGNAL=0$ | ||
^VERIFICATION SUCCESSFUL$ | ||
-- | ||
-- |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
#include <stdlib.h> | ||
|
||
struct my_struct | ||
{ | ||
int *field1; | ||
int *field2; | ||
}; | ||
|
||
void example(struct my_struct *s) | ||
{ | ||
s->field2 = malloc(sizeof(*(s->field2))); | ||
} | ||
|
||
int main() | ||
{ | ||
struct my_struct *s; | ||
__CPROVER_assume(__CPROVER_points_to_valid_memory(s)); | ||
example(s); | ||
__CPROVER_assert(__CPROVER_points_to_valid_memory(s->field2), ""); | ||
return 0; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
CORE | ||
main.c | ||
--pointer-check --expand-pointer-predicates | ||
^\[main.assertion.1\] line \d+ assertion: SUCCESS$ | ||
^EXIT=0$ | ||
^SIGNAL=0$ | ||
^VERIFICATION SUCCESSFUL$ | ||
-- | ||
-- |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
#include <stdlib.h> | ||
|
||
struct my_struct | ||
{ | ||
int *field; | ||
}; | ||
|
||
void example(struct my_struct *s) | ||
{ | ||
__CPROVER_assume(__CPROVER_points_to_valid_memory(s)); | ||
size_t size; | ||
__CPROVER_assume(size == sizeof(*(s->field))); | ||
__CPROVER_assume(__CPROVER_points_to_valid_memory(s->field, size)); | ||
int read = *(s->field); | ||
} | ||
|
||
int main() | ||
{ | ||
struct my_struct *s; | ||
example(s); | ||
return 0; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
CORE | ||
main.c | ||
--pointer-check --expand-pointer-predicates | ||
^EXIT=0$ | ||
^SIGNAL=0$ | ||
^VERIFICATION SUCCESSFUL$ | ||
-- | ||
-- |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
#include <stdlib.h> | ||
|
||
int main() | ||
{ | ||
int *x; | ||
int *y; | ||
__CPROVER_assume(__CPROVER_points_to_valid_memory(x, 2 * sizeof(int))); | ||
__CPROVER_assume(__CPROVER_points_to_valid_memory(y, 2 * sizeof(int) - 1)); | ||
(void)(x[0]); // Should succeed | ||
(void)(x[1]); // Should succeed | ||
(void)(x[2]); // Should fail | ||
(void)(x[-1]); // Should fail | ||
(void)(y[0]); // Should succeed | ||
(void)(y[1]); // Should fail | ||
return 0; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
CORE | ||
main.c | ||
--pointer-check --expand-pointer-predicates | ||
^\[main.pointer_dereference.[0-9]+\] line \d+ dereference failure: dead object in x\[\(signed long( long)? int\)0\]: SUCCESS$ | ||
^\[main.pointer_dereference.[0-9]+\] line \d+ dereference failure: pointer outside object bounds in x\[\(signed long( long)? int\)0\]: SUCCESS$ | ||
^\[main.pointer_dereference.[0-9]+\] line \d+ dereference failure: pointer outside object bounds in x\[\(signed long( long)? int\)1\]: SUCCESS$ | ||
^\[main.pointer_dereference.[0-9]+\] line \d+ dereference failure: pointer outside object bounds in x\[\(signed long( long)? int\)2\]: FAILURE$ | ||
^\[main.pointer_dereference.[0-9]+\] line \d+ dereference failure: pointer outside object bounds in x\[\(signed long( long)? int\)-1\]: FAILURE$ | ||
^\[main.pointer_dereference.[0-9]+\] line \d+ dereference failure: dead object in y\[\(signed long( long)? int\)0\]: SUCCESS$ | ||
^\[main.pointer_dereference.[0-9]+\] line \d+ dereference failure: pointer outside object bounds in y\[\(signed long( long)? int\)0\]: SUCCESS$ | ||
^\[main.pointer_dereference.[0-9]+\] line \d+ dereference failure: pointer outside object bounds in y\[\(signed long( long)? int\)1\]: FAILURE$ | ||
^EXIT=10$ | ||
^SIGNAL=0$ | ||
^VERIFICATION FAILED$ | ||
-- | ||
-- |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
#include <stdlib.h> | ||
|
||
int main() | ||
{ | ||
char *x; | ||
__CPROVER_assume(__CPROVER_points_to_valid_memory(x)); | ||
(void)(*x); // Should succeed | ||
(void)(*(x + 1)); // Should fail | ||
(void)(*(x - 1)); // Should fail | ||
return 0; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
CORE | ||
main.c | ||
--pointer-check --expand-pointer-predicates | ||
^\[main.pointer_dereference.[0-9]+\] line \d+ dereference failure: dead object in \*x: SUCCESS$ | ||
^\[main.pointer_dereference.[0-9]+\] line \d+ dereference failure: pointer outside object bounds in \*x: SUCCESS$ | ||
^\[main.pointer_dereference.[0-9]+\] line \d+ dereference failure: pointer outside object bounds in x\[\(signed long( long)? int\)1\]: FAILURE$ | ||
^\[main.pointer_dereference.[0-9]+\] line \d+ dereference failure: pointer outside object bounds in \*\(x - \(signed long( long)? int\)1\): FAILURE$ | ||
^EXIT=10$ | ||
^SIGNAL=0$ | ||
^VERIFICATION FAILED$ | ||
-- | ||
-- |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -34,6 +34,8 @@ Author: Daniel Kroening, kroening@kroening.com | |
#include "anonymous_member.h" | ||
#include "padding.h" | ||
|
||
bool is_lvalue(const exprt &expr); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This shouldn't be necessary, use |
||
|
||
void c_typecheck_baset::typecheck_expr(exprt &expr) | ||
{ | ||
if(expr.id()==ID_already_typechecked) | ||
|
@@ -2109,6 +2111,63 @@ exprt c_typecheck_baset::do_special_functions( | |
|
||
return same_object_expr; | ||
} | ||
else if(identifier == CPROVER_PREFIX "points_to_valid_memory") | ||
{ | ||
if(expr.arguments().size() != 2 && expr.arguments().size() != 1) | ||
{ | ||
error().source_location = f_op.source_location(); | ||
error() << "points_to_valid_memory expects one or two operands" << eom; | ||
throw 0; | ||
} | ||
if(!is_lvalue(expr.arguments().front())) | ||
{ | ||
error().source_location = f_op.source_location(); | ||
error() << "ptr argument to points_to_valid_memory" | ||
<< " must be an lvalue" << eom; | ||
throw 0; | ||
} | ||
|
||
exprt same_object_expr; | ||
if(expr.arguments().size() == 2) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is established above, no need to check again. |
||
{ | ||
if( | ||
expr.arguments()[1].type().id() != ID_unsignedbv && | ||
expr.arguments()[1].type().id() != ID_signedbv) | ||
{ | ||
error().source_location = f_op.source_location(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd prefer for those changes to be squashed into the earlier commit as otherwise that code wouldn't compile (which makes bisecting hard). |
||
error() << "size argument to points_to_valid_memory" | ||
<< " must be coercible to size_t" << eom; | ||
throw 0; | ||
} | ||
same_object_expr = | ||
points_to_valid_memory(expr.arguments()[0], expr.arguments()[1]); | ||
} | ||
else if(expr.arguments().size() == 1) | ||
{ | ||
PRECONDITION(expr.arguments()[0].type().id() == ID_pointer); | ||
|
||
const typet &base_type = expr.arguments()[0].type().subtype(); | ||
auto expr_size = size_of_expr(base_type, *this); | ||
if(!expr_size) | ||
{ | ||
error().source_location = expr.source_location(); | ||
error() << "cannot determine size of pointed-to memory region" << eom; | ||
throw 0; | ||
} | ||
|
||
expr_size->add(ID_C_c_sizeof_type) = base_type; | ||
|
||
same_object_expr = | ||
points_to_valid_memory(expr.arguments()[0], *expr_size); | ||
} | ||
else | ||
{ | ||
UNREACHABLE; | ||
} | ||
same_object_expr.add_source_location() = source_location; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe |
||
|
||
return same_object_expr; | ||
} | ||
else if(identifier==CPROVER_PREFIX "buffer_size") | ||
{ | ||
if(expr.arguments().size()!=1) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the cause of the Windows failure:
goto-cl
exits with exit code 64 on errors (cf. other intentionally-failing tests,git grep -w 64 regression/ansi-c
).