@@ -99,25 +99,21 @@ class goto_checkt
9999
100100 using conditionst = std::list<conditiont>;
101101
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 &);
113109 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 &);
119115
120- std::string array_name (const exprt &expr );
116+ std::string array_name (const exprt &);
121117
122118 void add_guarded_claim (
123119 const exprt &expr,
@@ -935,9 +931,7 @@ void goto_checkt::pointer_overflow_check(
935931
936932void goto_checkt::pointer_validity_check (
937933 const dereference_exprt &expr,
938- const guardt &guard,
939- const exprt &access_lb,
940- const exprt &access_ub)
934+ const guardt &guard)
941935{
942936 if (!enable_pointer_check)
943937 return ;
@@ -948,157 +942,18 @@ void goto_checkt::pointer_validity_check(
948942
949943 assert (base_type_eq (pointer_type.subtype (), expr.type (), ns));
950944
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));
960947
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)
971949 {
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);
1102957 }
1103958}
1104959
@@ -1535,24 +1390,31 @@ void goto_checkt::check_rec(const exprt &expr, guardt &guard, bool address)
15351390 const dereference_exprt &deref=
15361391 to_dereference_expr (member.struct_op ());
15371392
1538- check_rec (deref.op0 (), guard, false );
1393+ check_rec (deref.pointer (), guard, false );
15391394
15401395 // avoid building the following expressions when pointer_validity_check
15411396 // would return immediately anyway
15421397 if (!enable_pointer_check)
15431398 return ;
15441399
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
15461402
15471403 exprt member_offset=member_offset_expr (member, ns);
1548- exprt size=size_of_expr (expr.type (), ns);
15491404
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 ();
15521409
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);
15541412
1555- return ;
1413+ const dereference_exprt new_deref (new_address, expr.type ());
1414+ pointer_validity_check (new_deref, guard);
1415+
1416+ return ;
1417+ }
15561418 }
15571419
15581420 forall_operands (it, expr)
@@ -1614,11 +1476,9 @@ void goto_checkt::check_rec(const exprt &expr, guardt &guard, bool address)
16141476 expr.id ()==ID_ge || expr.id ()==ID_gt)
16151477 pointer_rel_check (expr, guard);
16161478 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+ }
16221482}
16231483
16241484void goto_checkt::check (const exprt &expr)
0 commit comments