Skip to content

Commit 6d22293

Browse files
committed
Error handling cleanup in solvers/flattening
1 parent 5ac1771 commit 6d22293

8 files changed

+103
-51
lines changed

src/solvers/flattening/boolbv_add_sub.cpp

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@ Author: Daniel Kroening, [email protected]
1515

1616
bvt boolbvt::convert_add_sub(const exprt &expr)
1717
{
18+
PRECONDITION(
19+
expr.id() == ID_plus || expr.id() == ID_minus ||
20+
expr.id() == "no-overflow-plus" || expr.id() == "no-overflow-minus");
21+
1822
const typet &type=ns.follow(expr.type());
1923

2024
if(type.id()!=ID_unsignedbv &&
@@ -33,17 +37,20 @@ bvt boolbvt::convert_add_sub(const exprt &expr)
3337

3438
const exprt::operandst &operands=expr.operands();
3539

36-
if(operands.empty())
37-
throw "operator "+expr.id_string()+" takes at least one operand";
40+
DATA_INVARIANT(
41+
!operands.empty(),
42+
"operator " + expr.id_string() + " takes at least one operand");
3843

3944
const exprt &op0=expr.op0();
4045
DATA_INVARIANT(
4146
op0.type() == type, "add/sub with mixed types:\n" + expr.pretty());
4247

4348
bvt bv=convert_bv(op0);
4449

45-
if(bv.size()!=width)
46-
throw "convert_add_sub: unexpected operand 0 width";
50+
INVARIANT(
51+
bv.size() == width,
52+
"the width of the bitvector resulting from the first operand should be "
53+
"equal to the width indicated by the expression type");
4754

4855
bool subtract=(expr.id()==ID_minus ||
4956
expr.id()=="no-overflow-minus");
@@ -69,17 +76,21 @@ bvt boolbvt::convert_add_sub(const exprt &expr)
6976

7077
const bvt &op=convert_bv(*it);
7178

72-
if(op.size()!=width)
73-
throw "convert_add_sub: unexpected operand width";
79+
INVARIANT(
80+
op.size() == width,
81+
"the width of the bitvector resulting from the expression operand should"
82+
"be equal to the width indicated by the expression type");
7483

7584
if(type.id()==ID_vector || type.id()==ID_complex)
7685
{
7786
const typet &subtype=ns.follow(type.subtype());
7887

7988
std::size_t sub_width=boolbv_width(subtype);
8089

81-
if(sub_width==0 || width%sub_width!=0)
82-
throw "convert_add_sub: unexpected vector operand width";
90+
INVARIANT(sub_width != 0, "vector elements shall have nonzero bit width");
91+
INVARIANT(
92+
width % sub_width == 0,
93+
"total vector bit width shall be a multiple of the element bit width");
8394

8495
std::size_t size=width/sub_width;
8596
bv.resize(width);
@@ -91,7 +102,8 @@ bvt boolbvt::convert_add_sub(const exprt &expr)
91102

92103
for(std::size_t j=0; j<tmp_op.size(); j++)
93104
{
94-
assert(i*sub_width+j<op.size());
105+
INVARIANT(
106+
i * sub_width + j < op.size(), "bit index shall be within bounds");
95107
tmp_op[j]=op[i*sub_width+j];
96108
}
97109

@@ -100,7 +112,8 @@ bvt boolbvt::convert_add_sub(const exprt &expr)
100112

101113
for(std::size_t j=0; j<tmp_result.size(); j++)
102114
{
103-
assert(i*sub_width+j<bv.size());
115+
INVARIANT(
116+
i * sub_width + j < bv.size(), "bit index shall be within bounds");
104117
tmp_result[j]=bv[i*sub_width+j];
105118
}
106119

@@ -113,11 +126,14 @@ bvt boolbvt::convert_add_sub(const exprt &expr)
113126
else
114127
tmp_result=bv_utils.add_sub(tmp_result, tmp_op, subtract);
115128

116-
assert(tmp_result.size()==sub_width);
129+
INVARIANT(
130+
tmp_result.size() == sub_width,
131+
"applying the add/sub operation shall not change the bitwidth");
117132

118133
for(std::size_t j=0; j<tmp_result.size(); j++)
119134
{
120-
assert(i*sub_width+j<bv.size());
135+
INVARIANT(
136+
i * sub_width + j < bv.size(), "bit index shall be within bounds");
121137
bv[i*sub_width+j]=tmp_result[j];
122138
}
123139
}

src/solvers/flattening/boolbv_array.cpp

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,10 @@ Author: Daniel Kroening, [email protected]
66
77
\*******************************************************************/
88

9-
109
#include "boolbv.h"
1110

11+
#include <util/invariant.h>
12+
1213
bvt boolbvt::convert_array(const exprt &expr)
1314
{
1415
std::size_t width=boolbv_width(expr.type());
@@ -18,9 +19,11 @@ bvt boolbvt::convert_array(const exprt &expr)
1819

1920
if(expr.type().id()==ID_array)
2021
{
21-
assert(expr.has_operands());
22+
DATA_INVARIANT(
23+
expr.has_operands(),
24+
"the bit width being nonzero implies that the array has a nonzero size "
25+
"in which case the array shall have operands");
2226
const exprt::operandst &operands=expr.operands();
23-
assert(!operands.empty());
2427
std::size_t op_width=width/operands.size();
2528

2629
bvt bv;
@@ -30,8 +33,10 @@ bvt boolbvt::convert_array(const exprt &expr)
3033
{
3134
const bvt &tmp=convert_bv(*it);
3235

33-
if(tmp.size()!=op_width)
34-
throw "convert_array: unexpected operand width";
36+
INVARIANT(
37+
tmp.size() == op_width,
38+
"bit width of an operand bitvector shall be equal to the total bit "
39+
"width of the array divided by the number of elements");
3540

3641
forall_literals(it2, tmp)
3742
bv.push_back(*it2);

src/solvers/flattening/boolbv_array_of.cpp

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,13 @@ Author: Daniel Kroening, [email protected]
99
#include "boolbv.h"
1010

1111
#include <util/arith_tools.h>
12+
#include <util/invariant.h>
1213
#include <util/std_types.h>
1314

1415
bvt boolbvt::convert_array_of(const array_of_exprt &expr)
1516
{
16-
if(expr.type().id()!=ID_array)
17-
throw "array_of must be array-typed";
17+
DATA_INVARIANT(
18+
expr.type().id() == ID_array, "array_of expression shall have array type");
1819

1920
const array_typet &array_type=to_array_type(expr.type());
2021

@@ -45,8 +46,10 @@ bvt boolbvt::convert_array_of(const array_of_exprt &expr)
4546
bvt bv;
4647
bv.resize(width);
4748

48-
if(size*tmp.size()!=width)
49-
throw "convert_array_of: unexpected operand width";
49+
INVARIANT(
50+
size * tmp.size() == width,
51+
"total array bit width shall equal the number of elements times the "
52+
"element bit with");
5053

5154
std::size_t offset=0;
5255

@@ -56,7 +59,8 @@ bvt boolbvt::convert_array_of(const array_of_exprt &expr)
5659
bv[offset]=tmp[j];
5760
}
5861

59-
assert(offset==bv.size());
62+
INVARIANT(
63+
offset == bv.size(), "we shall have iterated over all the bit indices");
6064

6165
return bv;
6266
}

src/solvers/flattening/boolbv_byte_update.cpp

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,18 @@ Author: Daniel Kroening, [email protected]
99
#include "boolbv.h"
1010

1111
#include <iostream>
12-
#include <cassert>
1312

1413
#include <util/arith_tools.h>
1514
#include <util/byte_operators.h>
15+
#include <util/invariant.h>
1616

1717
#include "bv_endianness_map.h"
1818

1919
bvt boolbvt::convert_byte_update(const byte_update_exprt &expr)
2020
{
21-
if(expr.operands().size()!=3)
22-
throw "byte_update takes three operands";
21+
DATA_INVARIANT(
22+
expr.operands().size() == 3,
23+
"byte_update expression shall have three operands");
2324

2425
const exprt &op=expr.op0();
2526
const exprt &offset_expr=expr.offset();
@@ -70,8 +71,11 @@ bvt boolbvt::convert_byte_update(const byte_update_exprt &expr)
7071
size_t index_op=map_op.map_bit(offset_i+i);
7172
size_t index_value=map_value.map_bit(i);
7273

73-
assert(index_op<bv.size());
74-
assert(index_value<value_bv.size());
74+
INVARIANT(
75+
index_op < bv.size(), "bit vector index shall be within bounds");
76+
INVARIANT(
77+
index_value < value_bv.size(),
78+
"bit vector index shall be within bounds");
7579

7680
bv[index_op]=value_bv[index_value];
7781
}

src/solvers/flattening/boolbv_case.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ Author: Daniel Kroening, [email protected]
1212

1313
bvt boolbvt::convert_case(const exprt &expr)
1414
{
15+
PRECONDITION(expr.id() == ID_case);
16+
1517
const std::vector<exprt> &operands=expr.operands();
1618

1719
std::size_t width=boolbv_width(expr.type());
@@ -26,11 +28,11 @@ bvt boolbvt::convert_case(const exprt &expr)
2628
Forall_literals(it, bv)
2729
*it=prop.new_variable();
2830

29-
if(operands.size()<3)
30-
throw "case takes at least three operands";
31+
DATA_INVARIANT(
32+
operands.size() >= 3, "case should have at least three operands");
3133

32-
if((operands.size()%2)!=1)
33-
throw "number of case operands must be odd";
34+
DATA_INVARIANT(
35+
operands.size() % 2 == 1, "number of case operands should be odd");
3436

3537
enum { FIRST, COMPARE, VALUE } what=FIRST;
3638
bvt compare_bv;
@@ -81,7 +83,7 @@ bvt boolbvt::convert_case(const exprt &expr)
8183
break;
8284

8385
default:
84-
assert(false);
86+
UNREACHABLE;
8587
}
8688
}
8789

src/solvers/flattening/boolbv_complex.cpp

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,14 @@ Author: Daniel Kroening, [email protected]
66
77
\*******************************************************************/
88

9-
109
#include "boolbv.h"
1110

11+
#include <util/invariant.h>
12+
1213
bvt boolbvt::convert_complex(const exprt &expr)
1314
{
15+
PRECONDITION(expr.id() == ID_complex);
16+
1417
std::size_t width=boolbv_width(expr.type());
1518

1619
if(width==0)
@@ -31,8 +34,10 @@ bvt boolbvt::convert_complex(const exprt &expr)
3134
{
3235
const bvt &tmp=convert_bv(*it);
3336

34-
if(tmp.size()!=op_width)
35-
throw "convert_complex: unexpected operand width";
37+
INVARIANT(
38+
tmp.size() == op_width,
39+
"bit width of operand bitvector shall be equal to the total bit "
40+
"width divided by the number of operands");
3641

3742
forall_literals(it2, tmp)
3843
bv.push_back(*it2);
@@ -47,29 +52,31 @@ bvt boolbvt::convert_complex(const exprt &expr)
4752

4853
bvt boolbvt::convert_complex_real(const complex_real_exprt &expr)
4954
{
55+
PRECONDITION(expr.id() == ID_complex_real);
56+
5057
std::size_t width=boolbv_width(expr.type());
5158

5259
if(width==0)
5360
return conversion_failed(expr);
5461

55-
bvt bv = convert_bv(expr.op());
62+
bvt bv = convert_bv(expr.op(), width * 2);
5663

57-
assert(bv.size()==width*2);
5864
bv.resize(width); // chop
5965

6066
return bv;
6167
}
6268

6369
bvt boolbvt::convert_complex_imag(const complex_imag_exprt &expr)
6470
{
71+
PRECONDITION(expr.id() == ID_complex_imag);
72+
6573
std::size_t width=boolbv_width(expr.type());
6674

6775
if(width==0)
6876
return conversion_failed(expr);
6977

70-
bvt bv = convert_bv(expr.op());
78+
bvt bv = convert_bv(expr.op(), width * 2);
7179

72-
assert(bv.size()==width*2);
7380
bv.erase(bv.begin(), bv.begin()+width);
7481

7582
return bv;

src/solvers/flattening/boolbv_concatenation.cpp

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,23 @@ Author: Daniel Kroening, [email protected]
66
77
\*******************************************************************/
88

9-
109
#include "boolbv.h"
1110

11+
#include <util/invariant.h>
12+
1213
bvt boolbvt::convert_concatenation(const exprt &expr)
1314
{
15+
PRECONDITION(expr.id() == ID_concatenation);
16+
1417
std::size_t width=boolbv_width(expr.type());
1518

1619
if(width==0)
1720
return conversion_failed(expr);
1821

1922
const exprt::operandst &operands=expr.operands();
2023

21-
if(operands.empty())
22-
throw "concatenation takes at least one operand";
24+
DATA_INVARIANT(
25+
!operands.empty(), "concatentation shall have at least one operand");
2326

2427
std::size_t offset=width;
2528
bvt bv;
@@ -29,17 +32,20 @@ bvt boolbvt::convert_concatenation(const exprt &expr)
2932
{
3033
const bvt &op=convert_bv(*it);
3134

32-
if(op.size()>offset)
33-
throw "concatenation operand width too big";
35+
INVARIANT(
36+
op.size() <= offset,
37+
"concatentation operand must fit into the result bitvector");
3438

3539
offset-=op.size();
3640

3741
for(std::size_t i=0; i<op.size(); i++)
3842
bv[offset+i]=op[i];
3943
}
4044

41-
if(offset!=0)
42-
throw "concatenation operand width too small";
45+
INVARIANT(
46+
offset == 0,
47+
"all bits in the result bitvector must have been filled up by the "
48+
"concatentation operands");
4349

4450
return bv;
4551
}

0 commit comments

Comments
 (0)