CBMC
Loading...
Searching...
No Matches
pointer_expr.h
Go to the documentation of this file.
1/*******************************************************************\
2
3Module: API to expression classes for Pointers
4
5Author: Daniel Kroening, kroening@kroening.com
6
7\*******************************************************************/
8
9#ifndef CPROVER_UTIL_POINTER_EXPR_H
10#define CPROVER_UTIL_POINTER_EXPR_H
11
14
15#include "bitvector_types.h"
16#include "std_expr.h"
17
18class namespacet;
19
24{
25public:
26 pointer_typet(typet _base_type, std::size_t width)
27 : bitvector_typet(ID_pointer, width)
28 {
29 add_subtype() = std::move(_base_type);
30 }
31
35 const typet &base_type() const
36 {
37 return subtype();
38 }
39
44 {
45 return subtype();
46 }
47
48 // Use .base_type() instead -- this method will be removed
49 const typet &subtype() const
50 {
51 // The existence of get_sub() front is enforced by check(...)
52 return static_cast<const typet &>(get_sub().front());
53 }
54
55 // Use .base_type() instead -- this method will be removed
57 {
58 // The existence of get_sub() front is enforced by check(...)
59 return static_cast<typet &>(get_sub().front());
60 }
61
63 {
64 return signedbv_typet(get_width());
65 }
66
67 static void check(
68 const typet &type,
70 {
71 bitvector_typet::check(type, vm);
73 }
74};
75
79template <>
80inline bool can_cast_type<pointer_typet>(const typet &type)
81{
82 return type.id() == ID_pointer;
83}
84
93inline const pointer_typet &to_pointer_type(const typet &type)
94{
97 return static_cast<const pointer_typet &>(type);
98}
99
102{
105 return static_cast<pointer_typet &>(type);
106}
107
110inline bool is_void_pointer(const typet &type)
111{
112 return type.id() == ID_pointer &&
113 to_pointer_type(type).base_type().id() == ID_empty;
114}
115
121{
122public:
123 reference_typet(typet _subtype, std::size_t _width)
124 : pointer_typet(std::move(_subtype), _width)
125 {
126 set(ID_C_reference, true);
127 }
128
129 static void check(
130 const typet &type,
132 {
133 PRECONDITION(type.id() == ID_pointer);
135 vm, type.get_sub().size() == 1, "reference must have one type parameter");
137 static_cast<const reference_typet &>(type);
139 vm, !reference_type.get(ID_width).empty(), "reference must have width");
141 vm, reference_type.get_width() > 0, "reference must have non-zero width");
142 }
143};
144
148template <>
149inline bool can_cast_type<reference_typet>(const typet &type)
150{
151 return can_cast_type<pointer_typet>(type) && type.get_bool(ID_C_reference);
152}
153
162inline const reference_typet &to_reference_type(const typet &type)
163{
165 return static_cast<const reference_typet &>(type);
166}
167
170{
172 return static_cast<reference_typet &>(type);
173}
174
175bool is_reference(const typet &type);
176
177bool is_rvalue_reference(const typet &type);
178
181{
182public:
184 : binary_exprt(
185 exprt(ID_unknown),
186 ID_object_descriptor,
187 exprt(ID_unknown),
188 typet())
189 {
190 }
191
193 : binary_exprt(
194 std::move(_object),
195 ID_object_descriptor,
196 exprt(ID_unknown),
197 typet())
198 {
199 }
200
205 void build(const exprt &expr, const namespacet &ns);
206
208 {
209 return op0();
210 }
211
212 const exprt &object() const
213 {
214 return op0();
215 }
216
217 static const exprt &root_object(const exprt &expr);
218 const exprt &root_object() const
219 {
220 return root_object(object());
221 }
222
224 {
225 return op1();
226 }
227
228 const exprt &offset() const
229 {
230 return op1();
231 }
232};
233
234template <>
236{
237 return base.id() == ID_object_descriptor;
238}
239
240inline void validate_expr(const object_descriptor_exprt &value)
241{
242 validate_operands(value, 2, "Object descriptor must have two operands");
243}
244
251inline const object_descriptor_exprt &
253{
254 PRECONDITION(expr.id() == ID_object_descriptor);
255 const object_descriptor_exprt &ret =
256 static_cast<const object_descriptor_exprt &>(expr);
257 validate_expr(ret);
258 return ret;
259}
260
263{
264 PRECONDITION(expr.id() == ID_object_descriptor);
265 object_descriptor_exprt &ret = static_cast<object_descriptor_exprt &>(expr);
266 validate_expr(ret);
267 return ret;
268}
269
272{
273public:
275 : binary_exprt(
276 exprt(ID_unknown),
277 ID_dynamic_object,
278 exprt(ID_unknown),
279 std::move(type))
280 {
281 }
282
283 void set_instance(unsigned int instance);
284
285 unsigned int get_instance() const;
286
288 {
289 return op1();
290 }
291
292 const exprt &valid() const
293 {
294 return op1();
295 }
296};
297
298template <>
300{
301 return base.id() == ID_dynamic_object;
302}
303
304inline void validate_expr(const dynamic_object_exprt &value)
305{
306 validate_operands(value, 2, "Dynamic object must have two operands");
307}
308
316{
317 PRECONDITION(expr.id() == ID_dynamic_object);
318 const dynamic_object_exprt &ret =
319 static_cast<const dynamic_object_exprt &>(expr);
320 validate_expr(ret);
321 return ret;
322}
323
326{
327 PRECONDITION(expr.id() == ID_dynamic_object);
328 dynamic_object_exprt &ret = static_cast<dynamic_object_exprt &>(expr);
329 validate_expr(ret);
330 return ret;
331}
332
335{
336public:
338 : unary_predicate_exprt(ID_is_dynamic_object, op)
339 {
340 }
341
343 {
344 return op();
345 }
346
347 const exprt &address() const
348 {
349 return op();
350 }
351};
352
353template <>
355{
356 return base.id() == ID_is_dynamic_object;
357}
358
359inline void validate_expr(const is_dynamic_object_exprt &value)
360{
361 validate_operands(value, 1, "is_dynamic_object must have one operand");
362}
363
364inline const is_dynamic_object_exprt &
366{
367 PRECONDITION(expr.id() == ID_is_dynamic_object);
369 expr.operands().size() == 1, "is_dynamic_object must have one operand");
370 return static_cast<const is_dynamic_object_exprt &>(expr);
371}
372
375{
376 PRECONDITION(expr.id() == ID_is_dynamic_object);
378 expr.operands().size() == 1, "is_dynamic_object must have one operand");
379 return static_cast<is_dynamic_object_exprt &>(expr);
380}
381
386{
387public:
390 ID_pointer_in_range,
391 std::move(a),
392 std::move(b),
393 std::move(c),
394 bool_typet())
395 {
396 PRECONDITION(op0().type().id() == ID_pointer);
397 PRECONDITION(op1().type().id() == ID_pointer);
398 PRECONDITION(op2().type().id() == ID_pointer);
399 }
400
401 const exprt &lower_bound() const
402 {
403 return op0();
404 }
405
406 const exprt &pointer() const
407 {
408 return op1();
409 }
410
411 const exprt &upper_bound() const
412 {
413 return op2();
414 }
415
416 // translate into equivalent conjunction
417 exprt lower() const;
418};
419
420template <>
422{
423 return base.id() == ID_pointer_in_range;
424}
425
426inline void validate_expr(const pointer_in_range_exprt &value)
427{
428 validate_operands(value, 3, "pointer_in_range must have three operands");
429}
430
432{
433 PRECONDITION(expr.id() == ID_pointer_in_range);
435 expr.operands().size() == 3, "pointer_in_range must have three operands");
436 return static_cast<const pointer_in_range_exprt &>(expr);
437}
438
441{
442 PRECONDITION(expr.id() == ID_pointer_in_range);
444 expr.operands().size() == 3, "pointer_in_range must have three operands");
445 return static_cast<pointer_in_range_exprt &>(expr);
446}
447
451{
452public:
454 exprt a,
455 exprt b,
456 exprt c,
457 exprt is_deallocated,
458 exprt is_dead)
460 ID_prophecy_pointer_in_range,
461 bool_typet{},
462 {std::move(a),
463 std::move(b),
464 std::move(c),
465 std::move(is_deallocated),
466 std::move(is_dead)})
467 {
468 PRECONDITION(op0().type().id() == ID_pointer);
469 PRECONDITION(op1().type().id() == ID_pointer);
470 PRECONDITION(op2().type().id() == ID_pointer);
471 }
472
473 const exprt &lower_bound() const
474 {
475 return op0();
476 }
477
478 const exprt &pointer() const
479 {
480 return op1();
481 }
482
483 const exprt &upper_bound() const
484 {
485 return op2();
486 }
487
488 const exprt &deallocated_ptr() const
489 {
490 return op3();
491 }
492
493 const exprt &dead_ptr() const
494 {
495 return operands()[4];
496 }
497
498 // translate into equivalent conjunction
499 exprt lower(const namespacet &ns) const;
500};
501
502template <>
504{
505 return base.id() == ID_prophecy_pointer_in_range;
506}
507
509{
511 value, 5, "prophecy_pointer_in_range must have five operands");
512}
513
516{
517 PRECONDITION(expr.id() == ID_prophecy_pointer_in_range);
519 expr.operands().size() == 5,
520 "prophecy_pointer_in_range must have five operands");
521 return static_cast<const prophecy_pointer_in_range_exprt &>(expr);
522}
523
527{
528 PRECONDITION(expr.id() == ID_prophecy_pointer_in_range);
530 expr.operands().size() == 5,
531 "prophecy_pointer_in_range must have five operands");
532 return static_cast<prophecy_pointer_in_range_exprt &>(expr);
533}
534
537{
538public:
539 explicit address_of_exprt(const exprt &op);
540
542 : unary_exprt(ID_address_of, std::move(op), std::move(_type))
543 {
544 }
545
547 {
548 return op0();
549 }
550
551 const exprt &object() const
552 {
553 return op0();
554 }
555};
556
557template <>
559{
560 return base.id() == ID_address_of;
561}
562
563inline void validate_expr(const address_of_exprt &value)
564{
565 validate_operands(value, 1, "Address of must have one operand");
566}
567
574inline const address_of_exprt &to_address_of_expr(const exprt &expr)
575{
576 PRECONDITION(expr.id() == ID_address_of);
577 const address_of_exprt &ret = static_cast<const address_of_exprt &>(expr);
578 validate_expr(ret);
579 return ret;
580}
581
584{
585 PRECONDITION(expr.id() == ID_address_of);
586 address_of_exprt &ret = static_cast<address_of_exprt &>(expr);
587 validate_expr(ret);
588 return ret;
589}
590
593{
594public:
595 explicit object_address_exprt(const symbol_exprt &);
596
598
600 {
601 return get(ID_identifier);
602 }
603
604 const pointer_typet &type() const
605 {
606 return static_cast<const pointer_typet &>(exprt::type());
607 }
608
610 {
611 return static_cast<pointer_typet &>(exprt::type());
612 }
613
615 const typet &object_type() const
616 {
617 return type().base_type();
618 }
619
621};
622
623template <>
625{
626 return base.id() == ID_object_address;
627}
628
629inline void validate_expr(const object_address_exprt &value)
630{
631 validate_operands(value, 0, "object_address must have zero operands");
632}
633
641{
642 PRECONDITION(expr.id() == ID_object_address);
643 const object_address_exprt &ret =
644 static_cast<const object_address_exprt &>(expr);
645 validate_expr(ret);
646 return ret;
647}
648
651{
652 PRECONDITION(expr.id() == ID_object_address);
653 object_address_exprt &ret = static_cast<object_address_exprt &>(expr);
654 validate_expr(ret);
655 return ret;
656}
657
661{
662public:
666 exprt base,
669
671 {
672 return op0();
673 }
674
675 const exprt &base() const
676 {
677 return op0();
678 }
679
680 const pointer_typet &type() const
681 {
682 return static_cast<const pointer_typet &>(exprt::type());
683 }
684
686 {
687 return static_cast<pointer_typet &>(exprt::type());
688 }
689
691 const typet &field_type() const
692 {
693 return type().base_type();
694 }
695
696 const typet &compound_type() const
697 {
698 return to_pointer_type(base().type()).base_type();
699 }
700
702 {
703 return get(ID_component_name);
704 }
705};
706
707template <>
709{
710 return expr.id() == ID_field_address;
711}
712
713inline void validate_expr(const field_address_exprt &value)
714{
715 validate_operands(value, 1, "field_address must have one operand");
716}
717
725{
726 PRECONDITION(expr.id() == ID_field_address);
727 const field_address_exprt &ret =
728 static_cast<const field_address_exprt &>(expr);
729 validate_expr(ret);
730 return ret;
731}
732
735{
736 PRECONDITION(expr.id() == ID_field_address);
737 field_address_exprt &ret = static_cast<field_address_exprt &>(expr);
738 validate_expr(ret);
739 return ret;
740}
741
745{
746public:
751
756
757 const pointer_typet &type() const
758 {
759 return static_cast<const pointer_typet &>(exprt::type());
760 }
761
763 {
764 return static_cast<pointer_typet &>(exprt::type());
765 }
766
768 const typet &element_type() const
769 {
770 return type().base_type();
771 }
772
774 {
775 return op0();
776 }
777
778 const exprt &base() const
779 {
780 return op0();
781 }
782
784 {
785 return op1();
786 }
787
788 const exprt &index() const
789 {
790 return op1();
791 }
792};
793
794template <>
796{
797 return expr.id() == ID_element_address;
798}
799
800inline void validate_expr(const element_address_exprt &value)
801{
802 validate_operands(value, 2, "element_address must have two operands");
803}
804
812{
813 PRECONDITION(expr.id() == ID_element_address);
814 const element_address_exprt &ret =
815 static_cast<const element_address_exprt &>(expr);
816 validate_expr(ret);
817 return ret;
818}
819
822{
823 PRECONDITION(expr.id() == ID_element_address);
824 element_address_exprt &ret = static_cast<element_address_exprt &>(expr);
825 validate_expr(ret);
826 return ret;
827}
828
831{
832public:
833 // The given operand must have pointer type.
834 explicit dereference_exprt(const exprt &op)
835 : unary_exprt(ID_dereference, op, to_pointer_type(op.type()).base_type())
836 {
837 }
838
840 : unary_exprt(ID_dereference, std::move(op), std::move(type))
841 {
842 }
843
845 {
846 return op0();
847 }
848
849 const exprt &pointer() const
850 {
851 return op0();
852 }
853
854 static void check(
855 const exprt &expr,
857 {
859 vm,
860 expr.operands().size() == 1,
861 "dereference expression must have one operand");
862 }
863
864 static void validate(
865 const exprt &expr,
866 const namespacet &ns,
868};
869
870template <>
872{
873 return base.id() == ID_dereference;
874}
875
876inline void validate_expr(const dereference_exprt &value)
877{
878 validate_operands(value, 1, "Dereference must have one operand");
879}
880
888{
889 PRECONDITION(expr.id() == ID_dereference);
890 const dereference_exprt &ret = static_cast<const dereference_exprt &>(expr);
891 validate_expr(ret);
892 return ret;
893}
894
897{
898 PRECONDITION(expr.id() == ID_dereference);
899 dereference_exprt &ret = static_cast<dereference_exprt &>(expr);
900 validate_expr(ret);
901 return ret;
902}
903
906{
907public:
909 : constant_exprt(ID_NULL, std::move(type))
910 {
911 }
912};
913
917{
918public:
920 : binary_predicate_exprt(std::move(pointer), id, std::move(size))
921 {
922 }
923
924 const exprt &pointer() const
925 {
926 return op0();
927 }
928
929 const exprt &size() const
930 {
931 return op1();
932 }
933};
934
935template <>
936inline bool can_cast_expr<r_or_w_ok_exprt>(const exprt &base)
937{
938 return base.id() == ID_r_ok || base.id() == ID_w_ok || base.id() == ID_rw_ok;
939}
940
941inline void validate_expr(const r_or_w_ok_exprt &value)
942{
943 validate_operands(value, 2, "r_or_w_ok must have two operands");
944}
945
946inline const r_or_w_ok_exprt &to_r_or_w_ok_expr(const exprt &expr)
947{
949 expr.id() == ID_r_ok || expr.id() == ID_w_ok || expr.id() == ID_rw_ok);
950 auto &ret = static_cast<const r_or_w_ok_exprt &>(expr);
951 validate_expr(ret);
952 return ret;
953}
954
957{
958public:
960 : r_or_w_ok_exprt(ID_r_ok, std::move(pointer), std::move(size))
961 {
962 }
963};
964
965template <>
966inline bool can_cast_expr<r_ok_exprt>(const exprt &base)
967{
968 return base.id() == ID_r_ok;
969}
970
971inline void validate_expr(const r_ok_exprt &value)
972{
973 validate_operands(value, 2, "r_ok must have two operands");
974}
975
976inline const r_ok_exprt &to_r_ok_expr(const exprt &expr)
977{
978 PRECONDITION(expr.id() == ID_r_ok);
979 const r_ok_exprt &ret = static_cast<const r_ok_exprt &>(expr);
980 validate_expr(ret);
981 return ret;
982}
983
986{
987public:
989 : r_or_w_ok_exprt(ID_w_ok, std::move(pointer), std::move(size))
990 {
991 }
992};
993
994template <>
995inline bool can_cast_expr<w_ok_exprt>(const exprt &base)
996{
997 return base.id() == ID_w_ok;
998}
999
1000inline void validate_expr(const w_ok_exprt &value)
1001{
1002 validate_operands(value, 2, "w_ok must have two operands");
1003}
1004
1005inline const w_ok_exprt &to_w_ok_expr(const exprt &expr)
1006{
1007 PRECONDITION(expr.id() == ID_w_ok);
1008 const w_ok_exprt &ret = static_cast<const w_ok_exprt &>(expr);
1009 validate_expr(ret);
1010 return ret;
1011}
1012
1016{
1017public:
1019 irep_idt id,
1020 exprt pointer,
1021 exprt size,
1022 exprt is_deallocated,
1023 exprt is_dead)
1025 id,
1026 bool_typet{},
1027 {std::move(pointer),
1028 std::move(size),
1029 std::move(is_deallocated),
1030 std::move(is_dead)})
1031 {
1032 }
1033
1036 id,
1037 std::move(pointer),
1038 std::move(size),
1039 nil_exprt{},
1040 nil_exprt{})
1041 {
1042 }
1043
1044 const exprt &pointer() const
1045 {
1046 return op0();
1047 }
1048
1049 const exprt &size() const
1050 {
1051 return op1();
1052 }
1053
1054 const exprt &deallocated_ptr() const
1055 {
1056 return op2();
1057 }
1058
1060 {
1061 return op2();
1062 }
1063
1064 const exprt &dead_ptr() const
1065 {
1066 return op3();
1067 }
1068
1070 {
1071 return op3();
1072 }
1073
1076 exprt lower(const namespacet &ns) const;
1077};
1078
1079template <>
1081{
1082 return base.id() == ID_prophecy_r_ok || base.id() == ID_prophecy_w_ok ||
1083 base.id() == ID_prophecy_rw_ok;
1084}
1085
1087{
1088 validate_operands(value, 4, "r_or_w_ok must have four operands");
1089}
1090
1091inline const prophecy_r_or_w_ok_exprt &
1093{
1095 expr.id() == ID_prophecy_r_ok || expr.id() == ID_prophecy_w_ok ||
1096 expr.id() == ID_prophecy_rw_ok);
1097 auto &ret = static_cast<const prophecy_r_or_w_ok_exprt &>(expr);
1098 validate_expr(ret);
1099 return ret;
1100}
1101
1104{
1105public:
1107 exprt pointer,
1108 exprt size,
1109 exprt is_deallocated,
1110 exprt is_dead)
1112 ID_prophecy_r_ok,
1113 std::move(pointer),
1114 std::move(size),
1115 std::move(is_deallocated),
1116 std::move(is_dead))
1117 {
1118 }
1119
1122 std::move(pointer),
1123 std::move(size),
1124 nil_exprt{},
1125 nil_exprt{})
1126 {
1127 }
1128};
1129
1130template <>
1132{
1133 return base.id() == ID_prophecy_r_ok;
1134}
1135
1136inline void validate_expr(const prophecy_r_ok_exprt &value)
1137{
1138 validate_operands(value, 4, "r_ok must have four operands");
1139}
1140
1142{
1143 PRECONDITION(expr.id() == ID_prophecy_r_ok);
1144 const prophecy_r_ok_exprt &ret =
1145 static_cast<const prophecy_r_ok_exprt &>(expr);
1146 validate_expr(ret);
1147 return ret;
1148}
1149
1152{
1153public:
1155 exprt pointer,
1156 exprt size,
1157 exprt is_deallocated,
1158 exprt is_dead)
1160 ID_prophecy_w_ok,
1161 std::move(pointer),
1162 std::move(size),
1163 std::move(is_deallocated),
1164 std::move(is_dead))
1165 {
1166 }
1167
1170 std::move(pointer),
1171 std::move(size),
1172 nil_exprt{},
1173 nil_exprt{})
1174 {
1175 }
1176};
1177
1178template <>
1180{
1181 return base.id() == ID_prophecy_w_ok;
1182}
1183
1184inline void validate_expr(const prophecy_w_ok_exprt &value)
1185{
1186 validate_operands(value, 4, "w_ok must have four operands");
1187}
1188
1190{
1191 PRECONDITION(expr.id() == ID_prophecy_w_ok);
1192 const prophecy_w_ok_exprt &ret =
1193 static_cast<const prophecy_w_ok_exprt &>(expr);
1194 validate_expr(ret);
1195 return ret;
1196}
1197
1207{
1208public:
1210 const irep_idt &_value,
1211 const exprt &_pointer)
1212 : unary_exprt(ID_annotated_pointer_constant, _pointer, _pointer.type())
1213 {
1214 set_value(_value);
1215 }
1216
1217 const irep_idt &get_value() const
1218 {
1219 return get(ID_value);
1220 }
1221
1222 void set_value(const irep_idt &value)
1223 {
1224 set(ID_value, value);
1225 }
1226
1228 {
1229 return op0();
1230 }
1231
1233 {
1234 return op0();
1235 }
1236};
1237
1238template <>
1240{
1241 return base.id() == ID_annotated_pointer_constant;
1242}
1243
1245{
1247 value, 1, "Annotated pointer constant must have one operand");
1248}
1249
1258{
1259 PRECONDITION(expr.id() == ID_annotated_pointer_constant);
1261 static_cast<const annotated_pointer_constant_exprt &>(expr);
1262 validate_expr(ret);
1263 return ret;
1264}
1265
1269{
1270 PRECONDITION(expr.id() == ID_annotated_pointer_constant);
1272 static_cast<annotated_pointer_constant_exprt &>(expr);
1273 validate_expr(ret);
1274 return ret;
1275}
1276
1279{
1280public:
1282 : unary_exprt(ID_pointer_offset, std::move(pointer), std::move(type))
1283 {
1284 }
1285
1287 {
1288 return op0();
1289 }
1290
1291 const exprt &pointer() const
1292 {
1293 return op0();
1294 }
1295};
1296
1297template <>
1299{
1300 return base.id() == ID_pointer_offset;
1301}
1302
1303inline void validate_expr(const pointer_offset_exprt &value)
1304{
1305 validate_operands(value, 1, "pointer_offset must have one operand");
1307 value.pointer().type().id() == ID_pointer,
1308 "pointer_offset must have pointer-typed operand");
1309}
1310
1318{
1319 PRECONDITION(expr.id() == ID_pointer_offset);
1320 const pointer_offset_exprt &ret =
1321 static_cast<const pointer_offset_exprt &>(expr);
1322 validate_expr(ret);
1323 return ret;
1324}
1325
1328{
1329 PRECONDITION(expr.id() == ID_pointer_offset);
1330 pointer_offset_exprt &ret = static_cast<pointer_offset_exprt &>(expr);
1331 validate_expr(ret);
1332 return ret;
1333}
1334
1337{
1338public:
1340 : unary_exprt(ID_pointer_object, std::move(pointer), std::move(type))
1341 {
1342 }
1343
1345 {
1346 return op0();
1347 }
1348
1349 const exprt &pointer() const
1350 {
1351 return op0();
1352 }
1353};
1354
1355template <>
1357{
1358 return base.id() == ID_pointer_object;
1359}
1360
1361inline void validate_expr(const pointer_object_exprt &value)
1362{
1363 validate_operands(value, 1, "pointer_object must have one operand");
1365 value.pointer().type().id() == ID_pointer,
1366 "pointer_object must have pointer-typed operand");
1367}
1368
1376{
1377 PRECONDITION(expr.id() == ID_pointer_object);
1378 const pointer_object_exprt &ret =
1379 static_cast<const pointer_object_exprt &>(expr);
1380 validate_expr(ret);
1381 return ret;
1382}
1383
1386{
1387 PRECONDITION(expr.id() == ID_pointer_object);
1388 pointer_object_exprt &ret = static_cast<pointer_object_exprt &>(expr);
1389 validate_expr(ret);
1390 return ret;
1391}
1392
1396{
1397public:
1399 : unary_exprt(ID_object_size, std::move(pointer), std::move(type))
1400 {
1401 }
1402
1404 {
1405 return op();
1406 }
1407
1408 const exprt &pointer() const
1409 {
1410 return op();
1411 }
1412};
1413
1421{
1422 PRECONDITION(expr.id() == ID_object_size);
1423 const object_size_exprt &ret = static_cast<const object_size_exprt &>(expr);
1424 validate_expr(ret);
1425 return ret;
1426}
1427
1430{
1431 PRECONDITION(expr.id() == ID_object_size);
1432 object_size_exprt &ret = static_cast<object_size_exprt &>(expr);
1433 validate_expr(ret);
1434 return ret;
1435}
1436
1437template <>
1439{
1440 return base.id() == ID_object_size;
1441}
1442
1443inline void validate_expr(const object_size_exprt &value)
1444{
1445 validate_operands(value, 1, "Object size expression must have one operand.");
1448 "Object size expression must have pointer typed operand.");
1449}
1450
1455{
1456public:
1458 : unary_predicate_exprt(ID_is_cstring, std::move(address))
1459 {
1460 PRECONDITION(as_const(*this).address().type().id() == ID_pointer);
1461 }
1462
1464 {
1465 return op0();
1466 }
1467
1468 const exprt &address() const
1469 {
1470 return op0();
1471 }
1472};
1473
1474template <>
1476{
1477 return base.id() == ID_is_cstring;
1478}
1479
1480inline void validate_expr(const is_cstring_exprt &value)
1481{
1482 validate_operands(value, 1, "is_cstring must have one operand");
1483}
1484
1492{
1493 PRECONDITION(expr.id() == ID_is_cstring);
1494 const is_cstring_exprt &ret = static_cast<const is_cstring_exprt &>(expr);
1495 validate_expr(ret);
1496 return ret;
1497}
1498
1501{
1502 PRECONDITION(expr.id() == ID_is_cstring);
1503 is_cstring_exprt &ret = static_cast<is_cstring_exprt &>(expr);
1504 validate_expr(ret);
1505 return ret;
1506}
1507
1513{
1514public:
1516 : unary_exprt(ID_cstrlen, std::move(address), std::move(type))
1517 {
1518 PRECONDITION(as_const(*this).address().type().id() == ID_pointer);
1519 }
1520
1522 {
1523 return op0();
1524 }
1525
1526 const exprt &address() const
1527 {
1528 return op0();
1529 }
1530};
1531
1532template <>
1533inline bool can_cast_expr<cstrlen_exprt>(const exprt &base)
1534{
1535 return base.id() == ID_cstrlen;
1536}
1537
1538inline void validate_expr(const cstrlen_exprt &value)
1539{
1540 validate_operands(value, 1, "cstrlen must have one operand");
1541}
1542
1549inline const cstrlen_exprt &to_cstrlen_expr(const exprt &expr)
1550{
1551 PRECONDITION(expr.id() == ID_cstrlen);
1552 const cstrlen_exprt &ret = static_cast<const cstrlen_exprt &>(expr);
1553 validate_expr(ret);
1554 return ret;
1555}
1556
1559{
1560 PRECONDITION(expr.id() == ID_cstrlen);
1561 cstrlen_exprt &ret = static_cast<cstrlen_exprt &>(expr);
1562 validate_expr(ret);
1563 return ret;
1564}
1565
1569{
1570public:
1572 : unary_predicate_exprt(ID_live_object, std::move(pointer))
1573 {
1574 PRECONDITION(as_const(*this).pointer().type().id() == ID_pointer);
1575 }
1576
1578 {
1579 return op0();
1580 }
1581
1582 const exprt &pointer() const
1583 {
1584 return op0();
1585 }
1586};
1587
1588template <>
1590{
1591 return base.id() == ID_live_object;
1592}
1593
1594inline void validate_expr(const live_object_exprt &value)
1595{
1596 validate_operands(value, 1, "live_object must have one operand");
1597}
1598
1606{
1607 PRECONDITION(expr.id() == ID_live_object);
1608 const live_object_exprt &ret = static_cast<const live_object_exprt &>(expr);
1609 validate_expr(ret);
1610 return ret;
1611}
1612
1615{
1616 PRECONDITION(expr.id() == ID_live_object);
1617 live_object_exprt &ret = static_cast<live_object_exprt &>(expr);
1618 validate_expr(ret);
1619 return ret;
1620}
1621
1625{
1626public:
1628 : unary_predicate_exprt(ID_writeable_object, std::move(pointer))
1629 {
1630 PRECONDITION(as_const(*this).pointer().type().id() == ID_pointer);
1631 }
1632
1634 {
1635 return op0();
1636 }
1637
1638 const exprt &pointer() const
1639 {
1640 return op0();
1641 }
1642};
1643
1644template <>
1646{
1647 return base.id() == ID_writeable_object;
1648}
1649
1650inline void validate_expr(const writeable_object_exprt &value)
1651{
1652 validate_operands(value, 1, "writeable_object must have one operand");
1653}
1654
1662{
1663 PRECONDITION(expr.id() == ID_writeable_object);
1664 const writeable_object_exprt &ret =
1665 static_cast<const writeable_object_exprt &>(expr);
1666 validate_expr(ret);
1667 return ret;
1668}
1669
1672{
1673 PRECONDITION(expr.id() == ID_writeable_object);
1674 writeable_object_exprt &ret = static_cast<writeable_object_exprt &>(expr);
1675 validate_expr(ret);
1676 return ret;
1677}
1678
1681{
1682public:
1684 : multi_ary_exprt(ID_separate, std::move(__operands), bool_typet())
1685 {
1686 }
1687
1690 std::move(__op0),
1691 ID_separate,
1692 std::move(__op1),
1693 bool_typet())
1694 {
1695 }
1696};
1697
1698template <>
1699inline bool can_cast_expr<separate_exprt>(const exprt &base)
1700{
1701 return base.id() == ID_separate;
1702}
1703
1704inline void validate_expr(const separate_exprt &value)
1705{
1706}
1707
1714inline const separate_exprt &to_separate_expr(const exprt &expr)
1715{
1716 PRECONDITION(expr.id() == ID_separate);
1717 const separate_exprt &ret = static_cast<const separate_exprt &>(expr);
1718 validate_expr(ret);
1719 return ret;
1720}
1721
1724{
1725 PRECONDITION(expr.id() == ID_separate);
1726 separate_exprt &ret = static_cast<separate_exprt &>(expr);
1727 validate_expr(ret);
1728 return ret;
1729}
1730
1731#endif // CPROVER_UTIL_POINTER_EXPR_H
const T & as_const(T &value)
Return a reference to the same object but ensures the type is const.
Definition as_const.h:14
Pre-defined bitvector types.
reference_typet reference_type(const typet &subtype)
Definition c_types.cpp:240
Operator to return the address of an object.
const exprt & object() const
address_of_exprt(const exprt &op)
address_of_exprt(exprt op, pointer_typet _type)
Pointer-typed bitvector constant annotated with the pointer expression that the bitvector is the nume...
const irep_idt & get_value() const
void set_value(const irep_idt &value)
const exprt & symbolic_pointer() const
annotated_pointer_constant_exprt(const irep_idt &_value, const exprt &_pointer)
binary_exprt(const exprt &_lhs, const irep_idt &_id, exprt _rhs)
Definition std_expr.h:651
exprt & op0()
Definition expr.h:134
exprt & op1()
Definition expr.h:137
binary_predicate_exprt(exprt _op0, const irep_idt &_id, exprt _op1)
Definition std_expr.h:739
std::size_t get_width() const
std::size_t width() const
static void check(const typet &type, const validation_modet vm=validation_modet::INVARIANT)
bitvector_typet(const irep_idt &_id)
The Boolean type.
Definition std_types.h:35
constant_exprt(const irep_idt &_value, typet _type)
Definition std_expr.h:3009
An expression, akin to ISO C's strlen, that denotes the length of a zero-terminated string that start...
cstrlen_exprt(exprt address, typet type)
exprt & address()
const exprt & address() const
Operator to dereference a pointer.
static void check(const exprt &expr, const validation_modet vm=validation_modet::INVARIANT)
dereference_exprt(const exprt &op)
const exprt & pointer() const
static void validate(const exprt &expr, const namespacet &ns, const validation_modet vm=validation_modet::INVARIANT)
Check that the dereference expression has the right number of operands, refers to something with a po...
dereference_exprt(exprt op, typet type)
Representation of heap-allocated objects.
unsigned int get_instance() const
void set_instance(unsigned int instance)
const exprt & valid() const
dynamic_object_exprt(typet type)
Operator to return the address of an array element relative to a base address.
element_address_exprt(const exprt &base, exprt index)
constructor for element addresses.
const typet & element_type() const
returns the type of the array element whose address is represented
const exprt & index() const
pointer_typet & type()
const pointer_typet & type() const
const exprt & base() const
exprt & op3()
Definition expr.h:143
expr_protectedt(irep_idt _id, typet _type)
Definition expr.h:353
exprt & op0()
Definition expr.h:134
exprt & op1()
Definition expr.h:137
exprt & op2()
Definition expr.h:140
Base class for all expressions.
Definition expr.h:57
std::vector< exprt > operandst
Definition expr.h:59
exprt()
Definition expr.h:62
typet & type()
Return the type of the expression.
Definition expr.h:85
operandst & operands()
Definition expr.h:95
Operator to return the address of a field relative to a base address.
const typet & field_type() const
returns the type of the field whose address is represented
const exprt & base() const
const irep_idt & component_name() const
pointer_typet & type()
const typet & compound_type() const
field_address_exprt(exprt base, const irep_idt &component_name, pointer_typet type)
constructor for field addresses.
const pointer_typet & type() const
bool get_bool(const irep_idt &name) const
Definition irep.cpp:57
const irep_idt & get(const irep_idt &name) const
Definition irep.cpp:44
void set(const irep_idt &name, const irep_idt &value)
Definition irep.h:414
subt & get_sub()
Definition irep.h:450
const irep_idt & id() const
Definition irep.h:390
A predicate that indicates that a zero-terminated string starts at the given address.
const exprt & address() const
is_cstring_exprt(exprt address)
Evaluates to true if the operand is a pointer to a dynamic object.
is_dynamic_object_exprt(const exprt &op)
const exprt & address() const
A predicate that indicates that the object pointed to is live.
const exprt & pointer() const
live_object_exprt(exprt pointer)
multi_ary_exprt(const irep_idt &_id, operandst _operands, typet _type)
Definition std_expr.h:910
A namespacet is essentially one or two symbol tables bound together, to allow for symbol lookups in t...
Definition namespace.h:91
The NIL expression.
Definition std_expr.h:3144
null_pointer_exprt(pointer_typet type)
nullary_exprt(const irep_idt &_id, typet _type)
Definition std_expr.h:25
Operator to return the address of an object.
const pointer_typet & type() const
pointer_typet & type()
symbol_exprt object_expr() const
irep_idt object_identifier() const
const typet & object_type() const
returns the type of the object whose address is represented
object_address_exprt(const symbol_exprt &)
Split an expression into a base object and a (byte) offset.
const exprt & root_object() const
object_descriptor_exprt(exprt _object)
const exprt & offset() const
void build(const exprt &expr, const namespacet &ns)
Given an expression expr, attempt to find the underlying object it represents by skipping over type c...
const exprt & object() const
Expression for finding the size (in bytes) of the object a pointer points to.
object_size_exprt(exprt pointer, typet type)
const exprt & pointer() const
pointer_in_range(a, b, c) evaluates to true iff same_object(a, b, c) ∧ r_ok(a, offset(c)-offset(a)) ∧...
pointer_in_range_exprt(exprt a, exprt b, exprt c)
const exprt & upper_bound() const
const exprt & lower_bound() const
const exprt & pointer() const
A numerical identifier for the object a pointer points to.
const exprt & pointer() const
pointer_object_exprt(exprt pointer, typet type)
The offset (in bytes) of a pointer relative to the object.
pointer_offset_exprt(exprt pointer, typet type)
const exprt & pointer() const
The pointer type These are both 'bitvector_typet' (they have a width) and 'type_with_subtypet' (they ...
static void check(const typet &type, const validation_modet vm=validation_modet::INVARIANT)
signedbv_typet difference_type() const
const typet & base_type() const
The type of the data what we point to.
typet & base_type()
The type of the data what we point to.
pointer_typet(typet _base_type, std::size_t width)
const typet & subtype() const
typet & subtype()
pointer_in_range (see pointer_in_range_exprt) with prophecy expressions to encode whether a pointer r...
const exprt & upper_bound() const
const exprt & dead_ptr() const
const exprt & lower_bound() const
const exprt & pointer() const
const exprt & deallocated_ptr() const
exprt lower(const namespacet &ns) const
prophecy_pointer_in_range_exprt(exprt a, exprt b, exprt c, exprt is_deallocated, exprt is_dead)
A predicate that indicates that an address range is ok to read.
prophecy_r_ok_exprt(exprt pointer, exprt size)
prophecy_r_ok_exprt(exprt pointer, exprt size, exprt is_deallocated, exprt is_dead)
A base class for a predicate that indicates that an address range is ok to read or write or both.
prophecy_r_or_w_ok_exprt(irep_idt id, exprt pointer, exprt size, exprt is_deallocated, exprt is_dead)
const exprt & deallocated_ptr() const
exprt lower(const namespacet &ns) const
Lower an r_or_w_ok_exprt to arithmetic and logic expressions.
const exprt & dead_ptr() const
const exprt & pointer() const
prophecy_r_or_w_ok_exprt(irep_idt id, exprt pointer, exprt size)
const exprt & size() const
A predicate that indicates that an address range is ok to write.
prophecy_w_ok_exprt(exprt pointer, exprt size)
prophecy_w_ok_exprt(exprt pointer, exprt size, exprt is_deallocated, exprt is_dead)
A predicate that indicates that an address range is ok to read.
r_ok_exprt(exprt pointer, exprt size)
A base class for a predicate that indicates that an address range is ok to read or write or both.
const exprt & size() const
r_or_w_ok_exprt(irep_idt id, exprt pointer, exprt size)
const exprt & pointer() const
The reference type.
reference_typet(typet _subtype, std::size_t _width)
static void check(const typet &type, const validation_modet vm=validation_modet::INVARIANT)
A predicate that indicates that the objects pointed to are distinct.
separate_exprt(exprt::operandst __operands)
separate_exprt(exprt __op0, exprt __op1)
Fixed-width bit-vector with two's complement interpretation.
Expression to hold a symbol (variable).
Definition std_expr.h:132
ternary_exprt(const irep_idt &_id, exprt _op0, exprt _op1, exprt _op2, typet _type)
Definition std_expr.h:71
exprt & op0()
Definition expr.h:134
exprt & op1()
Definition expr.h:137
exprt & op2()
Definition expr.h:140
static void check(const typet &type, const validation_modet vm=validation_modet::INVARIANT)
Definition type.h:199
The type of an expression, extends irept.
Definition type.h:29
typet()
Definition type.h:31
typet & add_subtype()
Definition type.h:53
unary_exprt(const irep_idt &_id, const exprt &_op)
Definition std_expr.h:366
const exprt & op() const
Definition std_expr.h:394
unary_predicate_exprt(const irep_idt &_id, exprt _op)
Definition std_expr.h:576
A predicate that indicates that an address range is ok to write.
w_ok_exprt(exprt pointer, exprt size)
A predicate that indicates that the object pointed to is writeable.
writeable_object_exprt(exprt pointer)
const exprt & pointer() const
void validate_operands(const exprt &value, exprt::operandst::size_type number, const char *message, bool allow_more=false)
Definition expr_cast.h:250
bool can_cast_type(const typet &base)
Check whether a reference to a generic typet is of a specific derived class.
STL namespace.
const live_object_exprt & to_live_object_expr(const exprt &expr)
Cast an exprt to a live_object_exprt.
bool can_cast_expr< separate_exprt >(const exprt &base)
const separate_exprt & to_separate_expr(const exprt &expr)
Cast an exprt to a separate_exprt.
void validate_expr(const object_descriptor_exprt &value)
bool can_cast_type< reference_typet >(const typet &type)
Check whether a reference to a typet is a reference_typet.
const prophecy_r_ok_exprt & to_prophecy_r_ok_expr(const exprt &expr)
bool can_cast_expr< field_address_exprt >(const exprt &expr)
bool is_void_pointer(const typet &type)
This method tests, if the given typet is a pointer of type void.
bool can_cast_type< pointer_typet >(const typet &type)
Check whether a reference to a typet is a pointer_typet.
const prophecy_w_ok_exprt & to_prophecy_w_ok_expr(const exprt &expr)
const object_descriptor_exprt & to_object_descriptor_expr(const exprt &expr)
Cast an exprt to an object_descriptor_exprt.
bool can_cast_expr< prophecy_w_ok_exprt >(const exprt &base)
bool can_cast_expr< live_object_exprt >(const exprt &base)
bool is_reference(const typet &type)
Returns true if the type is a reference.
const r_or_w_ok_exprt & to_r_or_w_ok_expr(const exprt &expr)
const element_address_exprt & to_element_address_expr(const exprt &expr)
Cast an exprt to an element_address_exprt.
const annotated_pointer_constant_exprt & to_annotated_pointer_constant_expr(const exprt &expr)
Cast an exprt to an annotated_pointer_constant_exprt.
bool can_cast_expr< dynamic_object_exprt >(const exprt &base)
const object_address_exprt & to_object_address_expr(const exprt &expr)
Cast an exprt to an object_address_exprt.
const cstrlen_exprt & to_cstrlen_expr(const exprt &expr)
Cast an exprt to a cstrlen_exprt.
bool can_cast_expr< pointer_in_range_exprt >(const exprt &base)
bool can_cast_expr< prophecy_pointer_in_range_exprt >(const exprt &base)
bool can_cast_expr< dereference_exprt >(const exprt &base)
bool is_rvalue_reference(const typet &type)
Returns if the type is an R value reference.
bool can_cast_expr< is_dynamic_object_exprt >(const exprt &base)
const writeable_object_exprt & to_writeable_object_expr(const exprt &expr)
Cast an exprt to a writeable_object_exprt.
bool can_cast_expr< cstrlen_exprt >(const exprt &base)
const reference_typet & to_reference_type(const typet &type)
Cast a typet to a reference_typet.
bool can_cast_expr< object_address_exprt >(const exprt &base)
const prophecy_pointer_in_range_exprt & to_prophecy_pointer_in_range_expr(const exprt &expr)
bool can_cast_expr< object_size_exprt >(const exprt &base)
bool can_cast_expr< is_cstring_exprt >(const exprt &base)
bool can_cast_expr< annotated_pointer_constant_exprt >(const exprt &base)
const pointer_in_range_exprt & to_pointer_in_range_expr(const exprt &expr)
bool can_cast_expr< address_of_exprt >(const exprt &base)
const address_of_exprt & to_address_of_expr(const exprt &expr)
Cast an exprt to an address_of_exprt.
bool can_cast_expr< pointer_offset_exprt >(const exprt &base)
const pointer_typet & to_pointer_type(const typet &type)
Cast a typet to a pointer_typet.
bool can_cast_expr< w_ok_exprt >(const exprt &base)
const w_ok_exprt & to_w_ok_expr(const exprt &expr)
const prophecy_r_or_w_ok_exprt & to_prophecy_r_or_w_ok_expr(const exprt &expr)
const r_ok_exprt & to_r_ok_expr(const exprt &expr)
bool can_cast_expr< element_address_exprt >(const exprt &expr)
bool can_cast_expr< r_ok_exprt >(const exprt &base)
const dereference_exprt & to_dereference_expr(const exprt &expr)
Cast an exprt to a dereference_exprt.
const pointer_offset_exprt & to_pointer_offset_expr(const exprt &expr)
Cast an exprt to a pointer_offset_exprt.
const pointer_object_exprt & to_pointer_object_expr(const exprt &expr)
Cast an exprt to a pointer_object_exprt.
const dynamic_object_exprt & to_dynamic_object_expr(const exprt &expr)
Cast an exprt to a dynamic_object_exprt.
const is_cstring_exprt & to_is_cstring_expr(const exprt &expr)
Cast an exprt to a is_cstring_exprt.
bool can_cast_expr< r_or_w_ok_exprt >(const exprt &base)
const field_address_exprt & to_field_address_expr(const exprt &expr)
Cast an exprt to an field_address_exprt.
bool can_cast_expr< object_descriptor_exprt >(const exprt &base)
const object_size_exprt & to_object_size_expr(const exprt &expr)
Cast an exprt to a object_size_exprt.
const is_dynamic_object_exprt & to_is_dynamic_object_expr(const exprt &expr)
bool can_cast_expr< prophecy_r_or_w_ok_exprt >(const exprt &base)
bool can_cast_expr< writeable_object_exprt >(const exprt &base)
bool can_cast_expr< pointer_object_exprt >(const exprt &base)
bool can_cast_expr< prophecy_r_ok_exprt >(const exprt &base)
#define DATA_INVARIANT(CONDITION, REASON)
This condition should be used to document that assumptions that are made on goto_functions,...
Definition invariant.h:534
#define PRECONDITION(CONDITION)
Definition invariant.h:463
API to expression classes.
#define DATA_CHECK(vm, condition, message)
This macro takes a condition which denotes a well-formedness criterion on goto programs,...
Definition validate.h:22
validation_modet
dstringt irep_idt