Skip to content

Commit 44844d8

Browse files
authored
Merge pull request #4575 from smowton/smowton/cleanup/factor-value-set-deref
value-set-dereference: factor out should_ignore_value
2 parents d14ffbc + 9231d22 commit 44844d8

File tree

3 files changed

+58
-44
lines changed

3 files changed

+58
-44
lines changed

src/goto-symex/symex_main.cpp

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -623,19 +623,16 @@ void goto_symext::try_filter_value_sets(
623623
}
624624

625625
const bool exclude_null_derefs = false;
626-
value_set_dereferencet::valuet possible_value =
627-
value_set_dereferencet::build_reference_to(
628-
value_set_element,
629-
*symbol_expr,
630-
exclude_null_derefs,
631-
language_mode,
632-
ns);
633-
634-
if(possible_value.ignore)
626+
if(value_set_dereferencet::should_ignore_value(
627+
value_set_element, exclude_null_derefs, language_mode))
635628
{
636629
continue;
637630
}
638631

632+
value_set_dereferencet::valuet possible_value =
633+
value_set_dereferencet::build_reference_to(
634+
value_set_element, *symbol_expr, ns);
635+
639636
exprt replacement_expr =
640637
possible_value.value.is_nil()
641638
? static_cast<exprt>(null_pointer_exprt{symbol_type})

src/pointer-analysis/value_set_dereference.cpp

Lines changed: 46 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -67,26 +67,23 @@ exprt value_set_dereferencet::dereference(const exprt &pointer)
6767

6868
// get the values of these
6969

70+
std::vector<exprt> retained_values;
71+
for(const auto &value : points_to_set)
72+
{
73+
if(!should_ignore_value(value, exclude_null_derefs, language_mode))
74+
retained_values.push_back(value);
75+
}
76+
7077
std::list<valuet> values;
7178

72-
for(value_setst::valuest::const_iterator
73-
it=points_to_set.begin();
74-
it!=points_to_set.end();
75-
it++)
79+
for(const auto &value : retained_values)
7680
{
77-
valuet value =
78-
build_reference_to(*it, pointer, exclude_null_derefs, language_mode, ns);
79-
81+
values.push_back(build_reference_to(value, pointer, ns));
8082
#if 0
8183
std::cout << "V: " << format(value.pointer_guard) << " --> ";
8284
std::cout << format(value.value);
83-
if(value.ignore)
84-
std::cout << " (ignored)";
8585
std::cout << '\n';
8686
#endif
87-
88-
if(!value.ignore)
89-
values.push_back(value);
9087
}
9188

9289
// can this fail?
@@ -243,31 +240,59 @@ bool value_set_dereferencet::dereference_type_compare(
243240
return false;
244241
}
245242

243+
/// Determine whether possible alias `what` should be ignored when replacing a
244+
/// pointer by its referees.
245+
/// We currently ignore a `null` object when \p exclude_null_derefs is true
246+
/// (pass true if you know the dereferenced pointer cannot be null), and also
247+
/// ignore integer addresses when \p language_mode is "java"
246248
/// \param what: value set entry to convert to an expression: either
247249
/// ID_unknown, ID_invalid, or an object_descriptor_exprt giving a referred
248250
/// object and offset.
249-
/// \param pointer_expr: pointer expression that may point to `what`
250251
/// \param exclude_null_derefs: Ignore value-set entries that indicate a
251252
/// given dereference may follow a null pointer
252253
/// \param language_mode: Mode for any new symbols created to represent a
253254
/// dereference failure
255+
/// \return true if \p what should be ignored as a possible alias
256+
bool value_set_dereferencet::should_ignore_value(
257+
const exprt &what,
258+
bool exclude_null_derefs,
259+
const irep_idt &language_mode)
260+
{
261+
if(what.id() == ID_unknown || what.id() == ID_invalid)
262+
{
263+
return false;
264+
}
265+
266+
const object_descriptor_exprt &o = to_object_descriptor_expr(what);
267+
268+
const exprt &root_object = o.root_object();
269+
if(root_object.id() == ID_null_object)
270+
{
271+
return exclude_null_derefs;
272+
}
273+
else if(root_object.id() == ID_integer_address)
274+
{
275+
return language_mode == ID_java;
276+
}
277+
278+
return false;
279+
}
280+
281+
/// \param what: value set entry to convert to an expression: either
282+
/// ID_unknown, ID_invalid, or an object_descriptor_exprt giving a referred
283+
/// object and offset.
284+
/// \param pointer_expr: pointer expression that may point to `what`
254285
/// \param ns: A namespace
255-
/// \return a `valuet` object containing `guard`, `value` and `ignore` fields.
256-
/// The `ignore` field is true for a `null` object when `exclude_null_derefs`
257-
/// is true (set by our creator when they know \p what cannot be null)
258-
//// and for integer addresses in java mode.
286+
/// \return a `valuet` object containing `guard` and `value` fields.
259287
/// The guard is an appropriate check to determine whether `pointer_expr`
260288
/// really points to `what`; for example `pointer_expr == &what`.
261289
/// The value corresponds to the dereferenced pointer_expr assuming it is
262290
/// pointing to the object described by `what`.
263291
/// For example, we might return
264-
/// `{.value = global, .pointer_guard = (pointer_expr == &global),
265-
/// .ignore = false}`
292+
/// `{.value = global, .pointer_guard = (pointer_expr == &global)}`
266293
value_set_dereferencet::valuet value_set_dereferencet::build_reference_to(
267294
const exprt &what,
268295
const exprt &pointer_expr,
269-
const bool exclude_null_derefs,
270-
const irep_idt language_mode,
271296
const namespacet &ns)
272297
{
273298
const typet &dereference_type = pointer_expr.type().subtype();
@@ -294,10 +319,6 @@ value_set_dereferencet::valuet value_set_dereferencet::build_reference_to(
294319

295320
if(root_object.id() == ID_null_object)
296321
{
297-
if(exclude_null_derefs)
298-
{
299-
result.ignore = true;
300-
}
301322
}
302323
else if(root_object.id()==ID_dynamic_object)
303324
{
@@ -313,12 +334,6 @@ value_set_dereferencet::valuet value_set_dereferencet::build_reference_to(
313334
// This is stuff like *((char *)5).
314335
// This is turned into an access to __CPROVER_memory[...].
315336

316-
if(language_mode == ID_java)
317-
{
318-
result.ignore = true;
319-
return result;
320-
}
321-
322337
const symbolt &memory_symbol=ns.lookup(CPROVER_PREFIX "memory");
323338
const symbol_exprt symbol_expr(memory_symbol.name, memory_symbol.type);
324339

src/pointer-analysis/value_set_dereference.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,18 +60,20 @@ class value_set_dereferencet final
6060
public:
6161
exprt value;
6262
exprt pointer_guard;
63-
bool ignore;
6463

65-
valuet():value(nil_exprt()), pointer_guard(false_exprt()), ignore(false)
64+
valuet() : value(nil_exprt()), pointer_guard(false_exprt())
6665
{
6766
}
6867
};
6968

69+
static bool should_ignore_value(
70+
const exprt &what,
71+
bool exclude_null_derefs,
72+
const irep_idt &language_mode);
73+
7074
static valuet build_reference_to(
7175
const exprt &what,
7276
const exprt &pointer,
73-
bool exclude_null_derefs,
74-
irep_idt language_mode,
7577
const namespacet &ns);
7678

7779
static bool dereference_type_compare(

0 commit comments

Comments
 (0)