cprover
cpp_typecheck_conversions.cpp
Go to the documentation of this file.
1 /*******************************************************************\
2 
3 Module: C++ Language Type Checking
4 
5 Author:
6 
7 \*******************************************************************/
8 
11 
12 #include "cpp_typecheck.h"
13 
14 #include <util/arith_tools.h>
15 #include <util/c_types.h>
16 #include <util/config.h>
17 #include <util/expr_util.h>
18 #include <util/pointer_expr.h>
19 #include <util/simplify_expr.h>
20 #include <util/std_expr.h>
21 
22 #include <ansi-c/c_qualifiers.h>
23 
24 #include "cpp_util.h"
25 
47  const exprt &expr,
48  exprt &new_expr) const
49 {
50  assert(expr.get_bool(ID_C_lvalue));
51 
52  if(expr.type().id() == ID_code)
53  return false;
54 
55  if(
56  expr.type().id() == ID_struct &&
58  return false;
59 
60  if(expr.type().id() == ID_union && to_union_type(expr.type()).is_incomplete())
61  return false;
62 
63  new_expr=expr;
64  new_expr.remove(ID_C_lvalue);
65 
66  return true;
67 }
68 
78  const exprt &expr,
79  exprt &new_expr) const
80 {
81  assert(expr.type().id()==ID_array);
82 
83  index_exprt index(expr, from_integer(0, c_index_type()));
84 
85  index.set(ID_C_lvalue, true);
86 
87  new_expr=address_of_exprt(index);
88 
89  return true;
90 }
91 
100  const exprt &expr, exprt &new_expr) const
101 {
102  if(!expr.get_bool(ID_C_lvalue))
103  return false;
104 
105  new_expr=address_of_exprt(expr);
106 
107  return true;
108 }
109 
116  const exprt &expr,
117  const typet &type,
118  exprt &new_expr) const
119 {
120  if(expr.type().id()!=ID_pointer ||
121  is_reference(expr.type()))
122  return false;
123 
124  if(expr.get_bool(ID_C_lvalue))
125  return false;
126 
127  if(expr.type()!=type)
128  return false;
129 
130  typet sub_from = to_pointer_type(expr.type()).base_type();
131  typet sub_to = to_pointer_type(type).base_type();
132  bool const_to=true;
133 
134  while(sub_from.id()==ID_pointer)
135  {
136  c_qualifierst qual_from(sub_from);
137  c_qualifierst qual_to(sub_to);
138 
139  if(!qual_to.is_constant)
140  const_to=false;
141 
142  if(qual_from.is_constant && !qual_to.is_constant)
143  return false;
144 
145  if(qual_from!=qual_to && !const_to)
146  return false;
147 
148  typet tmp1=sub_from.subtype();
149  sub_from.swap(tmp1);
150 
151  typet tmp2=sub_to.subtype();
152  sub_to.swap(tmp2);
153  }
154 
155  c_qualifierst qual_from(sub_from);
156  c_qualifierst qual_to(sub_to);
157 
158  if(qual_from.is_subset_of(qual_to))
159  {
160  new_expr=expr;
161  new_expr.type()=type;
162  return true;
163  }
164 
165  return false;
166 }
167 
194  const exprt &expr,
195  exprt &new_expr) const
196 {
197  if(expr.get_bool(ID_C_lvalue))
198  return false;
199 
200  c_qualifierst qual_from;
201  qual_from.read(expr.type());
202 
203  typet int_type=signed_int_type();
204  qual_from.write(int_type);
205 
206  if(expr.type().id()==ID_signedbv)
207  {
208  std::size_t width=to_signedbv_type(expr.type()).get_width();
209  if(width >= config.ansi_c.int_width)
210  return false;
211  new_expr = typecast_exprt(expr, int_type);
212  return true;
213  }
214 
215  if(expr.type().id()==ID_unsignedbv)
216  {
217  std::size_t width=to_unsignedbv_type(expr.type()).get_width();
218  if(width >= config.ansi_c.int_width)
219  return false;
220  new_expr = typecast_exprt(expr, int_type);
221  return true;
222  }
223 
224  if(expr.type().id() == ID_bool || expr.type().id() == ID_c_bool)
225  {
226  new_expr = typecast_exprt(expr, int_type);
227  return true;
228  }
229 
230  if(expr.type().id()==ID_c_enum_tag)
231  {
232  new_expr = typecast_exprt(expr, int_type);
233  return true;
234  }
235 
236  return false;
237 }
238 
247  const exprt &expr,
248  exprt &new_expr) const
249 {
250  if(expr.get_bool(ID_C_lvalue))
251  return false;
252 
253  // we only do that with 'float',
254  // not with 'double' or 'long double'
255  if(expr.type()!=float_type())
256  return false;
257 
258  std::size_t width=to_floatbv_type(expr.type()).get_width();
259 
260  if(width!=config.ansi_c.single_width)
261  return false;
262 
263  c_qualifierst qual_from;
264  qual_from.read(expr.type());
265 
266  new_expr = typecast_exprt(expr, double_type());
267  qual_from.write(new_expr.type());
268 
269  return true;
270 }
271 
301  const exprt &expr,
302  const typet &type,
303  exprt &new_expr) const
304 {
305  if(type.id()!=ID_signedbv &&
306  type.id()!=ID_unsignedbv)
307  return false;
308 
309  if(
310  expr.type().id() != ID_signedbv && expr.type().id() != ID_unsignedbv &&
311  expr.type().id() != ID_c_bool && expr.type().id() != ID_bool &&
312  expr.type().id() != ID_c_enum_tag)
313  {
314  return false;
315  }
316 
317  if(expr.get_bool(ID_C_lvalue))
318  return false;
319 
320  c_qualifierst qual_from;
321  qual_from.read(expr.type());
322  new_expr = typecast_exprt::conditional_cast(expr, type);
323  qual_from.write(new_expr.type());
324 
325  return true;
326 }
327 
348  const exprt &expr,
349  const typet &type,
350  exprt &new_expr) const
351 {
352  if(expr.get_bool(ID_C_lvalue))
353  return false;
354 
355  if(expr.type().id()==ID_floatbv ||
356  expr.type().id()==ID_fixedbv)
357  {
358  if(type.id()!=ID_signedbv &&
359  type.id()!=ID_unsignedbv)
360  return false;
361  }
362  else if(expr.type().id()==ID_signedbv ||
363  expr.type().id()==ID_unsignedbv ||
364  expr.type().id()==ID_c_enum_tag)
365  {
366  if(type.id()!=ID_fixedbv &&
367  type.id()!=ID_floatbv)
368  return false;
369  }
370  else
371  return false;
372 
373  c_qualifierst qual_from;
374  qual_from.read(expr.type());
375  new_expr = typecast_exprt::conditional_cast(expr, type);
376  qual_from.write(new_expr.type());
377 
378  return true;
379 }
380 
381 
399  const exprt &expr,
400  const typet &type,
401  exprt &new_expr) const
402 {
403  if(expr.type().id()!=ID_floatbv &&
404  expr.type().id()!=ID_fixedbv)
405  return false;
406 
407  if(type.id()!=ID_floatbv &&
408  type.id()!=ID_fixedbv)
409  return false;
410 
411  if(expr.get_bool(ID_C_lvalue))
412  return false;
413 
414  c_qualifierst qual_from;
415 
416  qual_from.read(expr.type());
417  new_expr = typecast_exprt::conditional_cast(expr, type);
418  qual_from.write(new_expr.type());
419 
420  return true;
421 }
422 
456  const exprt &expr,
457  const typet &type,
458  exprt &new_expr)
459 {
460  if(type.id()!=ID_pointer ||
461  is_reference(type))
462  return false;
463 
464  if(expr.get_bool(ID_C_lvalue))
465  return false;
466 
467  // integer 0 to NULL pointer conversion?
468  if(simplify_expr(expr, *this).is_zero() &&
469  expr.type().id()!=ID_pointer)
470  {
471  new_expr=expr;
472  new_expr.set(ID_value, ID_NULL);
473  new_expr.type()=type;
474  return true;
475  }
476 
477  if(type.find(ID_to_member).is_not_nil())
478  return false;
479 
480  if(
481  expr.type().id() != ID_pointer ||
482  expr.type().find(ID_to_member).is_not_nil())
483  {
484  return false;
485  }
486 
487  typet sub_from = follow(to_pointer_type(expr.type()).base_type());
488  typet sub_to = follow(to_pointer_type(type).base_type());
489 
490  // std::nullptr_t to _any_ pointer type
491  if(sub_from.id()==ID_nullptr)
492  return true;
493 
494  // anything but function pointer to void *
495  if(sub_from.id()!=ID_code && sub_to.id()==ID_empty)
496  {
497  c_qualifierst qual_from;
498  qual_from.read(to_pointer_type(expr.type()).base_type());
499  new_expr = typecast_exprt::conditional_cast(expr, type);
500  qual_from.write(new_expr.type().subtype());
501  return true;
502  }
503 
504  // struct * to struct *
505  if(sub_from.id()==ID_struct && sub_to.id()==ID_struct)
506  {
507  const struct_typet &from_struct=to_struct_type(sub_from);
508  const struct_typet &to_struct=to_struct_type(sub_to);
509  if(subtype_typecast(from_struct, to_struct))
510  {
511  c_qualifierst qual_from;
512  qual_from.read(to_pointer_type(expr.type()).base_type());
513  new_expr=expr;
514  make_ptr_typecast(new_expr, type);
515  qual_from.write(new_expr.type().subtype());
516  return true;
517  }
518  }
519 
520  return false;
521 }
522 
554  const exprt &expr,
555  const typet &type,
556  exprt &new_expr)
557 {
558  if(
559  type.id() != ID_pointer || is_reference(type) ||
560  type.find(ID_to_member).is_nil())
561  {
562  return false;
563  }
564 
565  if(expr.type().id() != ID_pointer || expr.type().find(ID_to_member).is_nil())
566  return false;
567 
568  if(
569  to_pointer_type(type).base_type() !=
570  to_pointer_type(expr.type()).base_type())
571  {
572  // base types are different
573  if(
574  to_pointer_type(type).base_type().id() == ID_code &&
575  to_pointer_type(expr.type()).base_type().id() == ID_code)
576  {
577  code_typet code1=to_code_type(expr.type().subtype());
578  assert(!code1.parameters().empty());
579  code_typet::parametert this1=code1.parameters()[0];
580  INVARIANT(this1.get_this(), "first parameter should be `this'");
581  code1.parameters().erase(code1.parameters().begin());
582 
583  code_typet code2=to_code_type(type.subtype());
584  assert(!code2.parameters().empty());
585  code_typet::parametert this2=code2.parameters()[0];
586  INVARIANT(this2.get_this(), "first parameter should be `this'");
587  code2.parameters().erase(code2.parameters().begin());
588 
589  if(this2.type().subtype().get_bool(ID_C_constant) &&
590  !this1.type().subtype().get_bool(ID_C_constant))
591  return false;
592 
593  // give a second chance ignoring `this'
594  if(code1!=code2)
595  return false;
596  }
597  else
598  return false;
599  }
600 
601  if(expr.get_bool(ID_C_lvalue))
602  return false;
603 
604  if(expr.id()==ID_constant &&
605  expr.get(ID_value)==ID_NULL)
606  {
607  new_expr = typecast_exprt::conditional_cast(expr, type);
608  return true;
609  }
610 
611  const struct_typet &from_struct = to_struct_type(
612  follow(static_cast<const typet &>(expr.type().find(ID_to_member))));
613 
614  const struct_typet &to_struct =
615  to_struct_type(follow(static_cast<const typet &>(type.find(ID_to_member))));
616 
617  if(subtype_typecast(to_struct, from_struct))
618  {
619  new_expr = typecast_exprt::conditional_cast(expr, type);
620  return true;
621  }
622 
623  return false;
624 }
625 
636  const exprt &expr, exprt &new_expr) const
637 {
638  if(expr.get_bool(ID_C_lvalue))
639  return false;
640 
641  if(
642  expr.type().id() != ID_signedbv && expr.type().id() != ID_unsignedbv &&
643  expr.type().id() != ID_pointer && expr.type().id() != ID_bool &&
644  expr.type().id() != ID_c_enum_tag)
645  {
646  return false;
647  }
648 
649  c_qualifierst qual_from;
650  qual_from.read(expr.type());
651 
652  typet Bool = c_bool_type();
653  qual_from.write(Bool);
654 
655  new_expr = typecast_exprt::conditional_cast(expr, Bool);
656  return true;
657 }
658 
680  const exprt &expr,
681  const typet &type,
682  exprt &new_expr,
683  unsigned &rank)
684 {
685  assert(!is_reference(expr.type()) && !is_reference(type));
686 
687  exprt curr_expr=expr;
688 
689  // bit fields are converted like their underlying type
690  if(type.id()==ID_c_bit_field)
691  return standard_conversion_sequence(expr, type.subtype(), new_expr, rank);
692 
693  // we turn bit fields into their underlying type
694  if(curr_expr.type().id()==ID_c_bit_field)
695  curr_expr = typecast_exprt(curr_expr, curr_expr.type().subtype());
696 
697  if(curr_expr.type().id()==ID_array)
698  {
699  if(type.id()==ID_pointer)
700  {
701  if(!standard_conversion_array_to_pointer(curr_expr, new_expr))
702  return false;
703  }
704  }
705  else if(curr_expr.type().id()==ID_code &&
706  type.id()==ID_pointer)
707  {
708  if(!standard_conversion_function_to_pointer(curr_expr, new_expr))
709  return false;
710  }
711  else if(curr_expr.get_bool(ID_C_lvalue))
712  {
713  if(!standard_conversion_lvalue_to_rvalue(curr_expr, new_expr))
714  return false;
715  }
716  else
717  new_expr=curr_expr;
718 
719  curr_expr.swap(new_expr);
720 
721  // two enums are the same if the tag is the same,
722  // even if the width differs (enum bit-fields!)
723  if(follow(type).id()==ID_c_enum &&
724  follow(curr_expr.type()).id()==ID_c_enum)
725  {
726  if(follow(type).find(ID_tag)==
727  follow(curr_expr.type()).find(ID_tag))
728  return true;
729  else
730  {
731  // In contrast to C, we simply don't allow implicit conversions
732  // between enums.
733  return false;
734  }
735  }
736 
737  // need to consider #c_type
738  if(follow(curr_expr.type())!=follow(type) ||
739  curr_expr.type().get(ID_C_c_type)!=type.get(ID_C_c_type))
740  {
741  if(type.id()==ID_signedbv ||
742  type.id()==ID_unsignedbv ||
743  follow(type).id()==ID_c_enum)
744  {
745  if(!standard_conversion_integral_promotion(curr_expr, new_expr) ||
746  new_expr.type() != type)
747  {
748  if(!standard_conversion_integral_conversion(curr_expr, type, new_expr))
749  {
751  curr_expr, type, new_expr))
752  return false;
753  }
754 
755  rank+=3;
756  }
757  else
758  rank+=2;
759  }
760  else if(type.id()==ID_floatbv || type.id()==ID_fixedbv)
761  {
762  if(!standard_conversion_floating_point_promotion(curr_expr, new_expr) ||
763  new_expr.type() != type)
764  {
766  curr_expr, type, new_expr) &&
768  curr_expr, type, new_expr))
769  return false;
770 
771  rank += 3;
772  }
773  else
774  rank += 2;
775  }
776  else if(type.id()==ID_pointer)
777  {
778  if(expr.type().subtype().id()==ID_nullptr)
779  {
780  // std::nullptr_t to _any_ pointer type is ok
781  new_expr = typecast_exprt::conditional_cast(new_expr, type);
782  }
783  else if(!standard_conversion_pointer(curr_expr, type, new_expr))
784  {
785  if(!standard_conversion_pointer_to_member(curr_expr, type, new_expr))
786  return false;
787  }
788 
789  rank += 3;
790  }
791  else if(type.id() == ID_c_bool)
792  {
793  if(!standard_conversion_boolean(curr_expr, new_expr))
794  return false;
795 
796  rank += 3;
797  }
798  else if(type.id() == ID_bool)
799  {
800  new_expr = is_not_zero(curr_expr, *this);
801 
802  rank += 3;
803  }
804  else
805  return false;
806  }
807  else
808  new_expr=curr_expr;
809 
810  curr_expr.swap(new_expr);
811 
812  if(curr_expr.type().id()==ID_pointer)
813  {
814  typet sub_from=curr_expr.type();
815  typet sub_to=type;
816 
817  do
818  {
819  typet tmp_from=sub_from.subtype();
820  sub_from.swap(tmp_from);
821  typet tmp_to=sub_to.subtype();
822  sub_to.swap(tmp_to);
823 
824  c_qualifierst qual_from;
825  qual_from.read(sub_from);
826 
827  c_qualifierst qual_to;
828  qual_to.read(sub_to);
829 
830  if(qual_from!=qual_to)
831  {
832  rank+=1;
833  break;
834  }
835  }
836  while(sub_from.id()==ID_pointer);
837 
838  if(!standard_conversion_qualification(curr_expr, type, new_expr))
839  return false;
840  }
841  else
842  {
843  new_expr=curr_expr;
844  new_expr.type()=type;
845  }
846 
847  return true;
848 }
849 
856  const exprt &expr,
857  const typet &type,
858  exprt &new_expr,
859  unsigned &rank)
860 {
861  assert(!is_reference(expr.type()));
862  assert(!is_reference(type));
863 
864  const typet &from=follow(expr.type());
865  const typet &to=follow(type);
866 
867  new_expr.make_nil();
868 
869  // special case:
870  // A conversion from a type to the same type is given an exact
871  // match rank even though a user-defined conversion is used
872 
873  if(from==to)
874  rank+=0;
875  else
876  rank+=4; // higher than all the standard conversions
877 
878  if(to.id()==ID_struct)
879  {
880  std::string err_msg;
881 
882  if(cpp_is_pod(to))
883  {
884  if(from.id()==ID_struct)
885  {
886  const struct_typet &from_struct=to_struct_type(from);
887  const struct_typet &to_struct=to_struct_type(to);
888 
889  // potentially requires
890  // expr.get_bool(ID_C_lvalue) ??
891 
892  if(subtype_typecast(from_struct, to_struct))
893  {
894  exprt address=address_of_exprt(expr);
895 
896  // simplify address
897  if(expr.id()==ID_dereference)
898  address = to_dereference_expr(expr).pointer();
899 
900  pointer_typet ptr_sub=pointer_type(type);
901  c_qualifierst qual_from;
902  qual_from.read(expr.type());
903  qual_from.write(ptr_sub.base_type());
904  make_ptr_typecast(address, ptr_sub);
905 
906  const dereference_exprt deref(address);
907 
908  // create temporary object
909  side_effect_exprt tmp_object_expr(
910  ID_temporary_object, type, expr.source_location());
911  tmp_object_expr.copy_to_operands(deref);
912  tmp_object_expr.set(ID_C_lvalue, true);
913  tmp_object_expr.set(ID_mode, ID_cpp);
914 
915  new_expr.swap(tmp_object_expr);
916  return true;
917  }
918  }
919  }
920  else
921  {
922  bool found=false;
923 
924  for(const auto &component : to_struct_type(to).components())
925  {
926  if(component.get_bool(ID_from_base))
927  continue;
928 
929  if(component.get_bool(ID_is_explicit))
930  continue;
931 
932  const typet &comp_type = component.type();
933 
934  if(comp_type.id() !=ID_code)
935  continue;
936 
937  if(to_code_type(comp_type).return_type().id() != ID_constructor)
938  continue;
939 
940  // TODO: ellipsis
941 
942  const auto &parameters = to_code_type(comp_type).parameters();
943 
944  if(parameters.size() != 2)
945  continue;
946 
947  exprt curr_arg1 = parameters[1];
948  typet arg1_type=curr_arg1.type();
949 
950  if(is_reference(arg1_type))
951  {
952  typet tmp=arg1_type.subtype();
953  arg1_type.swap(tmp);
954  }
955 
956  unsigned tmp_rank=0;
957  if(arg1_type.id() != ID_struct_tag)
958  {
959  exprt tmp_expr;
961  expr, arg1_type, tmp_expr, tmp_rank))
962  {
963  // check if it's ambiguous
964  if(found)
965  return false;
966  found=true;
967 
968  if(expr.get_bool(ID_C_lvalue))
969  tmp_expr.set(ID_C_lvalue, true);
970 
971  tmp_expr.add_source_location()=expr.source_location();
972 
973  exprt func_symb = cpp_symbol_expr(lookup(component.get_name()));
974  func_symb.type()=comp_type;
976 
977  // create temporary object
979  std::move(func_symb),
980  {tmp_expr},
982  expr.source_location());
984 
985  new_expr.swap(ctor_expr);
986  assert(new_expr.get(ID_statement)==ID_temporary_object);
987 
988  if(to.get_bool(ID_C_constant))
989  new_expr.type().set(ID_C_constant, true);
990 
991  rank += tmp_rank;
992  }
993  }
994  else if(from.id() == ID_struct && arg1_type.id() == ID_struct_tag)
995  {
996  // try derived-to-base conversion
997  address_of_exprt expr_pfrom(expr, pointer_type(expr.type()));
998  pointer_typet pto=pointer_type(arg1_type);
999 
1000  exprt expr_ptmp;
1001  tmp_rank=0;
1003  expr_pfrom, pto, expr_ptmp, tmp_rank))
1004  {
1005  // check if it's ambiguous
1006  if(found)
1007  return false;
1008  found=true;
1009 
1010  rank+=tmp_rank;
1011 
1012  // create temporary object
1013  dereference_exprt expr_deref(expr_ptmp);
1014  expr_deref.set(ID_C_lvalue, true);
1015  expr_deref.add_source_location()=expr.source_location();
1016 
1017  exprt new_object(ID_new_object, type);
1018  new_object.set(ID_C_lvalue, true);
1019  new_object.type().set(ID_C_constant, false);
1020 
1021  exprt func_symb = cpp_symbol_expr(lookup(component.get_name()));
1022  func_symb.type()=comp_type;
1024 
1026  std::move(func_symb),
1027  {expr_deref},
1029  expr.source_location());
1031 
1032  new_expr.swap(ctor_expr);
1033 
1034  INVARIANT(
1035  new_expr.get(ID_statement)==ID_temporary_object,
1036  "statement ID");
1037 
1038  if(to.get_bool(ID_C_constant))
1039  new_expr.type().set(ID_C_constant, true);
1040  }
1041  }
1042  }
1043  if(found)
1044  return true;
1045  }
1046  }
1047 
1048  // conversion operators
1049  if(from.id()==ID_struct)
1050  {
1051  bool found=false;
1052  for(const auto &component : to_struct_type(from).components())
1053  {
1054  if(component.get_bool(ID_from_base))
1055  continue;
1056 
1057  if(!component.get_bool(ID_is_cast_operator))
1058  continue;
1059 
1060  const code_typet &comp_type = to_code_type(component.type());
1062  comp_type.parameters().size() == 1, "expected exactly one parameter");
1063 
1064  typet this_type = comp_type.parameters().front().type();
1065  this_type.set(ID_C_reference, true);
1066 
1067  exprt this_expr(expr);
1068  this_type.set(ID_C_this, true);
1069 
1070  unsigned tmp_rank=0;
1071  exprt tmp_expr;
1072 
1074  this_expr, this_type, tmp_expr, tmp_rank))
1075  {
1076  // To take care of the possible virtual case,
1077  // we build the function as a member expression.
1078  const cpp_namet cpp_func_name(component.get_base_name());
1079 
1080  exprt member_func(ID_member);
1081  member_func.add(ID_component_cpp_name)=cpp_func_name;
1082  member_func.copy_to_operands(already_typechecked_exprt{expr});
1083 
1085  std::move(member_func),
1086  {},
1088  expr.source_location());
1090 
1091  if(standard_conversion_sequence(func_expr, type, tmp_expr, tmp_rank))
1092  {
1093  // check if it's ambiguous
1094  if(found)
1095  return false;
1096  found=true;
1097 
1098  rank+=tmp_rank;
1099  new_expr.swap(tmp_expr);
1100  }
1101  }
1102  }
1103  if(found)
1104  return true;
1105  }
1106 
1107  return new_expr.is_not_nil();
1108 }
1109 
1115  const exprt &expr,
1116  const typet &type) const
1117 {
1118  assert(is_reference(type));
1119  assert(!is_reference(expr.type()));
1120 
1121  typet from=follow(expr.type());
1122  typet to=follow(type.subtype());
1123 
1124  // need to check #c_type
1125  if(from.get(ID_C_c_type)!=to.get(ID_C_c_type))
1126  return false;
1127 
1128  if(from==to)
1129  return true;
1130 
1131  if(from.id()==ID_struct &&
1132  to.id()==ID_struct)
1133  return subtype_typecast(to_struct_type(from),
1134  to_struct_type(to));
1135 
1136  if(from.id()==ID_struct &&
1137  type.get_bool(ID_C_this) &&
1138  type.subtype().id()==ID_empty)
1139  {
1140  // virtual-call case
1141  return true;
1142  }
1143 
1144  return false;
1145 }
1146 
1152  const exprt &expr,
1153  const typet &type,
1154  unsigned &rank) const
1155 {
1156  assert(is_reference(type));
1157  assert(!is_reference(expr.type()));
1158 
1159  if(!reference_related(expr, type))
1160  return false;
1161 
1162  if(expr.type()!=type.subtype())
1163  rank+=3;
1164 
1165  c_qualifierst qual_from;
1166  qual_from.read(expr.type());
1167 
1168  c_qualifierst qual_to;
1169  qual_to.read(type.subtype());
1170 
1171  if(qual_from!=qual_to)
1172  rank+=1;
1173 
1174  if(qual_from.is_subset_of(qual_to))
1175  return true;
1176 
1177  return false;
1178 }
1179 
1215  exprt expr,
1216  const typet &type,
1217  exprt &new_expr,
1218  unsigned &rank)
1219 {
1220  assert(is_reference(type));
1221  assert(!is_reference(expr.type()));
1222 
1223  unsigned backup_rank=rank;
1224 
1225  if(type.get_bool(ID_C_this) &&
1226  !expr.get_bool(ID_C_lvalue))
1227  {
1228  // `this' has to be an lvalue
1229  if(expr.get(ID_statement)==ID_temporary_object)
1230  expr.set(ID_C_lvalue, true);
1231  else if(expr.get(ID_statement)==ID_function_call)
1232  expr.set(ID_C_lvalue, true);
1233  else if(expr.get_bool(ID_C_temporary_avoided))
1234  {
1235  expr.remove(ID_C_temporary_avoided);
1236  exprt temporary;
1237  new_temporary(expr.source_location(), expr.type(), expr, temporary);
1238  expr.swap(temporary);
1239  expr.set(ID_C_lvalue, true);
1240  }
1241  else
1242  return false;
1243  }
1244 
1245  if(
1246  expr.get_bool(ID_C_lvalue) ||
1247  to_reference_type(type).base_type().get_bool(ID_C_constant))
1248  {
1249  if(reference_compatible(expr, type, rank))
1250  {
1251  if(!expr.get_bool(ID_C_lvalue))
1252  {
1253  // create temporary object
1254  side_effect_exprt tmp{ID_temporary_object,
1255  {std::move(expr)},
1256  to_reference_type(type).base_type(),
1257  expr.source_location()};
1258  tmp.set(ID_mode, ID_cpp);
1259  expr.swap(tmp);
1260  }
1261 
1262  {
1263  address_of_exprt tmp(expr, reference_type(expr.type()));
1264  tmp.add_source_location()=expr.source_location();
1265  new_expr.swap(tmp);
1266  }
1267 
1268  if(expr.type()!=type.subtype())
1269  {
1270  c_qualifierst qual_from;
1271  qual_from.read(expr.type());
1272  new_expr = typecast_exprt::conditional_cast(new_expr, type);
1273  qual_from.write(new_expr.type().subtype());
1274  }
1275 
1276  return true;
1277  }
1278 
1279  rank=backup_rank;
1280  }
1281 
1282  // conversion operators
1283  const typet &from_type = follow(expr.type());
1284  if(from_type.id()==ID_struct)
1285  {
1286  for(const auto &component : to_struct_type(from_type).components())
1287  {
1288  if(component.get_bool(ID_from_base))
1289  continue;
1290 
1291  if(!component.get_bool(ID_is_cast_operator))
1292  continue;
1293 
1294  const code_typet &component_type = to_code_type(component.type());
1295 
1296  // otherwise it cannot bind directly (not an lvalue)
1297  if(!is_reference(component_type.return_type()))
1298  continue;
1299 
1300  assert(component_type.parameters().size()==1);
1301 
1302  typet this_type =
1303  component_type.parameters().front().type();
1304  this_type.set(ID_C_reference, true);
1305 
1306  exprt this_expr(expr);
1307 
1308  this_type.set(ID_C_this, true);
1309 
1310  unsigned tmp_rank=0;
1311 
1312  exprt tmp_expr;
1314  this_expr, this_type, tmp_expr, tmp_rank))
1315  {
1316  // To take care of the possible virtual case,
1317  // we build the function as a member expression.
1318  const cpp_namet cpp_func_name(component.get_base_name());
1319 
1320  exprt member_func(ID_member);
1321  member_func.add(ID_component_cpp_name)=cpp_func_name;
1322  member_func.copy_to_operands(already_typechecked_exprt{expr});
1323 
1325  std::move(member_func),
1326  {},
1328  expr.source_location());
1330 
1331  // let's check if the returned value binds directly
1332  exprt returned_value=func_expr;
1333  add_implicit_dereference(returned_value);
1334 
1335  if(returned_value.get_bool(ID_C_lvalue) &&
1336  reference_compatible(returned_value, type, rank))
1337  {
1338  // returned values are lvalues in case of references only
1340  is_reference(to_dereference_expr(returned_value).op().type()),
1341  "the returned value must be pointer to reference");
1342 
1343  new_expr = to_multi_ary_expr(returned_value).op0();
1344 
1345  if(returned_value.type() != type.subtype())
1346  {
1347  c_qualifierst qual_from;
1348  qual_from.read(returned_value.type());
1349  make_ptr_typecast(new_expr, type);
1350  qual_from.write(new_expr.type().subtype());
1351  }
1352  rank+=4+tmp_rank;
1353  return true;
1354  }
1355  }
1356  }
1357  }
1358 
1359  // No temporary allowed for `this'
1360  if(type.get_bool(ID_C_this))
1361  return false;
1362 
1363  if(!type.subtype().get_bool(ID_C_constant) ||
1364  type.subtype().get_bool(ID_C_volatile))
1365  return false;
1366 
1367  // TODO: handle the case for implicit parameters
1368  if(!type.subtype().get_bool(ID_C_constant) &&
1369  !expr.get_bool(ID_C_lvalue))
1370  return false;
1371 
1372  exprt arg_expr=expr;
1373 
1374  if(arg_expr.type().id() == ID_struct_tag)
1375  {
1376  // required to initialize the temporary
1377  arg_expr.set(ID_C_lvalue, true);
1378  }
1379 
1380  if(user_defined_conversion_sequence(arg_expr, type.subtype(), new_expr, rank))
1381  {
1382  address_of_exprt tmp(new_expr, reference_type(new_expr.type()));
1383  tmp.add_source_location()=new_expr.source_location();
1384  new_expr.swap(tmp);
1385  return true;
1386  }
1387 
1388  rank=backup_rank;
1389  if(standard_conversion_sequence(expr, type.subtype(), new_expr, rank))
1390  {
1391  {
1392  // create temporary object
1393  side_effect_exprt tmp(
1394  ID_temporary_object, type.subtype(), expr.source_location());
1395  tmp.set(ID_mode, ID_cpp);
1396  // tmp.set(ID_C_lvalue, true);
1397  tmp.add_to_operands(std::move(new_expr));
1398  new_expr.swap(tmp);
1399  }
1400 
1401  address_of_exprt tmp(new_expr, pointer_type(new_expr.type()));
1402  tmp.type().set(ID_C_reference, true);
1403  tmp.add_source_location()=new_expr.source_location();
1404 
1405  new_expr=tmp;
1406  return true;
1407  }
1408 
1409  return false;
1410 }
1411 
1419  const exprt &expr,
1420  const typet &type,
1421  exprt &new_expr,
1422  unsigned &rank)
1423 {
1424  unsigned backup_rank=rank;
1425 
1426  exprt e=expr;
1428 
1429  if(is_reference(type))
1430  {
1431  if(!reference_binding(e, type, new_expr, rank))
1432  return false;
1433 
1434  #if 0
1435  simplify_exprt simplify(*this);
1436  simplify.simplify(new_expr);
1437  new_expr.type().set(ID_C_reference, true);
1438  #endif
1439  }
1440  else if(!standard_conversion_sequence(e, type, new_expr, rank))
1441  {
1442  rank=backup_rank;
1443  if(!user_defined_conversion_sequence(e, type, new_expr, rank))
1444  return false;
1445 
1446  #if 0
1447  simplify_exprt simplify(*this);
1448  simplify.simplify(new_expr);
1449  #endif
1450  }
1451 
1452  return true;
1453 }
1454 
1461  const exprt &expr,
1462  const typet &type,
1463  exprt &new_expr)
1464 {
1465  unsigned rank=0;
1466  return implicit_conversion_sequence(expr, type, new_expr, rank);
1467 }
1468 
1475  const exprt &expr,
1476  const typet &type,
1477  unsigned &rank)
1478 {
1479  exprt new_expr;
1480  return implicit_conversion_sequence(expr, type, new_expr, rank);
1481 }
1482 
1484 {
1485  exprt e=expr;
1486 
1487  if(
1488  e.id() == ID_initializer_list && cpp_is_pod(type) &&
1489  e.operands().size() == 1)
1490  {
1491  e = to_unary_expr(expr).op();
1492  }
1493 
1494  if(!implicit_conversion_sequence(e, type, expr))
1495  {
1498  error() << "invalid implicit conversion from '" << to_string(e.type())
1499  << "' to '" << to_string(type) << "'" << eom;
1500 #if 0
1501  str << "\n " << follow(e.type()).pretty() << '\n';
1502  str << "\n " << type.pretty() << '\n';
1503 #endif
1504  throw 0;
1505  }
1506 }
1507 
1551  exprt &expr,
1552  const typet &type)
1553 {
1554  assert(is_reference(type));
1556 
1557  unsigned rank=0;
1558  exprt new_expr;
1559  if(reference_binding(expr, type, new_expr, rank))
1560  {
1561  expr.swap(new_expr);
1562  return;
1563  }
1564 
1566  error() << "bad reference initializer" << eom;
1567  throw 0;
1568 }
1569 
1571  const typet &t1,
1572  const typet &t2) const
1573 {
1574  assert(t1.id()==ID_pointer && t2.id()==ID_pointer);
1575  typet nt1=t1;
1576  typet nt2=t2;
1577 
1578  if(is_reference(nt1))
1579  nt1.remove(ID_C_reference);
1580  nt1.remove(ID_to_member);
1581 
1582  if(is_reference(nt2))
1583  nt2.remove(ID_C_reference);
1584  nt2.remove(ID_to_member);
1585 
1586  // substitute final subtypes
1587  std::vector<typet> snt1;
1588  snt1.push_back(nt1);
1589 
1590  while(snt1.back().has_subtype())
1591  {
1592  snt1.reserve(snt1.size()+1);
1593  snt1.push_back(snt1.back().subtype());
1594  }
1595 
1596  c_qualifierst q1;
1597  q1.read(snt1.back());
1598 
1599  bool_typet newnt1;
1600  q1.write(newnt1);
1601  snt1.back()=newnt1;
1602 
1603  std::vector<typet> snt2;
1604  snt2.push_back(nt2);
1605  while(snt2.back().has_subtype())
1606  {
1607  snt2.reserve(snt2.size()+1);
1608  snt2.push_back(snt2.back().subtype());
1609  }
1610 
1611  c_qualifierst q2;
1612  q2.read(snt2.back());
1613 
1614  bool_typet newnt2;
1615  q2.write(newnt2);
1616  snt2.back()=newnt2;
1617 
1618  const std::size_t k=snt1.size() < snt2.size() ? snt1.size() : snt2.size();
1619 
1620  for(std::size_t i=k; i > 1; i--)
1621  {
1622  snt1[snt1.size()-2].subtype()=snt1[snt1.size()-1];
1623  snt1.pop_back();
1624 
1625  snt2[snt2.size()-2].subtype()=snt2[snt2.size()-1];
1626  snt2.pop_back();
1627  }
1628 
1629  exprt e1("Dummy", snt1.back());
1630  exprt e2;
1631 
1632  return !standard_conversion_qualification(e1, snt2.back(), e2);
1633 }
1634 
1636  const exprt &expr,
1637  const typet &type,
1638  exprt &new_expr)
1639 {
1640  PRECONDITION(!is_reference(expr.type()));
1641 
1642  exprt curr_expr=expr;
1643 
1644  if(curr_expr.type().id()==ID_array)
1645  {
1646  if(type.id()==ID_pointer)
1647  {
1648  if(!standard_conversion_array_to_pointer(curr_expr, new_expr))
1649  return false;
1650  }
1651  }
1652  else if(curr_expr.type().id()==ID_code &&
1653  type.id()==ID_pointer)
1654  {
1655  if(!standard_conversion_function_to_pointer(curr_expr, new_expr))
1656  return false;
1657  }
1658  else if(curr_expr.get_bool(ID_C_lvalue))
1659  {
1660  if(!standard_conversion_lvalue_to_rvalue(curr_expr, new_expr))
1661  return false;
1662  }
1663  else
1664  new_expr=curr_expr;
1665 
1666  if(is_reference(type))
1667  {
1668  if(!expr.get_bool(ID_C_lvalue))
1669  return false;
1670 
1671  if(new_expr.type()!=type.subtype())
1672  return false;
1673 
1674  address_of_exprt address_of(expr, to_pointer_type(type));
1675  add_implicit_dereference(address_of);
1676  new_expr=address_of;
1677  return true;
1678  }
1679  else if(type.id()==ID_pointer)
1680  {
1681  if(type!=new_expr.type())
1682  return false;
1683 
1684  // add proper typecast
1685  typecast_exprt typecast_expr(expr, type);
1686  new_expr.swap(typecast_expr);
1687  return true;
1688  }
1689 
1690  return false;
1691 }
1692 
1694  const exprt &expr,
1695  const typet &type,
1696  exprt &new_expr)
1697 {
1698  exprt e(expr);
1699 
1700  if(type.id()==ID_pointer)
1701  {
1702  if(e.id()==ID_dereference && e.get_bool(ID_C_implicit))
1703  e = to_dereference_expr(expr).pointer();
1704 
1705  if(e.type().id()==ID_pointer &&
1706  cast_away_constness(e.type(), type))
1707  return false;
1708  }
1709 
1711 
1712  if(is_reference(type))
1713  {
1714  if(type.subtype().id() != ID_struct_tag)
1715  return false;
1716  }
1717  else if(type.id()==ID_pointer)
1718  {
1719  if(type.find(ID_to_member).is_not_nil())
1720  return false;
1721 
1722  if(type.subtype().id()==ID_empty)
1723  {
1724  if(!e.get_bool(ID_C_lvalue))
1725  return false;
1726  UNREACHABLE; // currently not supported
1727  }
1728  else if(type.subtype().id() == ID_struct_tag)
1729  {
1730  if(e.get_bool(ID_C_lvalue))
1731  {
1732  exprt tmp(e);
1733 
1735  return false;
1736  }
1737  }
1738  else return false;
1739  }
1740  else return false;
1741 
1742  return static_typecast(e, type, new_expr);
1743 }
1744 
1746  const exprt &expr,
1747  const typet &type,
1748  exprt &new_expr,
1749  bool check_constantness)
1750 {
1751  exprt e=expr;
1752 
1753  if(check_constantness && type.id()==ID_pointer)
1754  {
1755  if(e.id()==ID_dereference && e.get_bool(ID_C_implicit))
1756  e = to_dereference_expr(expr).pointer();
1757 
1758  if(e.type().id()==ID_pointer &&
1759  cast_away_constness(e.type(), type))
1760  return false;
1761  }
1762 
1764 
1765  if(!is_reference(type))
1766  {
1767  exprt tmp;
1768 
1769  if(e.id()==ID_code)
1770  {
1772  e.swap(tmp);
1773  else
1774  return false;
1775  }
1776 
1777  if(e.type().id()==ID_array)
1778  {
1780  e.swap(tmp);
1781  else
1782  return false;
1783  }
1784 
1785  if(e.get_bool(ID_C_lvalue))
1786  {
1788  e.swap(tmp);
1789  else
1790  return false;
1791  }
1792  }
1793 
1794  if(e.type().id()==ID_pointer &&
1795  (type.id()==ID_unsignedbv || type.id()==ID_signedbv))
1796  {
1797  // pointer to integer, always ok
1798  new_expr = typecast_exprt::conditional_cast(e, type);
1799  return true;
1800  }
1801 
1802  if(
1803  (e.type().id() == ID_unsignedbv || e.type().id() == ID_signedbv ||
1804  e.type().id() == ID_c_bool || e.type().id() == ID_bool) &&
1805  type.id() == ID_pointer && !is_reference(type))
1806  {
1807  // integer to pointer
1808  if(simplify_expr(e, *this).is_zero())
1809  {
1810  // NULL
1811  new_expr=e;
1812  new_expr.set(ID_value, ID_NULL);
1813  new_expr.type()=type;
1814  }
1815  else
1816  {
1817  new_expr = typecast_exprt::conditional_cast(e, type);
1818  }
1819  return true;
1820  }
1821 
1822  if(e.type().id()==ID_pointer &&
1823  type.id()==ID_pointer &&
1824  !is_reference(type))
1825  {
1826  // pointer to pointer: we ok it all.
1827  // This is more generous than the standard.
1828  new_expr = typecast_exprt::conditional_cast(expr, type);
1829  return true;
1830  }
1831 
1832  if(is_reference(type) && e.get_bool(ID_C_lvalue))
1833  {
1835  return true;
1836  }
1837 
1838  return false;
1839 }
1840 
1842  const exprt &expr, // source expression
1843  const typet &type, // destination type
1844  exprt &new_expr,
1845  bool check_constantness)
1846 {
1847  exprt e=expr;
1848 
1849  if(check_constantness && type.id()==ID_pointer)
1850  {
1851  if(e.id()==ID_dereference && e.get_bool(ID_C_implicit))
1852  e = to_dereference_expr(expr).pointer();
1853 
1854  if(e.type().id()==ID_pointer &&
1855  cast_away_constness(e.type(), type))
1856  return false;
1857  }
1858 
1860 
1861  if(type.get_bool(ID_C_reference))
1862  {
1863  unsigned rank=0;
1864  if(reference_binding(e, type, new_expr, rank))
1865  return true;
1866 
1867  typet subto=follow(type.subtype());
1868  typet from=follow(e.type());
1869 
1870  if(subto.id()==ID_struct && from.id()==ID_struct)
1871  {
1872  if(!expr.get_bool(ID_C_lvalue))
1873  return false;
1874 
1875  c_qualifierst qual_from;
1876  qual_from.read(e.type());
1877 
1878  c_qualifierst qual_to;
1879  qual_to.read(type.subtype());
1880 
1881  if(!qual_to.is_subset_of(qual_from))
1882  return false;
1883 
1884  const struct_typet &from_struct = to_struct_type(from);
1885  const struct_typet &subto_struct = to_struct_type(subto);
1886 
1887  if(subtype_typecast(subto_struct, from_struct))
1888  {
1889  if(e.id()==ID_dereference)
1890  {
1891  make_ptr_typecast(to_dereference_expr(e).pointer(), type);
1892  new_expr.swap(to_dereference_expr(e).pointer());
1893  return true;
1894  }
1895 
1896  exprt address_of=address_of_exprt(e);
1897  make_ptr_typecast(address_of, type);
1898  new_expr.swap(address_of);
1899  return true;
1900  }
1901  }
1902  return false;
1903  }
1904 
1905  if(type.id()==ID_empty)
1906  {
1907  new_expr = typecast_exprt::conditional_cast(e, type);
1908  return true;
1909  }
1910 
1911  // int/enum to enum
1912  if(type.id()==ID_c_enum_tag &&
1913  (e.type().id()==ID_signedbv ||
1914  e.type().id()==ID_unsignedbv ||
1915  e.type().id()==ID_c_enum_tag))
1916  {
1917  new_expr = typecast_exprt::conditional_cast(e, type);
1918  new_expr.remove(ID_C_lvalue);
1919  return true;
1920  }
1921 
1922  if(implicit_conversion_sequence(e, type, new_expr))
1923  {
1924  if(!cpp_is_pod(type))
1925  {
1926  exprt temporary;
1927  new_temporary(
1928  e.source_location(),
1929  type,
1930  already_typechecked_exprt{new_expr},
1931  temporary);
1932  new_expr.swap(temporary);
1933  }
1934  else
1935  {
1936  // try to avoid temporary
1937  new_expr.set(ID_C_temporary_avoided, true);
1938  if(new_expr.get_bool(ID_C_lvalue))
1939  new_expr.remove(ID_C_lvalue);
1940  }
1941 
1942  return true;
1943  }
1944 
1945  if(type.id()==ID_pointer && e.type().id()==ID_pointer)
1946  {
1947  if(type.find(ID_to_member).is_nil() && e.type().find(ID_to_member).is_nil())
1948  {
1949  typet to=follow(type.subtype());
1950  typet from=follow(e.type().subtype());
1951 
1952  if(from.id()==ID_empty)
1953  {
1954  new_expr = typecast_exprt::conditional_cast(e, type);
1955  return true;
1956  }
1957 
1958  if(to.id()==ID_struct && from.id()==ID_struct)
1959  {
1960  if(e.get_bool(ID_C_lvalue))
1961  {
1962  exprt tmp(e);
1964  return false;
1965  }
1966 
1967  const struct_typet &from_struct = to_struct_type(from);
1968  const struct_typet &to_struct = to_struct_type(to);
1969  if(subtype_typecast(to_struct, from_struct))
1970  {
1971  make_ptr_typecast(e, type);
1972  new_expr.swap(e);
1973  return true;
1974  }
1975  }
1976 
1977  return false;
1978  }
1979  else if(
1980  type.find(ID_to_member).is_not_nil() &&
1981  e.type().find(ID_to_member).is_not_nil())
1982  {
1983  if(type.subtype()!=e.type().subtype())
1984  return false;
1985 
1986  const struct_typet &from_struct = to_struct_type(
1987  follow(static_cast<const typet &>(e.type().find(ID_to_member))));
1988 
1989  const struct_typet &to_struct = to_struct_type(
1990  follow(static_cast<const typet &>(type.find(ID_to_member))));
1991 
1992  if(subtype_typecast(from_struct, to_struct))
1993  {
1994  new_expr = typecast_exprt::conditional_cast(e, type);
1995  return true;
1996  }
1997  }
1998  else if(
1999  type.find(ID_to_member).is_nil() &&
2000  e.type().find(ID_to_member).is_not_nil())
2001  {
2002  if(type.subtype() != e.type().subtype())
2003  return false;
2004 
2005  const struct_typet &from_struct = to_struct_type(
2006  follow(static_cast<const typet &>(e.type().find(ID_to_member))));
2007 
2008  new_expr = e;
2009  new_expr.type().add(ID_to_member) = from_struct;
2010 
2011  return true;
2012  }
2013  else
2014  return false;
2015  }
2016 
2017  return false;
2018 }
constant_exprt from_integer(const mp_integer &int_value, const typet &type)
Definition: arith_tools.cpp:99
void base_type(typet &type, const namespacet &ns)
Definition: base_type.cpp:109
const floatbv_typet & to_floatbv_type(const typet &type)
Cast a typet to a floatbv_typet.
const signedbv_typet & to_signedbv_type(const typet &type)
Cast a typet to a signedbv_typet.
const unsignedbv_typet & to_unsignedbv_type(const typet &type)
Cast a typet to an unsignedbv_typet.
floatbv_typet float_type()
Definition: c_types.cpp:195
reference_typet reference_type(const typet &subtype)
Definition: c_types.cpp:258
signedbv_typet signed_int_type()
Definition: c_types.cpp:40
pointer_typet pointer_type(const typet &subtype)
Definition: c_types.cpp:253
typet c_bool_type()
Definition: c_types.cpp:118
bitvector_typet c_index_type()
Definition: c_types.cpp:16
floatbv_typet double_type()
Definition: c_types.cpp:203
const union_typet & to_union_type(const typet &type)
Cast a typet to a union_typet.
Definition: c_types.h:162
Operator to return the address of an object.
Definition: pointer_expr.h:361
static void make_already_typechecked(exprt &expr)
std::size_t get_width() const
Definition: std_types.h:864
The Boolean type.
Definition: std_types.h:36
virtual void write(typet &src) const override
virtual void read(const typet &src) override
virtual bool is_subset_of(const qualifierst &other) const override
Definition: c_qualifiers.h:108
bool get_this() const
Definition: std_types.h:600
Base type of functions.
Definition: std_types.h:539
const typet & return_type() const
Definition: std_types.h:645
const parameterst & parameters() const
Definition: std_types.h:655
struct configt::ansi_ct ansi_c
bool implicit_conversion_sequence(const exprt &expr, const typet &type, exprt &new_expr, unsigned &rank)
implicit conversion sequence
bool reference_compatible(const exprt &expr, const typet &type, unsigned &rank) const
Reference-compatible.
bool standard_conversion_floating_point_conversion(const exprt &expr, const typet &type, exprt &new_expr) const
Floating-point conversion.
bool reinterpret_typecast(const exprt &expr, const typet &type, exprt &new_expr, bool check_constantness=true)
bool standard_conversion_boolean(const exprt &expr, exprt &new_expr) const
Boolean conversion.
bool standard_conversion_pointer(const exprt &expr, const typet &type, exprt &new_expr)
Pointer conversion.
void implicit_typecast(exprt &expr, const typet &type) override
bool standard_conversion_integral_conversion(const exprt &expr, const typet &type, exprt &new_expr) const
Integral conversion.
bool standard_conversion_sequence(const exprt &expr, const typet &type, exprt &new_expr, unsigned &rank)
Standard Conversion Sequence.
bool standard_conversion_qualification(const exprt &expr, const typet &, exprt &new_expr) const
Qualification conversion.
void typecheck_side_effect_function_call(side_effect_expr_function_callt &) override
bool cpp_is_pod(const typet &type) const
Definition: cpp_is_pod.cpp:16
bool standard_conversion_floating_point_promotion(const exprt &expr, exprt &new_expr) const
Floating-point-promotion conversion.
bool standard_conversion_floating_integral_conversion(const exprt &expr, const typet &type, exprt &new_expr) const
Floating-integral conversion.
bool const_typecast(const exprt &expr, const typet &type, exprt &new_expr)
void new_temporary(const source_locationt &source_location, const typet &, const exprt::operandst &ops, exprt &temporary)
void show_instantiation_stack(std::ostream &)
bool standard_conversion_function_to_pointer(const exprt &expr, exprt &new_expr) const
Function-to-pointer conversion.
bool standard_conversion_array_to_pointer(const exprt &expr, exprt &new_expr) const
Array-to-pointer conversion.
bool dynamic_typecast(const exprt &expr, const typet &type, exprt &new_expr)
bool user_defined_conversion_sequence(const exprt &expr, const typet &type, exprt &new_expr, unsigned &rank)
User-defined conversion sequence.
bool standard_conversion_lvalue_to_rvalue(const exprt &expr, exprt &new_expr) const
Lvalue-to-rvalue conversion.
bool cast_away_constness(const typet &t1, const typet &t2) const
void add_implicit_dereference(exprt &)
bool static_typecast(const exprt &expr, const typet &type, exprt &new_expr, bool check_constantness=true)
bool subtype_typecast(const struct_typet &from, const struct_typet &to) const
bool standard_conversion_integral_promotion(const exprt &expr, exprt &new_expr) const
Integral-promotion conversion.
std::string to_string(const typet &) override
void make_ptr_typecast(exprt &expr, const typet &dest_type)
bool standard_conversion_pointer_to_member(const exprt &expr, const typet &type, exprt &new_expr)
Pointer-to-member conversion.
void reference_initializer(exprt &expr, const typet &type)
A reference to type "cv1 T1" is initialized by an expression of type "cv2 T2" as follows:
bool reference_binding(exprt expr, const typet &type, exprt &new_expr, unsigned &rank)
Reference binding.
bool reference_related(const exprt &expr, const typet &type) const
Reference-related.
Operator to dereference a pointer.
Definition: pointer_expr.h:648
Base class for all expressions.
Definition: expr.h:54
const source_locationt & find_source_location() const
Get a source_locationt from the expression or from its operands (non-recursively).
Definition: expr.cpp:165
void copy_to_operands(const exprt &expr)
Copy the given argument to the end of exprt's operands.
Definition: expr.h:129
source_locationt & add_source_location()
Definition: expr.h:235
const source_locationt & source_location() const
Definition: expr.h:230
typet & type()
Return the type of the expression.
Definition: expr.h:82
operandst & operands()
Definition: expr.h:92
void add_to_operands(const exprt &expr)
Add the given argument to the end of exprt's operands.
Definition: expr.h:136
Array index operator.
Definition: std_expr.h:1328
bool get_bool(const irep_idt &name) const
Definition: irep.cpp:58
std::string pretty(unsigned indent=0, unsigned max_indent=0) const
Definition: irep.cpp:495
const irept & find(const irep_idt &name) const
Definition: irep.cpp:106
const irep_idt & get(const irep_idt &name) const
Definition: irep.cpp:45
void remove(const irep_idt &name)
Definition: irep.cpp:96
void set(const irep_idt &name, const irep_idt &value)
Definition: irep.h:420
bool is_not_nil() const
Definition: irep.h:380
const irep_idt & id() const
Definition: irep.h:396
void make_nil()
Definition: irep.h:454
void swap(irept &irep)
Definition: irep.h:442
irept & add(const irep_idt &name)
Definition: irep.cpp:116
bool is_nil() const
Definition: irep.h:376
source_locationt source_location
Definition: message.h:247
mstreamt & error() const
Definition: message.h:399
static eomt eom
Definition: message.h:297
exprt & op0()
Definition: std_expr.h:844
const typet & follow(const typet &) const
Resolve type symbol to the type it points to.
Definition: namespace.cpp:49
const symbolt & lookup(const irep_idt &name) const
Lookup a symbol in the namespace.
Definition: namespace.h:43
The pointer type These are both 'bitvector_typet' (they have a width) and 'type_with_subtypet' (they ...
Definition: pointer_expr.h:24
const typet & base_type() const
The type of the data what we point to.
Definition: pointer_expr.h:35
A side_effect_exprt representation of a function call side effect.
Definition: std_code.h:1692
An expression containing a side effect.
Definition: std_code.h:1450
Structure type, corresponds to C style structs.
Definition: std_types.h:231
bool is_incomplete() const
A struct/union may be incomplete.
Definition: std_types.h:185
Semantic type conversion.
Definition: std_expr.h:1920
static exprt conditional_cast(const exprt &expr, const typet &type)
Definition: std_expr.h:1928
The type of an expression, extends irept.
Definition: type.h:29
const typet & subtype() const
Definition: type.h:48
const exprt & op() const
Definition: std_expr.h:293
configt config
Definition: config.cpp:25
C++ Language Type Checking.
symbol_exprt cpp_symbol_expr(const symbolt &symbol)
Definition: cpp_util.cpp:14
exprt is_not_zero(const exprt &src, const namespacet &ns)
converts a scalar/float expression to C/C++ Booleans
Definition: expr_util.cpp:97
Deprecated expression utility functions.
std::string from_type(const namespacet &ns, const irep_idt &identifier, const typet &type)
API to expression classes for Pointers.
bool is_reference(const typet &type)
Returns true if the type is a reference.
Definition: std_types.cpp:137
const dereference_exprt & to_dereference_expr(const exprt &expr)
Cast an exprt to a dereference_exprt.
Definition: pointer_expr.h:704
const pointer_typet & to_pointer_type(const typet &type)
Cast a typet to a pointer_typet.
Definition: pointer_expr.h:79
const reference_typet & to_reference_type(const typet &type)
Cast a typet to a reference_typet.
Definition: pointer_expr.h:148
bool simplify(exprt &expr, const namespacet &ns)
exprt simplify_expr(exprt src, const namespacet &ns)
#define UNREACHABLE
This should be used to mark dead code.
Definition: invariant.h:503
#define DATA_INVARIANT(CONDITION, REASON)
This condition should be used to document that assumptions that are made on goto_functions,...
Definition: invariant.h:510
#define PRECONDITION(CONDITION)
Definition: invariant.h:463
auto component(T &struct_expr, const irep_idt &name, const namespacet &ns) -> decltype(struct_expr.op0())
Definition: std_expr.cpp:48
API to expression classes.
const multi_ary_exprt & to_multi_ary_expr(const exprt &expr)
Cast an exprt to a multi_ary_exprt.
Definition: std_expr.h:899
const unary_exprt & to_unary_expr(const exprt &expr)
Cast an exprt to a unary_exprt.
Definition: std_expr.h:328
const struct_typet & to_struct_type(const typet &type)
Cast a typet to a struct_typet.
Definition: std_types.h:308
const code_typet & to_code_type(const typet &type)
Cast a typet to a code_typet.
Definition: std_types.h:744
std::size_t single_width
Definition: config.h:116
std::size_t int_width
Definition: config.h:109