18
18
#include < util/std_types.h>
19
19
#include < util/guard.h>
20
20
#include < util/base_type.h>
21
+ #include < util/pointer_offset_size.h>
21
22
#include < util/pointer_predicates.h>
22
23
#include < util/cprover_prefix.h>
23
24
#include < util/options.h>
@@ -73,7 +74,11 @@ class goto_checkt
73
74
void undefined_shift_check (const shift_exprt &expr, const guardt &guard);
74
75
void pointer_rel_check (const exprt &expr, const guardt &guard);
75
76
void pointer_overflow_check (const exprt &expr, const guardt &guard);
76
- void pointer_validity_check (const dereference_exprt &expr, const guardt &guard);
77
+ void pointer_validity_check (
78
+ const dereference_exprt &expr,
79
+ const guardt &guard,
80
+ const exprt &access_lb,
81
+ const exprt &access_ub);
77
82
void integer_overflow_check (const exprt &expr, const guardt &guard);
78
83
void conversion_check (const exprt &expr, const guardt &guard);
79
84
void float_overflow_check (const exprt &expr, const guardt &guard);
@@ -966,7 +971,9 @@ Function: goto_checkt::pointer_validity_check
966
971
967
972
void goto_checkt::pointer_validity_check (
968
973
const dereference_exprt &expr,
969
- const guardt &guard)
974
+ const guardt &guard,
975
+ const exprt &access_lb,
976
+ const exprt &access_ub)
970
977
{
971
978
if (!enable_pointer_check)
972
979
return ;
@@ -1029,63 +1036,62 @@ void goto_checkt::pointer_validity_check(
1029
1036
expr,
1030
1037
guard);
1031
1038
1032
- if (mode != ID_java)
1033
- {
1034
- if (flags.is_unknown () || flags.is_dynamic_heap ())
1035
- add_guarded_claim (
1036
- not_exprt (deallocated (pointer, ns)),
1037
- " dereference failure: deallocated dynamic object" ,
1038
- " pointer dereference" ,
1039
- expr.find_source_location (),
1040
- expr,
1041
- guard);
1039
+ if (flags.is_unknown () || flags.is_dynamic_heap ())
1040
+ add_guarded_claim (
1041
+ not_exprt (deallocated (pointer, ns)),
1042
+ " dereference failure: deallocated dynamic object" ,
1043
+ " pointer dereference" ,
1044
+ expr.find_source_location (),
1045
+ expr,
1046
+ guard);
1042
1047
1043
- if (flags.is_unknown () || flags.is_dynamic_local ())
1044
- add_guarded_claim (
1045
- not_exprt (dead_object (pointer, ns)),
1046
- " dereference failure: dead object" ,
1047
- " pointer dereference" ,
1048
- expr.find_source_location (),
1049
- expr,
1050
- guard);
1051
- }
1048
+ if (flags.is_unknown () || flags.is_dynamic_local ())
1049
+ add_guarded_claim (
1050
+ not_exprt (dead_object (pointer, ns)),
1051
+ " dereference failure: dead object" ,
1052
+ " pointer dereference" ,
1053
+ expr.find_source_location (),
1054
+ expr,
1055
+ guard);
1052
1056
1053
- if (enable_bounds_check )
1057
+ if (flags. is_unknown () || flags. is_dynamic_heap () )
1054
1058
{
1055
- if (flags.is_unknown () || flags.is_dynamic_heap ())
1056
- {
1057
- exprt dynamic_bounds=
1058
- or_exprt (dynamic_object_lower_bound (pointer),
1059
- dynamic_object_upper_bound (pointer, dereference_type, ns));
1059
+ exprt dynamic_bounds=
1060
+ or_exprt (dynamic_object_lower_bound (pointer, ns, access_lb),
1061
+ dynamic_object_upper_bound (
1062
+ pointer,
1063
+ dereference_type,
1064
+ ns,
1065
+ access_ub));
1060
1066
1061
- add_guarded_claim (
1062
- implies_exprt (malloc_object (pointer, ns), not_exprt (dynamic_bounds)),
1063
- " dereference failure: dynamic object bounds" ,
1064
- " pointer dereference" ,
1065
- expr.find_source_location (),
1066
- expr,
1067
- guard);
1068
- }
1067
+ add_guarded_claim (
1068
+ implies_exprt (malloc_object (pointer, ns), not_exprt (dynamic_bounds)),
1069
+ " dereference failure: pointer outside dynamic object bounds" ,
1070
+ " pointer dereference" ,
1071
+ expr.find_source_location (),
1072
+ expr,
1073
+ guard);
1069
1074
}
1070
1075
1071
- if (enable_bounds_check)
1076
+ if (flags.is_unknown () ||
1077
+ flags.is_dynamic_local () ||
1078
+ flags.is_static_lifetime ())
1072
1079
{
1073
- if (flags. is_unknown () ||
1074
- flags. is_dynamic_local () ||
1075
- flags. is_static_lifetime ())
1076
- {
1077
- exprt object_bounds=
1078
- or_exprt ( object_lower_bound (pointer) ,
1079
- object_upper_bound (pointer, dereference_type, ns ));
1080
+ exprt object_bounds=
1081
+ or_exprt ( object_lower_bound (pointer, ns, access_lb),
1082
+ object_upper_bound (
1083
+ pointer,
1084
+ dereference_type,
1085
+ ns ,
1086
+ access_ub ));
1080
1087
1081
- add_guarded_claim (
1082
- or_exprt (dynamic_object (pointer), not_exprt (object_bounds)),
1083
- " dereference failure: object bounds" ,
1084
- " pointer dereference" ,
1085
- expr.find_source_location (),
1086
- expr,
1087
- guard);
1088
- }
1088
+ add_guarded_claim (
1089
+ or_exprt (dynamic_object (pointer), not_exprt (object_bounds)),
1090
+ " dereference failure: pointer outside object bounds" ,
1091
+ " pointer dereference" ,
1092
+ expr.find_source_location (),
1093
+ expr,
1094
+ guard);
1089
1095
}
1090
1096
}
1091
1097
}
@@ -1133,7 +1139,7 @@ void goto_checkt::bounds_check(
1133
1139
typet array_type=ns.follow (expr.array ().type ());
1134
1140
1135
1141
if (array_type.id ()==ID_pointer)
1136
- return ; // done by the pointer code
1142
+ throw " index got pointer as array type " ;
1137
1143
else if (array_type.id ()==ID_incomplete_array)
1138
1144
throw " index got incomplete array" ;
1139
1145
else if (array_type.id ()!=ID_array && array_type.id ()!=ID_vector)
@@ -1193,6 +1199,8 @@ void goto_checkt::bounds_check(
1193
1199
}
1194
1200
}
1195
1201
1202
+ exprt type_matches_size=true_exprt ();
1203
+
1196
1204
if (ode.root_object ().id ()==ID_dereference)
1197
1205
{
1198
1206
const exprt &pointer=
@@ -1218,13 +1226,18 @@ void goto_checkt::bounds_check(
1218
1226
1219
1227
add_guarded_claim (
1220
1228
precond,
1221
- name+" upper bound" ,
1229
+ name+" dynamic object upper bound" ,
1222
1230
" array bounds" ,
1223
1231
expr.find_source_location (),
1224
1232
expr,
1225
1233
guard);
1226
1234
1227
- return ;
1235
+ exprt type_size=size_of_expr (ode.root_object ().type (), ns);
1236
+ if (type_size.is_not_nil ())
1237
+ type_matches_size=
1238
+ equal_exprt (
1239
+ size,
1240
+ typecast_exprt (type_size, size.type ()));
1228
1241
}
1229
1242
1230
1243
const exprt &size=array_type.id ()==ID_array ?
@@ -1257,7 +1270,7 @@ void goto_checkt::bounds_check(
1257
1270
inequality.op1 ().make_typecast (inequality.op0 ().type ());
1258
1271
1259
1272
add_guarded_claim (
1260
- inequality,
1273
+ implies_exprt (type_matches_size, inequality) ,
1261
1274
name+" upper bound" ,
1262
1275
" array bounds" ,
1263
1276
expr.find_source_location (),
@@ -1430,6 +1443,27 @@ void goto_checkt::check_rec(
1430
1443
1431
1444
return ;
1432
1445
}
1446
+ else if (expr.id ()==ID_member &&
1447
+ to_member_expr (expr).struct_op ().id ()==ID_dereference)
1448
+ {
1449
+ const member_exprt &member=to_member_expr (expr);
1450
+ const dereference_exprt &deref=
1451
+ to_dereference_expr (member.struct_op ());
1452
+
1453
+ check_rec (deref.op0 (), guard, false );
1454
+
1455
+ exprt access_ub=nil_exprt ();
1456
+
1457
+ exprt member_offset=member_offset_expr (member, ns);
1458
+ exprt size=size_of_expr (expr.type (), ns);
1459
+
1460
+ if (member_offset.is_not_nil () && size.is_not_nil ())
1461
+ access_ub=plus_exprt (member_offset, size);
1462
+
1463
+ pointer_validity_check (deref, guard, member_offset, access_ub);
1464
+
1465
+ return ;
1466
+ }
1433
1467
1434
1468
forall_operands (it, expr)
1435
1469
check_rec (*it, guard, false );
@@ -1487,7 +1521,11 @@ void goto_checkt::check_rec(
1487
1521
expr.id ()==ID_ge || expr.id ()==ID_gt)
1488
1522
pointer_rel_check (expr, guard);
1489
1523
else if (expr.id ()==ID_dereference)
1490
- pointer_validity_check (to_dereference_expr (expr), guard);
1524
+ pointer_validity_check (
1525
+ to_dereference_expr (expr),
1526
+ guard,
1527
+ nil_exprt (),
1528
+ size_of_expr (expr.type (), ns));
1491
1529
}
1492
1530
1493
1531
/* ******************************************************************\
0 commit comments