Skip to content

Commit 9e2e7eb

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. The test is based on SV-COMP's array-memsafety/count_down_unsafe_false-valid-deref.c.
1 parent 43363a3 commit 9e2e7eb

File tree

4 files changed

+62
-22
lines changed

4 files changed

+62
-22
lines changed
+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#include <stdlib.h>
2+
extern int __VERIFIER_nondet_int(void);
3+
4+
int main()
5+
{
6+
int i, j;
7+
int val;
8+
int length = __VERIFIER_nondet_int();
9+
if(length < 1)
10+
length = 1;
11+
int *arr = alloca(length);
12+
if(!arr)
13+
return 0;
14+
for(i = 0; i < length; i++)
15+
{
16+
val = __VERIFIER_nondet_int();
17+
if(val < 0)
18+
{
19+
val = 0;
20+
}
21+
arr[i] = val;
22+
}
23+
for(j = 0; j < length; j++)
24+
{
25+
while(arr[j] > 0)
26+
{
27+
arr[j]--;
28+
}
29+
}
30+
return 0;
31+
}
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

+22-17
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
{
@@ -504,22 +506,18 @@ void arrayst::add_array_constraints(
504506
void arrayst::add_array_constraints_with(
505507
const index_sett &index_set,
506508
const with_exprt &expr)
507-
{
508-
const exprt::operandst &operands = expr.operands();
509-
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)
518509
{
519510
// we got x=(y with [i:=v])
520511
// add constraint x[i]=v
521512

513+
std::unordered_set<exprt, irep_hash> updated_indices;
514+
515+
const exprt::operandst &operands = expr.operands();
516+
for(std::size_t i = 1; i + 1 < operands.size(); i += 2)
522517
{
518+
const exprt &index = operands[i];
519+
const exprt &value = operands[i + 1];
520+
523521
index_exprt index_expr(expr, index, expr.type().subtype());
524522

525523
if(index_expr.type()!=value.type())
@@ -531,22 +529,29 @@ void arrayst::add_array_constraints_with(
531529
}
532530

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

538538
// use other array index applications for "else" case
539539
// add constraint x[I]=y[I] for I!=i
540540

541541
for(auto other_index : index_set)
542542
{
543-
if(other_index!=index)
543+
if(updated_indices.find(other_index) == updated_indices.end())
544544
{
545545
// we first build the guard
546+
exprt::operandst disjuncts;
547+
disjuncts.reserve(updated_indices.size());
548+
for(const auto &index : updated_indices)
549+
{
550+
disjuncts.push_back(equal_exprt{
551+
index, typecast_exprt::conditional_cast(other_index, index.type())});
552+
}
546553

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

551556
if(guard_lit!=const_literal(true))
552557
{

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)