Skip to content

Commit 1161a36

Browse files
committed
Error handling cleanup in solvers/flattening
Files boolbv_quantifier.cpp to boolbv_typecast.cpp
1 parent 5fa1c86 commit 1161a36

File tree

6 files changed

+104
-75
lines changed

6 files changed

+104
-75
lines changed

src/solvers/flattening/boolbv_quantifier.cpp

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,8 @@ Author: Daniel Kroening, [email protected]
88

99
#include "boolbv.h"
1010

11-
#include <cassert>
12-
1311
#include <util/arith_tools.h>
12+
#include <util/invariant.h>
1413
#include <util/replace_expr.h>
1514
#include <util/simplify_expr.h>
1615

@@ -32,8 +31,8 @@ exprt get_quantifier_var_min(
3231
const exprt &var_expr,
3332
const exprt &quantifier_expr)
3433
{
35-
assert(quantifier_expr.id()==ID_or ||
36-
quantifier_expr.id()==ID_and);
34+
PRECONDITION(quantifier_expr.id() == ID_or || quantifier_expr.id() == ID_and);
35+
3736
exprt res;
3837
res.make_false();
3938
if(quantifier_expr.id()==ID_or)
@@ -80,8 +79,7 @@ exprt get_quantifier_var_max(
8079
const exprt &var_expr,
8180
const exprt &quantifier_expr)
8281
{
83-
assert(quantifier_expr.id()==ID_or ||
84-
quantifier_expr.id()==ID_and);
82+
PRECONDITION(quantifier_expr.id() == ID_or || quantifier_expr.id() == ID_and);
8583
exprt res;
8684
res.make_false();
8785
if(quantifier_expr.id()==ID_or)
@@ -140,11 +138,15 @@ exprt get_quantifier_var_max(
140138
bool instantiate_quantifier(exprt &expr,
141139
const namespacet &ns)
142140
{
143-
if(!(expr.id()==ID_forall || expr.id()==ID_exists))
144-
return true;
141+
PRECONDITION(expr.id() == ID_forall || expr.id() == ID_exists);
145142

146-
assert(expr.operands().size()==2);
147-
assert(expr.op0().id()==ID_symbol);
143+
DATA_INVARIANT(
144+
expr.operands().size() == 2,
145+
"quantifier expressions shall have two operands");
146+
147+
DATA_INVARIANT(
148+
expr.op0().id() == ID_symbol,
149+
"quantified variable shall be a symbol");
148150

149151
exprt var_expr=expr.op0();
150152

@@ -203,6 +205,8 @@ bool instantiate_quantifier(exprt &expr,
203205

204206
literalt boolbvt::convert_quantifier(const exprt &src)
205207
{
208+
PRECONDITION(src.id() == ID_forall || src.id() == ID_exists);
209+
206210
exprt expr(src);
207211
if(!instantiate_quantifier(expr, ns))
208212
return SUB::convert_rest(src);

src/solvers/flattening/boolbv_reduction.cpp

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,9 @@ literalt boolbvt::convert_reduction(const unary_exprt &expr)
1313
{
1414
const bvt &op_bv=convert_bv(expr.op());
1515

16-
if(op_bv.empty())
17-
throw "reduction operators take one non-empty operand";
16+
INVARIANT(
17+
!op_bv.empty(),
18+
"reduction operand bitvector shall have width at least one");
1819

1920
enum { O_OR, O_AND, O_XOR } op;
2021

@@ -27,7 +28,7 @@ literalt boolbvt::convert_reduction(const unary_exprt &expr)
2728
else if(id==ID_reduction_xor || id==ID_reduction_xnor)
2829
op=O_XOR;
2930
else
30-
throw "unexpected reduction operator";
31+
UNREACHABLE;
3132

3233
literalt l=op_bv[0];
3334

@@ -53,8 +54,9 @@ bvt boolbvt::convert_bv_reduction(const unary_exprt &expr)
5354
{
5455
const bvt &op_bv=convert_bv(expr.op());
5556

56-
if(op_bv.empty())
57-
throw "reduction operators take one non-empty operand";
57+
INVARIANT(
58+
!op_bv.empty(),
59+
"reduction operand bitvector shall have width at least one");
5860

5961
enum { O_OR, O_AND, O_XOR } op;
6062

@@ -67,7 +69,7 @@ bvt boolbvt::convert_bv_reduction(const unary_exprt &expr)
6769
else if(id==ID_reduction_xor || id==ID_reduction_xnor)
6870
op=O_XOR;
6971
else
70-
throw "unexpected reduction operator";
72+
UNREACHABLE;
7173

7274
const typet &op_type=expr.op().type();
7375

src/solvers/flattening/boolbv_replication.cpp

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -18,29 +18,33 @@ bvt boolbvt::convert_replication(const replication_exprt &expr)
1818
return conversion_failed(expr);
1919

2020
mp_integer times;
21-
if(to_integer(expr.op0(), times))
22-
throw "replication takes constant as first parameter";
21+
bool error = to_integer(expr.op0(), times);
22+
INVARIANT(
23+
!error,
24+
"first operand of replication expression shall be convertible to an "
25+
"integer");
2326

2427
bvt bv;
2528
bv.resize(width);
2629

2730
const std::size_t u_times=integer2unsigned(times);
2831
const bvt &op=convert_bv(expr.op1());
29-
std::size_t offset=0;
3032

31-
for(std::size_t i=0; i<u_times; i++)
32-
{
33-
if(op.size()+offset>width)
34-
throw "replication operand width too big";
33+
INVARIANT(
34+
op.size() * u_times == bv.size(),
35+
"result bitvector width shall be equal to the operand bitvector width times"
36+
"the number of replications");
3537

36-
for(std::size_t i=0; i<op.size(); i++)
37-
bv[i+offset]=op[i];
38+
std::size_t bit_idx = 0;
3839

39-
offset+=op.size();
40+
for(std::size_t i = 0; i < u_times; i++)
41+
{
42+
for(const auto &bit : op)
43+
{
44+
bv[bit_idx] = bit;
45+
bit_idx++;
46+
}
4047
}
4148

42-
if(offset!=bv.size())
43-
throw "replication operand width too small";
44-
4549
return bv;
4650
}

src/solvers/flattening/boolbv_shift.cpp

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,7 @@ bvt boolbvt::convert_shift(const binary_exprt &expr)
3030
if(width==0)
3131
return conversion_failed(expr);
3232

33-
const bvt &op=convert_bv(expr.op0());
34-
35-
if(op.size()!=width)
36-
throw "convert_shift: unexpected operand 0 width";
33+
const bvt &op=convert_bv(expr.op0(), width);
3734

3835
bv_utilst::shiftt shift;
3936

@@ -48,15 +45,17 @@ bvt boolbvt::convert_shift(const binary_exprt &expr)
4845
else if(expr.id()==ID_ror)
4946
shift=bv_utilst::shiftt::ROTATE_RIGHT;
5047
else
51-
throw "unexpected shift operator";
48+
UNREACHABLE;
5249

5350
// we allow a constant as shift distance
5451

5552
if(expr.op1().is_constant())
5653
{
5754
mp_integer i;
58-
if(to_integer(expr.op1(), i))
59-
throw "convert_shift: failed to convert constant";
55+
bool error = to_integer(expr.op1(), i);
56+
INVARIANT(
57+
!error,
58+
"shift distance operand shall be convertible to an integer");
6059

6160
std::size_t distance;
6261

src/solvers/flattening/boolbv_struct.cpp

Lines changed: 26 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -19,53 +19,55 @@ bvt boolbvt::convert_struct(const struct_exprt &expr)
1919

2020
const struct_typet::componentst &components=struct_type.components();
2121

22-
if(expr.operands().size()!=components.size())
23-
{
24-
error().source_location=expr.find_source_location();
25-
error() << "struct: wrong number of arguments" << eom;
26-
throw 0;
27-
}
22+
DATA_INVARIANT_WITH_DIAGNOSTICS(
23+
expr.operands().size() == components.size(),
24+
"number of operands of a struct expression shall equal the number of"
25+
"components as indicated by its type",
26+
expr.find_source_location());
2827

2928
bvt bv;
3029
bv.resize(width);
3130

32-
std::size_t offset=0;
31+
//std::size_t offset=0;
32+
std::size_t bit_idx = 0;
3333

3434
exprt::operandst::const_iterator op_it=expr.operands().begin();
3535
for(const auto &comp : components)
3636
{
3737
const typet &subtype=comp.type();
3838
const exprt &op=*op_it;
3939

40-
if(!base_type_eq(subtype, op.type(), ns))
41-
{
42-
error().source_location=expr.find_source_location();
43-
error() << "struct: component type does not match: "
44-
<< subtype.pretty() << " vs. "
45-
<< op.type().pretty() << eom;
46-
throw 0;
47-
}
40+
DATA_INVARIANT_WITH_DIAGNOSTICS(
41+
base_type_eq(subtype, op.type(), ns),
42+
"type of a struct expression operand shall equal the type of the "
43+
"corresponding struct component",
44+
expr.find_source_location(),
45+
subtype.pretty(),
46+
op.type().pretty());
4847

4948
std::size_t subtype_width=boolbv_width(subtype);
5049

5150
if(subtype_width!=0)
5251
{
53-
const bvt &op_bv=convert_bv(op);
54-
55-
assert(offset<width);
56-
assert(op_bv.size()==subtype_width);
57-
assert(offset+op_bv.size()<=width);
52+
const bvt &op_bv=convert_bv(op, subtype_width);
5853

59-
for(std::size_t j=0; j<op_bv.size(); j++)
60-
bv[offset+j]=op_bv[j];
54+
INVARIANT(
55+
bit_idx + op_bv.size() <= width,
56+
"bit index shall be within bounds");
6157

62-
offset+=op_bv.size();
58+
for(const auto &bit : op_bv)
59+
{
60+
bv[bit_idx] = bit;
61+
bit_idx++;
62+
}
6363
}
6464

6565
++op_it;
6666
}
6767

68-
assert(offset==width);
68+
INVARIANT(
69+
bit_idx == width,
70+
"all bits in the bitvector shall have been assigned");
6971

7072
return bv;
7173
}

src/solvers/flattening/boolbv_typecast.cpp

Lines changed: 33 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,10 @@ bool boolbvt::type_conversion(
9393
upper,
9494
ns.follow(dest_type.subtype()),
9595
upper_res);
96-
assert(lower_res.size()+upper_res.size()==dest_width);
96+
INVARIANT(
97+
lower_res.size() + upper_res.size() == dest_width,
98+
"lower result bitvector size plus upper result bitvector size shall "
99+
"equal the destination bitvector size");
97100
dest=lower_res;
98101
dest.insert(dest.end(), upper_res.begin(), upper_res.end());
99102
return false;
@@ -102,7 +105,10 @@ bool boolbvt::type_conversion(
102105

103106
if(src_type.id()==ID_complex)
104107
{
105-
assert(dest_type.id()!=ID_complex);
108+
INVARIANT(
109+
dest_type.id() == ID_complex,
110+
"destination type shall be of complex type when source type is of "
111+
"complex type");
106112
if(dest_type.id()==ID_signedbv ||
107113
dest_type.id()==ID_unsignedbv ||
108114
dest_type.id()==ID_floatbv ||
@@ -187,7 +193,9 @@ bool boolbvt::type_conversion(
187193
return false;
188194

189195
case bvtypet::IS_BV:
190-
assert(src_width==dest_width);
196+
INVARIANT(
197+
src_width == dest_width,
198+
"source bitvector size shall equal the destination bitvector size");
191199
dest=src;
192200
return false;
193201

@@ -202,7 +210,9 @@ bool boolbvt::type_conversion(
202210

203211
dest=convert_bv(f.to_expr());
204212

205-
assert(src_width==1);
213+
INVARIANT(
214+
src_width == 1,
215+
"bitvector of type boolean shall have width one");
206216

207217
Forall_literals(it, dest)
208218
*it=prop.land(*it, src[0]);
@@ -245,7 +255,9 @@ bool boolbvt::type_conversion(
245255
{
246256
// position in bv
247257
std::size_t p=dest_fraction_bits+i;
248-
assert(p<dest_width);
258+
INVARIANT(
259+
p < dest_width,
260+
"bit index shall be within bounds");
249261

250262
if(i<op_int_bits)
251263
dest[p]=src[i+op_fraction_bits];
@@ -257,7 +269,9 @@ bool boolbvt::type_conversion(
257269
}
258270
else if(src_bvtype==bvtypet::IS_BV)
259271
{
260-
assert(src_width==dest_width);
272+
INVARIANT(
273+
src_width == dest_width,
274+
"source bitvector with shall equal the destination bitvector width");
261275
dest=src;
262276
return false;
263277
}
@@ -299,7 +313,9 @@ bool boolbvt::type_conversion(
299313
std::size_t fraction_bits=
300314
to_fixedbv_type(dest_type).get_fraction_bits();
301315

302-
assert(src_width==1);
316+
INVARIANT(
317+
src_width == 1,
318+
"bitvector of type boolean shall have width one");
303319

304320
for(std::size_t i=0; i<dest_width; i++)
305321
{
@@ -416,7 +432,9 @@ bool boolbvt::type_conversion(
416432
{
417433
// bool to integer
418434

419-
assert(src_width==1);
435+
INVARIANT(
436+
src_width == 1,
437+
"bitvector of type boolean shall have width one");
420438

421439
for(std::size_t i=0; i<dest_width; i++)
422440
{
@@ -483,7 +501,9 @@ bool boolbvt::type_conversion(
483501
break;
484502

485503
case bvtypet::IS_BV:
486-
assert(src_width==dest_width);
504+
INVARIANT(
505+
src_width == dest_width,
506+
"source bitvector width shall equal the destination bitvector width");
487507
dest=src;
488508
return false;
489509

@@ -590,20 +610,18 @@ bool boolbvt::type_conversion(
590610
/// conversion from bitvector types to boolean
591611
literalt boolbvt::convert_typecast(const typecast_exprt &expr)
592612
{
593-
assert(expr.operands().size()==1);
594-
595-
if(expr.op0().type().id()==ID_range)
613+
if(expr.op().type().id() == ID_range)
596614
{
597-
mp_integer from=string2integer(expr.op0().type().get_string(ID_from));
598-
mp_integer to=string2integer(expr.op0().type().get_string(ID_to));
615+
mp_integer from=string2integer(expr.op().type().get_string(ID_from));
616+
mp_integer to=string2integer(expr.op().type().get_string(ID_to));
599617

600618
if(from==1 && to==1)
601619
return const_literal(true);
602620
else if(from==0 && to==0)
603621
return const_literal(false);
604622
}
605623

606-
const bvt &bv=convert_bv(expr.op0());
624+
const bvt &bv=convert_bv(expr.op());
607625

608626
if(!bv.empty())
609627
return prop.lor(bv);

0 commit comments

Comments
 (0)