|
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;
|
@@ -1047,42 +1054,44 @@ void goto_checkt::pointer_validity_check(
|
1047 | 1054 | expr,
|
1048 | 1055 | guard);
|
1049 | 1056 |
|
1050 |
| - if(enable_bounds_check) |
| 1057 | + if(flags.is_unknown() || flags.is_dynamic_heap()) |
1051 | 1058 | {
|
1052 |
| - if(flags.is_unknown() || flags.is_dynamic_heap()) |
1053 |
| - { |
1054 |
| - exprt dynamic_bounds= |
1055 |
| - or_exprt(dynamic_object_lower_bound(pointer), |
1056 |
| - 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)); |
1057 | 1066 |
|
1058 |
| - add_guarded_claim( |
1059 |
| - implies_exprt(malloc_object(pointer, ns), not_exprt(dynamic_bounds)), |
1060 |
| - "dereference failure: dynamic object bounds", |
1061 |
| - "pointer dereference", |
1062 |
| - expr.find_source_location(), |
1063 |
| - expr, |
1064 |
| - guard); |
1065 |
| - } |
| 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); |
1066 | 1074 | }
|
1067 | 1075 |
|
1068 |
| - if(enable_bounds_check) |
| 1076 | + if(flags.is_unknown() || |
| 1077 | + flags.is_dynamic_local() || |
| 1078 | + flags.is_static_lifetime()) |
1069 | 1079 | {
|
1070 |
| - if(flags.is_unknown() || |
1071 |
| - flags.is_dynamic_local() || |
1072 |
| - flags.is_static_lifetime()) |
1073 |
| - { |
1074 |
| - exprt object_bounds= |
1075 |
| - or_exprt(object_lower_bound(pointer), |
1076 |
| - 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)); |
1077 | 1087 |
|
1078 |
| - add_guarded_claim( |
1079 |
| - or_exprt(dynamic_object(pointer), not_exprt(object_bounds)), |
1080 |
| - "dereference failure: object bounds", |
1081 |
| - "pointer dereference", |
1082 |
| - expr.find_source_location(), |
1083 |
| - expr, |
1084 |
| - guard); |
1085 |
| - } |
| 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); |
1086 | 1095 | }
|
1087 | 1096 | }
|
1088 | 1097 | }
|
@@ -1130,7 +1139,7 @@ void goto_checkt::bounds_check(
|
1130 | 1139 | typet array_type=ns.follow(expr.array().type());
|
1131 | 1140 |
|
1132 | 1141 | if(array_type.id()==ID_pointer)
|
1133 |
| - return; // done by the pointer code |
| 1142 | + throw "index got pointer as array type"; |
1134 | 1143 | else if(array_type.id()==ID_incomplete_array)
|
1135 | 1144 | throw "index got incomplete array";
|
1136 | 1145 | else if(array_type.id()!=ID_array && array_type.id()!=ID_vector)
|
@@ -1434,6 +1443,27 @@ void goto_checkt::check_rec(
|
1434 | 1443 |
|
1435 | 1444 | return;
|
1436 | 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 | + } |
1437 | 1467 |
|
1438 | 1468 | forall_operands(it, expr)
|
1439 | 1469 | check_rec(*it, guard, false);
|
@@ -1491,7 +1521,11 @@ void goto_checkt::check_rec(
|
1491 | 1521 | expr.id()==ID_ge || expr.id()==ID_gt)
|
1492 | 1522 | pointer_rel_check(expr, guard);
|
1493 | 1523 | else if(expr.id()==ID_dereference)
|
1494 |
| - 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)); |
1495 | 1529 | }
|
1496 | 1530 |
|
1497 | 1531 | /*******************************************************************\
|
|
0 commit comments