Skip to content

Commit cf51b59

Browse files
committed
Added __CPROVER_array_replace to complement __CPROVER_array_set
1 parent 7a18ac5 commit cf51b59

File tree

9 files changed

+84
-53
lines changed

9 files changed

+84
-53
lines changed

src/ansi-c/ansi_c_internal_additions.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,11 @@ void ansi_c_internal_additions(std::string &code)
211211
// arrays
212212
// NOLINTNEXTLINE(whitespace/line_length)
213213
"__CPROVER_bool __CPROVER_array_equal(const void *array1, const void *array2);\n"
214+
// overwrite all of *dest (possibly using nondet values), even
215+
// if *src is smaller
214216
"void __CPROVER_array_copy(const void *dest, const void *src);\n"
217+
// replace at most size-of-*src bytes in *dest
218+
"void __CPROVER_array_replace(const void *dest, const void *src);\n"
215219
"void __CPROVER_array_set(const void *dest, ...);\n"
216220

217221
// k-induction

src/ansi-c/expr2c.cpp

+36
Original file line numberDiff line numberDiff line change
@@ -3826,6 +3826,9 @@ std::string expr2ct::convert_code(
38263826
if(statement==ID_array_copy)
38273827
return convert_code_array_copy(src, indent);
38283828

3829+
if(statement==ID_array_replace)
3830+
return convert_code_array_replace(src, indent);
3831+
38293832
if(statement=="set_may" ||
38303833
statement=="set_must")
38313834
return
@@ -4227,6 +4230,39 @@ std::string expr2ct::convert_code_array_copy(
42274230

42284231
/*******************************************************************\
42294232
4233+
Function: expr2ct::convert_code_array_replace
4234+
4235+
Inputs:
4236+
4237+
Outputs:
4238+
4239+
Purpose:
4240+
4241+
\*******************************************************************/
4242+
4243+
std::string expr2ct::convert_code_array_replace(
4244+
const codet &src,
4245+
unsigned indent)
4246+
{
4247+
std::string dest=indent_str(indent)+"ARRAY_REPLACE(";
4248+
4249+
forall_operands(it, src)
4250+
{
4251+
unsigned p;
4252+
std::string arg_str=convert(*it, p);
4253+
4254+
if(it!=src.operands().begin())
4255+
dest+=", ";
4256+
dest+=arg_str;
4257+
}
4258+
4259+
dest+=");";
4260+
4261+
return dest;
4262+
}
4263+
4264+
/*******************************************************************\
4265+
42304266
Function: expr2ct::convert_code_assert
42314267
42324268
Inputs:

src/ansi-c/expr2c_class.h

+1
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,7 @@ class expr2ct
204204
std::string convert_code_output(const codet &src, unsigned indent);
205205
std::string convert_code_array_set(const codet &src, unsigned indent);
206206
std::string convert_code_array_copy(const codet &src, unsigned indent);
207+
std::string convert_code_array_replace(const codet &src, unsigned indent);
207208

208209
virtual std::string convert(const exprt &src, unsigned &precedence);
209210

src/ansi-c/library/cprover.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,8 @@ float __CPROVER_fabsf(float);
102102
// arrays
103103
//__CPROVER_bool __CPROVER_array_equal(const void *array1, const void *array2);
104104
void __CPROVER_array_copy(const void *dest, const void *src);
105-
//void __CPROVER_array_set(const void *dest, ...);
105+
void __CPROVER_array_set(const void *dest, ...);
106+
void __CPROVER_array_replace(const void *dest, const void *src);
106107

107108
#if 0
108109
// k-induction

src/goto-programs/builtin_functions.cpp

+20-47
Original file line numberDiff line numberDiff line change
@@ -984,7 +984,7 @@ exprt goto_convertt::get_array_argument(const exprt &src)
984984

985985
/*******************************************************************\
986986
987-
Function: goto_convertt::do_array_set
987+
Function: goto_convertt::do_array_op
988988
989989
Inputs:
990990
@@ -994,7 +994,8 @@ Function: goto_convertt::do_array_set
994994
995995
\*******************************************************************/
996996

997-
void goto_convertt::do_array_set(
997+
void goto_convertt::do_array_op(
998+
const irep_idt &id,
998999
const exprt &lhs,
9991000
const exprt &function,
10001001
const exprt::operandst &arguments,
@@ -1003,47 +1004,16 @@ void goto_convertt::do_array_set(
10031004
if(arguments.size()!=2)
10041005
{
10051006
error().source_location=function.find_source_location();
1006-
error() << "array_set expects two arguments" << eom;
1007+
error() << id << " expects two arguments" << eom;
10071008
throw 0;
10081009
}
10091010

1010-
codet array_set_statement;
1011-
array_set_statement.set_statement(ID_array_set);
1012-
array_set_statement.operands()=arguments;
1011+
codet array_op_statement;
1012+
array_op_statement.set_statement(id);
1013+
array_op_statement.operands()=arguments;
1014+
array_op_statement.add_source_location()=function.source_location();
10131015

1014-
copy(array_set_statement, OTHER, dest);
1015-
}
1016-
1017-
/*******************************************************************\
1018-
1019-
Function: goto_convertt::do_array_copy
1020-
1021-
Inputs:
1022-
1023-
Outputs:
1024-
1025-
Purpose:
1026-
1027-
\*******************************************************************/
1028-
1029-
void goto_convertt::do_array_copy(
1030-
const exprt &lhs,
1031-
const exprt &function,
1032-
const exprt::operandst &arguments,
1033-
goto_programt &dest)
1034-
{
1035-
if(arguments.size()!=2)
1036-
{
1037-
error().source_location=function.find_source_location();
1038-
error() << "array_copy expects two arguments" << eom;
1039-
throw 0;
1040-
}
1041-
1042-
codet array_copy_statement;
1043-
array_copy_statement.set_statement(ID_array_copy);
1044-
array_copy_statement.operands()=arguments;
1045-
1046-
copy(array_copy_statement, OTHER, dest);
1016+
copy(array_op_statement, OTHER, dest);
10471017
}
10481018

10491019
/*******************************************************************\
@@ -1096,6 +1066,7 @@ void goto_convertt::do_array_equal(
10961066
assignment.lhs()=lhs;
10971067
assignment.rhs()=binary_exprt(
10981068
lhs_array, ID_array_equal, rhs_array, lhs.type());
1069+
assignment.add_source_location()=function.source_location();
10991070

11001071
convert(assignment, dest);
11011072
}
@@ -1427,19 +1398,21 @@ void goto_convertt::do_function_call_symbol(
14271398
assignment.add_source_location()=function.source_location();
14281399
copy(assignment, ASSIGN, dest);
14291400
}
1430-
else if(has_prefix(id2string(identifier), CPROVER_PREFIX "array_set"))
1401+
else if(identifier==CPROVER_PREFIX "array_equal")
14311402
{
1432-
do_array_set(lhs, function, arguments, dest);
1403+
do_array_equal(lhs, function, arguments, dest);
14331404
}
1434-
else if(identifier==CPROVER_PREFIX "array_equal" ||
1435-
identifier=="__CPROVER::array_equal")
1405+
else if(identifier==CPROVER_PREFIX "array_set")
14361406
{
1437-
do_array_equal(lhs, function, arguments, dest);
1407+
do_array_op(ID_array_set, lhs, function, arguments, dest);
1408+
}
1409+
else if(identifier==CPROVER_PREFIX "array_copy")
1410+
{
1411+
do_array_op(ID_array_copy, lhs, function, arguments, dest);
14381412
}
1439-
else if(identifier==CPROVER_PREFIX "array_copy" ||
1440-
identifier=="__CPROVER::array_equal")
1413+
else if(identifier==CPROVER_PREFIX "array_replace")
14411414
{
1442-
do_array_copy(lhs, function, arguments, dest);
1415+
do_array_op(ID_array_replace, lhs, function, arguments, dest);
14431416
}
14441417
else if(identifier=="printf")
14451418
/*

src/goto-programs/goto_convert_class.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -537,7 +537,8 @@ class goto_convertt:public messaget
537537
const exprt &rhs,
538538
const exprt::operandst &arguments,
539539
goto_programt &dest);
540-
void do_array_copy(
540+
void do_array_op(
541+
const irep_idt &id,
541542
const exprt &lhs,
542543
const exprt &rhs,
543544
const exprt::operandst &arguments,

src/goto-symex/symex_other.cpp

+15-4
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,8 @@ void goto_symext::symex_other(
8585
{
8686
// we ignore this for now
8787
}
88-
else if(statement==ID_array_copy)
88+
else if(statement==ID_array_copy ||
89+
statement==ID_array_replace)
8990
{
9091
assert(code.operands().size()==2);
9192

@@ -120,11 +121,21 @@ void goto_symext::symex_other(
120121
clean_code.op1().type(), ns))
121122
{
122123
byte_extract_exprt be(byte_extract_id());
123-
be.type()=clean_code.op0().type();
124-
be.op()=clean_code.op1();
125124
be.offset()=from_integer(0, index_type());
126125

127-
clean_code.op1()=be;
126+
if(statement==ID_array_copy)
127+
{
128+
be.op()=clean_code.op1();
129+
be.type()=clean_code.op0().type();
130+
clean_code.op1()=be;
131+
}
132+
else
133+
{
134+
// ID_array_replace
135+
be.op()=clean_code.op0();
136+
be.type()=clean_code.op1().type();
137+
clean_code.op0()=be;
138+
}
128139
}
129140

130141
code_assignt assignment;

src/pointer-analysis/value_set.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -1802,6 +1802,9 @@ void value_sett::apply_code(
18021802
else if(statement==ID_array_copy)
18031803
{
18041804
}
1805+
else if(statement==ID_array_replace)
1806+
{
1807+
}
18051808
else if(statement==ID_assume)
18061809
{
18071810
guard(to_code_assume(code).op0(), ns);

src/util/irep_ids.def

+1
Original file line numberDiff line numberDiff line change
@@ -804,6 +804,7 @@ IREP_ID_ONE(cprover_string_to_lower_case_func)
804804
IREP_ID_ONE(cprover_string_to_upper_case_func)
805805
IREP_ID_ONE(cprover_string_trim_func)
806806
IREP_ID_ONE(cprover_string_value_of_func)
807+
IREP_ID_ONE(array_replace)
807808

808809
#undef IREP_ID_ONE
809810
#undef IREP_ID_TWO

0 commit comments

Comments
 (0)