Skip to content

Commit 5914d75

Browse files
authored
Merge pull request diffblue#6004 from padhi-aws-forks/use_array_of_bool_fix
[smt_convt] Fix usage of `use_array_of_bool`
2 parents 9f060b2 + 3e27734 commit 5914d75

File tree

4 files changed

+89
-8
lines changed

4 files changed

+89
-8
lines changed
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#include <assert.h>
2+
#include <stdbool.h>
3+
#include <stdlib.h>
4+
5+
__CPROVER_bool w[8];
6+
7+
void main()
8+
{
9+
_Bool x[8] = {false};
10+
__CPROVER_bool y[8] = {false};
11+
bool *z = calloc(8, sizeof(bool));
12+
13+
unsigned idx;
14+
__CPROVER_assume(0 <= idx && idx < 8);
15+
16+
assert(w[idx] == x[idx]);
17+
assert(x[idx] == y[idx]);
18+
assert(y[idx] == z[idx]);
19+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
CORE broken-smt-backend
2+
main.c
3+
--smt2 --outfile -
4+
\(= \(select array_of\.2 i\) \(ite false #b1 #b0\)\)
5+
\(= \(select array\.3 \(\(_ zero_extend 32\) \|main::1::idx!0@1#1\|\)\) #b1\)
6+
\(= \(select array\.3 \(_ bv\d+ 64\)\) \(ite false #b1 #b0\)\)
7+
^EXIT=0$
8+
^SIGNAL=0$
9+
--
10+
\(= \(select array_of\.2 i\) false\)
11+
\(= \(select array\.3 \(\(_ zero_extend 32\) \|main::1::idx!0@1#1\|\)\) #b1 #b0\)
12+
\(= \(select array\.3 \(_ bv\d+ 64\)\) false\)
13+
--
14+
This test checks for correctness of BitVec-array encoding of Boolean arrays.
15+
16+
Ideally, we shouldn't have to check the SMT output, but should run with backend
17+
SMT solvers. However, we currently cannot because of #5977 (also see #6005).
18+
19+
For now, we tag this test as `broken-smt-backend` to avoid running main.c
20+
with `--z3` or `--cprover-smt2`, both of which encode Boolean arrays directly.
21+
Instead, we generate a generic SMT encoding with `--smt2` and check the output.
22+
23+
Explanation of regexes:
24+
line 4,10: array.2 elements should be BitVec not Bool
25+
line 5,11: equality operator (=) should have 2 arguments not 3
26+
line 6,12: array.3 elements should be BitVec not Bool
27+
28+
Once #5977 and #6005 are resolved, we should:
29+
- remove `broken-smt-backend` tag
30+
- run with `--smt2 --cprover-smt2` and `--smt2 --z3`
31+
- check for successful verification

regression/validate-trace-xml-schema/check.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212

1313
# some tests in the cbmc suite don't work for the trace checks for one reason or another
1414
ExcludedTests = list(map(lambda s: os.path.join(test_base_dir, s[0], s[1]), [
15+
# these tests dump the raw SMT2 output (using --outfile)
16+
['array_of_bool_as_bitvec', 'test-smt2-outfile.desc'],
1517
# these tests expect input from stdin
1618
['json-interface1', 'test_wrong_option.desc'],
1719
['json-interface1', 'test.desc'],

src/solvers/smt2/smt2_conv.cpp

Lines changed: 37 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3871,7 +3871,7 @@ void smt2_convt::convert_index(const index_exprt &expr)
38713871
out << " ";
38723872
convert_expr(typecast_exprt(expr.index(), array_type.size().type()));
38733873
out << ")";
3874-
out << " #b1 #b0)";
3874+
out << " #b1)";
38753875
}
38763876
else
38773877
{
@@ -4405,19 +4405,29 @@ void smt2_convt::find_symbols(const exprt &expr)
44054405
if(defined_expressions.find(expr) == defined_expressions.end())
44064406
{
44074407
const auto &array_of = to_array_of_expr(expr);
4408+
const auto &array_type = array_of.type();
44084409

44094410
const irep_idt id =
44104411
"array_of." + std::to_string(defined_expressions.size());
44114412
out << "; the following is a substitute for lambda i. x\n";
44124413
out << "(declare-fun " << id << " () ";
4413-
convert_type(array_of.type());
4414+
convert_type(array_type);
44144415
out << ")\n";
44154416

44164417
// use a quantifier-based initialization instead of lambda
44174418
out << "(assert (forall ((i ";
4418-
convert_type(array_of.type().size().type());
4419+
convert_type(array_type.size().type());
44194420
out << ")) (= (select " << id << " i) ";
4420-
convert_expr(array_of.what());
4421+
if(array_type.subtype().id() == ID_bool && !use_array_of_bool)
4422+
{
4423+
out << "(ite ";
4424+
convert_expr(array_of.what());
4425+
out << " #b1 #b0)";
4426+
}
4427+
else
4428+
{
4429+
convert_expr(array_of.what());
4430+
}
44214431
out << ")))\n";
44224432

44234433
defined_expressions[expr] = id;
@@ -4431,12 +4441,13 @@ void smt2_convt::find_symbols(const exprt &expr)
44314441
if(defined_expressions.find(expr) == defined_expressions.end())
44324442
{
44334443
const auto &array_comprehension = to_array_comprehension_expr(expr);
4434-
const auto &array_size = array_comprehension.type().size();
4444+
const auto &array_type = array_comprehension.type();
4445+
const auto &array_size = array_type.size();
44354446

44364447
const irep_idt id =
44374448
"array_comprehension." + std::to_string(defined_expressions.size());
44384449
out << "(declare-fun " << id << " () ";
4439-
convert_type(array_comprehension.type());
4450+
convert_type(array_type);
44404451
out << ")\n";
44414452

44424453
out << "; the following is a substitute for lambda i . x(i)\n";
@@ -4455,7 +4466,16 @@ void smt2_convt::find_symbols(const exprt &expr)
44554466
out << ")) (= (select " << id << " ";
44564467
convert_expr(array_comprehension.arg());
44574468
out << ") ";
4458-
convert_expr(array_comprehension.body());
4469+
if(array_type.subtype().id() == ID_bool && !use_array_of_bool)
4470+
{
4471+
out << "(ite ";
4472+
convert_expr(array_comprehension.body());
4473+
out << " #b1 #b0)";
4474+
}
4475+
else
4476+
{
4477+
convert_expr(array_comprehension.body());
4478+
}
44594479
out << "))))\n";
44604480

44614481
defined_expressions[expr] = id;
@@ -4479,7 +4499,16 @@ void smt2_convt::find_symbols(const exprt &expr)
44794499
out << "(assert (= (select " << id << " ";
44804500
convert_expr(from_integer(i, array_type.size().type()));
44814501
out << ") "; // select
4482-
convert_expr(expr.operands()[i]);
4502+
if(array_type.subtype().id() == ID_bool && !use_array_of_bool)
4503+
{
4504+
out << "(ite ";
4505+
convert_expr(expr.operands()[i]);
4506+
out << " #b1 #b0)";
4507+
}
4508+
else
4509+
{
4510+
convert_expr(expr.operands()[i]);
4511+
}
44834512
out << "))" << "\n"; // =, assert
44844513
}
44854514

0 commit comments

Comments
 (0)