Skip to content

Commit f971997

Browse files
committed
Error handling cleanup in solvers/flattening
Files boolbv_quantifier.cpp to boolbv_typecast.cpp
1 parent 684b210 commit f971997

7 files changed

+95
-78
lines changed

src/solvers/flattening/boolbv_quantifier.cpp

Lines changed: 13 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,14 @@ 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, "quantified variable shall be a symbol");
148149

149150
exprt var_expr=expr.op0();
150151

@@ -203,6 +204,8 @@ bool instantiate_quantifier(exprt &expr,
203204

204205
literalt boolbvt::convert_quantifier(const exprt &src)
205206
{
207+
PRECONDITION(src.id() == ID_forall || src.id() == ID_exists);
208+
206209
exprt expr(src);
207210
if(!instantiate_quantifier(expr, ns))
208211
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: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -17,30 +17,29 @@ bvt boolbvt::convert_replication(const replication_exprt &expr)
1717
if(width==0)
1818
return conversion_failed(expr);
1919

20-
mp_integer times;
21-
if(to_integer(expr.op0(), times))
22-
throw "replication takes constant as first parameter";
20+
mp_integer times = numeric_cast_v<mp_integer>(expr.times());
2321

2422
bvt bv;
2523
bv.resize(width);
2624

2725
const std::size_t u_times=integer2unsigned(times);
28-
const bvt &op=convert_bv(expr.op1());
29-
std::size_t offset=0;
26+
const bvt &op = convert_bv(expr.op());
3027

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";
28+
INVARIANT(
29+
op.size() * u_times == bv.size(),
30+
"result bitvector width shall be equal to the operand bitvector width times"
31+
"the number of replications");
3532

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

39-
offset+=op.size();
35+
for(std::size_t i = 0; i < u_times; i++)
36+
{
37+
for(const auto &bit : op)
38+
{
39+
bv[bit_idx] = bit;
40+
bit_idx++;
41+
}
4042
}
4143

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

src/solvers/flattening/boolbv_shift.cpp

Lines changed: 3 additions & 8 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,13 @@ 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
{
57-
mp_integer i;
58-
if(to_integer(expr.op1(), i))
59-
throw "convert_shift: failed to convert constant";
54+
mp_integer i = numeric_cast_v<mp_integer>(expr.op1());
6055

6156
std::size_t distance;
6257

src/solvers/flattening/boolbv_struct.cpp

Lines changed: 23 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -19,53 +19,52 @@ 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 bit_idx = 0;
3332

3433
exprt::operandst::const_iterator op_it=expr.operands().begin();
3534
for(const auto &comp : components)
3635
{
3736
const typet &subtype=comp.type();
3837
const exprt &op=*op_it;
3938

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-
}
39+
DATA_INVARIANT_WITH_DIAGNOSTICS(
40+
base_type_eq(subtype, op.type(), ns),
41+
"type of a struct expression operand shall equal the type of the "
42+
"corresponding struct component",
43+
expr.find_source_location(),
44+
subtype.pretty(),
45+
op.type().pretty());
4846

4947
std::size_t subtype_width=boolbv_width(subtype);
5048

5149
if(subtype_width!=0)
5250
{
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);
51+
const bvt &op_bv = convert_bv(op, subtype_width);
5852

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

62-
offset+=op_bv.size();
56+
for(const auto &bit : op_bv)
57+
{
58+
bv[bit_idx] = bit;
59+
bit_idx++;
60+
}
6361
}
6462

6563
++op_it;
6664
}
6765

68-
assert(offset==width);
66+
INVARIANT(
67+
bit_idx == width, "all bits in the bitvector shall have been assigned");
6968

7069
return bv;
7170
}

src/solvers/flattening/boolbv_typecast.cpp

Lines changed: 28 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,8 @@ bool boolbvt::type_conversion(
202210

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

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

207216
Forall_literals(it, dest)
208217
*it=prop.land(*it, src[0]);
@@ -245,7 +254,7 @@ bool boolbvt::type_conversion(
245254
{
246255
// position in bv
247256
std::size_t p=dest_fraction_bits+i;
248-
assert(p<dest_width);
257+
INVARIANT(p < dest_width, "bit index shall be within bounds");
249258

250259
if(i<op_int_bits)
251260
dest[p]=src[i+op_fraction_bits];
@@ -257,7 +266,9 @@ bool boolbvt::type_conversion(
257266
}
258267
else if(src_bvtype==bvtypet::IS_BV)
259268
{
260-
assert(src_width==dest_width);
269+
INVARIANT(
270+
src_width == dest_width,
271+
"source bitvector with shall equal the destination bitvector width");
261272
dest=src;
262273
return false;
263274
}
@@ -299,7 +310,8 @@ bool boolbvt::type_conversion(
299310
std::size_t fraction_bits=
300311
to_fixedbv_type(dest_type).get_fraction_bits();
301312

302-
assert(src_width==1);
313+
INVARIANT(
314+
src_width == 1, "bitvector of type boolean shall have width one");
303315

304316
for(std::size_t i=0; i<dest_width; i++)
305317
{
@@ -416,7 +428,8 @@ bool boolbvt::type_conversion(
416428
{
417429
// bool to integer
418430

419-
assert(src_width==1);
431+
INVARIANT(
432+
src_width == 1, "bitvector of type boolean shall have width one");
420433

421434
for(std::size_t i=0; i<dest_width; i++)
422435
{
@@ -483,7 +496,9 @@ bool boolbvt::type_conversion(
483496
break;
484497

485498
case bvtypet::IS_BV:
486-
assert(src_width==dest_width);
499+
INVARIANT(
500+
src_width == dest_width,
501+
"source bitvector width shall equal the destination bitvector width");
487502
dest=src;
488503
return false;
489504

@@ -590,20 +605,18 @@ bool boolbvt::type_conversion(
590605
/// conversion from bitvector types to boolean
591606
literalt boolbvt::convert_typecast(const typecast_exprt &expr)
592607
{
593-
assert(expr.operands().size()==1);
594-
595-
if(expr.op0().type().id()==ID_range)
608+
if(expr.op().type().id() == ID_range)
596609
{
597-
mp_integer from=string2integer(expr.op0().type().get_string(ID_from));
598-
mp_integer to=string2integer(expr.op0().type().get_string(ID_to));
610+
mp_integer from = string2integer(expr.op().type().get_string(ID_from));
611+
mp_integer to = string2integer(expr.op().type().get_string(ID_to));
599612

600613
if(from==1 && to==1)
601614
return const_literal(true);
602615
else if(from==0 && to==0)
603616
return const_literal(false);
604617
}
605618

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

608621
if(!bv.empty())
609622
return prop.lor(bv);

src/util/std_expr.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4585,6 +4585,9 @@ inline const quantifier_exprt &to_quantifier_expr(const exprt &expr)
45854585
{
45864586
DATA_INVARIANT(expr.operands().size()==2,
45874587
"quantifier expressions must have two operands");
4588+
DATA_INVARIANT(
4589+
expr.op0().id() == ID_symbol,
4590+
"quantified variable shall be a symbol");
45884591
return static_cast<const quantifier_exprt &>(expr);
45894592
}
45904593

@@ -4593,6 +4596,9 @@ inline quantifier_exprt &to_quantifier_expr(exprt &expr)
45934596
{
45944597
DATA_INVARIANT(expr.operands().size()==2,
45954598
"quantifier expressions must have two operands");
4599+
DATA_INVARIANT(
4600+
expr.op0().id() == ID_symbol,
4601+
"quantified variable shall be a symbol");
45964602
return static_cast<quantifier_exprt &>(expr);
45974603
}
45984604

0 commit comments

Comments
 (0)