8
8
9
9
#include " boolbv.h"
10
10
11
- #include < cassert >
11
+ #include < algorithm >
12
12
#include < map>
13
13
#include < set>
14
14
@@ -36,7 +36,10 @@ bool boolbvt::literal(
36
36
{
37
37
if (expr.type ().id ()==ID_bool)
38
38
{
39
- assert (bit==0 );
39
+ INVARIANT (
40
+ bit == 0 ,
41
+ " boolean expressions shall be represented by a single bit and hence the "
42
+ " only valid bit index is 0" );
40
43
return prop_conv_solvert::literal (to_symbol_expr (expr), dest);
41
44
}
42
45
else
@@ -54,7 +57,8 @@ bool boolbvt::literal(
54
57
55
58
const boolbv_mapt::map_entryt &map_entry=it_m->second ;
56
59
57
- assert (bit<map_entry.literal_map .size ());
60
+ INVARIANT (
61
+ bit < map_entry.literal_map .size (), " bit index shall be within bounds" );
58
62
if (!map_entry.literal_map [bit].is_set )
59
63
return true ;
60
64
@@ -66,15 +70,11 @@ bool boolbvt::literal(
66
70
const index_exprt &index_expr=to_index_expr (expr);
67
71
68
72
std::size_t element_width=boolbv_width (index_expr.type ());
73
+ CHECK_RETURN (element_width != 0 );
69
74
70
- if (element_width==0 )
71
- throw " literal expects a bit-vector type" ;
75
+ mp_integer index = numeric_cast_v<mp_integer>(index_expr.index ());
72
76
73
- mp_integer index ;
74
- if (to_integer (index_expr.index (), index ))
75
- throw " literal expects constant index" ;
76
-
77
- std::size_t offset=integer2unsigned (index *element_width);
77
+ std::size_t offset = numeric_cast_v<std::size_t >(index * element_width);
78
78
79
79
return literal (index_expr.array (), bit+offset, dest);
80
80
}
@@ -96,18 +96,16 @@ bool boolbvt::literal(
96
96
return literal (expr.op0 (), bit+offset, dest);
97
97
98
98
std::size_t element_width=boolbv_width (subtype);
99
-
100
- if (element_width==0 )
101
- throw " literal expects a bit-vector type" ;
99
+ CHECK_RETURN (element_width != 0 );
102
100
103
101
offset+=element_width;
104
102
}
105
103
106
- throw " failed to find component" ;
104
+ INVARIANT ( false , " struct type should have accessed component" ) ;
107
105
}
108
106
}
109
107
110
- throw " found no literal for expression " ;
108
+ INVARIANT ( false , " expression should have a corresponding literal " ) ;
111
109
}
112
110
113
111
const bvt &
@@ -304,18 +302,6 @@ bvt boolbvt::convert_bitvector(const exprt &expr)
304
302
return convert_not (to_not_expr (expr));
305
303
else if (expr.id ()==ID_power)
306
304
return convert_power (to_binary_expr (expr));
307
- else if (expr.id ()==ID_float_debug1 ||
308
- expr.id ()==ID_float_debug2)
309
- {
310
- assert (expr.operands ().size ()==2 );
311
- bvt bv0=convert_bitvector (expr.op0 ());
312
- bvt bv1=convert_bitvector (expr.op1 ());
313
- float_utilst float_utils (prop, to_floatbv_type (expr.type ()));
314
- bvt bv=expr.id ()==ID_float_debug1?
315
- float_utils.debug1 (bv0, bv1):
316
- float_utils.debug2 (bv0, bv1);
317
- return bv;
318
- }
319
305
else if (expr.id () == ID_popcount)
320
306
return convert_bv (lower_popcount (to_popcount_expr (expr), ns));
321
307
@@ -329,8 +315,8 @@ bvt boolbvt::convert_lambda(const exprt &expr)
329
315
if (width==0 )
330
316
return conversion_failed (expr);
331
317
332
- if (expr. operands (). size ()!= 2 )
333
- throw " lambda takes two operands" ;
318
+ DATA_INVARIANT (
319
+ expr. operands (). size () == 2 , " lambda expression should have two operands" ) ;
334
320
335
321
if (expr.type ().id ()!=ID_array)
336
322
return conversion_failed (expr);
@@ -357,10 +343,12 @@ bvt boolbvt::convert_lambda(const exprt &expr)
357
343
358
344
const bvt &tmp=convert_bv (expr_op1);
359
345
360
- std::size_t offset=integer2unsigned (i*tmp.size ());
346
+ INVARIANT (
347
+ size * tmp.size () == width,
348
+ " total bitvector width shall equal the number of operands times the size "
349
+ " per operand" );
361
350
362
- if (size*tmp.size ()!=width)
363
- throw " convert_lambda: unexpected operand width" ;
351
+ std::size_t offset = numeric_cast_v<std::size_t >(i * tmp.size ());
364
352
365
353
for (std::size_t j=0 ; j<tmp.size (); j++)
366
354
bv[offset+j]=tmp[j];
@@ -398,10 +386,8 @@ bvt boolbvt::convert_symbol(const exprt &expr)
398
386
bvt bv;
399
387
bv.resize (width);
400
388
401
- const irep_idt &identifier=expr.get (ID_identifier);
402
-
403
- if (identifier.empty ())
404
- throw " convert_symbol got empty identifier" ;
389
+ const irep_idt &identifier = expr.get (ID_identifier);
390
+ CHECK_RETURN (!identifier.empty ());
405
391
406
392
if (width==0 )
407
393
{
@@ -412,13 +398,15 @@ bvt boolbvt::convert_symbol(const exprt &expr)
412
398
{
413
399
map.get_literals (identifier, type, width, bv);
414
400
415
- forall_literals (it, bv)
416
- if (it->var_no ()>=prop.no_variables () &&
417
- !it->is_constant ())
418
- {
419
- error () << identifier << eom;
420
- assert (false );
421
- }
401
+ INVARIANT_WITH_DIAGNOSTICS (
402
+ std::all_of (
403
+ bv.begin (),
404
+ bv.end (),
405
+ [this ](const literalt &l) {
406
+ return l.var_no () < prop.no_variables () || l.is_constant ();
407
+ }),
408
+ " variable number of non-constant literals should be within bounds" ,
409
+ id2string (identifier));
422
410
}
423
411
424
412
return bv;
0 commit comments