@@ -12,6 +12,7 @@ Date: July 2021
1212// / Specify write set in code contracts
1313
1414#include " assigns.h"
15+ #include " utils.h"
1516
1617#include < analyses/call_graph.h>
1718
@@ -52,14 +53,16 @@ static const slicet normalize_to_slice(const exprt &expr, const namespacet &ns)
5253}
5354
5455const symbolt assigns_clauset::conditional_address_ranget::generate_new_symbol (
56+ const std::string &prefix,
5557 const typet &type,
5658 const source_locationt &location) const
5759{
5860 return new_tmp_symbol (
5961 type,
6062 location,
6163 parent.symbol_table .lookup_ref (parent.function_name ).mode ,
62- parent.symbol_table );
64+ parent.symbol_table ,
65+ prefix);
6366}
6467
6568assigns_clauset::conditional_address_ranget::conditional_address_ranget (
@@ -70,11 +73,13 @@ assigns_clauset::conditional_address_ranget::conditional_address_ranget(
7073 parent(parent),
7174 slice(normalize_to_slice(expr, parent.ns)),
7275 validity_condition_var(
73- generate_new_symbol (bool_typet(), location).symbol_expr()),
76+ generate_new_symbol (" __car_valid " , bool_typet(), location).symbol_expr()),
7477 lower_bound_address_var(
75- generate_new_symbol (slice.first.type(), location).symbol_expr()),
78+ generate_new_symbol (" __car_lb" , slice.first.type(), location)
79+ .symbol_expr()),
7680 upper_bound_address_var(
77- generate_new_symbol (slice.first.type(), location).symbol_expr())
81+ generate_new_symbol (" __car_ub" , slice.first.type(), location)
82+ .symbol_expr())
7883{
7984}
8085
@@ -83,41 +88,54 @@ assigns_clauset::conditional_address_ranget::generate_snapshot_instructions()
8388 const
8489{
8590 goto_programt instructions;
86-
87- instructions.add (goto_programt::make_decl (validity_condition_var, location));
88- instructions.add (goto_programt::make_decl (lower_bound_address_var, location));
89- instructions.add (goto_programt::make_decl (upper_bound_address_var, location));
91+ // adding pragmas to the location to selectively disable checks
92+ // where it is sound to do so
93+ source_locationt location_no_checks = location;
94+ disable_pointer_checks (location_no_checks);
95+
96+ instructions.add (
97+ goto_programt::make_decl (validity_condition_var, location_no_checks));
98+ instructions.add (
99+ goto_programt::make_decl (lower_bound_address_var, location_no_checks));
100+ instructions.add (
101+ goto_programt::make_decl (upper_bound_address_var, location_no_checks));
90102
91103 instructions.add (goto_programt::make_assignment (
92104 lower_bound_address_var,
93105 null_pointer_exprt{to_pointer_type (slice.first .type ())},
94- location ));
106+ location_no_checks ));
95107 instructions.add (goto_programt::make_assignment (
96108 upper_bound_address_var,
97109 null_pointer_exprt{to_pointer_type (slice.first .type ())},
98- location ));
110+ location_no_checks ));
99111
100112 goto_programt skip_program;
101- const auto skip_target = skip_program.add (goto_programt::make_skip (location));
113+ const auto skip_target =
114+ skip_program.add (goto_programt::make_skip (location_no_checks));
102115
103116 const auto validity_check_expr =
104117 and_exprt{all_dereferences_are_valid (source_expr, parent.ns ),
105118 w_ok_exprt{slice.first , slice.second }};
106119 instructions.add (goto_programt::make_assignment (
107- validity_condition_var, validity_check_expr, location ));
120+ validity_condition_var, validity_check_expr, location_no_checks ));
108121
109122 instructions.add (goto_programt::make_goto (
110- skip_target, not_exprt{validity_condition_var}, location ));
123+ skip_target, not_exprt{validity_condition_var}, location_no_checks ));
111124
112125 instructions.add (goto_programt::make_assignment (
113- lower_bound_address_var, slice.first , location));
126+ lower_bound_address_var, slice.first , location_no_checks));
127+
128+ // the computation of the CAR upper bound can overflow into the object ID bits
129+ // of the pointer with very large allocation sizes.
130+ // We enable pointer overflow checks to detect such cases.
131+ source_locationt location_overflow_check = location;
132+ location_overflow_check.add_pragma (" enable:pointer-overflow-check" );
114133
115134 instructions.add (goto_programt::make_assignment (
116135 upper_bound_address_var,
117136 minus_exprt{plus_exprt{slice.first , slice.second },
118137 from_integer (1 , slice.second .type ())},
119- location));
120-
138+ location_overflow_check));
121139 instructions.destructive_append (skip_program);
122140
123141 // The assignments above are only performed on locally defined temporaries
@@ -130,14 +148,16 @@ const exprt
130148assigns_clauset::conditional_address_ranget::generate_unsafe_inclusion_check (
131149 const conditional_address_ranget &lhs) const
132150{
151+ // remark: both lb and ub are derived from the same object so checking
152+ // same_object(upper_bound_address_var, lhs.upper_bound_address_var)
153+ // is redundant
133154 return conjunction (
134155 {validity_condition_var,
135156 same_object (lower_bound_address_var, lhs.lower_bound_address_var ),
136- same_object (lhs.upper_bound_address_var , upper_bound_address_var),
137- less_than_or_equal_exprt{lower_bound_address_var,
138- lhs.lower_bound_address_var },
139- less_than_or_equal_exprt{lhs.upper_bound_address_var ,
140- upper_bound_address_var}});
157+ less_than_or_equal_exprt{pointer_offset (lower_bound_address_var),
158+ pointer_offset (lhs.lower_bound_address_var )},
159+ less_than_or_equal_exprt{pointer_offset (lhs.upper_bound_address_var ),
160+ pointer_offset (upper_bound_address_var)}});
141161}
142162
143163assigns_clauset::assigns_clauset (
0 commit comments