@@ -369,22 +369,39 @@ inline is_dynamic_object_exprt &to_is_dynamic_object_expr(exprt &expr)
369
369
// / pointer_in_range(a, b, c) evaluates to true iff
370
370
// / same_object(a, b, c) ∧ r_ok(a, offset(c)-offset(a)) ∧ a<=b ∧ b<=c
371
371
// / Note that the last inequality is weak, i.e., b may be equal to c.
372
- class pointer_in_range_exprt : public ternary_exprt
372
+ class pointer_in_range_exprt : public expr_protectedt
373
373
{
374
374
public:
375
- explicit pointer_in_range_exprt (exprt a, exprt b, exprt c)
376
- : ternary_exprt(
375
+ pointer_in_range_exprt (
376
+ exprt a,
377
+ exprt b,
378
+ exprt c,
379
+ exprt is_deallocated,
380
+ exprt is_dead)
381
+ : expr_protectedt(
377
382
ID_pointer_in_range,
378
- std::move (a),
379
- std::move(b),
380
- std::move(c),
381
- bool_typet())
383
+ bool_typet{},
384
+ {std::move (a),
385
+ std::move (b),
386
+ std::move (c),
387
+ std::move (is_deallocated),
388
+ std::move (is_dead)})
382
389
{
383
390
PRECONDITION (op0 ().type ().id () == ID_pointer);
384
391
PRECONDITION (op1 ().type ().id () == ID_pointer);
385
392
PRECONDITION (op2 ().type ().id () == ID_pointer);
386
393
}
387
394
395
+ pointer_in_range_exprt (exprt a, exprt b, exprt c)
396
+ : pointer_in_range_exprt(
397
+ std::move (a),
398
+ std::move(b),
399
+ std::move(c),
400
+ nil_exprt{},
401
+ nil_exprt{})
402
+ {
403
+ }
404
+
388
405
const exprt &lower_bound () const
389
406
{
390
407
return op0 ();
@@ -400,6 +417,26 @@ class pointer_in_range_exprt : public ternary_exprt
400
417
return op2 ();
401
418
}
402
419
420
+ const exprt &deallocated_ptr () const
421
+ {
422
+ return op3 ();
423
+ }
424
+
425
+ exprt &deallocated_ptr ()
426
+ {
427
+ return op3 ();
428
+ }
429
+
430
+ const exprt &dead_ptr () const
431
+ {
432
+ return operands ()[4 ];
433
+ }
434
+
435
+ exprt &dead_ptr ()
436
+ {
437
+ return operands ()[4 ];
438
+ }
439
+
403
440
// translate into equivalent conjunction
404
441
exprt lower () const ;
405
442
};
@@ -412,14 +449,14 @@ inline bool can_cast_expr<pointer_in_range_exprt>(const exprt &base)
412
449
413
450
inline void validate_expr (const pointer_in_range_exprt &value)
414
451
{
415
- validate_operands (value, 3 , " pointer_in_range must have three operands" );
452
+ validate_operands (value, 5 , " pointer_in_range must have five operands" );
416
453
}
417
454
418
455
inline const pointer_in_range_exprt &to_pointer_in_range_expr (const exprt &expr)
419
456
{
420
457
PRECONDITION (expr.id () == ID_pointer_in_range);
421
458
DATA_INVARIANT (
422
- expr.operands ().size () == 3 , " pointer_in_range must have three operands" );
459
+ expr.operands ().size () == 5 , " pointer_in_range must have five operands" );
423
460
return static_cast <const pointer_in_range_exprt &>(expr);
424
461
}
425
462
@@ -429,7 +466,7 @@ inline pointer_in_range_exprt &to_pointer_in_range_expr(exprt &expr)
429
466
{
430
467
PRECONDITION (expr.id () == ID_pointer_in_range);
431
468
DATA_INVARIANT (
432
- expr.operands ().size () == 3 , " pointer_in_range must have three operands" );
469
+ expr.operands ().size () == 5 , " pointer_in_range must have five operands" );
433
470
return static_cast <pointer_in_range_exprt &>(expr);
434
471
}
435
472
@@ -814,11 +851,32 @@ class null_pointer_exprt : public constant_exprt
814
851
815
852
// / \brief A base class for a predicate that indicates that an
816
853
// / address range is ok to read or write or both
817
- class r_or_w_ok_exprt : public binary_predicate_exprt
854
+ class r_or_w_ok_exprt : public expr_protectedt
818
855
{
819
856
public:
820
- explicit r_or_w_ok_exprt (irep_idt id, exprt pointer, exprt size)
821
- : binary_predicate_exprt(std::move(pointer), id, std::move(size))
857
+ r_or_w_ok_exprt (
858
+ irep_idt id,
859
+ exprt pointer,
860
+ exprt size,
861
+ exprt is_deallocated,
862
+ exprt is_dead)
863
+ : expr_protectedt(
864
+ id,
865
+ bool_typet{},
866
+ {std::move (pointer),
867
+ std::move (size),
868
+ std::move (is_deallocated),
869
+ std::move (is_dead)})
870
+ {
871
+ }
872
+
873
+ r_or_w_ok_exprt (irep_idt id, exprt pointer, exprt size)
874
+ : r_or_w_ok_exprt(
875
+ id,
876
+ std::move (pointer),
877
+ std::move(size),
878
+ nil_exprt{},
879
+ nil_exprt{})
822
880
{
823
881
}
824
882
@@ -831,6 +889,26 @@ class r_or_w_ok_exprt : public binary_predicate_exprt
831
889
{
832
890
return op1 ();
833
891
}
892
+
893
+ const exprt &deallocated_ptr () const
894
+ {
895
+ return op2 ();
896
+ }
897
+
898
+ exprt &deallocated_ptr ()
899
+ {
900
+ return op2 ();
901
+ }
902
+
903
+ const exprt &dead_ptr () const
904
+ {
905
+ return op3 ();
906
+ }
907
+
908
+ exprt &dead_ptr ()
909
+ {
910
+ return op3 ();
911
+ }
834
912
};
835
913
836
914
template <>
@@ -841,7 +919,7 @@ inline bool can_cast_expr<r_or_w_ok_exprt>(const exprt &base)
841
919
842
920
inline void validate_expr (const r_or_w_ok_exprt &value)
843
921
{
844
- validate_operands (value, 2 , " r_or_w_ok must have two operands" );
922
+ validate_operands (value, 4 , " r_or_w_ok must have four operands" );
845
923
}
846
924
847
925
inline const r_or_w_ok_exprt &to_r_or_w_ok_expr (const exprt &expr)
@@ -857,8 +935,18 @@ inline const r_or_w_ok_exprt &to_r_or_w_ok_expr(const exprt &expr)
857
935
class r_ok_exprt : public r_or_w_ok_exprt
858
936
{
859
937
public:
860
- explicit r_ok_exprt (exprt pointer, exprt size)
861
- : r_or_w_ok_exprt(ID_r_ok, std::move(pointer), std::move(size))
938
+ r_ok_exprt (exprt pointer, exprt size, exprt is_deallocated, exprt is_dead)
939
+ : r_or_w_ok_exprt(
940
+ ID_r_ok,
941
+ std::move (pointer),
942
+ std::move(size),
943
+ std::move(is_deallocated),
944
+ std::move(is_dead))
945
+ {
946
+ }
947
+
948
+ r_ok_exprt (exprt pointer, exprt size)
949
+ : r_ok_exprt(std::move(pointer), std::move(size), nil_exprt{}, nil_exprt{})
862
950
{
863
951
}
864
952
};
@@ -871,7 +959,7 @@ inline bool can_cast_expr<r_ok_exprt>(const exprt &base)
871
959
872
960
inline void validate_expr (const r_ok_exprt &value)
873
961
{
874
- validate_operands (value, 2 , " r_ok must have two operands" );
962
+ validate_operands (value, 4 , " r_ok must have four operands" );
875
963
}
876
964
877
965
inline const r_ok_exprt &to_r_ok_expr (const exprt &expr)
@@ -886,8 +974,18 @@ inline const r_ok_exprt &to_r_ok_expr(const exprt &expr)
886
974
class w_ok_exprt : public r_or_w_ok_exprt
887
975
{
888
976
public:
889
- explicit w_ok_exprt (exprt pointer, exprt size)
890
- : r_or_w_ok_exprt(ID_w_ok, std::move(pointer), std::move(size))
977
+ w_ok_exprt (exprt pointer, exprt size, exprt is_deallocated, exprt is_dead)
978
+ : r_or_w_ok_exprt(
979
+ ID_w_ok,
980
+ std::move (pointer),
981
+ std::move(size),
982
+ std::move(is_deallocated),
983
+ std::move(is_dead))
984
+ {
985
+ }
986
+
987
+ w_ok_exprt (exprt pointer, exprt size)
988
+ : w_ok_exprt(std::move(pointer), std::move(size), nil_exprt{}, nil_exprt{})
891
989
{
892
990
}
893
991
};
@@ -900,7 +998,7 @@ inline bool can_cast_expr<w_ok_exprt>(const exprt &base)
900
998
901
999
inline void validate_expr (const w_ok_exprt &value)
902
1000
{
903
- validate_operands (value, 2 , " w_ok must have two operands" );
1001
+ validate_operands (value, 4 , " w_ok must have four operands" );
904
1002
}
905
1003
906
1004
inline const w_ok_exprt &to_w_ok_expr (const exprt &expr)
0 commit comments