CBMC
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 = to_pointer_type(sub_from).base_type();
149  sub_from.swap(tmp1);
150 
151  typet tmp2 = sub_to.add_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(to_pointer_type(new_expr.type()).base_type());
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(to_pointer_type(new_expr.type()).base_type());
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  {
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(to_pointer_type(type).base_type());
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(
590  to_pointer_type(this2.type()).base_type().get_bool(ID_C_constant) &&
591  !to_pointer_type(this1.type()).base_type().get_bool(ID_C_constant))
592  return false;
593 
594  // give a second chance ignoring `this'
595  if(code1!=code2)
596  return false;
597  }
598  else
599  return false;
600  }
601 
602  if(expr.get_bool(ID_C_lvalue))
603  return false;
604 
605  if(expr.id() == ID_constant && is_null_pointer(to_constant_expr(expr)))
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)
692  expr, to_c_bit_field_type(type).underlying_type(), new_expr, rank);
693 
694  // we turn bit fields into their underlying type
695  if(curr_expr.type().id()==ID_c_bit_field)
696  curr_expr = typecast_exprt(
697  curr_expr, to_c_bit_field_type(curr_expr.type()).underlying_type());
698 
699  if(curr_expr.type().id()==ID_array)
700  {
701  if(type.id()==ID_pointer)
702  {
703  if(!standard_conversion_array_to_pointer(curr_expr, new_expr))
704  return false;
705  }
706  }
707  else if(curr_expr.type().id()==ID_code &&
708  type.id()==ID_pointer)
709  {
710  if(!standard_conversion_function_to_pointer(curr_expr, new_expr))
711  return false;
712  }
713  else if(curr_expr.get_bool(ID_C_lvalue))
714  {
715  if(!standard_conversion_lvalue_to_rvalue(curr_expr, new_expr))
716  return false;
717  }
718  else
719  new_expr=curr_expr;
720 
721  curr_expr.swap(new_expr);
722 
723  // two enums are the same if the tag is the same,
724  // even if the width differs (enum bit-fields!)
725  if(follow(type).id()==ID_c_enum &&
726  follow(curr_expr.type()).id()==ID_c_enum)
727  {
728  if(follow(type).find(ID_tag)==
729  follow(curr_expr.type()).find(ID_tag))
730  return true;
731  else
732  {
733  // In contrast to C, we simply don't allow implicit conversions
734  // between enums.
735  return false;
736  }
737  }
738 
739  // need to consider #c_type
740  if(follow(curr_expr.type())!=follow(type) ||
741  curr_expr.type().get(ID_C_c_type)!=type.get(ID_C_c_type))
742  {
743  if(type.id()==ID_signedbv ||
744  type.id()==ID_unsignedbv ||
745  follow(type).id()==ID_c_enum)
746  {
747  if(!standard_conversion_integral_promotion(curr_expr, new_expr) ||
748  new_expr.type() != type)
749  {
750  if(!standard_conversion_integral_conversion(curr_expr, type, new_expr))
751  {
753  curr_expr, type, new_expr))
754  return false;
755  }
756 
757  rank+=3;
758  }
759  else
760  rank+=2;
761  }
762  else if(type.id()==ID_floatbv || type.id()==ID_fixedbv)
763  {
764  if(!standard_conversion_floating_point_promotion(curr_expr, new_expr) ||
765  new_expr.type() != type)
766  {
768  curr_expr, type, new_expr) &&
770  curr_expr, type, new_expr))
771  return false;
772 
773  rank += 3;
774  }
775  else
776  rank += 2;
777  }
778  else if(type.id()==ID_pointer)
779  {
780  if(
781  expr.type().id() == ID_pointer &&
782  to_pointer_type(expr.type()).base_type().id() == ID_nullptr)
783  {
784  // std::nullptr_t to _any_ pointer type is ok
785  new_expr = typecast_exprt::conditional_cast(new_expr, type);
786  }
787  else if(!standard_conversion_pointer(curr_expr, type, new_expr))
788  {
789  if(!standard_conversion_pointer_to_member(curr_expr, type, new_expr))
790  return false;
791  }
792 
793  rank += 3;
794  }
795  else if(type.id() == ID_c_bool)
796  {
797  if(!standard_conversion_boolean(curr_expr, new_expr))
798  return false;
799 
800  rank += 3;
801  }
802  else if(type.id() == ID_bool)
803  {
804  new_expr = is_not_zero(curr_expr, *this);
805 
806  rank += 3;
807  }
808  else
809  return false;
810  }
811  else
812  new_expr=curr_expr;
813 
814  curr_expr.swap(new_expr);
815 
816  if(curr_expr.type().id()==ID_pointer)
817  {
818  typet sub_from=curr_expr.type();
819  typet sub_to=type;
820 
821  do
822  {
823  typet tmp_from = to_pointer_type(sub_from).base_type();
824  sub_from.swap(tmp_from);
825  typet tmp_to = sub_to.add_subtype();
826  sub_to.swap(tmp_to);
827 
828  c_qualifierst qual_from;
829  qual_from.read(sub_from);
830 
831  c_qualifierst qual_to;
832  qual_to.read(sub_to);
833 
834  if(qual_from!=qual_to)
835  {
836  rank+=1;
837  break;
838  }
839  }
840  while(sub_from.id()==ID_pointer);
841 
842  if(!standard_conversion_qualification(curr_expr, type, new_expr))
843  return false;
844  }
845  else
846  {
847  new_expr=curr_expr;
848  new_expr.type()=type;
849  }
850 
851  return true;
852 }
853 
860  const exprt &expr,
861  const typet &type,
862  exprt &new_expr,
863  unsigned &rank)
864 {
865  assert(!is_reference(expr.type()));
866  assert(!is_reference(type));
867 
868  const typet &from=follow(expr.type());
869  const typet &to=follow(type);
870 
871  new_expr.make_nil();
872 
873  // special case:
874  // A conversion from a type to the same type is given an exact
875  // match rank even though a user-defined conversion is used
876 
877  if(from==to)
878  rank+=0;
879  else
880  rank+=4; // higher than all the standard conversions
881 
882  if(to.id()==ID_struct)
883  {
884  std::string err_msg;
885 
886  if(cpp_is_pod(to))
887  {
888  if(from.id()==ID_struct)
889  {
890  const struct_typet &from_struct=to_struct_type(from);
891  const struct_typet &to_struct=to_struct_type(to);
892 
893  // potentially requires
894  // expr.get_bool(ID_C_lvalue) ??
895 
896  if(subtype_typecast(from_struct, to_struct))
897  {
898  exprt address=address_of_exprt(expr);
899 
900  // simplify address
901  if(expr.id()==ID_dereference)
902  address = to_dereference_expr(expr).pointer();
903 
904  pointer_typet ptr_sub=pointer_type(type);
905  c_qualifierst qual_from;
906  qual_from.read(expr.type());
907  qual_from.write(ptr_sub.base_type());
908  make_ptr_typecast(address, ptr_sub);
909 
910  const dereference_exprt deref(address);
911 
912  // create temporary object
913  side_effect_exprt tmp_object_expr(
914  ID_temporary_object, type, expr.source_location());
915  tmp_object_expr.copy_to_operands(deref);
916  tmp_object_expr.set(ID_C_lvalue, true);
917  tmp_object_expr.set(ID_mode, ID_cpp);
918 
919  new_expr.swap(tmp_object_expr);
920  return true;
921  }
922  }
923  }
924  else
925  {
926  bool found=false;
927 
928  for(const auto &component : to_struct_type(to).components())
929  {
930  if(component.get_bool(ID_from_base))
931  continue;
932 
933  if(component.get_bool(ID_is_explicit))
934  continue;
935 
936  const typet &comp_type = component.type();
937 
938  if(comp_type.id() !=ID_code)
939  continue;
940 
941  if(to_code_type(comp_type).return_type().id() != ID_constructor)
942  continue;
943 
944  // TODO: ellipsis
945 
946  const auto &parameters = to_code_type(comp_type).parameters();
947 
948  if(parameters.size() != 2)
949  continue;
950 
951  exprt curr_arg1 = parameters[1];
952  typet arg1_type=curr_arg1.type();
953 
954  if(is_reference(arg1_type))
955  {
956  typet tmp = to_reference_type(arg1_type).base_type();
957  arg1_type.swap(tmp);
958  }
959 
960  unsigned tmp_rank=0;
961  if(arg1_type.id() != ID_struct_tag)
962  {
963  exprt tmp_expr;
965  expr, arg1_type, tmp_expr, tmp_rank))
966  {
967  // check if it's ambiguous
968  if(found)
969  return false;
970  found=true;
971 
972  if(expr.get_bool(ID_C_lvalue))
973  tmp_expr.set(ID_C_lvalue, true);
974 
975  tmp_expr.add_source_location()=expr.source_location();
976 
977  exprt func_symb = cpp_symbol_expr(lookup(component.get_name()));
978  func_symb.type()=comp_type;
980 
981  // create temporary object
983  std::move(func_symb),
984  {tmp_expr},
986  expr.source_location());
988 
989  new_expr.swap(ctor_expr);
990  assert(new_expr.get(ID_statement)==ID_temporary_object);
991 
992  if(to.get_bool(ID_C_constant))
993  new_expr.type().set(ID_C_constant, true);
994 
995  rank += tmp_rank;
996  }
997  }
998  else if(from.id() == ID_struct && arg1_type.id() == ID_struct_tag)
999  {
1000  // try derived-to-base conversion
1001  address_of_exprt expr_pfrom(expr, pointer_type(expr.type()));
1002  pointer_typet pto=pointer_type(arg1_type);
1003 
1004  exprt expr_ptmp;
1005  tmp_rank=0;
1007  expr_pfrom, pto, expr_ptmp, tmp_rank))
1008  {
1009  // check if it's ambiguous
1010  if(found)
1011  return false;
1012  found=true;
1013 
1014  rank+=tmp_rank;
1015 
1016  // create temporary object
1017  dereference_exprt expr_deref(expr_ptmp);
1018  expr_deref.set(ID_C_lvalue, true);
1019  expr_deref.add_source_location()=expr.source_location();
1020 
1021  exprt new_object(ID_new_object, type);
1022  new_object.set(ID_C_lvalue, true);
1023  new_object.type().set(ID_C_constant, false);
1024 
1025  exprt func_symb = cpp_symbol_expr(lookup(component.get_name()));
1026  func_symb.type()=comp_type;
1028 
1030  std::move(func_symb),
1031  {expr_deref},
1033  expr.source_location());
1035 
1036  new_expr.swap(ctor_expr);
1037 
1038  INVARIANT(
1039  new_expr.get(ID_statement)==ID_temporary_object,
1040  "statement ID");
1041 
1042  if(to.get_bool(ID_C_constant))
1043  new_expr.type().set(ID_C_constant, true);
1044  }
1045  }
1046  }
1047  if(found)
1048  return true;
1049  }
1050  }
1051 
1052  // conversion operators
1053  if(from.id()==ID_struct)
1054  {
1055  bool found=false;
1056  for(const auto &component : to_struct_type(from).components())
1057  {
1058  if(component.get_bool(ID_from_base))
1059  continue;
1060 
1061  if(!component.get_bool(ID_is_cast_operator))
1062  continue;
1063 
1064  const code_typet &comp_type = to_code_type(component.type());
1066  comp_type.parameters().size() == 1, "expected exactly one parameter");
1067 
1068  typet this_type = comp_type.parameters().front().type();
1069  this_type.set(ID_C_reference, true);
1070 
1071  exprt this_expr(expr);
1072  this_type.set(ID_C_this, true);
1073 
1074  unsigned tmp_rank=0;
1075  exprt tmp_expr;
1076 
1078  this_expr, this_type, tmp_expr, tmp_rank))
1079  {
1080  // To take care of the possible virtual case,
1081  // we build the function as a member expression.
1082  const cpp_namet cpp_func_name(component.get_base_name());
1083 
1084  exprt member_func(ID_member);
1085  member_func.add(ID_component_cpp_name)=cpp_func_name;
1086  member_func.copy_to_operands(already_typechecked_exprt{expr});
1087 
1089  std::move(member_func),
1090  {},
1092  expr.source_location());
1094 
1095  if(standard_conversion_sequence(func_expr, type, tmp_expr, tmp_rank))
1096  {
1097  // check if it's ambiguous
1098  if(found)
1099  return false;
1100  found=true;
1101 
1102  rank+=tmp_rank;
1103  new_expr.swap(tmp_expr);
1104  }
1105  }
1106  }
1107  if(found)
1108  return true;
1109  }
1110 
1111  return new_expr.is_not_nil();
1112 }
1113 
1119  const exprt &expr,
1120  const typet &type) const
1121 {
1122  assert(is_reference(type));
1123  assert(!is_reference(expr.type()));
1124 
1125  typet from=follow(expr.type());
1126  typet to = follow(to_reference_type(type).base_type());
1127 
1128  // need to check #c_type
1129  if(from.get(ID_C_c_type)!=to.get(ID_C_c_type))
1130  return false;
1131 
1132  if(from==to)
1133  return true;
1134 
1135  if(from.id()==ID_struct &&
1136  to.id()==ID_struct)
1137  return subtype_typecast(to_struct_type(from),
1138  to_struct_type(to));
1139 
1140  if(
1141  from.id() == ID_struct && type.get_bool(ID_C_this) &&
1142  to_pointer_type(type).base_type().id() == ID_empty)
1143  {
1144  // virtual-call case
1145  return true;
1146  }
1147 
1148  return false;
1149 }
1150 
1156  const exprt &expr,
1157  const typet &type,
1158  unsigned &rank) const
1159 {
1160  assert(is_reference(type));
1161  assert(!is_reference(expr.type()));
1162 
1163  if(!reference_related(expr, type))
1164  return false;
1165 
1166  if(expr.type() != to_reference_type(type).base_type())
1167  rank+=3;
1168 
1169  c_qualifierst qual_from;
1170  qual_from.read(expr.type());
1171 
1172  c_qualifierst qual_to;
1173  qual_to.read(to_reference_type(type).base_type());
1174 
1175  if(qual_from!=qual_to)
1176  rank+=1;
1177 
1178  if(qual_from.is_subset_of(qual_to))
1179  return true;
1180 
1181  return false;
1182 }
1183 
1219  exprt expr,
1220  const typet &type,
1221  exprt &new_expr,
1222  unsigned &rank)
1223 {
1224  assert(is_reference(type));
1225  assert(!is_reference(expr.type()));
1226 
1227  unsigned backup_rank=rank;
1228 
1229  if(type.get_bool(ID_C_this) &&
1230  !expr.get_bool(ID_C_lvalue))
1231  {
1232  // `this' has to be an lvalue
1233  if(expr.get(ID_statement)==ID_temporary_object)
1234  expr.set(ID_C_lvalue, true);
1235  else if(expr.get(ID_statement)==ID_function_call)
1236  expr.set(ID_C_lvalue, true);
1237  else if(expr.get_bool(ID_C_temporary_avoided))
1238  {
1239  expr.remove(ID_C_temporary_avoided);
1240  exprt temporary;
1241  new_temporary(expr.source_location(), expr.type(), expr, temporary);
1242  expr.swap(temporary);
1243  expr.set(ID_C_lvalue, true);
1244  }
1245  else
1246  return false;
1247  }
1248 
1249  if(
1250  expr.get_bool(ID_C_lvalue) ||
1251  to_reference_type(type).base_type().get_bool(ID_C_constant))
1252  {
1253  if(reference_compatible(expr, type, rank))
1254  {
1255  if(!expr.get_bool(ID_C_lvalue))
1256  {
1257  // create temporary object
1258  side_effect_exprt tmp{ID_temporary_object,
1259  {std::move(expr)},
1260  to_reference_type(type).base_type(),
1261  expr.source_location()};
1262  tmp.set(ID_mode, ID_cpp);
1263  expr.swap(tmp);
1264  }
1265 
1266  {
1267  address_of_exprt tmp(expr, reference_type(expr.type()));
1268  tmp.add_source_location()=expr.source_location();
1269  new_expr.swap(tmp);
1270  }
1271 
1272  if(expr.type() != to_reference_type(type).base_type())
1273  {
1274  c_qualifierst qual_from;
1275  qual_from.read(expr.type());
1276  new_expr = typecast_exprt::conditional_cast(new_expr, type);
1277  qual_from.write(to_reference_type(new_expr.type()).base_type());
1278  }
1279 
1280  return true;
1281  }
1282 
1283  rank=backup_rank;
1284  }
1285 
1286  // conversion operators
1287  const typet &from_type = follow(expr.type());
1288  if(from_type.id()==ID_struct)
1289  {
1290  for(const auto &component : to_struct_type(from_type).components())
1291  {
1292  if(component.get_bool(ID_from_base))
1293  continue;
1294 
1295  if(!component.get_bool(ID_is_cast_operator))
1296  continue;
1297 
1298  const code_typet &component_type = to_code_type(component.type());
1299 
1300  // otherwise it cannot bind directly (not an lvalue)
1301  if(!is_reference(component_type.return_type()))
1302  continue;
1303 
1304  assert(component_type.parameters().size()==1);
1305 
1306  typet this_type =
1307  component_type.parameters().front().type();
1308  this_type.set(ID_C_reference, true);
1309 
1310  exprt this_expr(expr);
1311 
1312  this_type.set(ID_C_this, true);
1313 
1314  unsigned tmp_rank=0;
1315 
1316  exprt tmp_expr;
1318  this_expr, this_type, tmp_expr, tmp_rank))
1319  {
1320  // To take care of the possible virtual case,
1321  // we build the function as a member expression.
1322  const cpp_namet cpp_func_name(component.get_base_name());
1323 
1324  exprt member_func(ID_member);
1325  member_func.add(ID_component_cpp_name)=cpp_func_name;
1326  member_func.copy_to_operands(already_typechecked_exprt{expr});
1327 
1329  std::move(member_func),
1330  {},
1332  expr.source_location());
1334 
1335  // let's check if the returned value binds directly
1336  exprt returned_value=func_expr;
1337  add_implicit_dereference(returned_value);
1338 
1339  if(returned_value.get_bool(ID_C_lvalue) &&
1340  reference_compatible(returned_value, type, rank))
1341  {
1342  // returned values are lvalues in case of references only
1344  is_reference(to_dereference_expr(returned_value).op().type()),
1345  "the returned value must be pointer to reference");
1346 
1347  new_expr = to_multi_ary_expr(returned_value).op0();
1348 
1349  if(returned_value.type() != to_reference_type(type).base_type())
1350  {
1351  c_qualifierst qual_from;
1352  qual_from.read(returned_value.type());
1353  make_ptr_typecast(new_expr, type);
1354  qual_from.write(to_reference_type(new_expr.type()).base_type());
1355  }
1356  rank+=4+tmp_rank;
1357  return true;
1358  }
1359  }
1360  }
1361  }
1362 
1363  // No temporary allowed for `this'
1364  if(type.get_bool(ID_C_this))
1365  return false;
1366 
1367  if(
1368  !to_reference_type(type).base_type().get_bool(ID_C_constant) ||
1369  to_reference_type(type).base_type().get_bool(ID_C_volatile))
1370  return false;
1371 
1372  // TODO: handle the case for implicit parameters
1373  if(
1374  !to_reference_type(type).base_type().get_bool(ID_C_constant) &&
1375  !expr.get_bool(ID_C_lvalue))
1376  return false;
1377 
1378  exprt arg_expr=expr;
1379 
1380  if(arg_expr.type().id() == ID_struct_tag)
1381  {
1382  // required to initialize the temporary
1383  arg_expr.set(ID_C_lvalue, true);
1384  }
1385 
1387  arg_expr, to_reference_type(type).base_type(), new_expr, rank))
1388  {
1389  address_of_exprt tmp(new_expr, reference_type(new_expr.type()));
1390  tmp.add_source_location()=new_expr.source_location();
1391  new_expr.swap(tmp);
1392  return true;
1393  }
1394 
1395  rank=backup_rank;
1397  expr, to_reference_type(type).base_type(), new_expr, rank))
1398  {
1399  {
1400  // create temporary object
1401  side_effect_exprt tmp(
1402  ID_temporary_object,
1403  to_reference_type(type).base_type(),
1404  expr.source_location());
1405  tmp.set(ID_mode, ID_cpp);
1406  // tmp.set(ID_C_lvalue, true);
1407  tmp.add_to_operands(std::move(new_expr));
1408  new_expr.swap(tmp);
1409  }
1410 
1411  address_of_exprt tmp(new_expr, pointer_type(new_expr.type()));
1412  tmp.type().set(ID_C_reference, true);
1413  tmp.add_source_location()=new_expr.source_location();
1414 
1415  new_expr=tmp;
1416  return true;
1417  }
1418 
1419  return false;
1420 }
1421 
1429  const exprt &expr,
1430  const typet &type,
1431  exprt &new_expr,
1432  unsigned &rank)
1433 {
1434  unsigned backup_rank=rank;
1435 
1436  exprt e=expr;
1438 
1439  if(is_reference(type))
1440  {
1441  if(!reference_binding(e, type, new_expr, rank))
1442  return false;
1443 
1444  #if 0
1445  simplify_exprt simplify(*this);
1446  simplify.simplify(new_expr);
1447  new_expr.type().set(ID_C_reference, true);
1448  #endif
1449  }
1450  else if(!standard_conversion_sequence(e, type, new_expr, rank))
1451  {
1452  rank=backup_rank;
1453  if(!user_defined_conversion_sequence(e, type, new_expr, rank))
1454  return false;
1455 
1456  #if 0
1457  simplify_exprt simplify(*this);
1458  simplify.simplify(new_expr);
1459  #endif
1460  }
1461 
1462  return true;
1463 }
1464 
1471  const exprt &expr,
1472  const typet &type,
1473  exprt &new_expr)
1474 {
1475  unsigned rank=0;
1476  return implicit_conversion_sequence(expr, type, new_expr, rank);
1477 }
1478 
1485  const exprt &expr,
1486  const typet &type,
1487  unsigned &rank)
1488 {
1489  exprt new_expr;
1490  return implicit_conversion_sequence(expr, type, new_expr, rank);
1491 }
1492 
1494 {
1495  exprt e=expr;
1496 
1497  if(
1498  e.id() == ID_initializer_list && cpp_is_pod(type) &&
1499  e.operands().size() == 1)
1500  {
1501  e = to_unary_expr(expr).op();
1502  }
1503 
1504  if(!implicit_conversion_sequence(e, type, expr))
1505  {
1508  error() << "invalid implicit conversion from '" << to_string(e.type())
1509  << "' to '" << to_string(type) << "'" << eom;
1510 #if 0
1511  str << "\n " << follow(e.type()).pretty() << '\n';
1512  str << "\n " << type.pretty() << '\n';
1513 #endif
1514  throw 0;
1515  }
1516 }
1517 
1561  exprt &expr,
1562  const typet &type)
1563 {
1564  assert(is_reference(type));
1566 
1567  unsigned rank=0;
1568  exprt new_expr;
1569  if(reference_binding(expr, type, new_expr, rank))
1570  {
1571  expr.swap(new_expr);
1572  return;
1573  }
1574 
1576  error() << "bad reference initializer" << eom;
1577  throw 0;
1578 }
1579 
1581  const typet &t1,
1582  const typet &t2) const
1583 {
1584  assert(t1.id()==ID_pointer && t2.id()==ID_pointer);
1585  typet nt1=t1;
1586  typet nt2=t2;
1587 
1588  if(is_reference(nt1))
1589  nt1.remove(ID_C_reference);
1590  nt1.remove(ID_to_member);
1591 
1592  if(is_reference(nt2))
1593  nt2.remove(ID_C_reference);
1594  nt2.remove(ID_to_member);
1595 
1596  // substitute final subtypes
1597  std::vector<typet> snt1;
1598  snt1.push_back(nt1);
1599 
1600  while(snt1.back().has_subtype())
1601  {
1602  snt1.reserve(snt1.size()+1);
1603  snt1.push_back(to_type_with_subtype(snt1.back()).subtype());
1604  }
1605 
1606  c_qualifierst q1;
1607  q1.read(snt1.back());
1608 
1609  bool_typet newnt1;
1610  q1.write(newnt1);
1611  snt1.back()=newnt1;
1612 
1613  std::vector<typet> snt2;
1614  snt2.push_back(nt2);
1615  while(snt2.back().has_subtype())
1616  {
1617  snt2.reserve(snt2.size()+1);
1618  snt2.push_back(to_type_with_subtype(snt2.back()).subtype());
1619  }
1620 
1621  c_qualifierst q2;
1622  q2.read(snt2.back());
1623 
1624  bool_typet newnt2;
1625  q2.write(newnt2);
1626  snt2.back()=newnt2;
1627 
1628  const std::size_t k=snt1.size() < snt2.size() ? snt1.size() : snt2.size();
1629 
1630  for(std::size_t i=k; i > 1; i--)
1631  {
1632  to_type_with_subtype(snt1[snt1.size() - 2]).subtype() =
1633  snt1[snt1.size() - 1];
1634  snt1.pop_back();
1635 
1636  to_type_with_subtype(snt2[snt2.size() - 2]).subtype() =
1637  snt2[snt2.size() - 1];
1638  snt2.pop_back();
1639  }
1640 
1641  exprt e1("Dummy", snt1.back());
1642  exprt e2;
1643 
1644  return !standard_conversion_qualification(e1, snt2.back(), e2);
1645 }
1646 
1648  const exprt &expr,
1649  const typet &type,
1650  exprt &new_expr)
1651 {
1652  PRECONDITION(!is_reference(expr.type()));
1653 
1654  exprt curr_expr=expr;
1655 
1656  if(curr_expr.type().id()==ID_array)
1657  {
1658  if(type.id()==ID_pointer)
1659  {
1660  if(!standard_conversion_array_to_pointer(curr_expr, new_expr))
1661  return false;
1662  }
1663  }
1664  else if(curr_expr.type().id()==ID_code &&
1665  type.id()==ID_pointer)
1666  {
1667  if(!standard_conversion_function_to_pointer(curr_expr, new_expr))
1668  return false;
1669  }
1670  else if(curr_expr.get_bool(ID_C_lvalue))
1671  {
1672  if(!standard_conversion_lvalue_to_rvalue(curr_expr, new_expr))
1673  return false;
1674  }
1675  else
1676  new_expr=curr_expr;
1677 
1678  if(is_reference(type))
1679  {
1680  if(!expr.get_bool(ID_C_lvalue))
1681  return false;
1682 
1683  if(new_expr.type() != to_reference_type(type).base_type())
1684  return false;
1685 
1686  address_of_exprt address_of(expr, to_pointer_type(type));
1687  add_implicit_dereference(address_of);
1688  new_expr=address_of;
1689  return true;
1690  }
1691  else if(type.id()==ID_pointer)
1692  {
1693  if(type!=new_expr.type())
1694  return false;
1695 
1696  // add proper typecast
1697  typecast_exprt typecast_expr(expr, type);
1698  new_expr.swap(typecast_expr);
1699  return true;
1700  }
1701 
1702  return false;
1703 }
1704 
1706  const exprt &expr,
1707  const typet &type,
1708  exprt &new_expr)
1709 {
1710  exprt e(expr);
1711 
1712  if(type.id()==ID_pointer)
1713  {
1714  if(e.id()==ID_dereference && e.get_bool(ID_C_implicit))
1715  e = to_dereference_expr(expr).pointer();
1716 
1717  if(e.type().id()==ID_pointer &&
1718  cast_away_constness(e.type(), type))
1719  return false;
1720  }
1721 
1723 
1724  if(is_reference(type))
1725  {
1726  if(to_reference_type(type).base_type().id() != ID_struct_tag)
1727  return false;
1728  }
1729  else if(type.id()==ID_pointer)
1730  {
1731  if(type.find(ID_to_member).is_not_nil())
1732  return false;
1733 
1734  if(to_pointer_type(type).base_type().id() == ID_empty)
1735  {
1736  if(!e.get_bool(ID_C_lvalue))
1737  return false;
1738  UNREACHABLE; // currently not supported
1739  }
1740  else if(to_pointer_type(type).base_type().id() == ID_struct_tag)
1741  {
1742  if(e.get_bool(ID_C_lvalue))
1743  {
1744  exprt tmp(e);
1745 
1747  return false;
1748  }
1749  }
1750  else return false;
1751  }
1752  else return false;
1753 
1754  return static_typecast(e, type, new_expr);
1755 }
1756 
1758  const exprt &expr,
1759  const typet &type,
1760  exprt &new_expr,
1761  bool check_constantness)
1762 {
1763  exprt e=expr;
1764 
1765  if(check_constantness && type.id()==ID_pointer)
1766  {
1767  if(e.id()==ID_dereference && e.get_bool(ID_C_implicit))
1768  e = to_dereference_expr(expr).pointer();
1769 
1770  if(e.type().id()==ID_pointer &&
1771  cast_away_constness(e.type(), type))
1772  return false;
1773  }
1774 
1776 
1777  if(!is_reference(type))
1778  {
1779  exprt tmp;
1780 
1781  if(e.id()==ID_code)
1782  {
1784  e.swap(tmp);
1785  else
1786  return false;
1787  }
1788 
1789  if(e.type().id()==ID_array)
1790  {
1792  e.swap(tmp);
1793  else
1794  return false;
1795  }
1796 
1797  if(e.get_bool(ID_C_lvalue))
1798  {
1800  e.swap(tmp);
1801  else
1802  return false;
1803  }
1804  }
1805 
1806  if(e.type().id()==ID_pointer &&
1807  (type.id()==ID_unsignedbv || type.id()==ID_signedbv))
1808  {
1809  // pointer to integer, always ok
1810  new_expr = typecast_exprt::conditional_cast(e, type);
1811  return true;
1812  }
1813 
1814  if(
1815  (e.type().id() == ID_unsignedbv || e.type().id() == ID_signedbv ||
1816  e.type().id() == ID_c_bool || e.type().id() == ID_bool) &&
1817  type.id() == ID_pointer && !is_reference(type))
1818  {
1819  // integer to pointer
1820  if(simplify_expr(e, *this).is_zero())
1821  {
1822  // NULL
1823  new_expr=e;
1824  new_expr.set(ID_value, ID_NULL);
1825  new_expr.type()=type;
1826  }
1827  else
1828  {
1829  new_expr = typecast_exprt::conditional_cast(e, type);
1830  }
1831  return true;
1832  }
1833 
1834  if(e.type().id()==ID_pointer &&
1835  type.id()==ID_pointer &&
1836  !is_reference(type))
1837  {
1838  // pointer to pointer: we ok it all.
1839  // This is more generous than the standard.
1840  new_expr = typecast_exprt::conditional_cast(expr, type);
1841  return true;
1842  }
1843 
1844  if(is_reference(type) && e.get_bool(ID_C_lvalue))
1845  {
1847  return true;
1848  }
1849 
1850  return false;
1851 }
1852 
1854  const exprt &expr, // source expression
1855  const typet &type, // destination type
1856  exprt &new_expr,
1857  bool check_constantness)
1858 {
1859  exprt e=expr;
1860 
1861  if(check_constantness && type.id()==ID_pointer)
1862  {
1863  if(e.id()==ID_dereference && e.get_bool(ID_C_implicit))
1864  e = to_dereference_expr(expr).pointer();
1865 
1866  if(e.type().id()==ID_pointer &&
1867  cast_away_constness(e.type(), type))
1868  return false;
1869  }
1870 
1872 
1873  if(type.get_bool(ID_C_reference))
1874  {
1875  unsigned rank=0;
1876  if(reference_binding(e, type, new_expr, rank))
1877  return true;
1878 
1879  typet subto = follow(to_pointer_type(type).base_type());
1880  typet from=follow(e.type());
1881 
1882  if(subto.id()==ID_struct && from.id()==ID_struct)
1883  {
1884  if(!expr.get_bool(ID_C_lvalue))
1885  return false;
1886 
1887  c_qualifierst qual_from;
1888  qual_from.read(e.type());
1889 
1890  c_qualifierst qual_to;
1891  qual_to.read(to_pointer_type(type).base_type());
1892 
1893  if(!qual_to.is_subset_of(qual_from))
1894  return false;
1895 
1896  const struct_typet &from_struct = to_struct_type(from);
1897  const struct_typet &subto_struct = to_struct_type(subto);
1898 
1899  if(subtype_typecast(subto_struct, from_struct))
1900  {
1901  if(e.id()==ID_dereference)
1902  {
1903  make_ptr_typecast(to_dereference_expr(e).pointer(), type);
1904  new_expr.swap(to_dereference_expr(e).pointer());
1905  return true;
1906  }
1907 
1908  exprt address_of=address_of_exprt(e);
1909  make_ptr_typecast(address_of, type);
1910  new_expr.swap(address_of);
1911  return true;
1912  }
1913  }
1914  return false;
1915  }
1916 
1917  if(type.id()==ID_empty)
1918  {
1919  new_expr = typecast_exprt::conditional_cast(e, type);
1920  return true;
1921  }
1922 
1923  // int/enum to enum
1924  if(type.id()==ID_c_enum_tag &&
1925  (e.type().id()==ID_signedbv ||
1926  e.type().id()==ID_unsignedbv ||
1927  e.type().id()==ID_c_enum_tag))
1928  {
1929  new_expr = typecast_exprt::conditional_cast(e, type);
1930  new_expr.remove(ID_C_lvalue);
1931  return true;
1932  }
1933 
1934  if(implicit_conversion_sequence(e, type, new_expr))
1935  {
1936  if(!cpp_is_pod(type))
1937  {
1938  exprt temporary;
1939  new_temporary(
1940  e.source_location(),
1941  type,
1942  already_typechecked_exprt{new_expr},
1943  temporary);
1944  new_expr.swap(temporary);
1945  }
1946  else
1947  {
1948  // try to avoid temporary
1949  new_expr.set(ID_C_temporary_avoided, true);
1950  if(new_expr.get_bool(ID_C_lvalue))
1951  new_expr.remove(ID_C_lvalue);
1952  }
1953 
1954  return true;
1955  }
1956 
1957  if(type.id()==ID_pointer && e.type().id()==ID_pointer)
1958  {
1959  if(type.find(ID_to_member).is_nil() && e.type().find(ID_to_member).is_nil())
1960  {
1961  typet to = follow(to_pointer_type(type).base_type());
1962  typet from = follow(to_pointer_type(e.type()).base_type());
1963 
1964  if(from.id()==ID_empty)
1965  {
1966  new_expr = typecast_exprt::conditional_cast(e, type);
1967  return true;
1968  }
1969 
1970  if(to.id()==ID_struct && from.id()==ID_struct)
1971  {
1972  if(e.get_bool(ID_C_lvalue))
1973  {
1974  exprt tmp(e);
1976  return false;
1977  }
1978 
1979  const struct_typet &from_struct = to_struct_type(from);
1980  const struct_typet &to_struct = to_struct_type(to);
1981  if(subtype_typecast(to_struct, from_struct))
1982  {
1983  make_ptr_typecast(e, type);
1984  new_expr.swap(e);
1985  return true;
1986  }
1987  }
1988 
1989  return false;
1990  }
1991  else if(
1992  type.find(ID_to_member).is_not_nil() &&
1993  e.type().find(ID_to_member).is_not_nil())
1994  {
1995  if(
1996  to_pointer_type(type).base_type() !=
1998  return false;
1999 
2000  const struct_typet &from_struct = to_struct_type(
2001  follow(static_cast<const typet &>(e.type().find(ID_to_member))));
2002 
2003  const struct_typet &to_struct = to_struct_type(
2004  follow(static_cast<const typet &>(type.find(ID_to_member))));
2005 
2006  if(subtype_typecast(from_struct, to_struct))
2007  {
2008  new_expr = typecast_exprt::conditional_cast(e, type);
2009  return true;
2010  }
2011  }
2012  else if(
2013  type.find(ID_to_member).is_nil() &&
2014  e.type().find(ID_to_member).is_not_nil())
2015  {
2016  if(
2017  to_pointer_type(type).base_type() !=
2019  {
2020  return false;
2021  }
2022 
2023  const struct_typet &from_struct = to_struct_type(
2024  follow(static_cast<const typet &>(e.type().find(ID_to_member))));
2025 
2026  new_expr = e;
2027  new_expr.type().add(ID_to_member) = from_struct;
2028 
2029  return true;
2030  }
2031  else
2032  return false;
2033  }
2034 
2035  return false;
2036 }
c_qualifierst::read
virtual void read(const typet &src) override
Definition: c_qualifiers.cpp:62
exprt::copy_to_operands
void copy_to_operands(const exprt &expr)
Copy the given argument to the end of exprt's operands.
Definition: expr.h:155
UNREACHABLE
#define UNREACHABLE
This should be used to mark dead code.
Definition: invariant.h:503
to_union_type
const union_typet & to_union_type(const typet &type)
Cast a typet to a union_typet.
Definition: c_types.h:162
to_unsignedbv_type
const unsignedbv_typet & to_unsignedbv_type(const typet &type)
Cast a typet to an unsignedbv_typet.
Definition: bitvector_types.h:191
typecast_exprt::conditional_cast
static exprt conditional_cast(const exprt &expr, const typet &type)
Definition: std_expr.h:2025
to_unary_expr
const unary_exprt & to_unary_expr(const exprt &expr)
Cast an exprt to a unary_exprt.
Definition: std_expr.h:361
cpp_typecheckt::standard_conversion_floating_point_promotion
bool standard_conversion_floating_point_promotion(const exprt &expr, exprt &new_expr) const
Floating-point-promotion conversion.
Definition: cpp_typecheck_conversions.cpp:246
arith_tools.h
cpp_typecheckt::standard_conversion_boolean
bool standard_conversion_boolean(const exprt &expr, exprt &new_expr) const
Boolean conversion.
Definition: cpp_typecheck_conversions.cpp:635
to_struct_type
const struct_typet & to_struct_type(const typet &type)
Cast a typet to a struct_typet.
Definition: std_types.h:308
to_dereference_expr
const dereference_exprt & to_dereference_expr(const exprt &expr)
Cast an exprt to a dereference_exprt.
Definition: pointer_expr.h:716
cpp_typecheckt::reference_binding
bool reference_binding(exprt expr, const typet &type, exprt &new_expr, unsigned &rank)
Reference binding.
Definition: cpp_typecheck_conversions.cpp:1218
irept::make_nil
void make_nil()
Definition: irep.h:454
typet
The type of an expression, extends irept.
Definition: type.h:28
cpp_typecheckt::show_instantiation_stack
void show_instantiation_stack(std::ostream &)
Definition: cpp_instantiate_template.cpp:90
irept::pretty
std::string pretty(unsigned indent=0, unsigned max_indent=0) const
Definition: irep.cpp:495
to_floatbv_type
const floatbv_typet & to_floatbv_type(const typet &type)
Cast a typet to a floatbv_typet.
Definition: bitvector_types.h:367
cpp_typecheckt::reinterpret_typecast
bool reinterpret_typecast(const exprt &expr, const typet &type, exprt &new_expr, bool check_constantness=true)
Definition: cpp_typecheck_conversions.cpp:1757
irept::find
const irept & find(const irep_idt &name) const
Definition: irep.cpp:106
dereference_exprt
Operator to dereference a pointer.
Definition: pointer_expr.h:659
side_effect_expr_function_callt
A side_effect_exprt representation of a function call side effect.
Definition: std_code.h:1691
cpp_typecheckt::standard_conversion_integral_promotion
bool standard_conversion_integral_promotion(const exprt &expr, exprt &new_expr) const
Integral-promotion conversion.
Definition: cpp_typecheck_conversions.cpp:193
c_bool_type
typet c_bool_type()
Definition: c_types.cpp:118
cpp_typecheckt::new_temporary
void new_temporary(const source_locationt &source_location, const typet &, const exprt::operandst &ops, exprt &temporary)
Definition: cpp_constructor.cpp:263
cpp_typecheckt::standard_conversion_lvalue_to_rvalue
bool standard_conversion_lvalue_to_rvalue(const exprt &expr, exprt &new_expr) const
Lvalue-to-rvalue conversion.
Definition: cpp_typecheck_conversions.cpp:46
to_type_with_subtype
const type_with_subtypet & to_type_with_subtype(const typet &type)
Definition: type.h:193
cpp_typecheckt::standard_conversion_sequence
bool standard_conversion_sequence(const exprt &expr, const typet &type, exprt &new_expr, unsigned &rank)
Standard Conversion Sequence.
Definition: cpp_typecheck_conversions.cpp:679
exprt
Base class for all expressions.
Definition: expr.h:55
from_type
std::string from_type(const namespacet &ns, const irep_idt &identifier, const typet &type)
Definition: language_util.cpp:51
component
auto component(T &struct_expr, const irep_idt &name, const namespacet &ns) -> decltype(struct_expr.op0())
Definition: std_expr.cpp:76
cpp_typecheckt::reference_compatible
bool reference_compatible(const exprt &expr, const typet &type, unsigned &rank) const
Reference-compatible.
Definition: cpp_typecheck_conversions.cpp:1155
bool_typet
The Boolean type.
Definition: std_types.h:35
messaget::eom
static eomt eom
Definition: message.h:297
c_qualifiers.h
configt::ansi_c
struct configt::ansi_ct ansi_c
c_qualifierst::is_subset_of
virtual bool is_subset_of(const qualifierst &other) const override
Definition: c_qualifiers.h:108
cpp_typecheckt::standard_conversion_array_to_pointer
bool standard_conversion_array_to_pointer(const exprt &expr, exprt &new_expr) const
Array-to-pointer conversion.
Definition: cpp_typecheck_conversions.cpp:77
irept::get
const irep_idt & get(const irep_idt &name) const
Definition: irep.cpp:45
cpp_typecheckt::cpp_is_pod
bool cpp_is_pod(const typet &type) const
Definition: cpp_is_pod.cpp:16
exprt::type
typet & type()
Return the type of the expression.
Definition: expr.h:84
namespacet::lookup
bool lookup(const irep_idt &name, const symbolt *&symbol) const override
See documentation for namespace_baset::lookup().
Definition: namespace.cpp:138
irept::is_not_nil
bool is_not_nil() const
Definition: irep.h:380
cpp_typecheckt::standard_conversion_floating_point_conversion
bool standard_conversion_floating_point_conversion(const exprt &expr, const typet &type, exprt &new_expr) const
Floating-point conversion.
Definition: cpp_typecheck_conversions.cpp:398
to_code_type
const code_typet & to_code_type(const typet &type)
Cast a typet to a code_typet.
Definition: std_types.h:744
messaget::error
mstreamt & error() const
Definition: message.h:399
cpp_typecheckt::typecheck_side_effect_function_call
void typecheck_side_effect_function_call(side_effect_expr_function_callt &) override
Definition: cpp_typecheck_expr.cpp:1504
signed_int_type
signedbv_typet signed_int_type()
Definition: c_types.cpp:40
c_qualifierst::is_constant
bool is_constant
Definition: c_qualifiers.h:92
already_typechecked_exprt::make_already_typechecked
static void make_already_typechecked(exprt &expr)
Definition: c_typecheck_base.h:316
DATA_INVARIANT
#define DATA_INVARIANT(CONDITION, REASON)
This condition should be used to document that assumptions that are made on goto_functions,...
Definition: invariant.h:510
cpp_util.h
cpp_typecheckt::add_implicit_dereference
void add_implicit_dereference(exprt &)
Definition: cpp_typecheck_expr.cpp:1491
messaget::mstreamt::source_location
source_locationt source_location
Definition: message.h:247
cpp_typecheckt::reference_initializer
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:
Definition: cpp_typecheck_conversions.cpp:1560
irept::set
void set(const irep_idt &name, const irep_idt &value)
Definition: irep.h:420
PRECONDITION
#define PRECONDITION(CONDITION)
Definition: invariant.h:463
exprt::find_source_location
const source_locationt & find_source_location() const
Get a source_locationt from the expression or from its operands (non-recursively).
Definition: expr.cpp:165
cpp_symbol_expr
symbol_exprt cpp_symbol_expr(const symbolt &symbol)
Definition: cpp_util.cpp:14
dereference_exprt::pointer
exprt & pointer()
Definition: pointer_expr.h:673
c_qualifierst::write
virtual void write(typet &src) const override
Definition: c_qualifiers.cpp:89
float_type
floatbv_typet float_type()
Definition: c_types.cpp:195
pointer_expr.h
simplify
bool simplify(exprt &expr, const namespacet &ns)
Definition: simplify_expr.cpp:2926
cpp_typecheckt::make_ptr_typecast
void make_ptr_typecast(exprt &expr, const typet &dest_type)
Definition: cpp_typecheck_compound_type.cpp:1701
to_pointer_type
const pointer_typet & to_pointer_type(const typet &type)
Cast a typet to a pointer_typet.
Definition: pointer_expr.h:79
simplify_expr
exprt simplify_expr(exprt src, const namespacet &ns)
Definition: simplify_expr.cpp:2931
c_qualifierst
Definition: c_qualifiers.h:61
to_reference_type
const reference_typet & to_reference_type(const typet &type)
Cast a typet to a reference_typet.
Definition: pointer_expr.h:148
pointer_type
pointer_typet pointer_type(const typet &subtype)
Definition: c_types.cpp:253
simplify_exprt
Definition: simplify_expr_class.h:79
irept::swap
void swap(irept &irep)
Definition: irep.h:442
cpp_typecheckt::subtype_typecast
bool subtype_typecast(const struct_typet &from, const struct_typet &to) const
Definition: cpp_typecheck_compound_type.cpp:1687
code_typet
Base type of functions.
Definition: std_types.h:538
irept::is_nil
bool is_nil() const
Definition: irep.h:376
irept::id
const irep_idt & id() const
Definition: irep.h:396
cpp_typecheckt::standard_conversion_function_to_pointer
bool standard_conversion_function_to_pointer(const exprt &expr, exprt &new_expr) const
Function-to-pointer conversion.
Definition: cpp_typecheck_conversions.cpp:99
unary_exprt::op
const exprt & op() const
Definition: std_expr.h:326
code_typet::parameters
const parameterst & parameters() const
Definition: std_types.h:655
cpp_typecheckt::standard_conversion_pointer_to_member
bool standard_conversion_pointer_to_member(const exprt &expr, const typet &type, exprt &new_expr)
Pointer-to-member conversion.
Definition: cpp_typecheck_conversions.cpp:553
code_typet::parametert::get_this
bool get_this() const
Definition: std_types.h:600
cpp_typecheckt::static_typecast
bool static_typecast(const exprt &expr, const typet &type, exprt &new_expr, bool check_constantness=true)
Definition: cpp_typecheck_conversions.cpp:1853
cpp_typecheck.h
cpp_typecheckt::standard_conversion_integral_conversion
bool standard_conversion_integral_conversion(const exprt &expr, const typet &type, exprt &new_expr) const
Integral conversion.
Definition: cpp_typecheck_conversions.cpp:300
typet::add_subtype
typet & add_subtype()
Definition: type.h:71
double_type
floatbv_typet double_type()
Definition: c_types.cpp:203
c_bit_field_typet::underlying_type
const typet & underlying_type() const
Definition: c_types.h:30
config
configt config
Definition: config.cpp:25
to_signedbv_type
const signedbv_typet & to_signedbv_type(const typet &type)
Cast a typet to a signedbv_typet.
Definition: bitvector_types.h:241
simplify_expr.h
bitvector_typet::get_width
std::size_t get_width() const
Definition: std_types.h:876
cpp_typecheckt::user_defined_conversion_sequence
bool user_defined_conversion_sequence(const exprt &expr, const typet &type, exprt &new_expr, unsigned &rank)
User-defined conversion sequence.
Definition: cpp_typecheck_conversions.cpp:859
cpp_typecheckt::reference_related
bool reference_related(const exprt &expr, const typet &type) const
Reference-related.
Definition: cpp_typecheck_conversions.cpp:1118
reference_type
reference_typet reference_type(const typet &subtype)
Definition: c_types.cpp:258
to_c_bit_field_type
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:58
expr_util.h
Deprecated expression utility functions.
cpp_typecheckt::standard_conversion_qualification
bool standard_conversion_qualification(const exprt &expr, const typet &, exprt &new_expr) const
Qualification conversion.
Definition: cpp_typecheck_conversions.cpp:115
is_reference
bool is_reference(const typet &type)
Returns true if the type is a reference.
Definition: std_types.cpp:143
struct_typet
Structure type, corresponds to C style structs.
Definition: std_types.h:230
irept::add
irept & add(const irep_idt &name)
Definition: irep.cpp:116
cpp_typecheckt::const_typecast
bool const_typecast(const exprt &expr, const typet &type, exprt &new_expr)
Definition: cpp_typecheck_conversions.cpp:1647
namespace_baset::follow
const typet & follow(const typet &) const
Resolve type symbol to the type it points to.
Definition: namespace.cpp:49
is_not_zero
exprt is_not_zero(const exprt &src, const namespacet &ns)
converts a scalar/float expression to C/C++ Booleans
Definition: expr_util.cpp:98
from_integer
constant_exprt from_integer(const mp_integer &int_value, const typet &type)
Definition: arith_tools.cpp:100
cpp_typecheckt::cast_away_constness
bool cast_away_constness(const typet &t1, const typet &t2) const
Definition: cpp_typecheck_conversions.cpp:1580
pointer_typet::base_type
const typet & base_type() const
The type of the data what we point to.
Definition: pointer_expr.h:35
c_typecheck_baset::return_type
typet return_type
Definition: c_typecheck_base.h:170
cpp_typecheckt::implicit_typecast
void implicit_typecast(exprt &expr, const typet &type) override
Definition: cpp_typecheck_conversions.cpp:1493
cpp_typecheckt::standard_conversion_pointer
bool standard_conversion_pointer(const exprt &expr, const typet &type, exprt &new_expr)
Pointer conversion.
Definition: cpp_typecheck_conversions.cpp:455
code_typet::parametert
Definition: std_types.h:555
exprt::add_to_operands
void add_to_operands(const exprt &expr)
Add the given argument to the end of exprt's operands.
Definition: expr.h:162
already_typechecked_exprt
Definition: c_typecheck_base.h:308
config.h
type_with_subtypet::subtype
const typet & subtype() const
Definition: type.h:172
code_typet::return_type
const typet & return_type() const
Definition: std_types.h:645
cpp_typecheckt::standard_conversion_floating_integral_conversion
bool standard_conversion_floating_integral_conversion(const exprt &expr, const typet &type, exprt &new_expr) const
Floating-integral conversion.
Definition: cpp_typecheck_conversions.cpp:347
cpp_typecheckt::implicit_conversion_sequence
bool implicit_conversion_sequence(const exprt &expr, const typet &type, exprt &new_expr, unsigned &rank)
implicit conversion sequence
Definition: cpp_typecheck_conversions.cpp:1428
cpp_typecheckt::dynamic_typecast
bool dynamic_typecast(const exprt &expr, const typet &type, exprt &new_expr)
Definition: cpp_typecheck_conversions.cpp:1705
cpp_typecheckt::to_string
std::string to_string(const typet &) override
Definition: cpp_typecheck.cpp:82
exprt::operands
operandst & operands()
Definition: expr.h:94
is_null_pointer
bool is_null_pointer(const constant_exprt &expr)
Returns true if expr has a pointer type and a value NULL; it also returns true when expr has value ze...
Definition: expr_util.cpp:315
irept::remove
void remove(const irep_idt &name)
Definition: irep.cpp:96
index_exprt
Array index operator.
Definition: std_expr.h:1409
address_of_exprt
Operator to return the address of an object.
Definition: pointer_expr.h:370
configt::ansi_ct::single_width
std::size_t single_width
Definition: config.h:131
exprt::add_source_location
source_locationt & add_source_location()
Definition: expr.h:216
typecast_exprt
Semantic type conversion.
Definition: std_expr.h:2016
pointer_typet
The pointer type These are both 'bitvector_typet' (they have a width) and 'type_with_subtypet' (they ...
Definition: pointer_expr.h:23
uninitialized_typet
Definition: cpp_parse_tree.h:31
multi_ary_exprt::op0
exprt & op0()
Definition: std_expr.h:877
c_index_type
bitvector_typet c_index_type()
Definition: c_types.cpp:16
to_multi_ary_expr
const multi_ary_exprt & to_multi_ary_expr(const exprt &expr)
Cast an exprt to a multi_ary_exprt.
Definition: std_expr.h:932
std_expr.h
cpp_namet
Definition: cpp_name.h:16
exprt::source_location
const source_locationt & source_location() const
Definition: expr.h:211
struct_union_typet::is_incomplete
bool is_incomplete() const
A struct/union may be incomplete.
Definition: std_types.h:185
configt::ansi_ct::int_width
std::size_t int_width
Definition: config.h:124
c_types.h
irept::get_bool
bool get_bool(const irep_idt &name) const
Definition: irep.cpp:58
side_effect_exprt
An expression containing a side effect.
Definition: std_code.h:1449
validation_modet::INVARIANT
@ INVARIANT
to_constant_expr
const constant_exprt & to_constant_expr(const exprt &expr)
Cast an exprt to a constant_exprt.
Definition: std_expr.h:2992