Skip to content

Commit 95b7340

Browse files
authored
Merge pull request #6801 from diffblue/pointer_expr
Two pointer expression classes
2 parents 196e7d1 + 3ed1438 commit 95b7340

File tree

12 files changed

+152
-34
lines changed

12 files changed

+152
-34
lines changed

src/goto-instrument/accelerate/acceleration_utils.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -1057,7 +1057,7 @@ bool acceleration_utilst::assign_array(
10571057
{
10581058
if(idx.id()==ID_pointer_offset)
10591059
{
1060-
poly.from_expr(to_unary_expr(idx).op());
1060+
poly.from_expr(to_pointer_offset_expr(idx).pointer());
10611061
}
10621062
else
10631063
{

src/goto-instrument/contracts/instrument_spec_assigns.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -468,7 +468,7 @@ car_exprt instrument_spec_assignst::create_car_expr(
468468

469469
if(target.id() == ID_pointer_object)
470470
{
471-
const auto &arg = to_unary_expr(target).op();
471+
const auto &arg = to_pointer_object_expr(target).pointer();
472472
return {
473473
condition,
474474
target,

src/goto-instrument/contracts/utils.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,8 @@ void havoc_assigns_targetst::append_havoc_code_for_expr(
6969
{
7070
if(expr.id() == ID_pointer_object)
7171
{
72-
append_object_havoc_code_for_expr(location, expr.operands().front(), dest);
72+
append_object_havoc_code_for_expr(
73+
location, to_pointer_object_expr(expr).pointer(), dest);
7374
return;
7475
}
7576

src/goto-programs/interpreter_evaluate.cpp

+2-5
Original file line numberDiff line numberDiff line change
@@ -779,13 +779,10 @@ interpretert::mp_vectort interpretert::evaluate(const exprt &expr)
779779
}
780780
else if(expr.id()==ID_pointer_offset)
781781
{
782-
if(expr.operands().size()!=1)
783-
throw "pointer_offset expects one operand";
784-
785-
if(to_unary_expr(expr).op().type().id() != ID_pointer)
782+
if(to_pointer_offset_expr(expr).op().type().id() != ID_pointer)
786783
throw "pointer_offset expects a pointer operand";
787784

788-
mp_vectort result = evaluate(to_unary_expr(expr).op());
785+
mp_vectort result = evaluate(to_pointer_offset_expr(expr).op());
789786

790787
if(result.size()==1)
791788
{

src/pointer-analysis/value_set.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -309,7 +309,7 @@ bool value_sett::eval_pointer_offset(
309309
if(expr.id()==ID_pointer_offset)
310310
{
311311
const object_mapt reference_set =
312-
get_value_set(to_unary_expr(expr).op(), ns, true);
312+
get_value_set(to_pointer_offset_expr(expr).pointer(), ns, true);
313313

314314
exprt new_expr;
315315
mp_integer previous_offset=0;

src/solvers/flattening/bv_pointers.cpp

+10-8
Original file line numberDiff line numberDiff line change
@@ -683,17 +683,18 @@ bvt bv_pointerst::convert_bitvector(const exprt &expr)
683683
}
684684
else if(
685685
expr.id() == ID_pointer_offset &&
686-
to_unary_expr(expr).op().type().id() == ID_pointer)
686+
to_pointer_offset_expr(expr).pointer().type().id() == ID_pointer)
687687
{
688688
std::size_t width=boolbv_width(expr.type());
689689

690690
if(width==0)
691691
return conversion_failed(expr);
692692

693-
const exprt &op0 = to_unary_expr(expr).op();
694-
const bvt &op0_bv = convert_bv(op0);
693+
const exprt &pointer = to_pointer_offset_expr(expr).pointer();
694+
const bvt &pointer_bv = convert_bv(pointer);
695695

696-
bvt offset_bv = offset_literals(op0_bv, to_pointer_type(op0.type()));
696+
bvt offset_bv =
697+
offset_literals(pointer_bv, to_pointer_type(pointer.type()));
697698

698699
// we do a sign extension to permit negative offsets
699700
return bv_utils.sign_extension(offset_bv, width);
@@ -712,17 +713,18 @@ bvt bv_pointerst::convert_bitvector(const exprt &expr)
712713
}
713714
else if(
714715
expr.id() == ID_pointer_object &&
715-
to_unary_expr(expr).op().type().id() == ID_pointer)
716+
to_pointer_object_expr(expr).pointer().type().id() == ID_pointer)
716717
{
717718
std::size_t width=boolbv_width(expr.type());
718719

719720
if(width==0)
720721
return conversion_failed(expr);
721722

722-
const exprt &op0 = to_unary_expr(expr).op();
723-
const bvt &op0_bv = convert_bv(op0);
723+
const exprt &pointer = to_pointer_object_expr(expr).pointer();
724+
const bvt &pointer_bv = convert_bv(pointer);
724725

725-
bvt object_bv = object_literals(op0_bv, to_pointer_type(op0.type()));
726+
bvt object_bv =
727+
object_literals(pointer_bv, to_pointer_type(pointer.type()));
726728

727729
return bv_utils.zero_extension(object_bv, width);
728730
}

src/solvers/smt2/smt2_conv.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -1562,7 +1562,7 @@ void smt2_convt::convert_expr(const exprt &expr)
15621562
}
15631563
else if(expr.id()==ID_pointer_offset)
15641564
{
1565-
const auto &op = to_unary_expr(expr).op();
1565+
const auto &op = to_pointer_offset_expr(expr).pointer();
15661566

15671567
DATA_INVARIANT(
15681568
op.type().id() == ID_pointer,
@@ -1589,7 +1589,7 @@ void smt2_convt::convert_expr(const exprt &expr)
15891589
}
15901590
else if(expr.id()==ID_pointer_object)
15911591
{
1592-
const auto &op = to_unary_expr(expr).op();
1592+
const auto &op = to_pointer_object_expr(expr).pointer();
15931593

15941594
DATA_INVARIANT(
15951595
op.type().id() == ID_pointer,

src/util/pointer_expr.h

+116
Original file line numberDiff line numberDiff line change
@@ -873,4 +873,120 @@ to_annotated_pointer_constant_expr(exprt &expr)
873873
return ret;
874874
}
875875

876+
/// The offset (in bytes) of a pointer relative to the object
877+
class pointer_offset_exprt : public unary_exprt
878+
{
879+
public:
880+
explicit pointer_offset_exprt(exprt pointer, typet type)
881+
: unary_exprt(ID_pointer_offset, std::move(pointer), std::move(type))
882+
{
883+
}
884+
885+
exprt &pointer()
886+
{
887+
return op0();
888+
}
889+
890+
const exprt &pointer() const
891+
{
892+
return op0();
893+
}
894+
};
895+
896+
template <>
897+
inline bool can_cast_expr<pointer_offset_exprt>(const exprt &base)
898+
{
899+
return base.id() == ID_pointer_offset;
900+
}
901+
902+
inline void validate_expr(const pointer_offset_exprt &value)
903+
{
904+
validate_operands(value, 1, "pointer_offset must have one operand");
905+
DATA_INVARIANT(
906+
value.pointer().type().id() == ID_pointer,
907+
"pointer_offset must have pointer-typed operand");
908+
}
909+
910+
/// \brief Cast an exprt to a \ref pointer_offset_exprt
911+
///
912+
/// \a expr must be known to be \ref pointer_offset_exprt.
913+
///
914+
/// \param expr: Source expression
915+
/// \return Object of type \ref pointer_offset_exprt
916+
inline const pointer_offset_exprt &to_pointer_offset_expr(const exprt &expr)
917+
{
918+
PRECONDITION(expr.id() == ID_pointer_offset);
919+
const pointer_offset_exprt &ret =
920+
static_cast<const pointer_offset_exprt &>(expr);
921+
validate_expr(ret);
922+
return ret;
923+
}
924+
925+
/// \copydoc to_pointer_offset_expr(const exprt &)
926+
inline pointer_offset_exprt &to_pointer_offset_expr(exprt &expr)
927+
{
928+
PRECONDITION(expr.id() == ID_pointer_offset);
929+
pointer_offset_exprt &ret = static_cast<pointer_offset_exprt &>(expr);
930+
validate_expr(ret);
931+
return ret;
932+
}
933+
934+
/// A numerical identifier for the object a pointer points to
935+
class pointer_object_exprt : public unary_exprt
936+
{
937+
public:
938+
explicit pointer_object_exprt(exprt pointer, typet type)
939+
: unary_exprt(ID_pointer_object, std::move(pointer), std::move(type))
940+
{
941+
}
942+
943+
exprt &pointer()
944+
{
945+
return op0();
946+
}
947+
948+
const exprt &pointer() const
949+
{
950+
return op0();
951+
}
952+
};
953+
954+
template <>
955+
inline bool can_cast_expr<pointer_object_exprt>(const exprt &base)
956+
{
957+
return base.id() == ID_pointer_object;
958+
}
959+
960+
inline void validate_expr(const pointer_object_exprt &value)
961+
{
962+
validate_operands(value, 1, "pointer_object must have one operand");
963+
DATA_INVARIANT(
964+
value.pointer().type().id() == ID_pointer,
965+
"pointer_object must have pointer-typed operand");
966+
}
967+
968+
/// \brief Cast an exprt to a \ref pointer_object_exprt
969+
///
970+
/// \a expr must be known to be \ref pointer_object_exprt.
971+
///
972+
/// \param expr: Source expression
973+
/// \return Object of type \ref pointer_object_exprt
974+
inline const pointer_object_exprt &to_pointer_object_expr(const exprt &expr)
975+
{
976+
PRECONDITION(expr.id() == ID_pointer_object);
977+
const pointer_object_exprt &ret =
978+
static_cast<const pointer_object_exprt &>(expr);
979+
validate_expr(ret);
980+
return ret;
981+
}
982+
983+
/// \copydoc to_pointer_object_expr(const exprt &)
984+
inline pointer_object_exprt &to_pointer_object_expr(exprt &expr)
985+
{
986+
PRECONDITION(expr.id() == ID_pointer_object);
987+
pointer_object_exprt &ret = static_cast<pointer_object_exprt &>(expr);
988+
validate_expr(ret);
989+
return ret;
990+
}
991+
876992
#endif // CPROVER_UTIL_POINTER_EXPR_H

src/util/pointer_predicates.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ Author: Daniel Kroening, [email protected]
2222

2323
exprt pointer_object(const exprt &p)
2424
{
25-
return unary_exprt(ID_pointer_object, p, size_type());
25+
return pointer_object_exprt(p, size_type());
2626
}
2727

2828
exprt same_object(const exprt &p1, const exprt &p2)
@@ -37,7 +37,7 @@ exprt object_size(const exprt &pointer)
3737

3838
exprt pointer_offset(const exprt &pointer)
3939
{
40-
return unary_exprt(ID_pointer_offset, pointer, signed_size_type());
40+
return pointer_offset_exprt(pointer, signed_size_type());
4141
}
4242

4343
exprt deallocated(const exprt &pointer, const namespacet &ns)

src/util/simplify_expr.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -2388,7 +2388,7 @@ simplify_exprt::resultt<> simplify_exprt::simplify_node(exprt node)
23882388
}
23892389
else if(expr.id()==ID_pointer_object)
23902390
{
2391-
r = simplify_pointer_object(to_unary_expr(expr));
2391+
r = simplify_pointer_object(to_pointer_object_expr(expr));
23922392
}
23932393
else if(expr.id() == ID_is_dynamic_object)
23942394
{
@@ -2483,7 +2483,7 @@ simplify_exprt::resultt<> simplify_exprt::simplify_node(exprt node)
24832483
}
24842484
else if(expr.id()==ID_pointer_offset)
24852485
{
2486-
r = simplify_pointer_offset(to_unary_expr(expr));
2486+
r = simplify_pointer_offset(to_pointer_offset_expr(expr));
24872487
}
24882488
else if(expr.id()==ID_extractbit)
24892489
{

src/util/simplify_expr_class.h

+4-2
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ class mult_exprt;
5959
class namespacet;
6060
class not_exprt;
6161
class plus_exprt;
62+
class pointer_object_exprt;
63+
class pointer_offset_exprt;
6264
class popcount_exprt;
6365
class refined_string_exprt;
6466
class shift_exprt;
@@ -170,7 +172,7 @@ class simplify_exprt
170172
NODISCARD resultt<> simplify_member(const member_exprt &);
171173
NODISCARD resultt<> simplify_byte_update(const byte_update_exprt &);
172174
NODISCARD resultt<> simplify_byte_extract(const byte_extract_exprt &);
173-
NODISCARD resultt<> simplify_pointer_object(const unary_exprt &);
175+
NODISCARD resultt<> simplify_pointer_object(const pointer_object_exprt &);
174176
NODISCARD resultt<> simplify_object_size(const unary_exprt &);
175177
NODISCARD resultt<> simplify_is_dynamic_object(const unary_exprt &);
176178
NODISCARD resultt<> simplify_is_invalid_pointer(const unary_exprt &);
@@ -180,7 +182,7 @@ class simplify_exprt
180182
NODISCARD resultt<> simplify_unary_plus(const unary_plus_exprt &);
181183
NODISCARD resultt<> simplify_dereference(const dereference_exprt &);
182184
NODISCARD resultt<> simplify_address_of(const address_of_exprt &);
183-
NODISCARD resultt<> simplify_pointer_offset(const unary_exprt &);
185+
NODISCARD resultt<> simplify_pointer_offset(const pointer_offset_exprt &);
184186
NODISCARD resultt<> simplify_bswap(const bswap_exprt &);
185187
NODISCARD resultt<> simplify_isinf(const unary_exprt &);
186188
NODISCARD resultt<> simplify_isnan(const unary_exprt &);

src/util/simplify_expr_pointer.cpp

+9-9
Original file line numberDiff line numberDiff line change
@@ -245,17 +245,17 @@ simplify_exprt::simplify_address_of(const address_of_exprt &expr)
245245
}
246246

247247
simplify_exprt::resultt<>
248-
simplify_exprt::simplify_pointer_offset(const unary_exprt &expr)
248+
simplify_exprt::simplify_pointer_offset(const pointer_offset_exprt &expr)
249249
{
250-
const exprt &ptr = expr.op();
250+
const exprt &ptr = expr.pointer();
251251

252252
if(ptr.id()==ID_if && ptr.operands().size()==3)
253253
{
254254
if_exprt if_expr=lift_if(expr, 0);
255255
if_expr.true_case() =
256-
simplify_pointer_offset(to_unary_expr(if_expr.true_case()));
256+
simplify_pointer_offset(to_pointer_offset_expr(if_expr.true_case()));
257257
if_expr.false_case() =
258-
simplify_pointer_offset(to_unary_expr(if_expr.false_case()));
258+
simplify_pointer_offset(to_pointer_offset_expr(if_expr.false_case()));
259259
return changed(simplify_if(if_expr));
260260
}
261261

@@ -358,8 +358,8 @@ simplify_exprt::simplify_pointer_offset(const unary_exprt &expr)
358358
return unchanged(expr);
359359

360360
// this might change the type of the pointer!
361-
exprt pointer_offset_expr =
362-
simplify_pointer_offset(to_unary_expr(pointer_offset(ptr_expr.front())));
361+
exprt pointer_offset_expr = simplify_pointer_offset(
362+
to_pointer_offset_expr(pointer_offset(ptr_expr.front())));
363363

364364
exprt sum;
365365

@@ -481,7 +481,7 @@ simplify_exprt::resultt<> simplify_exprt::simplify_inequality_pointer_object(
481481
forall_operands(it, expr)
482482
{
483483
PRECONDITION(it->id() == ID_pointer_object);
484-
const exprt &op = to_unary_expr(*it).op();
484+
const exprt &op = to_pointer_object_expr(*it).pointer();
485485

486486
if(op.id()==ID_address_of)
487487
{
@@ -516,9 +516,9 @@ simplify_exprt::resultt<> simplify_exprt::simplify_inequality_pointer_object(
516516
}
517517

518518
simplify_exprt::resultt<>
519-
simplify_exprt::simplify_pointer_object(const unary_exprt &expr)
519+
simplify_exprt::simplify_pointer_object(const pointer_object_exprt &expr)
520520
{
521-
const exprt &op = expr.op();
521+
const exprt &op = expr.pointer();
522522

523523
auto op_result = simplify_object(op);
524524

0 commit comments

Comments
 (0)