13
13
14
14
#include < algorithm>
15
15
16
- #include < util/simplify_expr.h>
17
- #include < util/array_name.h>
18
- #include < util/ieee_float.h>
19
16
#include < util/arith_tools.h>
17
+ #include < util/array_name.h>
18
+ #include < util/base_type.h>
19
+ #include < util/cprover_prefix.h>
20
+ #include < util/c_types.h>
20
21
#include < util/expr_util.h>
21
22
#include < util/find_symbols.h>
22
- #include < util/std_expr.h>
23
- #include < util/std_types.h>
24
23
#include < util/guard.h>
25
- #include < util/base_type.h>
24
+ #include < util/ieee_float.h>
25
+ #include < util/options.h>
26
26
#include < util/pointer_offset_size.h>
27
27
#include < util/pointer_predicates.h>
28
- #include < util/cprover_prefix.h>
29
- #include < util/options.h>
28
+ #include < util/simplify_expr.h>
29
+ #include < util/std_expr.h>
30
+ #include < util/std_types.h>
30
31
31
32
#include < langapi/language.h>
32
33
#include < langapi/mode.h>
@@ -99,25 +100,21 @@ class goto_checkt
99
100
100
101
using conditionst = std::list<conditiont>;
101
102
102
- void bounds_check (const index_exprt &expr, const guardt &guard);
103
- void div_by_zero_check (const div_exprt &expr, const guardt &guard);
104
- void mod_by_zero_check (const mod_exprt &expr, const guardt &guard);
105
- void undefined_shift_check (const shift_exprt &expr, const guardt &guard);
106
- void pointer_rel_check (const exprt &expr, const guardt &guard);
107
- void pointer_overflow_check (const exprt &expr, const guardt &guard);
108
- void pointer_validity_check (
109
- const dereference_exprt &expr,
110
- const guardt &guard,
111
- const exprt &access_lb,
112
- const exprt &access_ub);
103
+ void bounds_check (const index_exprt &, const guardt &);
104
+ void div_by_zero_check (const div_exprt &, const guardt &);
105
+ void mod_by_zero_check (const mod_exprt &, const guardt &);
106
+ void undefined_shift_check (const shift_exprt &, const guardt &);
107
+ void pointer_rel_check (const exprt &, const guardt &);
108
+ void pointer_overflow_check (const exprt &, const guardt &);
109
+ void pointer_validity_check (const dereference_exprt &, const guardt &);
113
110
conditionst address_check (const exprt &address, const exprt &size);
114
- void integer_overflow_check (const exprt &expr , const guardt &guard );
115
- void conversion_check (const exprt &expr , const guardt &guard );
116
- void float_overflow_check (const exprt &expr , const guardt &guard );
117
- void nan_check (const exprt &expr , const guardt &guard );
118
- void rw_ok_check (exprt &expr );
111
+ void integer_overflow_check (const exprt &, const guardt &);
112
+ void conversion_check (const exprt &, const guardt &);
113
+ void float_overflow_check (const exprt &, const guardt &);
114
+ void nan_check (const exprt &, const guardt &);
115
+ void rw_ok_check (exprt &);
119
116
120
- std::string array_name (const exprt &expr );
117
+ std::string array_name (const exprt &);
121
118
122
119
void add_guarded_claim (
123
120
const exprt &expr,
@@ -935,9 +932,7 @@ void goto_checkt::pointer_overflow_check(
935
932
936
933
void goto_checkt::pointer_validity_check (
937
934
const dereference_exprt &expr,
938
- const guardt &guard,
939
- const exprt &access_lb,
940
- const exprt &access_ub)
935
+ const guardt &guard)
941
936
{
942
937
if (!enable_pointer_check)
943
938
return ;
@@ -948,164 +943,18 @@ void goto_checkt::pointer_validity_check(
948
943
949
944
assert (base_type_eq (pointer_type.subtype (), expr.type (), ns));
950
945
951
- local_bitvector_analysist::flagst flags =
952
- local_bitvector_analysis-> get (t, pointer );
946
+ auto conditions =
947
+ address_check (expr. pointer (), size_of_expr (expr. type (), ns) );
953
948
954
- // For Java, we only need to check for null
955
- if (mode==ID_java)
949
+ for (const auto &c : conditions)
956
950
{
957
- if (flags.is_unknown () || flags.is_null ())
958
- {
959
- notequal_exprt not_eq_null (pointer, null_pointer_exprt (pointer_type));
960
-
961
- add_guarded_claim (
962
- not_eq_null,
963
- " reference is null" ,
964
- " pointer dereference" ,
965
- expr.find_source_location (),
966
- expr,
967
- guard);
968
- }
969
- }
970
- else
971
- {
972
- exprt allocs=false_exprt ();
973
-
974
- if (!allocations.empty ())
975
- {
976
- exprt::operandst disjuncts;
977
-
978
- for (const auto &a : allocations)
979
- {
980
- typecast_exprt int_ptr (pointer, a.first .type ());
981
-
982
- exprt lb (int_ptr);
983
- if (access_lb.is_not_nil ())
984
- {
985
- if (!base_type_eq (lb.type (), access_lb.type (), ns))
986
- lb=plus_exprt (lb, typecast_exprt (access_lb, lb.type ()));
987
- else
988
- lb=plus_exprt (lb, access_lb);
989
- }
990
-
991
- binary_relation_exprt lb_check (a.first , ID_le, lb);
992
-
993
- exprt ub (int_ptr);
994
- if (access_ub.is_not_nil ())
995
- {
996
- if (!base_type_eq (ub.type (), access_ub.type (), ns))
997
- ub=plus_exprt (ub, typecast_exprt (access_ub, ub.type ()));
998
- else
999
- ub=plus_exprt (ub, access_ub);
1000
- }
1001
-
1002
- binary_relation_exprt ub_check (
1003
- ub, ID_le, plus_exprt (a.first , a.second ));
1004
-
1005
- disjuncts.push_back (and_exprt (lb_check, ub_check));
1006
- }
1007
-
1008
- allocs=disjunction (disjuncts);
1009
- }
1010
-
1011
- if (flags.is_unknown () ||
1012
- flags.is_null ())
1013
- {
1014
- add_guarded_claim (
1015
- or_exprt (allocs, not_exprt (null_pointer (pointer))),
1016
- " dereference failure: pointer NULL" ,
1017
- " pointer dereference" ,
1018
- expr.find_source_location (),
1019
- expr,
1020
- guard);
1021
- }
1022
-
1023
- if (flags.is_unknown ())
1024
- add_guarded_claim (
1025
- or_exprt (allocs, not_exprt (invalid_pointer (pointer))),
1026
- " dereference failure: pointer invalid" ,
1027
- " pointer dereference" ,
1028
- expr.find_source_location (),
1029
- expr,
1030
- guard);
1031
-
1032
- if (flags.is_uninitialized ())
1033
- add_guarded_claim (
1034
- or_exprt (allocs, not_exprt (invalid_pointer (pointer))),
1035
- " dereference failure: pointer uninitialized" ,
1036
- " pointer dereference" ,
1037
- expr.find_source_location (),
1038
- expr,
1039
- guard);
1040
-
1041
- if (flags.is_unknown () ||
1042
- flags.is_dynamic_heap ())
1043
- add_guarded_claim (
1044
- or_exprt (allocs, not_exprt (deallocated (pointer, ns))),
1045
- " dereference failure: deallocated dynamic object" ,
1046
- " pointer dereference" ,
1047
- expr.find_source_location (),
1048
- expr,
1049
- guard);
1050
-
1051
- if (flags.is_unknown () ||
1052
- flags.is_dynamic_local ())
1053
- add_guarded_claim (
1054
- or_exprt (allocs, not_exprt (dead_object (pointer, ns))),
1055
- " dereference failure: dead object" ,
1056
- " pointer dereference" ,
1057
- expr.find_source_location (),
1058
- expr,
1059
- guard);
1060
-
1061
- if (flags.is_unknown () ||
1062
- flags.is_dynamic_heap ())
1063
- {
1064
- const or_exprt dynamic_bounds (
1065
- dynamic_object_lower_bound (pointer, ns, access_lb),
1066
- dynamic_object_upper_bound (pointer, ns, access_ub));
1067
-
1068
- add_guarded_claim (
1069
- or_exprt (
1070
- allocs,
1071
- implies_exprt (
1072
- malloc_object (pointer, ns),
1073
- not_exprt (dynamic_bounds))),
1074
- " dereference failure: pointer outside dynamic object bounds" ,
1075
- " pointer dereference" ,
1076
- expr.find_source_location (),
1077
- expr,
1078
- guard);
1079
- }
1080
-
1081
- if (flags.is_unknown () ||
1082
- flags.is_dynamic_local () ||
1083
- flags.is_static_lifetime ())
1084
- {
1085
- const or_exprt object_bounds (
1086
- object_lower_bound (pointer, ns, access_lb),
1087
- object_upper_bound (pointer, ns, access_ub));
1088
-
1089
- add_guarded_claim (
1090
- or_exprt (allocs, dynamic_object (pointer), not_exprt (object_bounds)),
1091
- " dereference failure: pointer outside object bounds" ,
1092
- " pointer dereference" ,
1093
- expr.find_source_location (),
1094
- expr,
1095
- guard);
1096
- }
1097
-
1098
- if (flags.is_unknown () ||
1099
- flags.is_integer_address ())
1100
- {
1101
- add_guarded_claim (
1102
- implies_exprt (integer_address (pointer), allocs),
1103
- " dereference failure: invalid integer address" ,
1104
- " pointer dereference" ,
1105
- expr.find_source_location (),
1106
- expr,
1107
- guard);
1108
- }
951
+ add_guarded_claim (
952
+ c.assertion ,
953
+ c.description ,
954
+ " pointer dereference" ,
955
+ expr.find_source_location (),
956
+ expr,
957
+ guard);
1109
958
}
1110
959
}
1111
960
@@ -1547,24 +1396,38 @@ void goto_checkt::check_rec(const exprt &expr, guardt &guard, bool address)
1547
1396
const dereference_exprt &deref=
1548
1397
to_dereference_expr (member.struct_op ());
1549
1398
1550
- check_rec (deref.op0 (), guard, false );
1399
+ check_rec (deref.pointer (), guard, false );
1551
1400
1552
1401
// avoid building the following expressions when pointer_validity_check
1553
1402
// would return immediately anyway
1554
1403
if (!enable_pointer_check)
1555
1404
return ;
1556
1405
1557
- exprt access_ub=nil_exprt ();
1406
+ // we rewrite s->member into *(s+member_offset)
1407
+ // to avoid requiring memory safety of the entire struct
1558
1408
1559
1409
exprt member_offset=member_offset_expr (member, ns);
1560
- exprt size=size_of_expr (expr.type (), ns);
1561
1410
1562
- if (member_offset.is_not_nil () && size.is_not_nil ())
1563
- access_ub=plus_exprt (member_offset, size);
1411
+ if (member_offset.is_not_nil ())
1412
+ {
1413
+ pointer_typet new_pointer_type = to_pointer_type (deref.pointer ().type ());
1414
+ new_pointer_type.subtype () = expr.type ();
1564
1415
1565
- pointer_validity_check (deref, guard, member_offset, access_ub);
1416
+ const exprt char_pointer =
1417
+ typecast_exprt::conditional_cast (deref.pointer (), pointer_type (char_type ()));
1566
1418
1567
- return ;
1419
+ const exprt new_address = typecast_exprt (
1420
+ plus_exprt (char_pointer, member_offset), char_pointer.type ());
1421
+
1422
+ const exprt new_address_casted =
1423
+ typecast_exprt::conditional_cast (new_address, new_pointer_type);
1424
+
1425
+ dereference_exprt new_deref (new_address_casted, expr.type ());
1426
+ new_deref.add_source_location () = deref.source_location ();
1427
+ pointer_validity_check (new_deref, guard);
1428
+
1429
+ return ;
1430
+ }
1568
1431
}
1569
1432
1570
1433
forall_operands (it, expr)
@@ -1626,11 +1489,9 @@ void goto_checkt::check_rec(const exprt &expr, guardt &guard, bool address)
1626
1489
expr.id ()==ID_ge || expr.id ()==ID_gt)
1627
1490
pointer_rel_check (expr, guard);
1628
1491
else if (expr.id ()==ID_dereference)
1629
- pointer_validity_check (
1630
- to_dereference_expr (expr),
1631
- guard,
1632
- nil_exprt (),
1633
- size_of_expr (expr.type (), ns));
1492
+ {
1493
+ pointer_validity_check (to_dereference_expr (expr), guard);
1494
+ }
1634
1495
}
1635
1496
1636
1497
void goto_checkt::check (const exprt &expr)
0 commit comments