Skip to content

Commit 247cfa5

Browse files
committed
Error handling cleanup in solvers/flattening
Files boolbv_map.cpp to boolbv_overflow.cpp
1 parent 5b6a5e6 commit 247cfa5

File tree

7 files changed

+93
-94
lines changed

7 files changed

+93
-94
lines changed

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: 17 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ Author: Daniel Kroening, [email protected]
1212

1313
bvt boolbvt::convert_mult(const exprt &expr)
1414
{
15+
PRECONDITION(expr.id() == ID_mult || expr.id() == "no-overflow-mult");
16+
1517
std::size_t width=boolbv_width(expr.type());
1618

1719
if(width==0)
@@ -21,39 +23,34 @@ bvt boolbvt::convert_mult(const exprt &expr)
2123
bv.resize(width);
2224

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

2728
const exprt &op0=expr.op0();
2829

2930
bool no_overflow=expr.id()=="no-overflow-mult";
3031

32+
DATA_INVARIANT(
33+
op0.type() == expr.type(),
34+
"multiplication operands should have same type as expression");
35+
3136
if(expr.type().id()==ID_fixedbv)
3237
{
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";
38+
bv = convert_bv(op0, width);
4039

4140
std::size_t fraction_bits=
4241
to_fixedbv_type(expr.type()).get_fraction_bits();
4342

4443
for(exprt::operandst::const_iterator it=operands.begin()+1;
4544
it!=operands.end(); it++)
4645
{
47-
if(it->type()!=expr.type())
48-
throw "multiplication with mixed types";
46+
DATA_INVARIANT(
47+
it->type() == expr.type(),
48+
"multiplication operands should have same type as expression");
4949

5050
// do a sign extension by fraction_bits bits
5151
bv=bv_utils.sign_extension(bv, bv.size()+fraction_bits);
5252

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

5855
op=bv_utils.sign_extension(op, bv.size());
5956

@@ -68,28 +65,20 @@ bvt boolbvt::convert_mult(const exprt &expr)
6865
else if(expr.type().id()==ID_unsignedbv ||
6966
expr.type().id()==ID_signedbv)
7067
{
71-
if(op0.type()!=expr.type())
72-
throw "multiplication with mixed types";
73-
7468
bv_utilst::representationt rep=
7569
expr.type().id()==ID_signedbv?bv_utilst::representationt::SIGNED:
7670
bv_utilst::representationt::UNSIGNED;
7771

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

8374
for(exprt::operandst::const_iterator it=operands.begin()+1;
8475
it!=operands.end(); it++)
8576
{
86-
if(it->type()!=expr.type())
87-
throw "multiplication with mixed types";
88-
89-
const bvt &op=convert_bv(*it);
77+
DATA_INVARIANT(
78+
it->type() == expr.type(),
79+
"multiplication operands should have same type as expression");
9080

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

9483
if(no_overflow)
9584
bv=bv_utils.multiplier_no_overflow(bv, op, rep);

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
}

src/solvers/flattening/boolbv_overflow.cpp

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,9 @@ literalt boolbvt::convert_overflow(const exprt &expr)
1919
if(expr.id()==ID_overflow_plus ||
2020
expr.id()==ID_overflow_minus)
2121
{
22-
if(operands.size()!=2)
23-
throw "operator "+expr.id_string()+" takes two operands";
22+
DATA_INVARIANT(
23+
operands.size() == 2,
24+
"expression " + expr.id_string() + " should have two operands");
2425

2526
const bvt &bv0=convert_bv(operands[0]);
2627
const bvt &bv1=convert_bv(operands[1]);
@@ -38,27 +39,25 @@ literalt boolbvt::convert_overflow(const exprt &expr)
3839
}
3940
else if(expr.id()==ID_overflow_mult)
4041
{
41-
if(operands.size()!=2)
42-
throw "operator "+expr.id_string()+" takes two operands";
42+
DATA_INVARIANT(
43+
operands.size() == 2,
44+
"overflow_mult expression should have two operands");
4345

4446
if(operands[0].type().id()!=ID_unsignedbv &&
4547
operands[0].type().id()!=ID_signedbv)
4648
return SUB::convert_rest(expr);
4749

4850
bvt bv0=convert_bv(operands[0]);
49-
bvt bv1=convert_bv(operands[1]);
50-
51-
if(bv0.size()!=bv1.size())
52-
throw "operand size mismatch on overflow-*";
51+
bvt bv1 = convert_bv(operands[1], bv0.size());
5352

5453
bv_utilst::representationt rep=
5554
operands[0].type().id()==ID_signedbv?bv_utilst::representationt::SIGNED:
5655
bv_utilst::representationt::UNSIGNED;
5756

58-
if(operands[0].type()!=operands[1].type())
59-
throw "operand type mismatch on overflow-*";
57+
DATA_INVARIANT(
58+
operands[0].type() == operands[1].type(),
59+
"operands of overflow_mult expression shall have same type");
6060

61-
DATA_INVARIANT(bv0.size()==bv1.size(), "operands size mismatch");
6261
std::size_t old_size=bv0.size();
6362
std::size_t new_size=old_size*2;
6463

@@ -97,8 +96,8 @@ literalt boolbvt::convert_overflow(const exprt &expr)
9796
}
9897
else if(expr.id() == ID_overflow_shl)
9998
{
100-
if(operands.size() != 2)
101-
throw "operator " + expr.id_string() + " takes two operands";
99+
DATA_INVARIANT(
100+
operands.size() == 2, "overflow_shl expression should have two operands");
102101

103102
const bvt &bv0=convert_bv(operands[0]);
104103
const bvt &bv1=convert_bv(operands[1]);
@@ -163,8 +162,9 @@ literalt boolbvt::convert_overflow(const exprt &expr)
163162
}
164163
else if(expr.id()==ID_overflow_unary_minus)
165164
{
166-
if(operands.size()!=1)
167-
throw "operator "+expr.id_string()+" takes one operand";
165+
DATA_INVARIANT(
166+
operands.size() == 1,
167+
"overflow_unary_minus expression should have one operand");
168168

169169
const bvt &bv=convert_bv(operands[0]);
170170

@@ -173,18 +173,19 @@ literalt boolbvt::convert_overflow(const exprt &expr)
173173
else if(has_prefix(expr.id_string(), "overflow-typecast-"))
174174
{
175175
std::size_t bits=unsafe_string2unsigned(id2string(expr.id()).substr(18));
176+
INVARIANT(bits != 0, "");
176177

177178
const exprt::operandst &operands=expr.operands();
178179

179-
if(operands.size()!=1)
180-
throw "operator "+expr.id_string()+" takes one operand";
180+
DATA_INVARIANT(
181+
operands.size() == 1,
182+
"expression " + expr.id_string() + " should have one operand");
181183

182184
const exprt &op=operands[0];
183185

184186
const bvt &bv=convert_bv(op);
185187

186-
if(bits>=bv.size() || bits==0)
187-
throw "overflow-typecast got wrong number of bits";
188+
INVARIANT(bits < bv.size(), "");
188189

189190
// signed or unsigned?
190191
if(op.type().id()==ID_signedbv)

0 commit comments

Comments
 (0)