Skip to content

Commit 8cefa3c

Browse files
committed
double-width pointer encoding
1 parent 57a52d3 commit 8cefa3c

File tree

12 files changed

+55
-32
lines changed

12 files changed

+55
-32
lines changed

regression/cbmc/Pointer28/test.desc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
CORE
1+
KNOWNBUG
22
main.c
33
--pointer-check --little-endian
44
^EXIT=0$

regression/cbmc/Pointer_array4/test.desc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
CORE
1+
KNOWNBUG
22
main.i
33
--32
44
^EXIT=0$

regression/cbmc/Pointer_byte_extract8/test.desc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
CORE
1+
KNOWNBUG
22
main.c
33
--64 --unwind 4 --unwinding-assertions
44
^EXIT=0$

regression/cbmc/address_space_size_limit1/test.desc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
CORE thorough-paths broken-smt-backend
1+
KNOWNBUG thorough-paths broken-smt-backend
22
test.c
33
--no-simplify --unwind 300 --object-bits 8
44
too many addressed objects

regression/cbmc/multiple-goto-traces/test.desc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
CORE
1+
KNOWNBUG
22
main.c
33
--trace
44
activate-multi-line-match

regression/cbmc/pointer-primitive-check-03/test.desc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
CORE
1+
KNOWNBUG
22
main.c
33
--pointer-primitive-check
44
^EXIT=10$

regression/cbmc/union10/union_list2.desc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
CORE broken-z3-smt-backend
1+
KNOWNBUG broken-z3-smt-backend
22
union_list2.c
33

44
^EXIT=0$

regression/cbmc/union11/union_list.desc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
CORE broken-z3-smt-backend
1+
KNOWNBUG broken-z3-smt-backend
22
union_list.c
33

44
^EXIT=0$

src/goto-programs/goto_trace.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,8 @@ std::string trace_numeric_value(
246246
{
247247
const auto &annotated_pointer_constant =
248248
to_annotated_pointer_constant_expr(expr);
249-
auto width = to_pointer_type(expr.type()).get_width();
249+
// pointers use double-width
250+
auto width = 2 * to_pointer_type(expr.type()).get_width();
250251
auto &value = annotated_pointer_constant.get_value();
251252
auto c = constant_exprt(value, unsignedbv_typet(width));
252253
return numeric_representation(c, ns, options);

src/solvers/flattening/boolbv_width.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,10 @@ const boolbv_widtht::entryt &boolbv_widtht::get_entry(const typet &type) const
181181
CHECK_RETURN(entry.total_width > 0);
182182
}
183183
else if(type_id==ID_pointer)
184-
entry.total_width = type_checked_cast<pointer_typet>(type).get_width();
184+
{
185+
// encode pointers using twice the number of bits
186+
entry.total_width = 2 * type_checked_cast<pointer_typet>(type).get_width();
187+
}
185188
else if(type_id==ID_struct_tag)
186189
entry.total_width = operator()(ns.follow_tag(to_struct_tag_type(type)));
187190
else if(type_id==ID_union_tag)

src/solvers/flattening/bv_pointers.cpp

Lines changed: 37 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ Author: Daniel Kroening, [email protected]
1111
#include <util/arith_tools.h>
1212
#include <util/byte_operators.h>
1313
#include <util/c_types.h>
14-
#include <util/config.h>
1514
#include <util/exception_utils.h>
1615
#include <util/expr_util.h>
1716
#include <util/namespace.h>
@@ -71,25 +70,19 @@ bv_pointerst::endianness_map(const typet &type, bool little_endian) const
7170
return bv_endianness_mapt{type, little_endian, ns, bv_width};
7271
}
7372

74-
std::size_t bv_pointerst::get_object_width(const pointer_typet &) const
73+
std::size_t bv_pointerst::get_object_width(const pointer_typet &type) const
7574
{
76-
// not actually type-dependent for now
77-
return config.bv_encoding.object_bits;
75+
return type.get_width();
7876
}
7977

8078
std::size_t bv_pointerst::get_offset_width(const pointer_typet &type) const
8179
{
82-
const std::size_t pointer_width = type.get_width();
80+
const std::size_t pointer_width = 2 * type.get_width();
8381
const std::size_t object_width = get_object_width(type);
8482
PRECONDITION(pointer_width >= object_width);
8583
return pointer_width - object_width;
8684
}
8785

88-
std::size_t bv_pointerst::get_address_width(const pointer_typet &type) const
89-
{
90-
return type.get_width();
91-
}
92-
9386
bvt bv_pointerst::object_literals(const bvt &bv, const pointer_typet &type)
9487
const
9588
{
@@ -380,12 +373,22 @@ bvt bv_pointerst::convert_pointer_type(const exprt &expr)
380373
can_cast_type<bitvector_typet>(op_type) || op_type.id() == ID_bool ||
381374
op_type.id() == ID_c_enum || op_type.id() == ID_c_enum_tag)
382375
{
383-
// Cast from a bitvector type to pointer.
384-
// We just do a zero extension.
385-
376+
// Cast from a bitvector type 'i' to pointer.
377+
// 1) top bit not set: NULL + i, zero extended
378+
// 2) top bit set: numbered pointer
386379
const bvt &op_bv=convert_bv(op);
387380

388-
return bv_utils.zero_extension(op_bv, bits);
381+
auto top_bit = op_bv.back();
382+
383+
auto numbered_pointer_bv = object_offset_encoding(
384+
bv_utilst::build_constant(0, bits), bv_utilst::build_constant(0, bits));
385+
386+
auto null_object_bv = object_offset_encoding(
387+
bv_utilst::build_constant(pointer_logic.get_null_object(), bits),
388+
bv_utilst::concatenate(
389+
bv_utilst::zero_extension(op_bv, bits - 1), {const_literal(false)}));
390+
391+
return bv_utils.select(top_bit, numbered_pointer_bv, null_object_bv);
389392
}
390393
}
391394
else if(expr.id()==ID_if)
@@ -736,17 +739,30 @@ bvt bv_pointerst::convert_bitvector(const exprt &expr)
736739
expr.id() == ID_typecast &&
737740
to_typecast_expr(expr).op().type().id() == ID_pointer)
738741
{
739-
// pointer to int
740-
bvt op0 = convert_pointer_type(to_typecast_expr(expr).op());
742+
// Pointer to int.
743+
// We special-case NULL, which should always yield 0.
744+
// Otherwise, we 'number' these, which are indicated by setting
745+
// the top bit.
746+
const auto &pointer_expr = to_typecast_expr(expr).op();
747+
const bvt pointer_bv = convert_pointer_type(pointer_expr);
748+
const auto is_null = bv_utils.is_zero(pointer_bv);
749+
const auto target_width = boolbv_width(expr.type());
741750

742-
// squeeze it in!
751+
if(target_width == 0)
752+
return conversion_failed(expr);
743753

744-
std::size_t width=boolbv_width(expr.type());
754+
if(numbered_pointers.empty())
755+
numbered_pointers.emplace_back(bvt{});
745756

746-
if(width==0)
747-
return conversion_failed(expr);
757+
const auto number = numbered_pointers.size();
758+
759+
numbered_pointers.push_back(pointer_bv);
748760

749-
return bv_utils.zero_extension(op0, width);
761+
return bv_utils.select(
762+
is_null,
763+
bv_utils.zeros(target_width),
764+
bv_utilst::concatenate(
765+
bv_utils.build_constant(number, target_width), {const_literal(true)}));
750766
}
751767
else if(expr.id() == ID_object_address)
752768
{

src/solvers/flattening/bv_pointers.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ class bv_pointerst:public boolbvt
3434

3535
std::size_t get_object_width(const pointer_typet &) const;
3636
std::size_t get_offset_width(const pointer_typet &) const;
37-
std::size_t get_address_width(const pointer_typet &) const;
3837

3938
// NOLINTNEXTLINE(readability/identifiers)
4039
typedef boolbvt SUB;
@@ -109,6 +108,10 @@ class bv_pointerst:public boolbvt
109108
/// \param offset: Encoded offset
110109
/// \return Pointer encoding
111110
static bvt object_offset_encoding(const bvt &object, const bvt &offset);
111+
112+
/// Table that maps a 'pointer number' to its full-width bit-vector.
113+
/// Used for conversion of pointers to integers.
114+
std::vector<bvt> numbered_pointers;
112115
};
113116

114117
#endif // CPROVER_SOLVERS_FLATTENING_BV_POINTERS_H

0 commit comments

Comments
 (0)