Skip to content

Commit 6160036

Browse files
committed
Error handling cleanup in solvers/flattening
Files boolbv_map.cpp to boolbv_overflow.cpp
1 parent f2d33b8 commit 6160036

File tree

7 files changed

+99
-94
lines changed

7 files changed

+99
-94
lines changed

src/solvers/flattening/boolbv_map.cpp

Lines changed: 18 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,19 @@ 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(),
106+
"bit index shall be within bounds");
101107
map_bitt &mb=map_entry.literal_map[bit];
102108

103109
if(mb.is_set)
@@ -128,12 +134,16 @@ void boolbv_mapt::set_literals(
128134
forall_literals(it, literals)
129135
{
130136
const literalt &literal=*it;
131-
const std::size_t bit=it-literals.begin();
132137

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

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

139149
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();
@@ -46,22 +50,18 @@ bvt boolbvt::convert_member(const member_exprt &expr)
4650

4751
if(it->get_name()==component_name)
4852
{
49-
if(!base_type_eq(subtype, expr.type(), ns))
50-
{
51-
#if 0
52-
std::cout << "DEBUG " << expr.pretty() << "\n";
53-
#endif
54-
55-
error().source_location=expr.find_source_location();
56-
error() << "member: component type does not match: "
57-
<< subtype.pretty() << " vs. "
58-
<< expr.type().pretty() << eom;
59-
throw 0;
60-
}
53+
DATA_INVARIANT_WITH_DIAGNOSTICS(
54+
base_type_eq(subtype, expr.type(), ns),
55+
"struct component type shall match the member expression type",
56+
subtype.pretty(),
57+
expr.type().pretty());
6158

6259
bvt bv;
6360
bv.resize(sub_width);
64-
assert(offset+sub_width<=struct_bv.size());
61+
INVARIANT(
62+
offset + sub_width <= struct_bv.size(),
63+
"bitvector part corresponding to struct element shall be contained "
64+
"within the full struct bitvector");
6565

6666
for(std::size_t i=0; i<sub_width; i++)
6767
bv[i]=struct_bv[offset+i];
@@ -72,15 +72,10 @@ bvt boolbvt::convert_member(const member_exprt &expr)
7272
offset+=sub_width;
7373
}
7474

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

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: 19 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,36 @@ 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(
27+
!operands.empty(),
28+
"multiplication must have operands");
2629

2730
const exprt &op0=expr.op0();
2831

2932
bool no_overflow=expr.id()=="no-overflow-mult";
3033

34+
DATA_INVARIANT(
35+
op0->type() == expr.type(),
36+
"multiplication operands should have same type as expression");
37+
3138
if(expr.type().id()==ID_fixedbv)
3239
{
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";
40+
bv = convert_bv(op0, width);
4041

4142
std::size_t fraction_bits=
4243
to_fixedbv_type(expr.type()).get_fraction_bits();
4344

4445
for(exprt::operandst::const_iterator it=operands.begin()+1;
4546
it!=operands.end(); it++)
4647
{
47-
if(it->type()!=expr.type())
48-
throw "multiplication with mixed types";
48+
DATA_INVARIANT(
49+
it->type() == expr.type(),
50+
"multiplication operands should have same type as expression");
4951

5052
// do a sign extension by fraction_bits bits
5153
bv=bv_utils.sign_extension(bv, bv.size()+fraction_bits);
5254

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

5857
op=bv_utils.sign_extension(op, bv.size());
5958

@@ -68,28 +67,20 @@ bvt boolbvt::convert_mult(const exprt &expr)
6867
else if(expr.type().id()==ID_unsignedbv ||
6968
expr.type().id()==ID_signedbv)
7069
{
71-
if(op0.type()!=expr.type())
72-
throw "multiplication with mixed types";
73-
7470
bv_utilst::representationt rep=
7571
expr.type().id()==ID_signedbv?bv_utilst::representationt::SIGNED:
7672
bv_utilst::representationt::UNSIGNED;
7773

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

8376
for(exprt::operandst::const_iterator it=operands.begin()+1;
8477
it!=operands.end(); it++)
8578
{
86-
if(it->type()!=expr.type())
87-
throw "multiplication with mixed types";
88-
89-
const bvt &op=convert_bv(*it);
79+
DATA_INVARIANT(
80+
it->type() == expr.type(),
81+
"multiplication operands should have same type as expression");
9082

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

9485
if(no_overflow)
9586
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: 6 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,9 @@ 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(expr.id() == ID_onehot0, "");
33+
return !more_than_one_seen;
34+
}
3235
}

src/solvers/flattening/boolbv_overflow.cpp

Lines changed: 25 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,9 @@ 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,
101+
"overflow_shl expression should have two operands");
102102

103103
const bvt &bv0=convert_bv(operands[0]);
104104
const bvt &bv1=convert_bv(operands[1]);
@@ -163,8 +163,9 @@ literalt boolbvt::convert_overflow(const exprt &expr)
163163
}
164164
else if(expr.id()==ID_overflow_unary_minus)
165165
{
166-
if(operands.size()!=1)
167-
throw "operator "+expr.id_string()+" takes one operand";
166+
DATA_INVARIANT(
167+
operands.size() == 1,
168+
"overflow_unary_minus expression should have one operand");
168169

169170
const bvt &bv=convert_bv(operands[0]);
170171

@@ -173,18 +174,23 @@ literalt boolbvt::convert_overflow(const exprt &expr)
173174
else if(has_prefix(expr.id_string(), "overflow-typecast-"))
174175
{
175176
std::size_t bits=unsafe_string2unsigned(id2string(expr.id()).substr(18));
177+
INVARIANT(
178+
bits != 0,
179+
"");
176180

177181
const exprt::operandst &operands=expr.operands();
178182

179-
if(operands.size()!=1)
180-
throw "operator "+expr.id_string()+" takes one operand";
183+
DATA_INVARIANT(
184+
operands.size() == 1,
185+
"expression " + expr.id_string() + " should have one operand");
181186

182187
const exprt &op=operands[0];
183188

184189
const bvt &bv=convert_bv(op);
185190

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

189195
// signed or unsigned?
190196
if(op.type().id()==ID_signedbv)

0 commit comments

Comments
 (0)