@@ -931,4 +931,62 @@ inline pointer_offset_exprt &to_pointer_offset_expr(exprt &expr)
931931 return ret;
932932}
933933
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+
934992#endif // CPROVER_UTIL_POINTER_EXPR_H
0 commit comments