Skip to content

Commit b7bb6a1

Browse files
committed
Fix array constraints for with_exprt with >3 operands
The initial support for more than 3 operands in 02e508e generated possibly inconsistent constraints. Also update comments to describe multiple update operands. The test is based on SV-COMP's array-memsafety/count_down_unsafe_false-valid-deref.c.
1 parent 60fe468 commit b7bb6a1

File tree

4 files changed

+65
-25
lines changed

4 files changed

+65
-25
lines changed
+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#include <stdlib.h>
2+
3+
extern int __VERIFIER_nondet_int(void);
4+
5+
int main()
6+
{
7+
int i, j;
8+
int val;
9+
int length = __VERIFIER_nondet_int();
10+
if(length < 1)
11+
length = 1;
12+
int *arr = malloc(length);
13+
if(!arr)
14+
return 0;
15+
for(i = 0; i < length; i++)
16+
{
17+
val = __VERIFIER_nondet_int();
18+
if(val < 0)
19+
{
20+
val = 0;
21+
}
22+
arr[i] = val;
23+
}
24+
for(j = 0; j < length; j++)
25+
{
26+
while(arr[j] > 0)
27+
{
28+
arr[j]--;
29+
}
30+
}
31+
return 0;
32+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
CORE broken-smt-backend
2+
main.c
3+
--unwind 2 --pointer-check
4+
^EXIT=10$
5+
^SIGNAL=0$
6+
^VERIFICATION FAILED$
7+
^\*\* 2 of 14
8+
--
9+
^warning: ignoring

src/solvers/flattening/arrays.cpp

+24-20
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ Author: Daniel Kroening, [email protected]
2121
#include <iostream>
2222
#endif
2323

24+
#include <unordered_set>
25+
2426
arrayst::arrayst(const namespacet &_ns, propt &_prop)
2527
: equalityt(_prop), ns(_ns)
2628
{
@@ -505,21 +507,16 @@ void arrayst::add_array_constraints_with(
505507
const index_sett &index_set,
506508
const with_exprt &expr)
507509
{
510+
// We got x=(y with [i:=v, j:=w, ...]).
511+
// First add constraints x[i]=v, x[j]=w, ...
512+
std::unordered_set<exprt, irep_hash> updated_indices;
513+
508514
const exprt::operandst &operands = expr.operands();
509515
for(std::size_t i = 1; i + 1 < operands.size(); i += 2)
510-
add_array_constraints_with(index_set, expr, operands[i], operands[i + 1]);
511-
}
512-
513-
void arrayst::add_array_constraints_with(
514-
const index_sett &index_set,
515-
const with_exprt &expr,
516-
const exprt &index,
517-
const exprt &value)
518-
{
519-
// we got x=(y with [i:=v])
520-
// add constraint x[i]=v
521-
522516
{
517+
const exprt &index = operands[i];
518+
const exprt &value = operands[i + 1];
519+
523520
index_exprt index_expr(expr, index, expr.type().subtype());
524521

525522
if(index_expr.type()!=value.type())
@@ -531,22 +528,29 @@ void arrayst::add_array_constraints_with(
531528
}
532529

533530
lazy_constraintt lazy(
534-
lazy_typet::ARRAY_WITH, equal_exprt(index_expr, value));
535-
add_array_constraint(lazy, false); // added immediately
531+
lazy_typet::ARRAY_WITH, equal_exprt(index_expr, value));
532+
add_array_constraint(lazy, false); // added immediately
533+
534+
updated_indices.insert(index);
536535
}
537536

538-
// use other array index applications for "else" case
539-
// add constraint x[I]=y[I] for I!=i
537+
// For all other indices use the existing value, i.e., add constraints
538+
// x[I]=y[I] for I!=i,j,...
540539

541540
for(auto other_index : index_set)
542541
{
543-
if(other_index!=index)
542+
if(updated_indices.find(other_index) == updated_indices.end())
544543
{
545544
// we first build the guard
545+
exprt::operandst disjuncts;
546+
disjuncts.reserve(updated_indices.size());
547+
for(const auto &index : updated_indices)
548+
{
549+
disjuncts.push_back(equal_exprt{
550+
index, typecast_exprt::conditional_cast(other_index, index.type())});
551+
}
546552

547-
other_index = typecast_exprt::conditional_cast(other_index, index.type());
548-
549-
literalt guard_lit=convert(equal_exprt(index, other_index));
553+
literalt guard_lit = convert(disjunction(disjuncts));
550554

551555
if(guard_lit!=const_literal(true))
552556
{

src/solvers/flattening/arrays.h

-5
Original file line numberDiff line numberDiff line change
@@ -111,11 +111,6 @@ class arrayst:public equalityt
111111
const index_sett &index_set, const if_exprt &exprt);
112112
void add_array_constraints_with(
113113
const index_sett &index_set, const with_exprt &expr);
114-
void add_array_constraints_with(
115-
const index_sett &index_set,
116-
const with_exprt &expr,
117-
const exprt &index,
118-
const exprt &value);
119114
void add_array_constraints_update(
120115
const index_sett &index_set, const update_exprt &expr);
121116
void add_array_constraints_array_of(

0 commit comments

Comments
 (0)