@@ -18,6 +18,7 @@ Author: Daniel Kroening, kroening@kroening.com
1818#include < util/std_types.h>
1919#include < util/guard.h>
2020#include < util/base_type.h>
21+ #include < util/pointer_offset_size.h>
2122#include < util/pointer_predicates.h>
2223#include < util/cprover_prefix.h>
2324#include < util/options.h>
@@ -73,7 +74,11 @@ class goto_checkt
7374 void undefined_shift_check (const shift_exprt &expr, const guardt &guard);
7475 void pointer_rel_check (const exprt &expr, const guardt &guard);
7576 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);
7782 void integer_overflow_check (const exprt &expr, const guardt &guard);
7883 void conversion_check (const exprt &expr, const guardt &guard);
7984 void float_overflow_check (const exprt &expr, const guardt &guard);
@@ -966,7 +971,9 @@ Function: goto_checkt::pointer_validity_check
966971
967972void goto_checkt::pointer_validity_check (
968973 const dereference_exprt &expr,
969- const guardt &guard)
974+ const guardt &guard,
975+ const exprt &access_lb,
976+ const exprt &access_ub)
970977{
971978 if (!enable_pointer_check)
972979 return ;
@@ -1047,42 +1054,44 @@ void goto_checkt::pointer_validity_check(
10471054 expr,
10481055 guard);
10491056
1050- if (enable_bounds_check )
1057+ if (flags. is_unknown () || flags. is_dynamic_heap () )
10511058 {
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));
10571066
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);
10661074 }
10671075
1068- if (enable_bounds_check)
1076+ if (flags.is_unknown () ||
1077+ flags.is_dynamic_local () ||
1078+ flags.is_static_lifetime ())
10691079 {
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 ));
10771087
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);
10861095 }
10871096 }
10881097}
@@ -1130,7 +1139,7 @@ void goto_checkt::bounds_check(
11301139 typet array_type=ns.follow (expr.array ().type ());
11311140
11321141 if (array_type.id ()==ID_pointer)
1133- return ; // done by the pointer code
1142+ throw " index got pointer as array type " ;
11341143 else if (array_type.id ()==ID_incomplete_array)
11351144 throw " index got incomplete array" ;
11361145 else if (array_type.id ()!=ID_array && array_type.id ()!=ID_vector)
@@ -1434,6 +1443,27 @@ void goto_checkt::check_rec(
14341443
14351444 return ;
14361445 }
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+ }
14371467
14381468 forall_operands (it, expr)
14391469 check_rec (*it, guard, false );
@@ -1491,7 +1521,11 @@ void goto_checkt::check_rec(
14911521 expr.id ()==ID_ge || expr.id ()==ID_gt)
14921522 pointer_rel_check (expr, guard);
14931523 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));
14951529}
14961530
14971531/* ******************************************************************\
0 commit comments