Skip to content

Commit a989cca

Browse files
Owensmowton
Owen
authored andcommitted
Add pointer field to value_set_dereferencet::valuet
value_set_dereferencet::valuet is only used as the return value of value_set_dereferencet::build_reference_to. valuet::value is an expression for the object pointed to, which is what's needed for dereferencing. In other contexts, e.g. filtering value-sets, what is needed is an expression for the pointer. This logic already existed in try_filter_value_set, but putting it directly in build_reference_to makes it easier to use it in other places and makes it clear that it didn't cope with typecasts properly.
1 parent 73be2ed commit a989cca

File tree

3 files changed

+35
-13
lines changed

3 files changed

+35
-13
lines changed

src/goto-symex/symex_main.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -707,9 +707,11 @@ void goto_symext::try_filter_value_sets(
707707
// one of its possible values in turn. If that leads to a true for some
708708
// value_set_element then we can delete it from the value set that will be
709709
// used if the condition is false, and vice versa.
710-
for(const auto &value_set_element : value_set_elements)
710+
for(const exprt &value_set_element : value_set_elements)
711711
{
712-
if(value_set_element.id() == ID_unknown)
712+
if(
713+
value_set_element.id() == ID_unknown ||
714+
value_set_element.id() == ID_invalid)
713715
{
714716
continue;
715717
}
@@ -721,19 +723,17 @@ void goto_symext::try_filter_value_sets(
721723
continue;
722724
}
723725

724-
value_set_dereferencet::valuet possible_value =
726+
value_set_dereferencet::valuet value =
725727
value_set_dereferencet::build_reference_to(
726728
value_set_element, *symbol_expr, ns);
727729

728-
exprt replacement_expr =
729-
possible_value.value.is_nil()
730-
? static_cast<exprt>(null_pointer_exprt{symbol_type})
731-
: static_cast<exprt>(address_of_exprt{possible_value.value});
730+
if(value.pointer.is_nil())
731+
continue;
732732

733733
exprt modified_condition(condition);
734734

735735
address_of_aware_replace_symbolt replace_symbol{};
736-
replace_symbol.insert(*symbol_expr, replacement_expr);
736+
replace_symbol.insert(*symbol_expr, value.pointer);
737737
replace_symbol(modified_condition);
738738

739739
// This do_simplify() is needed for the following reason: if `condition` is

src/pointer-analysis/value_set_dereference.cpp

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ Author: Daniel Kroening, [email protected]
2222
#include <util/c_types.h>
2323
#include <util/config.h>
2424
#include <util/cprover_prefix.h>
25+
#include <util/expr_util.h>
2526
#include <util/format_type.h>
2627
#include <util/fresh_symbol.h>
2728
#include <util/options.h>
@@ -295,7 +296,9 @@ value_set_dereferencet::valuet value_set_dereferencet::build_reference_to(
295296
const exprt &pointer_expr,
296297
const namespacet &ns)
297298
{
298-
const typet &dereference_type = pointer_expr.type().subtype();
299+
const pointer_typet &pointer_type =
300+
type_checked_cast<pointer_typet>(pointer_expr.type());
301+
const typet &dereference_type = pointer_type.subtype();
299302

300303
if(what.id()==ID_unknown ||
301304
what.id()==ID_invalid)
@@ -319,6 +322,7 @@ value_set_dereferencet::valuet value_set_dereferencet::build_reference_to(
319322

320323
if(root_object.id() == ID_null_object)
321324
{
325+
result.pointer = null_pointer_exprt{pointer_type};
322326
}
323327
else if(root_object.id()==ID_dynamic_object)
324328
{
@@ -328,6 +332,7 @@ value_set_dereferencet::valuet value_set_dereferencet::build_reference_to(
328332

329333
// can't remove here, turn into *p
330334
result.value = dereference_exprt{pointer_expr};
335+
result.pointer = pointer_expr;
331336
}
332337
else if(root_object.id()==ID_integer_address)
333338
{
@@ -348,6 +353,7 @@ value_set_dereferencet::valuet value_set_dereferencet::build_reference_to(
348353
memory_symbol.type.subtype());
349354

350355
result.value=index_expr;
356+
result.pointer = address_of_exprt{index_expr};
351357
}
352358
else if(
353359
dereference_type_compare(
@@ -358,6 +364,8 @@ value_set_dereferencet::valuet value_set_dereferencet::build_reference_to(
358364
pointer_offset(pointer_expr),
359365
memory_symbol.type.subtype());
360366
result.value=typecast_exprt(index_expr, dereference_type);
367+
result.pointer =
368+
typecast_exprt{address_of_exprt{index_expr}, pointer_type};
361369
}
362370
else
363371
{
@@ -374,6 +382,7 @@ value_set_dereferencet::valuet value_set_dereferencet::build_reference_to(
374382
symbol_expr,
375383
pointer_offset(pointer_expr),
376384
dereference_type);
385+
result.pointer = address_of_exprt{result.value};
377386
}
378387
}
379388
}
@@ -406,6 +415,8 @@ value_set_dereferencet::valuet value_set_dereferencet::build_reference_to(
406415
// This is great, we are almost done.
407416

408417
result.value = typecast_exprt::conditional_cast(object, dereference_type);
418+
result.pointer =
419+
typecast_exprt::conditional_cast(object_pointer, pointer_type);
409420
}
410421
else if(
411422
root_object_type.id() == ID_array &&
@@ -449,9 +460,12 @@ value_set_dereferencet::valuet value_set_dereferencet::build_reference_to(
449460
// TODO: need to assert well-alignedness
450461
}
451462

452-
result.value = typecast_exprt::conditional_cast(
453-
index_exprt(root_object, adjusted_offset, root_object_type.subtype()),
454-
dereference_type);
463+
const index_exprt &index_expr =
464+
index_exprt(root_object, adjusted_offset, root_object_type.subtype());
465+
result.value =
466+
typecast_exprt::conditional_cast(index_expr, dereference_type);
467+
result.pointer = typecast_exprt::conditional_cast(
468+
address_of_exprt{index_expr}, pointer_type);
455469
}
456470
else
457471
{
@@ -465,11 +479,15 @@ value_set_dereferencet::valuet value_set_dereferencet::build_reference_to(
465479
// Successfully found a member, array index, or combination thereof
466480
// that matches the desired type and offset:
467481
result.value = subexpr.value();
482+
result.pointer = typecast_exprt::conditional_cast(
483+
address_of_exprt{skip_typecast(subexpr.value())}, pointer_type);
468484
return result;
469485
}
470486

471487
// we extract something from the root object
472488
result.value=o.root_object();
489+
result.pointer = typecast_exprt::conditional_cast(
490+
address_of_exprt{skip_typecast(o.root_object())}, pointer_type);
473491

474492
// this is relative to the root object
475493
exprt offset;

src/pointer-analysis/value_set_dereference.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,13 @@ class value_set_dereferencet final
5959
{
6060
public:
6161
exprt value;
62+
exprt pointer;
6263
exprt pointer_guard;
6364

64-
valuet() : value(nil_exprt()), pointer_guard(false_exprt())
65+
valuet()
66+
: value{nil_exprt{}},
67+
pointer{nil_exprt{}},
68+
pointer_guard{false_exprt{}}
6569
{
6670
}
6771
};

0 commit comments

Comments
 (0)