CBMC
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
c_typecast.cpp
Go to the documentation of this file.
1/*******************************************************************\
2
3Module:
4
5Author: Daniel Kroening, kroening@kroening.com
6
7\*******************************************************************/
8
9#include "c_typecast.h"
10
11#include <algorithm>
12
13#include <util/arith_tools.h>
14#include <util/c_types.h>
15#include <util/config.h>
16#include <util/expr_util.h>
18#include <util/namespace.h>
19#include <util/pointer_expr.h>
20#include <util/simplify_expr.h>
21#include <util/std_expr.h>
22
23#include "c_qualifiers.h"
24
26 exprt &expr,
27 const typet &dest_type,
28 const namespacet &ns)
29{
31 c_typecast.implicit_typecast(expr, dest_type);
32 return !c_typecast.errors.empty();
33}
34
36 const typet &src_type,
37 const typet &dest_type,
38 const namespacet &ns)
39{
41 exprt tmp;
42 tmp.type()=src_type;
43 c_typecast.implicit_typecast(tmp, dest_type);
44 return !c_typecast.errors.empty();
45}
46
50 const namespacet &ns)
51{
53 c_typecast.implicit_typecast_arithmetic(expr1, expr2);
54 return !c_typecast.errors.empty();
55}
56
57bool has_a_void_pointer(const typet &type)
58{
59 if(type.id()==ID_pointer)
60 {
61 const auto &pointer_type = to_pointer_type(type);
62
63 if(pointer_type.base_type().id() == ID_empty)
64 return true;
65
67 }
68 else
69 return false;
70}
71
73 const typet &src_type,
74 const typet &dest_type)
75{
76 // check qualifiers
77
78 if(
79 src_type.id() == ID_pointer && dest_type.id() == ID_pointer &&
80 to_pointer_type(src_type).base_type().get_bool(ID_C_constant) &&
81 !to_pointer_type(dest_type).base_type().get_bool(ID_C_constant))
82 {
83 return true;
84 }
85
87 return false;
88
89 const irep_idt &src_type_id=src_type.id();
90
92 {
94 to_c_bit_field_type(src_type).underlying_type(), dest_type);
95 }
96
98 {
100 src_type, to_c_bit_field_type(dest_type).underlying_type());
101 }
102
104 {
105 if(dest_type.id()==ID_bool ||
106 dest_type.id()==ID_c_bool ||
107 dest_type.id()==ID_integer ||
108 dest_type.id()==ID_real ||
109 dest_type.id()==ID_complex ||
110 dest_type.id()==ID_unsignedbv ||
111 dest_type.id()==ID_signedbv ||
112 dest_type.id()==ID_floatbv ||
113 dest_type.id()==ID_complex)
114 return false;
115 }
116 else if(src_type_id==ID_integer)
117 {
118 if(dest_type.id()==ID_bool ||
119 dest_type.id()==ID_c_bool ||
120 dest_type.id()==ID_real ||
121 dest_type.id()==ID_complex ||
122 dest_type.id()==ID_unsignedbv ||
123 dest_type.id()==ID_signedbv ||
124 dest_type.id()==ID_floatbv ||
125 dest_type.id()==ID_fixedbv ||
126 dest_type.id()==ID_pointer ||
127 dest_type.id()==ID_complex)
128 return false;
129 }
130 else if(src_type_id==ID_real)
131 {
132 if(dest_type.id()==ID_bool ||
133 dest_type.id()==ID_c_bool ||
134 dest_type.id()==ID_complex ||
135 dest_type.id()==ID_floatbv ||
136 dest_type.id()==ID_fixedbv ||
137 dest_type.id()==ID_complex)
138 return false;
139 }
140 else if(src_type_id==ID_rational)
141 {
142 if(dest_type.id()==ID_bool ||
143 dest_type.id()==ID_c_bool ||
144 dest_type.id()==ID_complex ||
145 dest_type.id()==ID_floatbv ||
146 dest_type.id()==ID_fixedbv ||
147 dest_type.id()==ID_complex)
148 return false;
149 }
150 else if(src_type_id==ID_bool)
151 {
152 if(dest_type.id()==ID_c_bool ||
153 dest_type.id()==ID_integer ||
154 dest_type.id()==ID_real ||
155 dest_type.id()==ID_unsignedbv ||
156 dest_type.id()==ID_signedbv ||
157 dest_type.id()==ID_pointer ||
158 dest_type.id()==ID_floatbv ||
159 dest_type.id()==ID_fixedbv ||
160 dest_type.id()==ID_c_enum ||
161 dest_type.id()==ID_c_enum_tag ||
162 dest_type.id()==ID_complex)
163 return false;
164 }
165 else if(src_type_id==ID_unsignedbv ||
170 {
171 if(dest_type.id()==ID_unsignedbv ||
172 dest_type.id()==ID_bool ||
173 dest_type.id()==ID_c_bool ||
174 dest_type.id()==ID_integer ||
175 dest_type.id()==ID_real ||
176 dest_type.id()==ID_rational ||
177 dest_type.id()==ID_signedbv ||
178 dest_type.id()==ID_floatbv ||
179 dest_type.id()==ID_fixedbv ||
180 dest_type.id()==ID_pointer ||
181 dest_type.id()==ID_c_enum ||
182 dest_type.id()==ID_c_enum_tag ||
183 dest_type.id()==ID_complex)
184 return false;
185 }
186 else if(src_type_id==ID_floatbv ||
188 {
189 if(dest_type.id()==ID_bool ||
190 dest_type.id()==ID_c_bool ||
191 dest_type.id()==ID_integer ||
192 dest_type.id()==ID_real ||
193 dest_type.id()==ID_rational ||
194 dest_type.id()==ID_signedbv ||
195 dest_type.id()==ID_unsignedbv ||
196 dest_type.id()==ID_floatbv ||
197 dest_type.id()==ID_fixedbv ||
198 dest_type.id()==ID_complex)
199 return false;
200 }
201 else if(src_type_id==ID_complex)
202 {
203 if(dest_type.id()==ID_complex)
204 {
206 to_complex_type(src_type).subtype(),
207 to_complex_type(dest_type).subtype());
208 }
209 else
210 {
211 // 6.3.1.7, par 2:
212
213 // When a value of complex type is converted to a real type, the
214 // imaginary part of the complex value is discarded and the value of the
215 // real part is converted according to the conversion rules for the
216 // corresponding real type.
217
220 }
221 }
222 else if(src_type_id==ID_array ||
224 {
225 if(dest_type.id()==ID_pointer)
226 {
227 const irept &dest_subtype = to_pointer_type(dest_type).base_type();
229
231 {
232 return false;
233 }
234 else if(
235 has_a_void_pointer(src_type) || // from void to anything
236 has_a_void_pointer(dest_type)) // to void from anything
237 {
238 return false;
239 }
240 }
241
242 if(
243 dest_type.id() == ID_array && to_type_with_subtype(src_type).subtype() ==
244 to_array_type(dest_type).element_type())
245 {
246 return false;
247 }
248
249 if(dest_type.id()==ID_bool ||
250 dest_type.id()==ID_c_bool ||
251 dest_type.id()==ID_unsignedbv ||
253 return false;
254 }
255 else if(src_type_id==ID_vector)
256 {
257 if(dest_type.id()==ID_vector)
258 return false;
259 }
260 else if(src_type_id==ID_complex)
261 {
262 if(dest_type.id()==ID_complex)
263 {
264 // We convert between complex types if we convert between
265 // their component types.
267 to_complex_type(src_type).subtype(),
268 to_complex_type(dest_type).subtype()))
269 {
270 return false;
271 }
272 }
273 }
274
275 return true;
276}
277
279{
280 if(
281 src_type.id() != ID_struct_tag &&
282 src_type.id() != ID_union_tag)
283 {
284 return src_type;
285 }
286
287 typet result_type=src_type;
288
289 // collect qualifiers
291
292 if(
294 {
295 const typet &followed_type = ns.follow_tag(*struct_tag_type);
296 result_type = followed_type;
298 }
299 else if(
301 {
302 const typet &followed_type = ns.follow_tag(*union_tag_type);
303 result_type = followed_type;
305 }
306
307 qualifiers.write(result_type);
308
309 return result_type;
310}
311
313 const typet &type) const
314{
315 if(type.id()==ID_signedbv)
316 {
317 const std::size_t width = to_bitvector_type(type).get_width();
318
319 if(width<=config.ansi_c.char_width)
320 return CHAR;
321 else if(width<=config.ansi_c.short_int_width)
322 return SHORT;
323 else if(width<=config.ansi_c.int_width)
324 return INT;
325 else if(width<=config.ansi_c.long_int_width)
326 return LONG;
327 else if(width<=config.ansi_c.long_long_int_width)
328 return LONGLONG;
329 else
330 return LARGE_SIGNED_INT;
331 }
332 else if(type.id()==ID_unsignedbv)
333 {
334 const std::size_t width = to_bitvector_type(type).get_width();
335
336 if(width<=config.ansi_c.char_width)
337 return UCHAR;
338 else if(width<=config.ansi_c.short_int_width)
339 return USHORT;
340 else if(width<=config.ansi_c.int_width)
341 return UINT;
342 else if(width<=config.ansi_c.long_int_width)
343 return ULONG;
344 else if(width<=config.ansi_c.long_long_int_width)
345 return ULONGLONG;
346 else
347 return LARGE_UNSIGNED_INT;
348 }
349 else if(type.id()==ID_bool)
350 return BOOL;
351 else if(type.id()==ID_c_bool)
352 return BOOL;
353 else if(type.id()==ID_floatbv)
354 {
355 const std::size_t width = to_bitvector_type(type).get_width();
356
357 if(width<=config.ansi_c.single_width)
358 return SINGLE;
359 else if(width<=config.ansi_c.double_width)
360 return DOUBLE;
361 else if(width<=config.ansi_c.long_double_width)
362 return LONGDOUBLE;
363 else if(width<=128)
364 return FLOAT128;
365 }
366 else if(type.id()==ID_fixedbv)
367 {
368 return FIXEDBV;
369 }
370 else if(type.id()==ID_pointer)
371 {
372 if(to_pointer_type(type).base_type().id() == ID_empty)
373 return VOIDPTR;
374 else
375 return PTR;
376 }
377 else if(type.id()==ID_array)
378 {
379 return PTR;
380 }
381 else if(type.id() == ID_c_enum || type.id() == ID_c_enum_tag)
382 {
383 return INT;
384 }
385 else if(type.id()==ID_rational)
386 return RATIONAL;
387 else if(type.id()==ID_real)
388 return REAL;
389 else if(type.id()==ID_complex)
390 return COMPLEX;
391 else if(type.id()==ID_c_bit_field)
392 {
393 const auto &bit_field_type = to_c_bit_field_type(type);
394
395 // We take the underlying type, and then apply the number
396 // of bits given
397 typet underlying_type;
398
399 if(bit_field_type.underlying_type().id() == ID_c_enum_tag)
400 {
401 const auto &followed =
402 ns.follow_tag(to_c_enum_tag_type(bit_field_type.underlying_type()));
403 if(followed.is_incomplete())
404 return INT;
405 else
406 underlying_type = followed.underlying_type();
407 }
408 else
409 underlying_type = bit_field_type.underlying_type();
410
412 underlying_type.id(), bit_field_type.get_width());
413
414 return get_c_type(new_type);
415 }
416 else if(type.id() == ID_integer)
417 return INTEGER;
418
419 return OTHER;
420}
421
423 exprt &expr,
425{
427
428 switch(c_type)
429 {
430 case PTR:
431 if(expr.type().id() == ID_array)
432 {
433 new_type = pointer_type(to_array_type(expr.type()).element_type());
434 break;
435 }
436 return;
437
438 case BOOL: UNREACHABLE; // should always be promoted to int
439 case CHAR: UNREACHABLE; // should always be promoted to int
440 case UCHAR: UNREACHABLE; // should always be promoted to int
441 case SHORT: UNREACHABLE; // should always be promoted to int
442 case USHORT: UNREACHABLE; // should always be promoted to int
443 case INT: new_type=signed_int_type(); break;
444 case UINT: new_type=unsigned_int_type(); break;
445 case LONG: new_type=signed_long_int_type(); break;
449 case SINGLE: new_type=float_type(); break;
450 case DOUBLE: new_type=double_type(); break;
451 case LONGDOUBLE: new_type=long_double_type(); break;
452 // NOLINTNEXTLINE(whitespace/line_length)
454 case RATIONAL: new_type=rational_typet(); break;
455 case REAL: new_type=real_typet(); break;
456 case INTEGER: new_type=integer_typet(); break;
457 case COMPLEX:
458 case OTHER:
459 case VOIDPTR:
460 case FIXEDBV:
462 case LARGE_SIGNED_INT:
463 return; // do nothing
464 }
465
466 if(new_type != expr.type())
467 do_typecast(expr, new_type);
468}
469
471 const typet &type) const
472{
474
475 // 6.3.1.1, par 2
476
477 // "If an int can represent all values of the original type, the
478 // value is converted to an int; otherwise, it is converted to
479 // an unsigned int."
480
481 c_typet max_type=std::max(c_type, INT); // minimum promotion
482
483 // The second case can arise if we promote any unsigned type
484 // that is as large as unsigned int. In this case the promotion configuration
485 // via the enum is actually wrong, and we need to fix this up.
486 if(
487 config.ansi_c.short_int_width == config.ansi_c.int_width &&
488 c_type == USHORT)
490 else if(
491 config.ansi_c.char_width == config.ansi_c.int_width && c_type == UCHAR)
493
494 if(max_type==UINT &&
495 type.id()==ID_c_bit_field &&
496 to_c_bit_field_type(type).get_width()<config.ansi_c.int_width)
498
499 return max_type;
500}
501
507
521
523 exprt &expr,
524 const typet &src_type,
525 const typet &orig_dest_type,
526 const typet &dest_type)
527{
528 // do transparent union
529 if(dest_type.id()==ID_union &&
531 src_type.id()!=ID_union)
532 {
533 // The argument corresponding to a transparent union type can be of any
534 // type in the union; no explicit cast is required.
535
536 // GCC docs say:
537 // If the union member type is a pointer, qualifiers like const on the
538 // referenced type must be respected, just as with normal pointer
539 // conversions.
540 // But it is accepted, and Clang doesn't even emit a warning (GCC 4.7 does)
542 if(
543 src_type.id() == ID_pointer &&
544 to_pointer_type(src_type).base_type().get_bool(ID_C_constant))
545 {
547 }
548
549 // Check union members.
550 for(const auto &comp : to_union_type(dest_type).components())
551 {
553 {
554 // build union constructor
555 union_exprt union_expr(comp.get_name(), expr, orig_dest_type);
556 if(!src_type.full_eq(src_type_no_const))
558 expr=union_expr;
559 return; // ok
560 }
561 }
562 }
563
564 if(dest_type.id()==ID_pointer)
565 {
566 // special case: 0 == NULL
567
568 if(simplify_expr(expr, ns).is_zero() && (
569 src_type.id()==ID_unsignedbv ||
570 src_type.id()==ID_signedbv ||
571 src_type.id()==ID_natural ||
572 src_type.id()==ID_integer))
573 {
575 return; // ok
576 }
577
578 if(src_type.id()==ID_pointer ||
579 src_type.id()==ID_array)
580 {
581 // we are quite generous about pointers
582
583 const typet &src_sub = to_type_with_subtype(src_type).subtype();
584 const typet &dest_sub = to_pointer_type(dest_type).base_type();
585
587 {
588 // from/to void is always good
589 }
590 else if(src_sub.id()==ID_code &&
591 dest_sub.id()==ID_code)
592 {
593 // very generous:
594 // between any two function pointers it's ok
595 }
596 else if(src_sub == dest_sub)
597 {
598 // ok
599 }
600 else if((is_number(src_sub) ||
601 src_sub.id()==ID_c_enum ||
602 src_sub.id()==ID_c_enum_tag) &&
604 dest_sub.id()==ID_c_enum ||
605 src_sub.id()==ID_c_enum_tag))
606 {
607 // Also generous: between any to scalar types it's ok.
608 // We should probably check the size.
609 }
610 else if(
611 src_sub.id() == ID_array && dest_sub.id() == ID_array &&
612 to_array_type(src_sub).element_type() ==
613 to_array_type(dest_sub).element_type())
614 {
615 // we ignore the size of the top-level array
616 // in the case of pointers to arrays
617 }
618 else
619 warnings.push_back("incompatible pointer types");
620
621 // check qualifiers
622
623 if(
624 to_type_with_subtype(src_type).subtype().get_bool(ID_C_volatile) &&
625 !to_pointer_type(dest_type).base_type().get_bool(ID_C_volatile))
626 {
627 warnings.push_back("disregarding volatile");
628 }
629
631 {
632 expr.type()=src_type; // because of qualifiers
633 }
634 else
636
637 return; // ok
638 }
639 }
640
642 errors.push_back("implicit conversion not permitted");
643 else if(src_type!=dest_type)
645}
646
648 exprt &expr1,
649 exprt &expr2)
650{
651 const typet &type1 = expr1.type();
652 const typet &type2 = expr2.type();
653
656
657 c_typet max_type=std::max(c_type1, c_type2);
658
660 {
661 // produce type
662 typet result_type = (max_type == c_type1) ? type1 : type2;
663
664 do_typecast(expr1, result_type);
665 do_typecast(expr2, result_type);
666
667 return;
668 }
669 else if(max_type==FIXEDBV)
670 {
671 typet result_type;
672
674 {
675 // get bigger of both
676 std::size_t width1=to_fixedbv_type(type1).get_width();
677 std::size_t width2=to_fixedbv_type(type2).get_width();
678 if(width1>=width2)
679 result_type=type1;
680 else
681 result_type=type2;
682 }
683 else if(c_type1==FIXEDBV)
684 result_type=type1;
685 else
686 result_type=type2;
687
688 do_typecast(expr1, result_type);
689 do_typecast(expr2, result_type);
690
691 return;
692 }
693 else if(max_type==COMPLEX)
694 {
696 {
697 // promote to the one with bigger subtype
698 if(
699 get_c_type(to_complex_type(type1).subtype()) >
700 get_c_type(to_complex_type(type2).subtype()))
701 {
703 }
704 else
706 }
707 else if(c_type1==COMPLEX)
708 {
709 INVARIANT(c_type2 != COMPLEX, "both types were COMPLEX");
712 }
713 else
714 {
715 INVARIANT(c_type2 == COMPLEX, "neither type was COMPLEX");
718 }
719
720 return;
721 }
722 else if(max_type==SINGLE || max_type==DOUBLE ||
724 {
725 // Special-case optimisation:
726 // If we have two non-standard sized floats, don't do implicit type
727 // promotion if we can possibly avoid it.
728 if(type1==type2)
729 return;
730 }
731 else if(max_type == OTHER)
732 {
733 errors.push_back("implicit arithmetic conversion not permitted");
734 return;
735 }
736
739}
740
742{
743 // special case: array -> pointer is actually
744 // something like address_of
745
746 const typet &src_type = expr.type();
747
748 if(src_type.id()==ID_array)
749 {
750 // This is the promotion from an array
751 // to a pointer to the first element.
753 if(error_opt.has_value())
754 {
755 errors.push_back(error_opt.value());
756 return;
757 }
758
759 index_exprt index(expr, from_integer(0, c_index_type()));
761 return;
762 }
763
765 {
766 // C booleans are special; we produce the
767 // explicit comparison with zero.
768 // Note that this requires ieee_float_notequal
769 // in case of floating-point numbers.
770
772 {
773 expr = typecast_exprt(is_not_zero(expr, ns), dest_type);
774 }
775 else if(dest_type.id()==ID_bool)
776 {
777 expr=is_not_zero(expr, ns);
778 }
779 else
780 {
781 expr = typecast_exprt(expr, dest_type);
782 }
783 }
784}
785
786std::optional<std::string>
788{
789 if(type.id() == ID_c_bit_field)
790 return std::string("cannot take address of a bit field");
791
792 if(type.id() == ID_bool)
793 return std::string("cannot take address of a proper Boolean");
794
796 {
797 // The width of the bitvector must be a multiple of CHAR_BIT.
798 auto width = to_bitvector_type(type).get_width();
799 if(width % config.ansi_c.char_width != 0)
800 {
801 return std::string(
802 "bitvector must have width that is a multiple of CHAR_BIT");
803 }
804 else
805 return {};
806 }
807
808 if(type.id() == ID_array)
809 return check_address_can_be_taken(to_array_type(type).element_type());
810
811 return {}; // ok
812}
configt config
Definition config.cpp:25
constant_exprt from_integer(const mp_integer &int_value, const typet &type)
const fixedbv_typet & to_fixedbv_type(const typet &type)
Cast a typet to a fixedbv_typet.
const bitvector_typet & to_bitvector_type(const typet &type)
Cast a typet to a bitvector_typet.
bool c_implicit_typecast(exprt &expr, const typet &dest_type, const namespacet &ns)
bool c_implicit_typecast_arithmetic(exprt &expr1, exprt &expr2, const namespacet &ns)
perform arithmetic prompotions and conversions
bool has_a_void_pointer(const typet &type)
bool check_c_implicit_typecast(const typet &src_type, const typet &dest_type, const namespacet &ns)
bool check_c_implicit_typecast(const typet &src_type, const typet &dest_type)
floatbv_typet float_type()
Definition c_types.cpp:177
signedbv_typet signed_long_int_type()
Definition c_types.cpp:72
unsignedbv_typet unsigned_int_type()
Definition c_types.cpp:36
unsignedbv_typet unsigned_long_long_int_type()
Definition c_types.cpp:93
unsignedbv_typet unsigned_long_int_type()
Definition c_types.cpp:86
signedbv_typet signed_int_type()
Definition c_types.cpp:22
pointer_typet pointer_type(const typet &subtype)
Definition c_types.cpp:235
signedbv_typet signed_long_long_int_type()
Definition c_types.cpp:79
floatbv_typet long_double_type()
Definition c_types.cpp:193
bitvector_typet c_index_type()
Definition c_types.cpp:16
floatbv_typet double_type()
Definition c_types.cpp:185
const c_bit_field_typet & to_c_bit_field_type(const typet &type)
Cast a typet to a c_bit_field_typet.
Definition c_types.h:80
const c_enum_tag_typet & to_c_enum_tag_type(const typet &type)
Cast a typet to a c_enum_tag_typet.
Definition c_types.h:377
const union_typet & to_union_type(const typet &type)
Cast a typet to a union_typet.
Definition c_types.h:184
Operator to return the address of an object.
ait supplies three of the four components needed: an abstract interpreter (in this case handling func...
Definition ai.h:562
Base class of fixed-width bit-vector types.
Definition std_types.h:909
@ LARGE_UNSIGNED_INT
Definition c_typecast.h:84
virtual void implicit_typecast_followed(exprt &expr, const typet &src_type, const typet &orig_dest_type, const typet &dest_type)
typet follow_with_qualifiers(const typet &src)
void do_typecast(exprt &dest, const typet &type)
virtual void implicit_typecast(exprt &expr, const typet &type)
c_typet get_c_type(const typet &type) const
virtual void implicit_typecast_arithmetic(exprt &expr)
std::list< std::string > warnings
Definition c_typecast.h:67
const namespacet & ns
Definition c_typecast.h:74
static std::optional< std::string > check_address_can_be_taken(const typet &)
c_typet minimum_promotion(const typet &type) const
std::list< std::string > errors
Definition c_typecast.h:66
struct configt::ansi_ct ansi_c
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:56
typet & type()
Return the type of the expression.
Definition expr.h:84
static ieee_float_spect quadruple_precision()
Definition ieee_float.h:82
Array index operator.
Definition std_expr.h:1470
Unbounded, signed integers (mathematical integers, not bitvectors)
There are a large number of kinds of tree structured or tree-like data in CPROVER.
Definition irep.h:364
const irep_idt & id() const
Definition irep.h:388
A namespacet is essentially one or two symbol tables bound together, to allow for symbol lookups in t...
Definition namespace.h:91
The null pointer constant.
const typet & base_type() const
The type of the data what we point to.
Unbounded, signed rational numbers.
Unbounded, signed real numbers.
Semantic type conversion.
Definition std_expr.h:2073
static exprt conditional_cast(const exprt &expr, const typet &type)
Definition std_expr.h:2081
The type of an expression, extends irept.
Definition type.h:29
Union constructor from single element.
Definition std_expr.h:1770
exprt is_not_zero(const exprt &src, const namespacet &ns)
converts a scalar/float expression to C/C++ Booleans
Definition expr_util.cpp:74
Deprecated expression utility functions.
bool is_number(const typet &type)
Returns true if the type is a rational, real, integer, natural, complex, unsignedbv,...
Mathematical types.
API to expression classes for Pointers.
const pointer_typet & to_pointer_type(const typet &type)
Cast a typet to a pointer_typet.
exprt simplify_expr(exprt src, const namespacet &ns)
#define UNREACHABLE
This should be used to mark dead code.
Definition invariant.h:525
#define INVARIANT(CONDITION, REASON)
This macro uses the wrapper function 'invariant_violated_string'.
Definition invariant.h:423
API to expression classes.
const complex_typet & to_complex_type(const typet &type)
Cast a typet to a complex_typet.
Definition std_types.h:1158
const array_typet & to_array_type(const typet &type)
Cast a typet to an array_typet.
Definition std_types.h:888
const type_with_subtypet & to_type_with_subtype(const typet &type)
Definition type.h:208