11
11
#include < util/arith_tools.h>
12
12
#include < util/c_types.h>
13
13
#include < util/config.h>
14
+ #include < util/exception_utils.h>
14
15
#include < util/pointer_offset_size.h>
15
16
16
17
literalt bv_pointerst::convert_rest (const exprt &expr)
17
18
{
18
- if (expr.type ().id ()!=ID_bool)
19
- throw " bv_pointerst::convert_rest got non-boolean operand" ;
19
+ PRECONDITION (expr.type ().id () == ID_bool);
20
20
21
21
const exprt::operandst &operands=expr.operands ();
22
22
@@ -112,9 +112,6 @@ bool bv_pointerst::convert_address_of_rec(
112
112
}
113
113
else if (expr.id ()==ID_index)
114
114
{
115
- if (expr.operands ().size ()!=2 )
116
- throw " index takes two operands" ;
117
-
118
115
const index_exprt &index_expr=to_index_expr (expr);
119
116
const exprt &array=index_expr.array ();
120
117
const exprt &index =index_expr.index ();
@@ -182,12 +179,13 @@ bool bv_pointerst::convert_address_of_rec(
182
179
// add offset
183
180
offset_arithmetic (bv, offset);
184
181
}
185
- else if (struct_op_type. id ()==ID_union)
182
+ else
186
183
{
184
+ INVARIANT (
185
+ struct_op_type.id () == ID_union,
186
+ " member expression should operate on struct or union" );
187
187
// nothing to do, all members have offset 0
188
188
}
189
- else
190
- throw " member takes struct or union operand" ;
191
189
192
190
return false ;
193
191
}
@@ -222,8 +220,7 @@ bool bv_pointerst::convert_address_of_rec(
222
220
223
221
bvt bv_pointerst::convert_pointer_type (const exprt &expr)
224
222
{
225
- if (expr.type ().id ()!=ID_pointer)
226
- throw " convert_pointer_type got non-pointer type" ;
223
+ PRECONDITION (expr.type ().id () == ID_pointer);
227
224
228
225
// make sure the config hasn't been changed
229
226
PRECONDITION (bits==boolbv_width (expr.type ()));
@@ -252,10 +249,9 @@ bvt bv_pointerst::convert_pointer_type(const exprt &expr)
252
249
}
253
250
else if (expr.id ()==ID_typecast)
254
251
{
255
- if (expr.operands ().size ()!=1 )
256
- throw " typecast takes one operand" ;
252
+ const typecast_exprt &typecast_expr = to_typecast_expr (expr);
257
253
258
- const exprt &op=expr. op0 ();
254
+ const exprt &op = typecast_expr. op ();
259
255
const typet &op_type=ns.follow (op.type ());
260
256
261
257
if (op_type.id ()==ID_pointer)
@@ -288,15 +284,14 @@ bvt bv_pointerst::convert_pointer_type(const exprt &expr)
288
284
}
289
285
else if (expr.id ()==ID_address_of)
290
286
{
291
- if (expr.operands ().size ()!=1 )
292
- throw expr.id_string ()+" takes one operand" ;
287
+ const address_of_exprt &address_of_expr = to_address_of_expr (expr);
293
288
294
289
bvt bv;
295
290
bv.resize (bits);
296
291
297
- if (convert_address_of_rec (expr. op0 (), bv))
292
+ if (convert_address_of_rec (address_of_expr. op (), bv))
298
293
{
299
- conversion_failed (expr , bv);
294
+ conversion_failed (address_of_expr , bv);
300
295
return bv;
301
296
}
302
297
@@ -324,15 +319,14 @@ bvt bv_pointerst::convert_pointer_type(const exprt &expr)
324
319
{
325
320
// this has to be pointer plus integer
326
321
327
- if (expr.operands ().size ()<2 )
328
- throw " operator + takes at least two operands" ;
322
+ const plus_exprt &plus_expr = to_plus_expr (expr);
329
323
330
324
bvt bv;
331
325
332
326
mp_integer size=0 ;
333
327
std::size_t count=0 ;
334
328
335
- forall_operands (it, expr )
329
+ forall_operands (it, plus_expr )
336
330
{
337
331
if (it->type ().id ()==ID_pointer)
338
332
{
@@ -356,14 +350,13 @@ bvt bv_pointerst::convert_pointer_type(const exprt &expr)
356
350
}
357
351
}
358
352
359
- if (count==0 )
360
- throw " found no pointer in pointer-type sum" ;
361
- else if (count!=1 )
362
- throw " found more than one pointer in sum" ;
353
+ INVARIANT (
354
+ count == 1 ,
355
+ " there should be exactly one pointer-type operand in a pointer-type sum" );
363
356
364
357
bvt sum=bv_utils.build_constant (0 , bits);
365
358
366
- forall_operands (it, expr )
359
+ forall_operands (it, plus_expr )
367
360
{
368
361
if (it->type ().id ()==ID_pointer)
369
362
continue ;
@@ -372,7 +365,7 @@ bvt bv_pointerst::convert_pointer_type(const exprt &expr)
372
365
it->type ().id ()!=ID_signedbv)
373
366
{
374
367
bvt bv;
375
- conversion_failed (expr , bv);
368
+ conversion_failed (plus_expr , bv);
376
369
return bv;
377
370
}
378
371
@@ -381,9 +374,7 @@ bvt bv_pointerst::convert_pointer_type(const exprt &expr)
381
374
bv_utilst::representationt::UNSIGNED;
382
375
383
376
bvt op=convert_bv (*it);
384
-
385
- if (op.empty ())
386
- throw " unexpected pointer arithmetic operand width" ;
377
+ CHECK_RETURN (!op.empty ());
387
378
388
379
// we cut any extra bits off
389
380
@@ -403,27 +394,28 @@ bvt bv_pointerst::convert_pointer_type(const exprt &expr)
403
394
{
404
395
// this is pointer-integer
405
396
406
- if (expr.operands ().size ()!=2 )
407
- throw " operator " +expr.id_string ()+" takes two operands" ;
397
+ const minus_exprt &minus_expr = to_minus_expr (expr);
408
398
409
- if (expr.op0 ().type ().id ()!=ID_pointer)
410
- throw " found no pointer in pointer type in difference" ;
399
+ INVARIANT (
400
+ minus_expr.op0 ().type ().id () == ID_pointer,
401
+ " first operand should be of pointer type" );
411
402
412
403
bvt bv;
413
404
414
- if (expr.op1 ().type ().id ()!=ID_unsignedbv &&
415
- expr.op1 ().type ().id ()!=ID_signedbv)
405
+ if (
406
+ minus_expr.op1 ().type ().id () != ID_unsignedbv &&
407
+ minus_expr.op1 ().type ().id () != ID_signedbv)
416
408
{
417
409
bvt bv;
418
- conversion_failed (expr , bv);
410
+ conversion_failed (minus_expr , bv);
419
411
return bv;
420
412
}
421
413
422
- const unary_minus_exprt neg_op1 (expr .op1 ());
414
+ const unary_minus_exprt neg_op1 (minus_expr .op1 ());
423
415
424
- bv= convert_bv (expr .op0 ());
416
+ bv = convert_bv (minus_expr .op0 ());
425
417
426
- typet pointer_sub_type=expr .op0 ().type ().subtype ();
418
+ typet pointer_sub_type = minus_expr .op0 ().type ().subtype ();
427
419
mp_integer element_size;
428
420
429
421
if (pointer_sub_type.id ()==ID_empty)
@@ -462,11 +454,15 @@ bvt bv_pointerst::convert_pointer_type(const exprt &expr)
462
454
{
463
455
return SUB::convert_byte_extract (to_byte_extract_expr (expr));
464
456
}
465
- else if (
466
- expr.id () == ID_byte_update_little_endian ||
467
- expr.id () == ID_byte_update_big_endian)
457
+ else
468
458
{
469
- throw " byte-wise updates of pointers are unsupported" ;
459
+ INVARIANT (
460
+ expr.id () != ID_byte_update_little_endian,
461
+ " byte-wise pointer updates are unsupported" );
462
+
463
+ INVARIANT (
464
+ expr.id () != ID_byte_update_big_endian,
465
+ " byte-wise pointer updates are unsupported" );
470
466
}
471
467
472
468
return conversion_failed (expr);
@@ -723,11 +719,13 @@ void bv_pointerst::add_addr(const exprt &expr, bvt &bv)
723
719
std::size_t a=pointer_logic.add_object (expr);
724
720
725
721
const std::size_t max_objects=std::size_t (1 )<<object_bits;
722
+
726
723
if (a==max_objects)
727
- throw
728
- " too many addressed objects: maximum number of objects is set to 2^n=" +
729
- std::to_string (max_objects)+" (with n=" +std::to_string (object_bits)+" ); " +
730
- " use the `--object-bits n` option to increase the maximum number" ;
724
+ throw analysis_exceptiont (
725
+ " too many addressed objects: maximum number of objects is set to 2^n=" +
726
+ std::to_string (max_objects) + " (with n=" + std::to_string (object_bits) +
727
+ " ); " +
728
+ " use the `--object-bits n` option to increase the maximum number" );
731
729
732
730
encode (a, bv);
733
731
}
0 commit comments