Skip to content

Commit 2fb47cc

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 80c47c9 commit 2fb47cc

File tree

3 files changed

+33
-13
lines changed

3 files changed

+33
-13
lines changed

src/goto-symex/symex_main.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -721,9 +721,11 @@ void goto_symext::try_filter_value_sets(
721721
// one of its possible values in turn. If that leads to a true for some
722722
// value_set_element then we can delete it from the value set that will be
723723
// used if the condition is false, and vice versa.
724-
for(const auto &value_set_element : value_set_elements)
724+
for(const exprt &value_set_element : value_set_elements)
725725
{
726-
if(value_set_element.id() == ID_unknown)
726+
if(
727+
value_set_element.id() == ID_unknown ||
728+
value_set_element.id() == ID_invalid)
727729
{
728730
continue;
729731
}
@@ -735,19 +737,17 @@ void goto_symext::try_filter_value_sets(
735737
continue;
736738
}
737739

738-
value_set_dereferencet::valuet possible_value =
740+
value_set_dereferencet::valuet value =
739741
value_set_dereferencet::build_reference_to(
740742
value_set_element, *symbol_expr, ns);
741743

742-
exprt replacement_expr =
743-
possible_value.value.is_nil()
744-
? static_cast<exprt>(null_pointer_exprt{symbol_type})
745-
: static_cast<exprt>(address_of_exprt{possible_value.value});
744+
if(value.pointer.is_nil())
745+
continue;
746746

747747
exprt modified_condition(condition);
748748

749749
address_of_aware_replace_symbolt replace_symbol{};
750-
replace_symbol.insert(*symbol_expr, replacement_expr);
750+
replace_symbol.insert(*symbol_expr, value.pointer);
751751
replace_symbol(modified_condition);
752752

753753
// 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
@@ -23,6 +23,7 @@ Author: Daniel Kroening, [email protected]
2323
#include <util/config.h>
2424
#include <util/cprover_prefix.h>
2525
#include <util/expr_iterator.h>
26+
#include <util/expr_util.h>
2627
#include <util/format_type.h>
2728
#include <util/fresh_symbol.h>
2829
#include <util/options.h>
@@ -361,7 +362,9 @@ value_set_dereferencet::valuet value_set_dereferencet::build_reference_to(
361362
const exprt &pointer_expr,
362363
const namespacet &ns)
363364
{
364-
const typet &dereference_type = pointer_expr.type().subtype();
365+
const pointer_typet &pointer_type =
366+
type_checked_cast<pointer_typet>(pointer_expr.type());
367+
const typet &dereference_type = pointer_type.subtype();
365368

366369
if(what.id()==ID_unknown ||
367370
what.id()==ID_invalid)
@@ -385,6 +388,7 @@ value_set_dereferencet::valuet value_set_dereferencet::build_reference_to(
385388

386389
if(root_object.id() == ID_null_object)
387390
{
391+
result.pointer = null_pointer_exprt{pointer_type};
388392
}
389393
else if(root_object.id()==ID_dynamic_object)
390394
{
@@ -394,6 +398,7 @@ value_set_dereferencet::valuet value_set_dereferencet::build_reference_to(
394398

395399
// can't remove here, turn into *p
396400
result.value = dereference_exprt{pointer_expr};
401+
result.pointer = pointer_expr;
397402
}
398403
else if(root_object.id()==ID_integer_address)
399404
{
@@ -414,6 +419,7 @@ value_set_dereferencet::valuet value_set_dereferencet::build_reference_to(
414419
memory_symbol.type.subtype());
415420

416421
result.value=index_expr;
422+
result.pointer = address_of_exprt{index_expr};
417423
}
418424
else if(
419425
dereference_type_compare(
@@ -424,6 +430,8 @@ value_set_dereferencet::valuet value_set_dereferencet::build_reference_to(
424430
pointer_offset(pointer_expr),
425431
memory_symbol.type.subtype());
426432
result.value=typecast_exprt(index_expr, dereference_type);
433+
result.pointer =
434+
typecast_exprt{address_of_exprt{index_expr}, pointer_type};
427435
}
428436
else
429437
{
@@ -440,6 +448,7 @@ value_set_dereferencet::valuet value_set_dereferencet::build_reference_to(
440448
symbol_expr,
441449
pointer_offset(pointer_expr),
442450
dereference_type);
451+
result.pointer = address_of_exprt{result.value};
443452
}
444453
}
445454
}
@@ -472,6 +481,8 @@ value_set_dereferencet::valuet value_set_dereferencet::build_reference_to(
472481
// This is great, we are almost done.
473482

474483
result.value = typecast_exprt::conditional_cast(object, dereference_type);
484+
result.pointer =
485+
typecast_exprt::conditional_cast(object_pointer, pointer_type);
475486
}
476487
else if(
477488
root_object_type.id() == ID_array &&
@@ -515,9 +526,12 @@ value_set_dereferencet::valuet value_set_dereferencet::build_reference_to(
515526
// TODO: need to assert well-alignedness
516527
}
517528

518-
result.value = typecast_exprt::conditional_cast(
519-
index_exprt(root_object, adjusted_offset, root_object_type.subtype()),
520-
dereference_type);
529+
const index_exprt &index_expr =
530+
index_exprt(root_object, adjusted_offset, root_object_type.subtype());
531+
result.value =
532+
typecast_exprt::conditional_cast(index_expr, dereference_type);
533+
result.pointer = typecast_exprt::conditional_cast(
534+
address_of_exprt{index_expr}, pointer_type);
521535
}
522536
else
523537
{
@@ -531,11 +545,15 @@ value_set_dereferencet::valuet value_set_dereferencet::build_reference_to(
531545
// Successfully found a member, array index, or combination thereof
532546
// that matches the desired type and offset:
533547
result.value = subexpr.value();
548+
result.pointer = typecast_exprt::conditional_cast(
549+
address_of_exprt{skip_typecast(subexpr.value())}, pointer_type);
534550
return result;
535551
}
536552

537553
// we extract something from the root object
538554
result.value=o.root_object();
555+
result.pointer = typecast_exprt::conditional_cast(
556+
address_of_exprt{skip_typecast(o.root_object())}, pointer_type);
539557

540558
// this is relative to the root object
541559
exprt offset;

src/pointer-analysis/value_set_dereference.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,11 @@ 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{}}, pointer{nil_exprt{}}, pointer_guard{false_exprt{}}
6567
{
6668
}
6769
};

0 commit comments

Comments
 (0)