Skip to content

Commit 8897709

Browse files
authored
Merge pull request #1800 from tautschnig/fix-process_array_expr
Fix process_array_expr to take into account pointer offset
2 parents c3ee2a1 + 9df769a commit 8897709

File tree

12 files changed

+278
-303
lines changed

12 files changed

+278
-303
lines changed

regression/cbmc-from-CVS/Array_operations1/main.c

-37
This file was deleted.
+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
void test_equal()
2+
{
3+
char array1[100], array2[100];
4+
_Bool cmp;
5+
int index;
6+
7+
cmp = __CPROVER_array_equal(array1, array2);
8+
9+
__CPROVER_assume(index >= 0 && index < 100);
10+
__CPROVER_assume(cmp);
11+
12+
__CPROVER_assert(array1[index] == array2[index], "arrays are equal");
13+
}
14+
15+
void test_copy()
16+
{
17+
char array1[100], array2[100], array3[90];
18+
19+
array2[10] = 11;
20+
array3[10] = 11;
21+
array2[99] = 42;
22+
__CPROVER_array_copy(array1, array2);
23+
24+
__CPROVER_assert(array1[10] == 11, "array1[10] is OK");
25+
__CPROVER_assert(array1[99] == 42, "array1[99] is OK");
26+
27+
__CPROVER_array_copy(array1, array3);
28+
__CPROVER_assert(array1[10] == 11, "array1[10] is OK");
29+
__CPROVER_assert(array1[99] == 42, "expected to fail");
30+
}
31+
32+
void test_replace()
33+
{
34+
char array1[100], array2[90];
35+
36+
array1[99] = 42;
37+
array2[10] = 11;
38+
__CPROVER_array_replace(array1, array2);
39+
40+
__CPROVER_assert(array1[10] == 11, "array1[10] is OK");
41+
__CPROVER_assert(array1[99] == 42, "array1[99] is OK");
42+
}
43+
44+
void test_set()
45+
{
46+
char array1[100];
47+
__CPROVER_array_set(array1, 111);
48+
__CPROVER_assert(array1[44] == 111, "array1[44] is OK");
49+
}
50+
51+
int main()
52+
{
53+
test_equal();
54+
test_copy();
55+
test_replace();
56+
test_set();
57+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
CORE
2+
main.c
3+
4+
^EXIT=10$
5+
^SIGNAL=0$
6+
^\[test_copy\.assertion\.4\] expected to fail: FAILURE$
7+
^\*\* 1 of 8 failed
8+
^VERIFICATION FAILED$
9+
--
10+
^warning: ignoring

regression/cbmc/memcpy2/main.c

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#include <assert.h>
2+
#include <string.h>
3+
4+
int main()
5+
{
6+
char A[3] = {'a', 'b', 'c'};
7+
char *p = A;
8+
char v1, v2;
9+
10+
memcpy(&v1, p, 1);
11+
++p;
12+
memcpy(&v2, p, 1);
13+
14+
assert(v1 == 'a');
15+
assert(v2 == 'b');
16+
17+
return 0;
18+
}

regression/cbmc/memcpy3/main.c

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#include <assert.h>
2+
#include <string.h>
3+
4+
int main()
5+
{
6+
int A[3] = {1, 2, 3};
7+
int *p = A;
8+
int v1, v2;
9+
10+
memcpy(&v1, p, sizeof(int));
11+
++p;
12+
memcpy(&v2, p, sizeof(int));
13+
14+
assert(v1 == 1);
15+
assert(v2 == 2);
16+
17+
return 0;
18+
}

regression/cbmc/memcpy3/test.desc

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
CORE
2+
main.c
3+
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
^VERIFICATION SUCCESSFUL$
7+
--
8+
^warning: ignoring

src/goto-programs/builtin_functions.cpp

+6-45
Original file line numberDiff line numberDiff line change
@@ -838,51 +838,12 @@ void goto_convertt::do_array_op(
838838
array_op_statement.operands()=arguments;
839839
array_op_statement.add_source_location()=function.source_location();
840840

841-
copy(array_op_statement, OTHER, dest);
842-
}
843-
844-
void goto_convertt::do_array_equal(
845-
const exprt &lhs,
846-
const exprt &function,
847-
const exprt::operandst &arguments,
848-
goto_programt &dest)
849-
{
850-
if(arguments.size()!=2)
851-
{
852-
error().source_location=function.find_source_location();
853-
error() << "array_equal expects two arguments" << eom;
854-
throw 0;
855-
}
856-
857-
const typet &arg0_type=ns.follow(arguments[0].type());
858-
const typet &arg1_type=ns.follow(arguments[1].type());
841+
// lhs is only used with array_equal, in all other cases it should be nil (as
842+
// they are of type void)
843+
if(id == ID_array_equal)
844+
array_op_statement.copy_to_operands(lhs);
859845

860-
if(arg0_type.id()!=ID_pointer ||
861-
arg1_type.id()!=ID_pointer)
862-
{
863-
error().source_location=function.find_source_location();
864-
error() << "array_equal expects pointer arguments" << eom;
865-
throw 0;
866-
}
867-
868-
if(lhs.is_not_nil())
869-
{
870-
code_assignt assignment;
871-
872-
// add dereferencing here
873-
dereference_exprt lhs_array, rhs_array;
874-
lhs_array.op0()=arguments[0];
875-
rhs_array.op0()=arguments[1];
876-
lhs_array.type()=arg0_type.subtype();
877-
rhs_array.type()=arg1_type.subtype();
878-
879-
assignment.lhs()=lhs;
880-
assignment.rhs()=binary_exprt(
881-
lhs_array, ID_array_equal, rhs_array, lhs.type());
882-
assignment.add_source_location()=function.source_location();
883-
884-
convert(assignment, dest);
885-
}
846+
copy(array_op_statement, OTHER, dest);
886847
}
887848

888849
bool is_lvalue(const exprt &expr)
@@ -1213,7 +1174,7 @@ void goto_convertt::do_function_call_symbol(
12131174
}
12141175
else if(identifier==CPROVER_PREFIX "array_equal")
12151176
{
1216-
do_array_equal(lhs, function, arguments, dest);
1177+
do_array_op(ID_array_equal, lhs, function, arguments, dest);
12171178
}
12181179
else if(identifier==CPROVER_PREFIX "array_set")
12191180
{

src/goto-symex/goto_symex.h

+1-3
Original file line numberDiff line numberDiff line change
@@ -245,15 +245,13 @@ class goto_symext
245245
// this does the following:
246246
// a) rename non-det choices
247247
// b) remove pointer dereferencing
248-
// c) rewrite array_equal expression into equality
248+
// c) clean up byte_extract on the lhs of an assignment
249249
void clean_expr(
250250
exprt &, statet &, bool write);
251251

252-
void replace_array_equal(exprt &);
253252
void trigger_auto_object(const exprt &, statet &);
254253
void initialize_auto_object(const exprt &, statet &);
255254
void process_array_expr(exprt &);
256-
void process_array_expr_rec(exprt &, const typet &) const;
257255
exprt make_auto_object(const typet &, statet &);
258256
virtual void dereference(exprt &, statet &, const bool write);
259257

0 commit comments

Comments
 (0)