Skip to content

Commit 755d839

Browse files
authored
Merge pull request #2933 from danpoe/refactor/error-handling-solvers-flattening-from-boolbv-map
Error handling cleanup in solvers/flattening 3
2 parents ae9ea6d + d57737a commit 755d839

11 files changed

+93
-137
lines changed

src/solvers/flattening/boolbv.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -222,9 +222,8 @@ bvt boolbvt::convert_bitvector(const exprt &expr)
222222
expr.id()=="no-overflow-plus" ||
223223
expr.id()=="no-overflow-minus")
224224
return convert_add_sub(expr);
225-
else if(expr.id()==ID_mult ||
226-
expr.id()=="no-overflow-mult")
227-
return convert_mult(expr);
225+
else if(expr.id() == ID_mult)
226+
return convert_mult(to_mult_expr(expr));
228227
else if(expr.id()==ID_div)
229228
return convert_div(to_div_expr(expr));
230229
else if(expr.id()==ID_mod)

src/solvers/flattening/boolbv.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ class boolbvt:public arrayst
152152
virtual bvt convert_union(const union_exprt &expr);
153153
virtual bvt convert_bv_typecast(const typecast_exprt &expr);
154154
virtual bvt convert_add_sub(const exprt &expr);
155-
virtual bvt convert_mult(const exprt &expr);
155+
virtual bvt convert_mult(const mult_exprt &expr);
156156
virtual bvt convert_div(const div_exprt &expr);
157157
virtual bvt convert_mod(const mod_exprt &expr);
158158
virtual bvt convert_floatbv_op(const exprt &expr);

src/solvers/flattening/boolbv_map.cpp

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,9 @@ boolbv_mapt::map_entryt &boolbv_mapt::get_map_entry(
6767
map_entry.literal_map.resize(map_entry.width);
6868
}
6969

70-
assert(map_entry.literal_map.size()==map_entry.width);
70+
INVARIANT(
71+
map_entry.literal_map.size() == map_entry.width,
72+
"number of literals in the literal map shall equal the bitvector width");
7173

7274
return map_entry;
7375
}
@@ -89,15 +91,18 @@ void boolbv_mapt::get_literals(
8991
{
9092
map_entryt &map_entry=get_map_entry(identifier, type);
9193

92-
assert(literals.size()==width);
93-
assert(map_entry.literal_map.size()==width);
94+
PRECONDITION(literals.size() == width);
95+
INVARIANT(
96+
map_entry.literal_map.size() == width,
97+
"number of literals in the literal map shall equal the bitvector width");
9498

9599
Forall_literals(it, literals)
96100
{
97101
literalt &l=*it;
98102
const std::size_t bit=it-literals.begin();
99103

100-
assert(bit<map_entry.literal_map.size());
104+
INVARIANT(
105+
bit < map_entry.literal_map.size(), "bit index shall be within bounds");
101106
map_bitt &mb=map_entry.literal_map[bit];
102107

103108
if(mb.is_set)
@@ -128,12 +133,15 @@ void boolbv_mapt::set_literals(
128133
forall_literals(it, literals)
129134
{
130135
const literalt &literal=*it;
131-
const std::size_t bit=it-literals.begin();
132136

133-
assert(literal.is_constant() ||
134-
literal.var_no()<prop.no_variables());
137+
INVARIANT(
138+
literal.is_constant() || literal.var_no() < prop.no_variables(),
139+
"variable number of non-constant literals shall be within bounds");
140+
141+
const std::size_t bit = it - literals.begin();
135142

136-
assert(bit<map_entry.literal_map.size());
143+
INVARIANT(
144+
bit < map_entry.literal_map.size(), "bit index shall be within bounds");
137145
map_bitt &mb=map_entry.literal_map[bit];
138146

139147
if(mb.is_set)

src/solvers/flattening/boolbv_member.cpp

Lines changed: 19 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,12 @@ bvt boolbvt::convert_member(const member_exprt &expr)
2828
from_integer(0, index_type()),
2929
expr.type()));
3030
}
31-
else if(struct_op_type.id()==ID_struct)
31+
else
3232
{
33+
INVARIANT(
34+
struct_op_type.id() == ID_struct,
35+
"member_exprt should denote access to a union or struct");
36+
3337
const irep_idt &component_name=expr.get_component_name();
3438
const struct_typet::componentst &components=
3539
to_struct_type(struct_op_type).components();
@@ -43,22 +47,18 @@ bvt boolbvt::convert_member(const member_exprt &expr)
4347

4448
if(c.get_name() == component_name)
4549
{
46-
if(!base_type_eq(subtype, expr.type(), ns))
47-
{
48-
#if 0
49-
std::cout << "DEBUG " << expr.pretty() << "\n";
50-
#endif
51-
52-
error().source_location=expr.find_source_location();
53-
error() << "member: component type does not match: "
54-
<< subtype.pretty() << " vs. "
55-
<< expr.type().pretty() << eom;
56-
throw 0;
57-
}
50+
DATA_INVARIANT_WITH_DIAGNOSTICS(
51+
base_type_eq(subtype, expr.type(), ns),
52+
"struct component type shall match the member expression type",
53+
subtype.pretty(),
54+
expr.type().pretty());
5855

5956
bvt bv;
6057
bv.resize(sub_width);
61-
assert(offset+sub_width<=struct_bv.size());
58+
INVARIANT(
59+
offset + sub_width <= struct_bv.size(),
60+
"bitvector part corresponding to struct element shall be contained "
61+
"within the full struct bitvector");
6262

6363
for(std::size_t i=0; i<sub_width; i++)
6464
bv[i]=struct_bv[offset+i];
@@ -69,15 +69,10 @@ bvt boolbvt::convert_member(const member_exprt &expr)
6969
offset+=sub_width;
7070
}
7171

72-
error().source_location=expr.find_source_location();
73-
error() << "component " << component_name
74-
<< " not found in structure" << eom;
75-
throw 0;
76-
}
77-
else
78-
{
79-
error().source_location=expr.find_source_location();
80-
error() << "member takes struct or union operand" << eom;
81-
throw 0;
72+
INVARIANT_WITH_DIAGNOSTICS(
73+
false,
74+
"struct type shall contain component accessed by member expression",
75+
expr.find_source_location(),
76+
id2string(component_name));
8277
}
8378
}

src/solvers/flattening/boolbv_mod.cpp

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -27,20 +27,22 @@ bvt boolbvt::convert_mod(const mod_exprt &expr)
2727
if(width==0)
2828
return conversion_failed(expr);
2929

30-
if(expr.op0().type().id()!=expr.type().id() ||
31-
expr.op1().type().id()!=expr.type().id())
32-
throw "mod got mixed-type operands";
30+
DATA_INVARIANT(
31+
expr.op0().type().id() == expr.type().id(),
32+
"type of the first operand of a modulo operation shall equal the "
33+
"expression type");
34+
35+
DATA_INVARIANT(
36+
expr.op1().type().id() == expr.type().id(),
37+
"type of the second operand of a modulo operation shall equal the "
38+
"expression type");
3339

3440
bv_utilst::representationt rep=
3541
expr.type().id()==ID_signedbv?bv_utilst::representationt::SIGNED:
3642
bv_utilst::representationt::UNSIGNED;
3743

38-
const bvt &op0=convert_bv(expr.op0());
39-
const bvt &op1=convert_bv(expr.op1());
40-
41-
if(op0.size()!=width ||
42-
op1.size()!=width)
43-
throw "convert_mod: unexpected operand width";
44+
const bvt &op0 = convert_bv(expr.op0(), width);
45+
const bvt &op1 = convert_bv(expr.op1(), width);
4446

4547
bvt res, rem;
4648

src/solvers/flattening/boolbv_mult.cpp

Lines changed: 16 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ Author: Daniel Kroening, [email protected]
1010

1111
#include <util/std_types.h>
1212

13-
bvt boolbvt::convert_mult(const exprt &expr)
13+
bvt boolbvt::convert_mult(const mult_exprt &expr)
1414
{
1515
std::size_t width=boolbv_width(expr.type());
1616

@@ -21,39 +21,32 @@ bvt boolbvt::convert_mult(const exprt &expr)
2121
bv.resize(width);
2222

2323
const exprt::operandst &operands=expr.operands();
24-
if(operands.empty())
25-
throw "mult without operands";
24+
DATA_INVARIANT(!operands.empty(), "multiplication must have operands");
2625

2726
const exprt &op0=expr.op0();
2827

29-
bool no_overflow=expr.id()=="no-overflow-mult";
28+
DATA_INVARIANT(
29+
op0.type() == expr.type(),
30+
"multiplication operands should have same type as expression");
3031

3132
if(expr.type().id()==ID_fixedbv)
3233
{
33-
if(op0.type()!=expr.type())
34-
throw "multiplication with mixed types";
35-
36-
bv=convert_bv(op0);
37-
38-
if(bv.size()!=width)
39-
throw "convert_mult: unexpected operand width";
34+
bv = convert_bv(op0, width);
4035

4136
std::size_t fraction_bits=
4237
to_fixedbv_type(expr.type()).get_fraction_bits();
4338

4439
for(exprt::operandst::const_iterator it=operands.begin()+1;
4540
it!=operands.end(); it++)
4641
{
47-
if(it->type()!=expr.type())
48-
throw "multiplication with mixed types";
42+
DATA_INVARIANT(
43+
it->type() == expr.type(),
44+
"multiplication operands should have same type as expression");
4945

5046
// do a sign extension by fraction_bits bits
5147
bv=bv_utils.sign_extension(bv, bv.size()+fraction_bits);
5248

53-
bvt op=convert_bv(*it);
54-
55-
if(op.size()!=width)
56-
throw "convert_mult: unexpected operand width";
49+
bvt op = convert_bv(*it, width);
5750

5851
op=bv_utils.sign_extension(op, bv.size());
5952

@@ -68,33 +61,22 @@ bvt boolbvt::convert_mult(const exprt &expr)
6861
else if(expr.type().id()==ID_unsignedbv ||
6962
expr.type().id()==ID_signedbv)
7063
{
71-
if(op0.type()!=expr.type())
72-
throw "multiplication with mixed types";
73-
7464
bv_utilst::representationt rep=
7565
expr.type().id()==ID_signedbv?bv_utilst::representationt::SIGNED:
7666
bv_utilst::representationt::UNSIGNED;
7767

78-
bv=convert_bv(op0);
79-
80-
if(bv.size()!=width)
81-
throw "convert_mult: unexpected operand width";
68+
bv = convert_bv(op0, width);
8269

8370
for(exprt::operandst::const_iterator it=operands.begin()+1;
8471
it!=operands.end(); it++)
8572
{
86-
if(it->type()!=expr.type())
87-
throw "multiplication with mixed types";
88-
89-
const bvt &op=convert_bv(*it);
73+
DATA_INVARIANT(
74+
it->type() == expr.type(),
75+
"multiplication operands should have same type as expression");
9076

91-
if(op.size()!=width)
92-
throw "convert_mult: unexpected operand width";
77+
const bvt &op = convert_bv(*it, width);
9378

94-
if(no_overflow)
95-
bv=bv_utils.multiplier_no_overflow(bv, op, rep);
96-
else
97-
bv=bv_utils.multiplier(bv, op, rep);
79+
bv = bv_utils.multiplier(bv, op, rep);
9880
}
9981

10082
return bv;

src/solvers/flattening/boolbv_not.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,7 @@ Author: Daniel Kroening, [email protected]
1212
bvt boolbvt::convert_not(const not_exprt &expr)
1313
{
1414
const bvt &op_bv=convert_bv(expr.op());
15-
16-
if(op_bv.empty())
17-
throw "not operator takes one non-empty operand";
15+
CHECK_RETURN(!op_bv.empty());
1816

1917
const typet &op_type=expr.op().type();
2018

src/solvers/flattening/boolbv_onehot.cpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ Author: Daniel Kroening, [email protected]
1111

1212
literalt boolbvt::convert_onehot(const unary_exprt &expr)
1313
{
14+
PRECONDITION(expr.id() == ID_onehot || expr.id() == ID_onehot0);
15+
1416
bvt op=convert_bv(expr.op());
1517

1618
literalt one_seen=const_literal(false);
@@ -25,8 +27,12 @@ literalt boolbvt::convert_onehot(const unary_exprt &expr)
2527

2628
if(expr.id()==ID_onehot)
2729
return prop.land(one_seen, !more_than_one_seen);
28-
else if(expr.id()==ID_onehot0)
29-
return !more_than_one_seen;
3030
else
31-
throw "unexpected onehot expression";
31+
{
32+
INVARIANT(
33+
expr.id() == ID_onehot0,
34+
"should be a onehot0 expression as other onehot expression kind has been "
35+
"handled in other branch");
36+
return !more_than_one_seen;
37+
}
3238
}

0 commit comments

Comments
 (0)