@@ -51,12 +51,15 @@ static exprt unpack_rec(
51
51
mp_integer element_width=pointer_offset_bits (subtype, ns);
52
52
// this probably doesn't really matter
53
53
#if 0
54
- if(element_width<=0)
55
- throw "cannot unpack array with non-constant element width:\n"+
56
- type.pretty();
57
- else if(element_width%8!=0)
58
- throw "cannot unpack array of non-byte aligned elements:\n"+
59
- type.pretty();
54
+ INVARIANT(
55
+ element_width > 0,
56
+ "element width of array should be constant",
57
+ irep_pretty_diagnosticst(type));
58
+
59
+ INVARIANT(
60
+ element_width % 8 == 0,
61
+ "elements in array should be byte-aligned",
62
+ irep_pretty_diagnosticst(type));
60
63
#endif
61
64
62
65
if (!unpack_byte_array && element_width==8 )
@@ -199,8 +202,6 @@ exprt flatten_byte_extract(
199
202
// big-endian: (short)concatenation(01,02)=0x0102
200
203
// little-endian: (short)concatenation(03,04)=0x0304
201
204
202
- assert (src.operands ().size ()==2 );
203
-
204
205
PRECONDITION (
205
206
src.id () == ID_byte_extract_little_endian ||
206
207
src.id () == ID_byte_extract_big_endian);
@@ -345,14 +346,14 @@ exprt flatten_byte_update(
345
346
const namespacet &ns,
346
347
bool negative_offset)
347
348
{
348
- assert (src.operands ().size ()== 3 );
349
+ mp_integer element_size = pointer_offset_size (src.value ().type (), ns );
349
350
350
- mp_integer element_size=
351
- pointer_offset_size (src. op2 (). type (), ns);
352
- if (element_size< 0 )
353
- throw " byte_update of unknown width: \n " +src. pretty ( );
351
+ INVARIANT_WITH_DIAGNOSTICS (
352
+ element_size >= 0 ,
353
+ " size of type in bytes must be known " ,
354
+ irep_pretty_diagnosticst (src) );
354
355
355
- const typet &t= ns.follow (src.op0 ().type ());
356
+ const typet &t = ns.follow (src.op ().type ());
356
357
357
358
if (t.id ()==ID_array)
358
359
{
@@ -368,44 +369,48 @@ exprt flatten_byte_update(
368
369
{
369
370
mp_integer sub_size=pointer_offset_size (subtype, ns);
370
371
371
- if (sub_size==-1 )
372
- throw " can't flatten byte_update for sub-type without size" ;
372
+ INVARIANT (
373
+ sub_size >= 0 ,
374
+ " bit width (rounded to full bytes) of subtype must be known" );
373
375
374
376
// byte array?
375
377
if (sub_size==1 )
376
378
{
377
379
// apply 'array-update-with' element_size times
378
- exprt result= src.op0 ();
380
+ exprt result = src.op ();
379
381
380
382
for (mp_integer i=0 ; i<element_size; ++i)
381
383
{
382
- exprt i_expr= from_integer (i, ns.follow (src.op1 ().type ()));
384
+ exprt i_expr = from_integer (i, ns.follow (src.offset ().type ()));
383
385
384
386
exprt new_value;
385
387
386
388
if (i==0 && element_size==1 ) // bytes?
387
389
{
388
- new_value= src.op2 ();
390
+ new_value = src.value ();
389
391
if (new_value.type ()!=subtype)
390
392
new_value.make_typecast (subtype);
391
393
}
392
394
else
393
395
{
396
+ INVARIANT (
397
+ src.id () == ID_byte_update_little_endian ||
398
+ src.id () == ID_byte_update_big_endian,
399
+ " byte update expression should either be little or big endian" );
400
+
394
401
byte_extract_exprt byte_extract_expr (
395
- src.id ()==ID_byte_update_little_endian?
396
- ID_byte_extract_little_endian:
397
- src.id ()==ID_byte_update_big_endian?
398
- ID_byte_extract_big_endian:
399
- throw " unexpected src.id() in flatten_byte_update" ,
402
+ src.id () == ID_byte_update_little_endian
403
+ ? ID_byte_extract_little_endian
404
+ : ID_byte_extract_big_endian,
400
405
subtype);
401
406
402
- byte_extract_expr.op ()= src.op2 ();
407
+ byte_extract_expr.op () = src.value ();
403
408
byte_extract_expr.offset ()=i_expr;
404
409
405
410
new_value=flatten_byte_extract (byte_extract_expr, ns);
406
411
}
407
412
408
- const plus_exprt where (src.op1 (), i_expr);
413
+ const plus_exprt where (src.offset (), i_expr);
409
414
410
415
with_exprt with_expr (result, where, new_value);
411
416
with_expr.type ()=src.type ();
@@ -417,34 +422,34 @@ exprt flatten_byte_update(
417
422
}
418
423
else // sub_size!=1
419
424
{
420
- exprt result= src.op0 ();
425
+ exprt result = src.op ();
421
426
422
427
// Number of potentially affected array cells:
423
428
mp_integer num_elements=
424
429
element_size/sub_size+((element_size%sub_size==0 )?1 :2 );
425
430
426
- const auto &offset_type= ns.follow (src.op1 ().type ());
431
+ const auto &offset_type = ns.follow (src.offset ().type ());
427
432
exprt zero_offset=from_integer (0 , offset_type);
428
433
429
434
exprt sub_size_expr=from_integer (sub_size, offset_type);
430
435
exprt element_size_expr=from_integer (element_size, offset_type);
431
436
432
437
// First potentially affected cell:
433
- div_exprt first_cell (src.op1 (), sub_size_expr);
438
+ div_exprt first_cell (src.offset (), sub_size_expr);
434
439
435
440
for (mp_integer i=0 ; i<num_elements; ++i)
436
441
{
437
442
plus_exprt cell_index (first_cell, from_integer (i, offset_type));
438
443
mult_exprt cell_offset (cell_index, sub_size_expr);
439
- index_exprt old_cell_value (src.op0 (), cell_index, subtype);
444
+ index_exprt old_cell_value (src.op (), cell_index, subtype);
440
445
bool is_first_cell=i==0 ;
441
446
bool is_last_cell=i==num_elements-1 ;
442
447
443
448
exprt new_value;
444
449
exprt stored_value_offset;
445
450
if (element_size<=sub_size)
446
451
{
447
- new_value= src.op2 ();
452
+ new_value = src.value ();
448
453
stored_value_offset=zero_offset;
449
454
}
450
455
else
@@ -458,19 +463,20 @@ exprt flatten_byte_update(
458
463
stored_value_offset=
459
464
from_integer (element_size-sub_size, offset_type);
460
465
else
461
- stored_value_offset=minus_exprt (cell_offset, src.op1 ());
462
-
463
- auto extract_opcode=
464
- src.id ()==ID_byte_update_little_endian ?
465
- ID_byte_extract_little_endian :
466
- src.id ()==ID_byte_update_big_endian ?
467
- ID_byte_extract_big_endian :
468
- throw " unexpected src.id() in flatten_byte_update" ;
466
+ stored_value_offset = minus_exprt (cell_offset, src.offset ());
467
+
468
+ INVARIANT (
469
+ src.id () == ID_byte_update_little_endian ||
470
+ src.id () == ID_byte_update_big_endian,
471
+ " byte update expression should either be little or big endian" );
472
+
469
473
byte_extract_exprt byte_extract_expr (
470
- extract_opcode,
471
- element_size<sub_size ? src.op2 ().type () : subtype);
474
+ src.id () == ID_byte_update_little_endian
475
+ ? ID_byte_extract_little_endian
476
+ : ID_byte_extract_big_endian,
477
+ element_size < sub_size ? src.value ().type () : subtype);
472
478
473
- byte_extract_expr.op ()= src.op2 ();
479
+ byte_extract_expr.op () = src.value ();
474
480
byte_extract_expr.offset ()=stored_value_offset;
475
481
476
482
new_value=flatten_byte_extract (byte_extract_expr, ns);
@@ -482,15 +488,13 @@ exprt flatten_byte_update(
482
488
// target array cell.
483
489
exprt overwrite_offset;
484
490
if (is_first_cell)
485
- overwrite_offset= mod_exprt (src.op1 (), sub_size_expr);
491
+ overwrite_offset = mod_exprt (src.offset (), sub_size_expr);
486
492
else if (is_last_cell)
487
493
{
488
494
// This is intentionally negated; passing is_last_cell
489
495
// to flatten below leads to it being negated again later.
490
- overwrite_offset=
491
- minus_exprt (
492
- minus_exprt (cell_offset, src.op1 ()),
493
- stored_value_offset);
496
+ overwrite_offset = minus_exprt (
497
+ minus_exprt (cell_offset, src.offset ()), stored_value_offset);
494
498
}
495
499
else
496
500
overwrite_offset=zero_offset;
@@ -517,9 +521,10 @@ exprt flatten_byte_update(
517
521
}
518
522
else
519
523
{
520
- throw
521
- " flatten_byte_update can only do arrays of scalars right now, "
522
- " but got " +subtype.id_string ();
524
+ PRECONDITION_WITH_DIAGNOSTICS (
525
+ false ,
526
+ " flatten_byte_update can only do arrays of scalars right now" ,
527
+ subtype.id_string ());
523
528
}
524
529
}
525
530
else if (t.id ()==ID_signedbv ||
@@ -530,11 +535,12 @@ exprt flatten_byte_update(
530
535
{
531
536
// do a shift, mask and OR
532
537
mp_integer type_width=pointer_offset_bits (t, ns);
533
- assert (type_width> 0 );
538
+ CHECK_RETURN (type_width > 0 );
534
539
std::size_t width=integer2size_t (type_width);
535
540
536
- if (element_size*8 >width)
537
- throw " flatten_byte_update to update element that is too large" ;
541
+ INVARIANT (
542
+ element_size * 8 <= width,
543
+ " element bit width must not be larger than width indicated by type" );
538
544
539
545
// build mask
540
546
exprt mask=
@@ -544,16 +550,16 @@ exprt flatten_byte_update(
544
550
exprt value_extended;
545
551
546
552
if (width>integer2unsigned (element_size)*8 )
547
- value_extended=
548
- concatenation_exprt (
549
- from_integer (
550
- 0 , unsignedbv_typet (width- integer2unsigned (element_size)* 8 ) ),
551
- src. op2 (), t);
553
+ value_extended = concatenation_exprt (
554
+ from_integer (
555
+ 0 , unsignedbv_typet (width - integer2unsigned (element_size) * 8 )),
556
+ src. value ( ),
557
+ t);
552
558
else
553
- value_extended= src.op2 ();
559
+ value_extended = src.value ();
554
560
555
- const typet &offset_type= ns.follow (src.op1 ().type ());
556
- mult_exprt offset_times_eight (src.op1 (), from_integer (8 , offset_type));
561
+ const typet &offset_type = ns.follow (src.offset ().type ());
562
+ mult_exprt offset_times_eight (src.offset (), from_integer (8 , offset_type));
557
563
558
564
binary_predicate_exprt offset_ge_zero (
559
565
offset_times_eight,
@@ -578,7 +584,7 @@ exprt flatten_byte_update(
578
584
}
579
585
580
586
// original_bits &= ~mask
581
- bitand_exprt bitand_expr (src.op0 (), bitnot_exprt (mask_shifted));
587
+ bitand_exprt bitand_expr (src.op (), bitnot_exprt (mask_shifted));
582
588
583
589
// original_bits |= newvalue
584
590
bitor_exprt bitor_expr (bitand_expr, value_shifted);
@@ -587,8 +593,10 @@ exprt flatten_byte_update(
587
593
}
588
594
else
589
595
{
590
- throw " flatten_byte_update can only do array and scalars "
591
- " right now, but got " +t.id_string ();
596
+ PRECONDITION_WITH_DIAGNOSTICS (
597
+ false ,
598
+ " flatten_byte_update can only do arrays and scalars right now" ,
599
+ t.id_string ());
592
600
}
593
601
}
594
602
0 commit comments