@@ -99,25 +99,21 @@ class goto_checkt
99
99
100
100
using conditionst = std::list<conditiont>;
101
101
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);
102
+ void bounds_check (const index_exprt &, const guardt &);
103
+ void div_by_zero_check (const div_exprt &, const guardt &);
104
+ void mod_by_zero_check (const mod_exprt &, const guardt &);
105
+ void undefined_shift_check (const shift_exprt &, const guardt &);
106
+ void pointer_rel_check (const exprt &, const guardt &);
107
+ void pointer_overflow_check (const exprt &, const guardt &);
108
+ void pointer_validity_check (const dereference_exprt &, const guardt &);
113
109
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 );
110
+ void integer_overflow_check (const exprt &, const guardt &);
111
+ void conversion_check (const exprt &, const guardt &);
112
+ void float_overflow_check (const exprt &, const guardt &);
113
+ void nan_check (const exprt &, const guardt &);
114
+ void rw_ok_check (exprt &);
119
115
120
- std::string array_name (const exprt &expr );
116
+ std::string array_name (const exprt &);
121
117
122
118
void add_guarded_claim (
123
119
const exprt &expr,
@@ -935,9 +931,7 @@ void goto_checkt::pointer_overflow_check(
935
931
936
932
void goto_checkt::pointer_validity_check (
937
933
const dereference_exprt &expr,
938
- const guardt &guard,
939
- const exprt &access_lb,
940
- const exprt &access_ub)
934
+ const guardt &guard)
941
935
{
942
936
if (!enable_pointer_check)
943
937
return ;
@@ -948,157 +942,18 @@ void goto_checkt::pointer_validity_check(
948
942
949
943
assert (base_type_eq (pointer_type.subtype (), expr.type (), ns));
950
944
951
- local_bitvector_analysist::flagst flags=
952
- local_bitvector_analysis->get (t, pointer);
953
-
954
- // For Java, we only need to check for null
955
- if (mode==ID_java)
956
- {
957
- if (flags.is_unknown () || flags.is_null ())
958
- {
959
- notequal_exprt not_eq_null (pointer, null_pointer_exprt (pointer_type));
945
+ auto conditions =
946
+ address_check (expr.pointer (), size_of_expr (expr.type (), ns));
960
947
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
948
+ for (const auto &c : conditions)
971
949
{
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
- flags.is_integer_address ())
1025
- add_guarded_claim (
1026
- or_exprt (allocs, not_exprt (invalid_pointer (pointer))),
1027
- " dereference failure: pointer invalid" ,
1028
- " pointer dereference" ,
1029
- expr.find_source_location (),
1030
- expr,
1031
- guard);
1032
-
1033
- if (flags.is_uninitialized ())
1034
- add_guarded_claim (
1035
- or_exprt (allocs, not_exprt (invalid_pointer (pointer))),
1036
- " dereference failure: pointer uninitialized" ,
1037
- " pointer dereference" ,
1038
- expr.find_source_location (),
1039
- expr,
1040
- guard);
1041
-
1042
- if (flags.is_unknown () ||
1043
- flags.is_dynamic_heap () ||
1044
- flags.is_integer_address ())
1045
- add_guarded_claim (
1046
- or_exprt (allocs, not_exprt (deallocated (pointer, ns))),
1047
- " dereference failure: deallocated dynamic object" ,
1048
- " pointer dereference" ,
1049
- expr.find_source_location (),
1050
- expr,
1051
- guard);
1052
-
1053
- if (flags.is_unknown () ||
1054
- flags.is_dynamic_local () ||
1055
- flags.is_integer_address ())
1056
- add_guarded_claim (
1057
- or_exprt (allocs, not_exprt (dead_object (pointer, ns))),
1058
- " dereference failure: dead object" ,
1059
- " pointer dereference" ,
1060
- expr.find_source_location (),
1061
- expr,
1062
- guard);
1063
-
1064
- if (flags.is_unknown () ||
1065
- flags.is_dynamic_heap () ||
1066
- flags.is_integer_address ())
1067
- {
1068
- const or_exprt dynamic_bounds (
1069
- dynamic_object_lower_bound (pointer, ns, access_lb),
1070
- dynamic_object_upper_bound (pointer, ns, access_ub));
1071
-
1072
- add_guarded_claim (
1073
- or_exprt (
1074
- allocs,
1075
- implies_exprt (
1076
- malloc_object (pointer, ns),
1077
- not_exprt (dynamic_bounds))),
1078
- " dereference failure: pointer outside dynamic object bounds" ,
1079
- " pointer dereference" ,
1080
- expr.find_source_location (),
1081
- expr,
1082
- guard);
1083
- }
1084
-
1085
- if (flags.is_unknown () ||
1086
- flags.is_dynamic_local () ||
1087
- flags.is_static_lifetime () ||
1088
- flags.is_integer_address ())
1089
- {
1090
- const or_exprt object_bounds (
1091
- object_lower_bound (pointer, ns, access_lb),
1092
- object_upper_bound (pointer, ns, access_ub));
1093
-
1094
- add_guarded_claim (
1095
- or_exprt (allocs, dynamic_object (pointer), not_exprt (object_bounds)),
1096
- " dereference failure: pointer outside object bounds" ,
1097
- " pointer dereference" ,
1098
- expr.find_source_location (),
1099
- expr,
1100
- guard);
1101
- }
950
+ add_guarded_claim (
951
+ c.assertion ,
952
+ c.description ,
953
+ " pointer dereference" ,
954
+ expr.find_source_location (),
955
+ expr,
956
+ guard);
1102
957
}
1103
958
}
1104
959
@@ -1535,24 +1390,31 @@ void goto_checkt::check_rec(const exprt &expr, guardt &guard, bool address)
1535
1390
const dereference_exprt &deref=
1536
1391
to_dereference_expr (member.struct_op ());
1537
1392
1538
- check_rec (deref.op0 (), guard, false );
1393
+ check_rec (deref.pointer (), guard, false );
1539
1394
1540
1395
// avoid building the following expressions when pointer_validity_check
1541
1396
// would return immediately anyway
1542
1397
if (!enable_pointer_check)
1543
1398
return ;
1544
1399
1545
- exprt access_ub=nil_exprt ();
1400
+ // we rewrite s->member into *(s+member_offset)
1401
+ // to avoid requiring memory safety of the entire struct
1546
1402
1547
1403
exprt member_offset=member_offset_expr (member, ns);
1548
- exprt size=size_of_expr (expr.type (), ns);
1549
1404
1550
- if (member_offset.is_not_nil () && size.is_not_nil ())
1551
- access_ub=plus_exprt (member_offset, size);
1405
+ if (member_offset.is_not_nil ())
1406
+ {
1407
+ pointer_typet new_pointer_type = to_pointer_type (deref.pointer ().type ());
1408
+ new_pointer_type.subtype () = expr.type ();
1552
1409
1553
- pointer_validity_check (deref, guard, member_offset, access_ub);
1410
+ const exprt new_address = typecast_exprt (
1411
+ plus_exprt (deref.pointer (), member_offset), new_pointer_type);
1554
1412
1555
- return ;
1413
+ const dereference_exprt new_deref (new_address, expr.type ());
1414
+ pointer_validity_check (new_deref, guard);
1415
+
1416
+ return ;
1417
+ }
1556
1418
}
1557
1419
1558
1420
forall_operands (it, expr)
@@ -1614,11 +1476,9 @@ void goto_checkt::check_rec(const exprt &expr, guardt &guard, bool address)
1614
1476
expr.id ()==ID_ge || expr.id ()==ID_gt)
1615
1477
pointer_rel_check (expr, guard);
1616
1478
else if (expr.id ()==ID_dereference)
1617
- pointer_validity_check (
1618
- to_dereference_expr (expr),
1619
- guard,
1620
- nil_exprt (),
1621
- size_of_expr (expr.type (), ns));
1479
+ {
1480
+ pointer_validity_check (to_dereference_expr (expr), guard);
1481
+ }
1622
1482
}
1623
1483
1624
1484
void goto_checkt::check (const exprt &expr)
0 commit comments