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

Lines changed: 1 addition & 1 deletion
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

Lines changed: 1 addition & 1 deletion
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

Lines changed: 2 additions & 1 deletion
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

Lines changed: 2 additions & 5 deletions
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

Lines changed: 1 addition & 1 deletion
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

Lines changed: 10 additions & 8 deletions
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

Lines changed: 2 additions & 2 deletions
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

Lines changed: 116 additions & 0 deletions
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

Lines changed: 2 additions & 2 deletions
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

Lines changed: 2 additions & 2 deletions
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
{

0 commit comments

Comments
 (0)