CBMC
Loading...
Searching...
No Matches
bitvector_expr.h
Go to the documentation of this file.
1/*******************************************************************\
2
3Module: API to expression classes for bitvectors
4
5Author: Daniel Kroening, kroening@kroening.com
6
7\*******************************************************************/
8
9#ifndef CPROVER_UTIL_BITVECTOR_EXPR_H
10#define CPROVER_UTIL_BITVECTOR_EXPR_H
11
14
15#include "std_expr.h"
16
19{
20public:
22 : unary_exprt(ID_bswap, std::move(_op), std::move(_type))
23 {
25 }
26
32
33 std::size_t get_bits_per_byte() const
34 {
36 }
37
42};
43
44template <>
45inline bool can_cast_expr<bswap_exprt>(const exprt &base)
46{
47 return base.id() == ID_bswap;
48}
49
50inline void validate_expr(const bswap_exprt &value)
51{
52 validate_operands(value, 1, "bswap must have one operand");
54 value.op().type() == value.type(), "bswap type must match operand type");
55}
56
63inline const bswap_exprt &to_bswap_expr(const exprt &expr)
64{
65 PRECONDITION(expr.id() == ID_bswap);
66 const bswap_exprt &ret = static_cast<const bswap_exprt &>(expr);
68 return ret;
69}
70
73{
74 PRECONDITION(expr.id() == ID_bswap);
75 bswap_exprt &ret = static_cast<bswap_exprt &>(expr);
77 return ret;
78}
79
82{
83public:
85 {
86 }
87};
88
89template <>
90inline bool can_cast_expr<bitnot_exprt>(const exprt &base)
91{
92 return base.id() == ID_bitnot;
93}
94
95inline void validate_expr(const bitnot_exprt &value)
96{
97 validate_operands(value, 1, "Bit-wise not must have one operand");
98}
99
106inline const bitnot_exprt &to_bitnot_expr(const exprt &expr)
107{
108 PRECONDITION(expr.id() == ID_bitnot);
109 const bitnot_exprt &ret = static_cast<const bitnot_exprt &>(expr);
111 return ret;
112}
113
116{
117 PRECONDITION(expr.id() == ID_bitnot);
118 bitnot_exprt &ret = static_cast<bitnot_exprt &>(expr);
120 return ret;
121}
122
127{
128public:
131 {
132 }
133
135 : multi_ary_exprt(ID_bitor, std::move(_operands), std::move(_type))
136 {
137 }
138};
139
140template <>
141inline bool can_cast_expr<bitor_exprt>(const exprt &base)
142{
143 return base.id() == ID_bitor;
144}
145
152inline const bitor_exprt &to_bitor_expr(const exprt &expr)
153{
154 PRECONDITION(expr.id() == ID_bitor);
155 return static_cast<const bitor_exprt &>(expr);
156}
157
160{
161 PRECONDITION(expr.id() == ID_bitor);
162 return static_cast<bitor_exprt &>(expr);
163}
164
173{
174public:
176 : multi_ary_exprt(std::move(_op0), ID_bitnor, std::move(_op1))
177 {
178 }
179
181 : multi_ary_exprt(ID_bitnor, std::move(_operands), std::move(_type))
182 {
183 }
184};
185
186template <>
187inline bool can_cast_expr<bitnor_exprt>(const exprt &base)
188{
189 return base.id() == ID_bitnor;
190}
191
198inline const bitnor_exprt &to_bitnor_expr(const exprt &expr)
199{
200 PRECONDITION(expr.id() == ID_bitnor);
201 return static_cast<const bitnor_exprt &>(expr);
202}
203
206{
207 PRECONDITION(expr.id() == ID_bitnor);
208 return static_cast<bitnor_exprt &>(expr);
209}
210
215{
216public:
218 : multi_ary_exprt(std::move(_op0), ID_bitxor, std::move(_op1))
219 {
220 }
221
223 : multi_ary_exprt(ID_bitxor, std::move(_operands), std::move(_type))
224 {
225 }
226};
227
228template <>
229inline bool can_cast_expr<bitxor_exprt>(const exprt &base)
230{
231 return base.id() == ID_bitxor;
232}
233
240inline const bitxor_exprt &to_bitxor_expr(const exprt &expr)
241{
242 PRECONDITION(expr.id() == ID_bitxor);
243 return static_cast<const bitxor_exprt &>(expr);
244}
245
248{
249 PRECONDITION(expr.id() == ID_bitxor);
250 return static_cast<bitxor_exprt &>(expr);
251}
252
261{
262public:
267
269 : multi_ary_exprt(ID_bitxnor, std::move(_operands), std::move(_type))
270 {
271 }
272};
273
274template <>
275inline bool can_cast_expr<bitxnor_exprt>(const exprt &base)
276{
277 return base.id() == ID_bitxnor;
278}
279
286inline const bitxnor_exprt &to_bitxnor_expr(const exprt &expr)
287{
288 PRECONDITION(expr.id() == ID_bitxnor);
290 return static_cast<const bitxnor_exprt &>(expr);
291}
292
295{
296 PRECONDITION(expr.id() == ID_bitxnor);
298 return static_cast<bitxnor_exprt &>(expr);
299}
300
305{
306public:
309 {
310 }
311
313 : multi_ary_exprt(ID_bitand, std::move(_operands), std::move(_type))
314 {
315 }
316};
317
318template <>
319inline bool can_cast_expr<bitand_exprt>(const exprt &base)
320{
321 return base.id() == ID_bitand;
322}
323
330inline const bitand_exprt &to_bitand_expr(const exprt &expr)
331{
332 PRECONDITION(expr.id() == ID_bitand);
333 return static_cast<const bitand_exprt &>(expr);
334}
335
338{
339 PRECONDITION(expr.id() == ID_bitand);
340 return static_cast<bitand_exprt &>(expr);
341}
342
351{
352public:
357
359 : multi_ary_exprt(ID_bitnand, std::move(_operands), std::move(_type))
360 {
361 }
362};
363
364template <>
365inline bool can_cast_expr<bitnand_exprt>(const exprt &base)
366{
367 return base.id() == ID_bitnand;
368}
369
376inline const bitnand_exprt &to_bitnand_expr(const exprt &expr)
377{
378 PRECONDITION(expr.id() == ID_bitnand);
379 return static_cast<const bitnand_exprt &>(expr);
380}
381
384{
385 PRECONDITION(expr.id() == ID_bitnand);
386 return static_cast<bitnand_exprt &>(expr);
387}
388
391{
392public:
394 : binary_exprt(std::move(_src), _id, std::move(_distance))
395 {
396 }
397
398 shift_exprt(exprt _src, const irep_idt &_id, const std::size_t _distance);
399
401 {
402 return op0();
403 }
404
405 const exprt &op() const
406 {
407 return op0();
408 }
409
411 {
412 return op1();
413 }
414
415 const exprt &distance() const
416 {
417 return op1();
418 }
419};
420
421template <>
422inline bool can_cast_expr<shift_exprt>(const exprt &base)
423{
424 return base.id() == ID_shl || base.id() == ID_ashr || base.id() == ID_lshr ||
425 base.id() == ID_ror || base.id() == ID_rol;
426}
427
428inline void validate_expr(const shift_exprt &value)
429{
430 validate_operands(value, 2, "Shifts must have two operands");
431}
432
439inline const shift_exprt &to_shift_expr(const exprt &expr)
440{
441 const shift_exprt &ret = static_cast<const shift_exprt &>(expr);
443 return ret;
444}
445
448{
449 shift_exprt &ret = static_cast<shift_exprt &>(expr);
451 return ret;
452}
453
455class shl_exprt : public shift_exprt
456{
457public:
459 : shift_exprt(std::move(_src), ID_shl, std::move(_distance))
460 {
461 }
462
463 shl_exprt(exprt _src, const std::size_t _distance)
465 {
466 }
467};
468
469template <>
470inline bool can_cast_expr<shl_exprt>(const exprt &base)
471{
472 return base.id() == ID_shl;
473}
474
481inline const shl_exprt &to_shl_expr(const exprt &expr)
482{
483 PRECONDITION(expr.id() == ID_shl);
484 const shl_exprt &ret = static_cast<const shl_exprt &>(expr);
486 return ret;
487}
488
491{
492 PRECONDITION(expr.id() == ID_shl);
493 shl_exprt &ret = static_cast<shl_exprt &>(expr);
495 return ret;
496}
497
500{
501public:
506
507 ashr_exprt(exprt _src, const std::size_t _distance)
509 {
510 }
511};
512
513template <>
514inline bool can_cast_expr<ashr_exprt>(const exprt &base)
515{
516 return base.id() == ID_ashr;
517}
518
521{
522public:
527
528 lshr_exprt(exprt _src, const std::size_t _distance)
529 : shift_exprt(std::move(_src), ID_lshr, std::move(_distance))
530 {
531 }
532};
533
534template <>
535inline bool can_cast_expr<lshr_exprt>(const exprt &base)
536{
537 return base.id() == ID_lshr;
538}
539
542{
543public:
549
550 extractbit_exprt(exprt _src, const std::size_t _index);
551
553 {
554 return op0();
555 }
556
558 {
559 return op1();
560 }
561
562 const exprt &src() const
563 {
564 return op0();
565 }
566
567 const exprt &index() const
568 {
569 return op1();
570 }
571};
572
573template <>
575{
576 return base.id() == ID_extractbit;
577}
578
579inline void validate_expr(const extractbit_exprt &value)
580{
581 validate_operands(value, 2, "Extract bit must have two operands");
582}
583
590inline const extractbit_exprt &to_extractbit_expr(const exprt &expr)
591{
592 PRECONDITION(expr.id() == ID_extractbit);
593 const extractbit_exprt &ret = static_cast<const extractbit_exprt &>(expr);
595 return ret;
596}
597
600{
601 PRECONDITION(expr.id() == ID_extractbit);
602 extractbit_exprt &ret = static_cast<extractbit_exprt &>(expr);
604 return ret;
605}
606
609{
610public:
619 std::move(_type),
620 {std::move(_src), std::move(_index)})
621 {
622 }
623
624 extractbits_exprt(exprt _src, const std::size_t _index, typet _type);
625
627 {
628 return op0();
629 }
630
632 {
633 return op1();
634 }
635
636 const exprt &src() const
637 {
638 return op0();
639 }
640
641 const exprt &index() const
642 {
643 return op1();
644 }
645};
646
647template <>
649{
650 return base.id() == ID_extractbits;
651}
652
653inline void validate_expr(const extractbits_exprt &value)
654{
655 validate_operands(value, 2, "Extractbits must have two operands");
656}
657
665{
666 PRECONDITION(expr.id() == ID_extractbits);
667 const extractbits_exprt &ret = static_cast<const extractbits_exprt &>(expr);
669 return ret;
670}
671
674{
675 PRECONDITION(expr.id() == ID_extractbits);
676 extractbits_exprt &ret = static_cast<extractbits_exprt &>(expr);
678 return ret;
679}
680
683{
684public:
692 _src.type(),
693 {_src, std::move(_index), std::move(_new_value)})
694 {
695 PRECONDITION(new_value().type().id() == ID_bool);
696 }
697
698 update_bit_exprt(exprt _src, const std::size_t _index, exprt _new_value);
699
701 {
702 return op0();
703 }
704
706 {
707 return op1();
708 }
709
711 {
712 return op2();
713 }
714
715 const exprt &src() const
716 {
717 return op0();
718 }
719
720 const exprt &index() const
721 {
722 return op1();
723 }
724
725 const exprt &new_value() const
726 {
727 return op2();
728 }
729
730 static void check(
731 const exprt &expr,
733 {
734 validate_operands(expr, 3, "update_bit must have three operands");
735 }
736
738 exprt lower() const;
739};
740
741template <>
743{
744 return base.id() == ID_update_bit;
745}
746
753inline const update_bit_exprt &to_update_bit_expr(const exprt &expr)
754{
755 PRECONDITION(expr.id() == ID_update_bit);
757 return static_cast<const update_bit_exprt &>(expr);
758}
759
762{
763 PRECONDITION(expr.id() == ID_update_bit);
765 return static_cast<update_bit_exprt &>(expr);
766}
767
770{
771public:
779 _src.type(),
780 {_src, std::move(_index), std::move(_new_value)})
781 {
782 }
783
785
787 {
788 return op0();
789 }
790
792 {
793 return op1();
794 }
795
797 {
798 return op2();
799 }
800
801 const exprt &src() const
802 {
803 return op0();
804 }
805
806 const exprt &index() const
807 {
808 return op1();
809 }
810
811 const exprt &new_value() const
812 {
813 return op2();
814 }
815
816 static void check(
817 const exprt &expr,
819 {
820 validate_operands(expr, 3, "update_bits must have three operands");
821 }
822
824 exprt lower() const;
825};
826
827template <>
829{
830 return base.id() == ID_update_bits;
831}
832
840{
841 PRECONDITION(expr.id() == ID_update_bits);
843 return static_cast<const update_bits_exprt &>(expr);
844}
845
848{
849 PRECONDITION(expr.id() == ID_update_bits);
851 return static_cast<update_bits_exprt &>(expr);
852}
853
856{
857public:
859 : binary_exprt(
860 std::move(_times),
862 std::move(_src),
863 std::move(_type))
864 {
865 }
866
868 {
869 return static_cast<constant_exprt &>(op0());
870 }
871
872 const constant_exprt &times() const
873 {
874 return static_cast<const constant_exprt &>(op0());
875 }
876
878 {
879 return op1();
880 }
881
882 const exprt &op() const
883 {
884 return op1();
885 }
886};
887
888template <>
890{
891 return base.id() == ID_replication;
892}
893
894inline void validate_expr(const replication_exprt &value)
895{
896 validate_operands(value, 2, "Bit-wise replication must have two operands");
897}
898
906{
907 PRECONDITION(expr.id() == ID_replication);
908 const replication_exprt &ret = static_cast<const replication_exprt &>(expr);
910 return ret;
911}
912
915{
916 PRECONDITION(expr.id() == ID_replication);
917 replication_exprt &ret = static_cast<replication_exprt &>(expr);
919 return ret;
920}
921
928{
929public:
934
938 {std::move(_op0), std::move(_op1)},
939 std::move(_type))
940 {
941 }
942};
943
944template <>
946{
947 return base.id() == ID_concatenation;
948}
949
957{
959 return static_cast<const concatenation_exprt &>(expr);
960}
961
964{
966 return static_cast<concatenation_exprt &>(expr);
967}
968
971{
972public:
974 : unary_exprt(ID_popcount, std::move(_op), std::move(_type))
975 {
976 }
977
978 explicit popcount_exprt(const exprt &_op)
980 {
981 }
982
985 exprt lower() const;
986};
987
988template <>
989inline bool can_cast_expr<popcount_exprt>(const exprt &base)
990{
991 return base.id() == ID_popcount;
992}
993
994inline void validate_expr(const popcount_exprt &value)
995{
996 validate_operands(value, 1, "popcount must have one operand");
997}
998
1005inline const popcount_exprt &to_popcount_expr(const exprt &expr)
1006{
1007 PRECONDITION(expr.id() == ID_popcount);
1008 const popcount_exprt &ret = static_cast<const popcount_exprt &>(expr);
1010 return ret;
1011}
1012
1015{
1016 PRECONDITION(expr.id() == ID_popcount);
1017 popcount_exprt &ret = static_cast<popcount_exprt &>(expr);
1019 return ret;
1020}
1021
1025{
1026public:
1028 : binary_predicate_exprt(std::move(_lhs), make_id(kind), std::move(_rhs))
1029 {
1030 INVARIANT(
1031 valid_id(id()),
1032 "The kind used to construct binary_overflow_exprt should be in the set "
1033 "of expected valid kinds.");
1034 }
1035
1036 static void check(
1037 const exprt &expr,
1039 {
1040 binary_exprt::check(expr, vm);
1041
1042 if(expr.id() != ID_overflow_shl)
1043 {
1045 DATA_CHECK(
1046 vm,
1047 binary_expr.lhs().type() == binary_expr.rhs().type(),
1048 "operand types must match");
1049 }
1050 }
1051
1052 static void validate(
1053 const exprt &expr,
1054 const namespacet &,
1056 {
1057 check(expr, vm);
1058 }
1059
1061 static bool valid_id(const irep_idt &id)
1062 {
1063 return id == ID_overflow_plus || id == ID_overflow_mult ||
1064 id == ID_overflow_minus || id == ID_overflow_shl;
1065 }
1066
1067private:
1068 static irep_idt make_id(const irep_idt &kind)
1069 {
1070 if(valid_id(kind))
1071 return kind;
1072 else
1073 return "overflow-" + id2string(kind);
1074 }
1075};
1076
1077template <>
1079{
1080 return binary_overflow_exprt::valid_id(base.id());
1081}
1082
1083inline void validate_expr(const binary_overflow_exprt &value)
1084{
1086 value, 2, "binary overflow expression must have two operands");
1087}
1088
1096{
1098 expr.id() == ID_overflow_plus || expr.id() == ID_overflow_mult ||
1099 expr.id() == ID_overflow_minus || expr.id() == ID_overflow_shl);
1100 const binary_overflow_exprt &ret =
1101 static_cast<const binary_overflow_exprt &>(expr);
1103 return ret;
1104}
1105
1108{
1110 expr.id() == ID_overflow_plus || expr.id() == ID_overflow_mult ||
1111 expr.id() == ID_overflow_minus || expr.id() == ID_overflow_shl);
1112 binary_overflow_exprt &ret = static_cast<binary_overflow_exprt &>(expr);
1114 return ret;
1115}
1116
1118{
1119public:
1124
1127 exprt lower() const;
1128};
1129
1130template <>
1132{
1133 return base.id() == ID_overflow_plus;
1134}
1135
1137{
1138public:
1143
1146 exprt lower() const;
1147};
1148
1149template <>
1151{
1152 return base.id() == ID_overflow_minus;
1153}
1154
1156{
1157public:
1162
1165 exprt lower() const;
1166};
1167
1168template <>
1170{
1171 return base.id() == ID_overflow_mult;
1172}
1173
1175{
1176public:
1181};
1182
1183template <>
1185{
1186 return base.id() == ID_overflow_shl;
1187}
1188
1192{
1193public:
1195 : unary_predicate_exprt("overflow-" + id2string(kind), std::move(_op))
1196 {
1197 }
1198
1199 static void check(
1200 const exprt &expr,
1202 {
1203 unary_exprt::check(expr, vm);
1204 }
1205
1206 static void validate(
1207 const exprt &expr,
1208 const namespacet &,
1210 {
1211 check(expr, vm);
1212 }
1213};
1214
1215template <>
1217{
1218 return base.id() == ID_overflow_unary_minus;
1219}
1220
1221inline void validate_expr(const unary_overflow_exprt &value)
1222{
1224 value, 1, "unary overflow expression must have one operand");
1225}
1226
1230{
1231public:
1236
1237 static void check(
1238 const exprt &expr,
1240 {
1241 unary_exprt::check(expr, vm);
1242 }
1243
1244 static void validate(
1245 const exprt &expr,
1246 const namespacet &,
1248 {
1249 check(expr, vm);
1250 }
1251};
1252
1253template <>
1255{
1256 return base.id() == ID_overflow_unary_minus;
1257}
1258
1260{
1262 value, 1, "unary minus overflow expression must have one operand");
1263}
1264
1272{
1274 const unary_overflow_exprt &ret =
1275 static_cast<const unary_overflow_exprt &>(expr);
1277 return ret;
1278}
1279
1282{
1284 unary_overflow_exprt &ret = static_cast<unary_overflow_exprt &>(expr);
1286 return ret;
1287}
1288
1295{
1296public:
1302
1305 {
1306 }
1307
1308 bool zero_permitted() const
1309 {
1310 return !get_bool(ID_C_bounds_check);
1311 }
1312
1313 void zero_permitted(bool value)
1314 {
1315 set(ID_C_bounds_check, !value);
1316 }
1317
1318 static void check(
1319 const exprt &expr,
1321 {
1322 DATA_CHECK(
1323 vm,
1324 expr.operands().size() == 1,
1325 "unary expression must have a single operand");
1326 DATA_CHECK(
1327 vm,
1329 "operand must be of bitvector type");
1330 }
1331
1332 static void validate(
1333 const exprt &expr,
1334 const namespacet &,
1336 {
1337 check(expr, vm);
1338 }
1339
1342 exprt lower() const;
1343};
1344
1345template <>
1347{
1348 return base.id() == ID_count_leading_zeros;
1349}
1350
1352{
1353 validate_operands(value, 1, "count_leading_zeros must have one operand");
1354}
1355
1362inline const count_leading_zeros_exprt &
1364{
1367 static_cast<const count_leading_zeros_exprt &>(expr);
1369 return ret;
1370}
1371
1381
1388{
1389public:
1395
1400
1401 bool zero_permitted() const
1402 {
1403 return !get_bool(ID_C_bounds_check);
1404 }
1405
1406 void zero_permitted(bool value)
1407 {
1408 set(ID_C_bounds_check, !value);
1409 }
1410
1411 static void check(
1412 const exprt &expr,
1414 {
1415 DATA_CHECK(
1416 vm,
1417 expr.operands().size() == 1,
1418 "unary expression must have a single operand");
1419 DATA_CHECK(
1420 vm,
1422 "operand must be of bitvector type");
1423 }
1424
1425 static void validate(
1426 const exprt &expr,
1427 const namespacet &,
1429 {
1430 check(expr, vm);
1431 }
1432
1435 exprt lower() const;
1436};
1437
1438template <>
1440{
1441 return base.id() == ID_count_trailing_zeros;
1442}
1443
1445{
1446 validate_operands(value, 1, "count_trailing_zeros must have one operand");
1447}
1448
1455inline const count_trailing_zeros_exprt &
1457{
1460 static_cast<const count_trailing_zeros_exprt &>(expr);
1462 return ret;
1463}
1464
1474
1477{
1478public:
1480 : unary_exprt(ID_bitreverse, std::move(op))
1481 {
1482 }
1483
1486 exprt lower() const;
1487};
1488
1489template <>
1491{
1492 return base.id() == ID_bitreverse;
1493}
1494
1495inline void validate_expr(const bitreverse_exprt &value)
1496{
1497 validate_operands(value, 1, "Bit-wise reverse must have one operand");
1498}
1499
1507{
1508 PRECONDITION(expr.id() == ID_bitreverse);
1509 const bitreverse_exprt &ret = static_cast<const bitreverse_exprt &>(expr);
1511 return ret;
1512}
1513
1516{
1517 PRECONDITION(expr.id() == ID_bitreverse);
1518 bitreverse_exprt &ret = static_cast<bitreverse_exprt &>(expr);
1520 return ret;
1521}
1522
1525{
1526public:
1531
1533 : binary_exprt(
1534 std::move(_lhs),
1536 std::move(_rhs),
1537 std::move(_type))
1538 {
1539 }
1540};
1541
1542template <>
1544{
1545 return base.id() == ID_saturating_plus;
1546}
1547
1548inline void validate_expr(const saturating_plus_exprt &value)
1549{
1550 validate_operands(value, 2, "saturating plus must have two operands");
1551}
1552
1560{
1562 const saturating_plus_exprt &ret =
1563 static_cast<const saturating_plus_exprt &>(expr);
1565 return ret;
1566}
1567
1570{
1572 saturating_plus_exprt &ret = static_cast<saturating_plus_exprt &>(expr);
1574 return ret;
1575}
1576
1579{
1580public:
1585};
1586
1587template <>
1589{
1590 return base.id() == ID_saturating_minus;
1591}
1592
1593inline void validate_expr(const saturating_minus_exprt &value)
1594{
1595 validate_operands(value, 2, "saturating minus must have two operands");
1596}
1597
1605{
1608 static_cast<const saturating_minus_exprt &>(expr);
1610 return ret;
1611}
1612
1615{
1617 saturating_minus_exprt &ret = static_cast<saturating_minus_exprt &>(expr);
1619 return ret;
1620}
1621
1625{
1626public:
1629 make_id(kind),
1631 {{ID_value, _lhs.type()},
1632 {"overflow-" + id2string(kind), bool_typet{}}}},
1633 {_lhs, std::move(_rhs)})
1634 {
1635 INVARIANT(
1636 valid_id(id()),
1637 "The kind used to construct overflow_result_exprt should be in the set "
1638 "of expected valid kinds.");
1639 }
1640
1643 make_id(kind),
1645 {{ID_value, _op.type()},
1646 {"overflow-" + id2string(kind), bool_typet{}}}},
1647 {_op})
1648 {
1649 INVARIANT(
1650 valid_id(id()),
1651 "The kind used to construct overflow_result_exprt should be in the set "
1652 "of expected valid kinds.");
1653 }
1654
1655 // make op0 and op1 public
1656 using exprt::op0;
1657 using exprt::op1;
1658
1659 const exprt &op2() const = delete;
1660 exprt &op2() = delete;
1661 const exprt &op3() const = delete;
1662 exprt &op3() = delete;
1663
1664 static void check(
1665 const exprt &expr,
1667 {
1669 binary_exprt::check(expr, vm);
1670
1671 if(
1673 expr.id() != ID_overflow_result_shl)
1674 {
1676 DATA_CHECK(
1677 vm,
1678 binary_expr.lhs().type() == binary_expr.rhs().type(),
1679 "operand types must match");
1680 }
1681 }
1682
1683 static void validate(
1684 const exprt &expr,
1685 const namespacet &,
1687 {
1688 check(expr, vm);
1689 }
1690
1692 static bool valid_id(const irep_idt &id)
1693 {
1694 return id == ID_overflow_result_plus || id == ID_overflow_result_mult ||
1697 }
1698
1699private:
1700 static irep_idt make_id(const irep_idt &kind)
1701 {
1702 return "overflow_result-" + id2string(kind);
1703 }
1704};
1705
1706template <>
1708{
1709 return overflow_result_exprt::valid_id(base.id());
1710}
1711
1712inline void validate_expr(const overflow_result_exprt &value)
1713{
1714 if(value.id() == ID_overflow_result_unary_minus)
1715 {
1717 value, 1, "unary overflow expression must have two operands");
1718 }
1719 else
1720 {
1722 value, 2, "binary overflow expression must have two operands");
1723 }
1724}
1725
1733{
1735 const overflow_result_exprt &ret =
1736 static_cast<const overflow_result_exprt &>(expr);
1738 return ret;
1739}
1740
1749
1753{
1754public:
1756 : unary_exprt(ID_find_first_set, std::move(_op), std::move(_type))
1757 {
1758 }
1759
1762 {
1763 }
1764
1765 static void check(
1766 const exprt &expr,
1768 {
1769 DATA_CHECK(
1770 vm,
1771 expr.operands().size() == 1,
1772 "unary expression must have a single operand");
1773 DATA_CHECK(
1774 vm,
1776 "operand must be of bitvector type");
1777 }
1778
1779 static void validate(
1780 const exprt &expr,
1781 const namespacet &,
1783 {
1784 check(expr, vm);
1785 }
1786
1789 exprt lower() const;
1790};
1791
1792template <>
1794{
1795 return base.id() == ID_find_first_set;
1796}
1797
1798inline void validate_expr(const find_first_set_exprt &value)
1799{
1800 validate_operands(value, 1, "find_first_set must have one operand");
1801}
1802
1810{
1812 const find_first_set_exprt &ret =
1813 static_cast<const find_first_set_exprt &>(expr);
1815 return ret;
1816}
1817
1820{
1822 find_first_set_exprt &ret = static_cast<find_first_set_exprt &>(expr);
1824 return ret;
1825}
1826
1833{
1834public:
1836 : unary_exprt(ID_zero_extend, std::move(_op), std::move(_type))
1837 {
1838 }
1839
1840 // a lowering to extraction or concatenation
1841 exprt lower() const;
1842};
1843
1844template <>
1846{
1847 return base.id() == ID_zero_extend;
1848}
1849
1857{
1858 PRECONDITION(expr.id() == ID_zero_extend);
1860 return static_cast<const zero_extend_exprt &>(expr);
1861}
1862
1865{
1866 PRECONDITION(expr.id() == ID_zero_extend);
1868 return static_cast<zero_extend_exprt &>(expr);
1869}
1870
1874{
1875public:
1878 {
1879 }
1880
1882 exprt lower() const;
1883};
1884
1891inline const onehot_exprt &to_onehot_expr(const exprt &expr)
1892{
1893 PRECONDITION(expr.id() == ID_onehot);
1894 onehot_exprt::check(expr);
1895 return static_cast<const onehot_exprt &>(expr);
1896}
1897
1900{
1901 PRECONDITION(expr.id() == ID_onehot);
1902 onehot_exprt::check(expr);
1903 return static_cast<onehot_exprt &>(expr);
1904}
1905
1909{
1910public:
1913 {
1914 }
1915
1917 exprt lower() const;
1918};
1919
1926inline const onehot0_exprt &to_onehot0_expr(const exprt &expr)
1927{
1928 PRECONDITION(expr.id() == ID_onehot0);
1930 return static_cast<const onehot0_exprt &>(expr);
1931}
1932
1935{
1936 PRECONDITION(expr.id() == ID_onehot0);
1938 return static_cast<onehot0_exprt &>(expr);
1939}
1940
1941#endif // CPROVER_UTIL_BITVECTOR_EXPR_H
bool can_cast_expr< count_trailing_zeros_exprt >(const exprt &base)
const bitxnor_exprt & to_bitxnor_expr(const exprt &expr)
Cast an exprt to a bitxnor_exprt.
const onehot0_exprt & to_onehot0_expr(const exprt &expr)
Cast an exprt to a onehot0_exprt.
const saturating_minus_exprt & to_saturating_minus_expr(const exprt &expr)
Cast an exprt to a saturating_minus_exprt.
const replication_exprt & to_replication_expr(const exprt &expr)
Cast an exprt to a replication_exprt.
const saturating_plus_exprt & to_saturating_plus_expr(const exprt &expr)
Cast an exprt to a saturating_plus_exprt.
bool can_cast_expr< mult_overflow_exprt >(const exprt &base)
bool can_cast_expr< replication_exprt >(const exprt &base)
bool can_cast_expr< bswap_exprt >(const exprt &base)
const shift_exprt & to_shift_expr(const exprt &expr)
Cast an exprt to a shift_exprt.
const bitnand_exprt & to_bitnand_expr(const exprt &expr)
Cast an exprt to a bitnand_exprt.
bool can_cast_expr< find_first_set_exprt >(const exprt &base)
bool can_cast_expr< saturating_plus_exprt >(const exprt &base)
const shl_exprt & to_shl_expr(const exprt &expr)
Cast an exprt to a shl_exprt.
bool can_cast_expr< bitreverse_exprt >(const exprt &base)
bool can_cast_expr< count_leading_zeros_exprt >(const exprt &base)
const popcount_exprt & to_popcount_expr(const exprt &expr)
Cast an exprt to a popcount_exprt.
const update_bits_exprt & to_update_bits_expr(const exprt &expr)
Cast an exprt to an update_bits_exprt.
bool can_cast_expr< bitnand_exprt >(const exprt &base)
bool can_cast_expr< shift_exprt >(const exprt &base)
bool can_cast_expr< bitand_exprt >(const exprt &base)
bool can_cast_expr< update_bits_exprt >(const exprt &base)
bool can_cast_expr< saturating_minus_exprt >(const exprt &base)
const extractbits_exprt & to_extractbits_expr(const exprt &expr)
Cast an exprt to an extractbits_exprt.
bool can_cast_expr< popcount_exprt >(const exprt &base)
const onehot_exprt & to_onehot_expr(const exprt &expr)
Cast an exprt to a onehot_exprt.
bool can_cast_expr< extractbits_exprt >(const exprt &base)
bool can_cast_expr< bitxor_exprt >(const exprt &base)
const binary_overflow_exprt & to_binary_overflow_expr(const exprt &expr)
Cast an exprt to a binary_overflow_exprt.
bool can_cast_expr< bitor_exprt >(const exprt &base)
bool can_cast_expr< update_bit_exprt >(const exprt &base)
bool can_cast_expr< minus_overflow_exprt >(const exprt &base)
void validate_expr(const bswap_exprt &value)
const find_first_set_exprt & to_find_first_set_expr(const exprt &expr)
Cast an exprt to a find_first_set_exprt.
bool can_cast_expr< ashr_exprt >(const exprt &base)
bool can_cast_expr< zero_extend_exprt >(const exprt &base)
bool can_cast_expr< shl_overflow_exprt >(const exprt &base)
bool can_cast_expr< bitxnor_exprt >(const exprt &base)
const bitor_exprt & to_bitor_expr(const exprt &expr)
Cast an exprt to a bitor_exprt.
const bitand_exprt & to_bitand_expr(const exprt &expr)
Cast an exprt to a bitand_exprt.
bool can_cast_expr< overflow_result_exprt >(const exprt &base)
const update_bit_exprt & to_update_bit_expr(const exprt &expr)
Cast an exprt to an update_bit_exprt.
const bitnot_exprt & to_bitnot_expr(const exprt &expr)
Cast an exprt to a bitnot_exprt.
const unary_overflow_exprt & to_unary_overflow_expr(const exprt &expr)
Cast an exprt to a unary_overflow_exprt.
const bitnor_exprt & to_bitnor_expr(const exprt &expr)
Cast an exprt to a bitnor_exprt.
bool can_cast_expr< concatenation_exprt >(const exprt &base)
bool can_cast_expr< unary_overflow_exprt >(const exprt &base)
const overflow_result_exprt & to_overflow_result_expr(const exprt &expr)
Cast an exprt to a overflow_result_exprt.
bool can_cast_expr< lshr_exprt >(const exprt &base)
bool can_cast_expr< shl_exprt >(const exprt &base)
const bitxor_exprt & to_bitxor_expr(const exprt &expr)
Cast an exprt to a bitxor_exprt.
const bswap_exprt & to_bswap_expr(const exprt &expr)
Cast an exprt to a bswap_exprt.
bool can_cast_expr< plus_overflow_exprt >(const exprt &base)
const count_leading_zeros_exprt & to_count_leading_zeros_expr(const exprt &expr)
Cast an exprt to a count_leading_zeros_exprt.
bool can_cast_expr< bitnot_exprt >(const exprt &base)
bool can_cast_expr< binary_overflow_exprt >(const exprt &base)
const bitreverse_exprt & to_bitreverse_expr(const exprt &expr)
Cast an exprt to a bitreverse_exprt.
const extractbit_exprt & to_extractbit_expr(const exprt &expr)
Cast an exprt to an extractbit_exprt.
bool can_cast_expr< unary_minus_overflow_exprt >(const exprt &base)
bool can_cast_expr< extractbit_exprt >(const exprt &base)
const concatenation_exprt & to_concatenation_expr(const exprt &expr)
Cast an exprt to a concatenation_exprt.
bool can_cast_expr< bitnor_exprt >(const exprt &base)
const zero_extend_exprt & to_zero_extend_expr(const exprt &expr)
Cast an exprt to a zero_extend_exprt.
const count_trailing_zeros_exprt & to_count_trailing_zeros_expr(const exprt &expr)
Cast an exprt to a count_trailing_zeros_exprt.
ait supplies three of the four components needed: an abstract interpreter (in this case handling func...
Definition ai.h:562
Arithmetic right shift.
ashr_exprt(exprt _src, exprt _distance)
ashr_exprt(exprt _src, const std::size_t _distance)
A base class for binary expressions.
Definition std_expr.h:638
static void check(const exprt &expr, const validation_modet vm=validation_modet::INVARIANT)
Definition std_expr.h:650
exprt & op0()
Definition expr.h:134
exprt & op1()
Definition expr.h:137
A Boolean expression returning true, iff operation kind would result in an overflow when applied to o...
static void check(const exprt &expr, const validation_modet vm=validation_modet::INVARIANT)
static void validate(const exprt &expr, const namespacet &, const validation_modet vm=validation_modet::INVARIANT)
static bool valid_id(const irep_idt &id)
Returns true iff id is a valid identifier of a binary_overflow_exprt.
static irep_idt make_id(const irep_idt &kind)
binary_overflow_exprt(exprt _lhs, const irep_idt &kind, exprt _rhs)
A base class for expressions that are predicates, i.e., Boolean-typed, and that take exactly two argu...
Definition std_expr.h:731
Bit-wise AND Any number of operands that is greater or equal one.
bitand_exprt(exprt::operandst _operands, typet _type)
bitand_exprt(const exprt &_op0, exprt _op1)
Bit-wise NAND.
bitnand_exprt(exprt _op0, exprt _op1)
bitnand_exprt(exprt::operandst _operands, typet _type)
Bit-wise NOR.
bitnor_exprt(exprt::operandst _operands, typet _type)
bitnor_exprt(exprt _op0, exprt _op1)
Bit-wise negation of bit-vectors.
bitnot_exprt(exprt op)
Bit-wise OR Any number of operands that is greater or equal one.
bitor_exprt(exprt::operandst _operands, typet _type)
bitor_exprt(const exprt &_op0, exprt _op1)
Reverse the order of bits in a bit-vector.
bitreverse_exprt(exprt op)
exprt lower() const
Lower a bitreverse_exprt to arithmetic and logic expressions.
Bit-wise XNOR.
bitxnor_exprt(exprt::operandst _operands, typet _type)
bitxnor_exprt(exprt _op0, exprt _op1)
Bit-wise XOR Any number of operands that is greater or equal one.
bitxor_exprt(exprt::operandst _operands, typet _type)
bitxor_exprt(exprt _op0, exprt _op1)
The Boolean type.
Definition std_types.h:36
The byte swap expression.
bswap_exprt(exprt _op, std::size_t bits_per_byte)
std::size_t get_bits_per_byte() const
bswap_exprt(exprt _op, std::size_t bits_per_byte, typet _type)
void set_bits_per_byte(std::size_t bits_per_byte)
Concatenation of bit-vector operands.
concatenation_exprt(operandst _operands, typet _type)
concatenation_exprt(exprt _op0, exprt _op1, typet _type)
A constant literal expression.
Definition std_expr.h:3126
The count leading zeros (counting the number of zero bits starting from the most-significant bit) exp...
static void validate(const exprt &expr, const namespacet &, const validation_modet vm=validation_modet::INVARIANT)
void zero_permitted(bool value)
exprt lower() const
Lower a count_leading_zeros_exprt to arithmetic and logic expressions.
count_leading_zeros_exprt(const exprt &_op)
static void check(const exprt &expr, const validation_modet vm=validation_modet::INVARIANT)
count_leading_zeros_exprt(exprt _op, bool _zero_permitted, typet _type)
The count trailing zeros (counting the number of zero bits starting from the least-significant bit) e...
count_trailing_zeros_exprt(const exprt &_op)
count_trailing_zeros_exprt(exprt _op, bool _zero_permitted, typet _type)
static void check(const exprt &expr, const validation_modet vm=validation_modet::INVARIANT)
static void validate(const exprt &expr, const namespacet &, const validation_modet vm=validation_modet::INVARIANT)
void zero_permitted(bool value)
exprt lower() const
Lower a count_trailing_zeros_exprt to arithmetic and logic expressions.
dstringt has one field, an unsigned integer no which is an index into a static table of strings.
Definition dstring.h:38
Base class for all expressions.
Definition expr.h:349
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
static void check(const exprt &, const validation_modet)
Check that the expression is well-formed (shallow checks only, i.e., subexpressions and its type are ...
Definition expr.h:259
exprt & op0()
Definition expr.h:134
exprt & op1()
Definition expr.h:137
typet & type()
Return the type of the expression.
Definition expr.h:85
operandst & operands()
Definition expr.h:95
Extracts a single bit of a bit-vector operand.
extractbit_exprt(exprt _src, exprt _index)
Extract the _index-th least significant bit from _src.
const exprt & index() const
const exprt & src() const
Extracts a sub-range of a bit-vector operand.
const exprt & index() const
extractbits_exprt(exprt _src, exprt _index, typet _type)
Extract the bits [_index .
const exprt & src() const
Returns one plus the index of the least-significant one bit, or zero if the operand is zero.
find_first_set_exprt(exprt _op, typet _type)
static void validate(const exprt &expr, const namespacet &, const validation_modet vm=validation_modet::INVARIANT)
exprt lower() const
Lower a find_first_set_exprt to arithmetic and logic expressions.
find_first_set_exprt(const exprt &_op)
static void check(const exprt &expr, const validation_modet vm=validation_modet::INVARIANT)
bool get_bool(const irep_idt &name) const
Definition irep.cpp:57
std::size_t get_size_t(const irep_idt &name) const
Definition irep.cpp:67
void set(const irep_idt &name, const irep_idt &value)
Definition irep.h:412
void set_size_t(const irep_idt &name, const std::size_t value)
Definition irep.cpp:82
const irep_idt & id() const
Definition irep.h:388
Logical right shift.
lshr_exprt(exprt _src, const std::size_t _distance)
lshr_exprt(exprt _src, exprt _distance)
minus_overflow_exprt(exprt _lhs, exprt _rhs)
exprt lower() const
Lower a minus_overflow_exprt to arithmetic and logic expressions.
mult_overflow_exprt(exprt _lhs, exprt _rhs)
exprt lower() const
Lower a mult_overflow_exprt to arithmetic and logic expressions.
A base class for multi-ary expressions Associativity is not specified.
Definition std_expr.h:912
A namespacet is essentially one or two symbol tables bound together, to allow for symbol lookups in t...
Definition namespace.h:91
A Boolean expression returning true iff the given operand consists of exactly one '0' and '1' otherwi...
onehot0_exprt(exprt _op)
exprt lower() const
lowering to extractbit
A Boolean expression returning true iff the given operand consists of exactly one '1' and '0' otherwi...
onehot_exprt(exprt _op)
exprt lower() const
lowering to extractbit
An expression returning both the result of the arithmetic operation under wrap-around semantics as we...
exprt & op3()=delete
overflow_result_exprt(exprt _lhs, const irep_idt &kind, exprt _rhs)
overflow_result_exprt(exprt _op, const irep_idt &kind)
static void validate(const exprt &expr, const namespacet &, const validation_modet vm=validation_modet::INVARIANT)
exprt & op2()=delete
static bool valid_id(const irep_idt &id)
Returns true iff id is a valid identifier of an overflow_exprt.
const exprt & op2() const =delete
static irep_idt make_id(const irep_idt &kind)
static void check(const exprt &expr, const validation_modet vm=validation_modet::INVARIANT)
const exprt & op3() const =delete
plus_overflow_exprt(exprt _lhs, exprt _rhs)
exprt lower() const
Lower a plus_overflow_exprt to arithmetic and logic expressions.
The popcount (counting the number of bits set to 1) expression.
exprt lower() const
Lower a popcount_exprt to arithmetic and logic expressions.
popcount_exprt(exprt _op, typet _type)
popcount_exprt(const exprt &_op)
Bit-vector replication.
const exprt & op() const
const constant_exprt & times() const
constant_exprt & times()
replication_exprt(constant_exprt _times, exprt _src, typet _type)
Saturating subtraction expression.
saturating_minus_exprt(exprt _lhs, exprt _rhs)
The saturating plus expression.
saturating_plus_exprt(exprt _lhs, exprt _rhs, typet _type)
saturating_plus_exprt(exprt _lhs, exprt _rhs)
A base class for shift and rotate operators.
exprt & distance()
shift_exprt(exprt _src, const irep_idt &_id, exprt _distance)
const exprt & distance() const
const exprt & op() const
Left shift.
shl_exprt(exprt _src, const std::size_t _distance)
shl_exprt(exprt _src, exprt _distance)
shl_overflow_exprt(exprt _lhs, exprt _rhs)
Structure type, corresponds to C style structs.
Definition std_types.h:231
The type of an expression, extends irept.
Definition type.h:29
Generic base class for unary expressions.
Definition std_expr.h:361
static void check(const exprt &expr, const validation_modet vm=validation_modet::INVARIANT)
Definition std_expr.h:373
const exprt & op() const
Definition std_expr.h:391
A Boolean expression returning true, iff negation would result in an overflow when applied to the (si...
static void validate(const exprt &expr, const namespacet &, const validation_modet vm=validation_modet::INVARIANT)
static void check(const exprt &expr, const validation_modet vm=validation_modet::INVARIANT)
A Boolean expression returning true, iff operation kind would result in an overflow when applied to t...
static void validate(const exprt &expr, const namespacet &, const validation_modet vm=validation_modet::INVARIANT)
unary_overflow_exprt(const irep_idt &kind, exprt _op)
static void check(const exprt &expr, const validation_modet vm=validation_modet::INVARIANT)
A base class for expressions that are predicates, i.e., Boolean-typed, and that take exactly one argu...
Definition std_expr.h:585
Replaces a sub-range of a bit-vector operand.
const exprt & src() const
const exprt & index() const
update_bit_exprt(exprt _src, exprt _index, exprt _new_value)
Replaces the bit [_index] from _src to produce a result of the same type as _src.
exprt lower() const
A lowering to masking, shifting, or.
const exprt & new_value() const
static void check(const exprt &expr, const validation_modet vm=validation_modet::INVARIANT)
Replaces a sub-range of a bit-vector operand.
const exprt & index() const
static void check(const exprt &expr, const validation_modet vm=validation_modet::INVARIANT)
update_bits_exprt(exprt _src, exprt _index, exprt _new_value)
Replace the bits [_index .
const exprt & new_value() const
exprt lower() const
A lowering to masking, shifting, or.
const exprt & src() const
update_bits_exprt(exprt _src, const std::size_t _index, exprt _new_value)
zero extension The operand is converted to the given type by either a) truncating if the new type is ...
zero_extend_exprt(exprt _op, typet _type)
void validate_operands(const exprt &value, exprt::operandst::size_type number, const char *message, bool allow_more=false)
Definition expr_cast.h:250
const std::string & id2string(const irep_idt &d)
Definition irep.h:44
STL namespace.
#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
#define INVARIANT(CONDITION, REASON)
This macro uses the wrapper function 'invariant_violated_string'.
Definition invariant.h:423
API to expression classes.
const binary_exprt & to_binary_expr(const exprt &expr)
Cast an exprt to a binary_exprt.
Definition std_expr.h:715
const unary_exprt & to_unary_expr(const exprt &expr)
Cast an exprt to a unary_exprt.
Definition std_expr.h:426
#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