Skip to content

Commit 7f41999

Browse files
Merge pull request #5639 from hannes-steffenhagen-diffblue/refactor/value-set-dereference-misc-refactor
Value set dereference misc refactor
2 parents 3dee27d + 471dca7 commit 7f41999

File tree

2 files changed

+74
-68
lines changed

2 files changed

+74
-68
lines changed

src/pointer-analysis/value_set_dereference.cpp

Lines changed: 70 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ Author: Daniel Kroening, [email protected]
3434
#include <util/simplify_expr.h>
3535
#include <util/ssa_expr.h>
3636

37+
#include <deque>
38+
3739
/// Returns true if \p expr is complicated enough that a local definition (using
3840
/// a let expression) is preferable to repeating it, potentially many times.
3941
/// Of course this is just a heuristic -- currently we allow any expression that
@@ -139,7 +141,13 @@ exprt value_set_dereferencet::dereference(
139141
}
140142
}
141143

142-
// type of the object
144+
return handle_dereference_base_case(pointer, display_points_to_sets);
145+
}
146+
147+
exprt value_set_dereferencet::handle_dereference_base_case(
148+
const exprt &pointer,
149+
bool display_points_to_sets)
150+
{ // type of the object
143151
const typet &type=pointer.type().subtype();
144152

145153
// collect objects the pointer may point to
@@ -167,95 +175,89 @@ exprt value_set_dereferencet::dereference(
167175
compare_against_pointer = fresh_binder.symbol_expr();
168176
}
169177

170-
std::list<valuet> values =
171-
make_range(retained_values).map([&](const exprt &value) {
172-
return build_reference_to(value, compare_against_pointer, ns);
178+
auto values =
179+
make_range(retained_values)
180+
.map([&](const exprt &value) {
181+
return build_reference_to(value, compare_against_pointer, ns);
182+
})
183+
.collect<std::deque<valuet>>();
184+
185+
const bool may_fail =
186+
values.empty() ||
187+
std::any_of(values.begin(), values.end(), [](const valuet &value) {
188+
return value.value.is_nil();
173189
});
174190

175-
// can this fail?
176-
bool may_fail;
177-
178-
if(values.empty())
179-
{
180-
may_fail=true;
181-
}
182-
else
183-
{
184-
may_fail=false;
185-
for(std::list<valuet>::const_iterator
186-
it=values.begin();
187-
it!=values.end();
188-
it++)
189-
if(it->value.is_nil())
190-
may_fail=true;
191-
}
192-
193191
if(may_fail)
194192
{
195-
// first see if we have a "failed object" for this pointer
196-
197-
exprt failure_value;
198-
199-
if(
200-
const symbolt *failed_symbol =
201-
dereference_callback.get_or_create_failed_symbol(pointer))
202-
{
203-
// yes!
204-
failure_value=failed_symbol->symbol_expr();
205-
failure_value.set(ID_C_invalid_object, true);
206-
}
207-
else
208-
{
209-
// else: produce new symbol
210-
symbolt &symbol = get_fresh_aux_symbol(
211-
type,
212-
"symex",
213-
"invalid_object",
214-
pointer.source_location(),
215-
language_mode,
216-
new_symbol_table);
217-
218-
// make it a lvalue, so we can assign to it
219-
symbol.is_lvalue=true;
220-
221-
failure_value=symbol.symbol_expr();
222-
failure_value.set(ID_C_invalid_object, true);
223-
}
224-
225-
valuet value;
226-
value.value=failure_value;
227-
value.pointer_guard=true_exprt();
228-
values.push_front(value);
193+
values.push_front(get_failure_value(pointer, type));
229194
}
230195

231196
// now build big case split, but we only do "good" objects
232197

233-
exprt value=nil_exprt();
198+
exprt result_value = nil_exprt{};
234199

235-
for(std::list<valuet>::const_iterator
236-
it=values.begin();
237-
it!=values.end();
238-
it++)
200+
for(const auto &value : values)
239201
{
240-
if(it->value.is_not_nil())
202+
if(value.value.is_not_nil())
241203
{
242-
if(value.is_nil()) // first?
243-
value=it->value;
204+
if(result_value.is_nil()) // first?
205+
result_value = value.value;
244206
else
245-
value=if_exprt(it->pointer_guard, it->value, value);
207+
result_value = if_exprt(value.pointer_guard, value.value, result_value);
246208
}
247209
}
248210

249211
if(compare_against_pointer != pointer)
250-
value = let_exprt(to_symbol_expr(compare_against_pointer), pointer, value);
212+
result_value =
213+
let_exprt(to_symbol_expr(compare_against_pointer), pointer, result_value);
251214

252215
if(display_points_to_sets)
253216
{
254217
log.status() << value_set_dereference_stats_to_json(
255-
pointer, points_to_set, retained_values, value);
218+
pointer, points_to_set, retained_values, result_value);
256219
}
257220

258-
return value;
221+
return result_value;
222+
}
223+
224+
value_set_dereferencet::valuet value_set_dereferencet::get_failure_value(
225+
const exprt &pointer,
226+
const typet &type)
227+
{
228+
// first see if we have a "failed object" for this pointer
229+
exprt failure_value;
230+
231+
if(
232+
const symbolt *failed_symbol =
233+
dereference_callback.get_or_create_failed_symbol(pointer))
234+
{
235+
// yes!
236+
failure_value = failed_symbol->symbol_expr();
237+
failure_value.set(ID_C_invalid_object, true);
238+
}
239+
else
240+
{
241+
// else: produce new symbol
242+
symbolt &symbol = get_fresh_aux_symbol(
243+
type,
244+
"symex",
245+
"invalid_object",
246+
pointer.source_location(),
247+
language_mode,
248+
new_symbol_table);
249+
250+
// make it a lvalue, so we can assign to it
251+
symbol.is_lvalue = true;
252+
253+
failure_value = symbol.symbol_expr();
254+
failure_value.set(ID_C_invalid_object, true);
255+
}
256+
257+
valuet result{};
258+
result.value = failure_value;
259+
result.pointer_guard = true_exprt();
260+
return result;
259261
}
260262

261263
/// Check if the two types have matching number of ID_pointer levels, with

src/pointer-analysis/value_set_dereference.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,10 @@ class value_set_dereferencet final
111111
/// disregard an apparent attempt to dereference NULL
112112
const bool exclude_null_derefs;
113113
const messaget &log;
114+
valuet get_failure_value(const exprt &pointer, const typet &type);
115+
exprt handle_dereference_base_case(
116+
const exprt &pointer,
117+
bool display_points_to_sets);
114118
};
115119

116120
#endif // CPROVER_POINTER_ANALYSIS_VALUE_SET_DEREFERENCE_H

0 commit comments

Comments
 (0)