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 <cstdlib>
15 
16 #include <util/arith_tools.h>
17 #include <util/config.h>
18 #include <util/expr_util.h>
19 #include <util/pointer_expr.h>
20 #include <util/simplify_expr.h>
21 #include <util/std_expr.h>
22 #include <util/std_types.h>
23 
24 #include <ansi-c/c_qualifiers.h>
25 #include <util/c_types.h>
26 
48  const exprt &expr,
49  exprt &new_expr) const
50 {
51  assert(expr.get_bool(ID_C_lvalue));
52 
53  if(expr.type().id() == ID_code)
54  return false;
55 
56  if(
57  expr.type().id() == ID_struct &&
59  return false;
60 
61  if(expr.type().id() == ID_union && to_union_type(expr.type()).is_incomplete())
62  return false;
63 
64  new_expr=expr;
65  new_expr.remove(ID_C_lvalue);
66 
67  return true;
68 }
69 
79  const exprt &expr,
80  exprt &new_expr) const
81 {
82  assert(expr.type().id()==ID_array);
83 
84  index_exprt index(
85  expr,
86  from_integer(0, index_type()));
87 
88  index.set(ID_C_lvalue, true);
89 
90  new_expr=address_of_exprt(index);
91 
92  return true;
93 }
94 
103  const exprt &expr, exprt &new_expr) const
104 {
105  if(!expr.get_bool(ID_C_lvalue))
106  return false;
107 
108  new_expr=address_of_exprt(expr);
109 
110  return true;
111 }
112 
119  const exprt &expr,
120  const typet &type,
121  exprt &new_expr) const
122 {
123  if(expr.type().id()!=ID_pointer ||
124  is_reference(expr.type()))
125  return false;
126 
127  if(expr.get_bool(ID_C_lvalue))
128  return false;
129 
130  if(expr.type()!=type)
131  return false;
132 
133  typet sub_from=expr.type().subtype();
134  typet sub_to=type.subtype();
135  bool const_to=true;
136 
137  while(sub_from.id()==ID_pointer)
138  {
139  c_qualifierst qual_from(sub_from);
140  c_qualifierst qual_to(sub_to);
141 
142  if(!qual_to.is_constant)
143  const_to=false;
144 
145  if(qual_from.is_constant && !qual_to.is_constant)
146  return false;
147 
148  if(qual_from!=qual_to && !const_to)
149  return false;
150 
151  typet tmp1=sub_from.subtype();
152  sub_from.swap(tmp1);
153 
154  typet tmp2=sub_to.subtype();
155  sub_to.swap(tmp2);
156  }
157 
158  c_qualifierst qual_from(sub_from);
159  c_qualifierst qual_to(sub_to);
160 
161  if(qual_from.is_subset_of(qual_to))
162  {
163  new_expr=expr;
164  new_expr.type()=type;
165  return true;
166  }
167 
168  return false;
169 }
170 
197  const exprt &expr,
198  exprt &new_expr) const
199 {
200  if(expr.get_bool(ID_C_lvalue))
201  return false;
202 
203  c_qualifierst qual_from;
204  qual_from.read(expr.type());
205 
206  typet int_type=signed_int_type();
207  qual_from.write(int_type);
208 
209  if(expr.type().id()==ID_signedbv)
210  {
211  std::size_t width=to_signedbv_type(expr.type()).get_width();
212  if(width >= config.ansi_c.int_width)
213  return false;
214  new_expr = typecast_exprt(expr, int_type);
215  return true;
216  }
217 
218  if(expr.type().id()==ID_unsignedbv)
219  {
220  std::size_t width=to_unsignedbv_type(expr.type()).get_width();
221  if(width >= config.ansi_c.int_width)
222  return false;
223  new_expr = typecast_exprt(expr, int_type);
224  return true;
225  }
226 
227  if(expr.type().id() == ID_bool || expr.type().id() == ID_c_bool)
228  {
229  new_expr = typecast_exprt(expr, int_type);
230  return true;
231  }
232 
233  if(expr.type().id()==ID_c_enum_tag)
234  {
235  new_expr = typecast_exprt(expr, int_type);
236  return true;
237  }
238 
239  return false;
240 }
241 
250  const exprt &expr,
251  exprt &new_expr) const
252 {
253  if(expr.get_bool(ID_C_lvalue))
254  return false;
255 
256  // we only do that with 'float',
257  // not with 'double' or 'long double'
258  if(expr.type()!=float_type())
259  return false;
260 
261  std::size_t width=to_floatbv_type(expr.type()).get_width();
262 
263  if(width!=config.ansi_c.single_width)
264  return false;
265 
266  c_qualifierst qual_from;
267  qual_from.read(expr.type());
268 
269  new_expr = typecast_exprt(expr, double_type());
270  qual_from.write(new_expr.type());
271 
272  return true;
273 }
274 
304  const exprt &expr,
305  const typet &type,
306  exprt &new_expr) const
307 {
308  if(type.id()!=ID_signedbv &&
309  type.id()!=ID_unsignedbv)
310  return false;
311 
312  if(
313  expr.type().id() != ID_signedbv && expr.type().id() != ID_unsignedbv &&
314  expr.type().id() != ID_c_bool && expr.type().id() != ID_bool &&
315  expr.type().id() != ID_c_enum_tag)
316  {
317  return false;
318  }
319 
320  if(expr.get_bool(ID_C_lvalue))
321  return false;
322 
323  c_qualifierst qual_from;
324  qual_from.read(expr.type());
325  new_expr = typecast_exprt::conditional_cast(expr, type);
326  qual_from.write(new_expr.type());
327 
328  return true;
329 }
330 
351  const exprt &expr,
352  const typet &type,
353  exprt &new_expr) const
354 {
355  if(expr.get_bool(ID_C_lvalue))
356  return false;
357 
358  if(expr.type().id()==ID_floatbv ||
359  expr.type().id()==ID_fixedbv)
360  {
361  if(type.id()!=ID_signedbv &&
362  type.id()!=ID_unsignedbv)
363  return false;
364  }
365  else if(expr.type().id()==ID_signedbv ||
366  expr.type().id()==ID_unsignedbv ||
367  expr.type().id()==ID_c_enum_tag)
368  {
369  if(type.id()!=ID_fixedbv &&
370  type.id()!=ID_floatbv)
371  return false;
372  }
373  else
374  return false;
375 
376  c_qualifierst qual_from;
377  qual_from.read(expr.type());
378  new_expr = typecast_exprt::conditional_cast(expr, type);
379  qual_from.write(new_expr.type());
380 
381  return true;
382 }
383 
384 
402  const exprt &expr,
403  const typet &type,
404  exprt &new_expr) const
405 {
406  if(expr.type().id()!=ID_floatbv &&
407  expr.type().id()!=ID_fixedbv)
408  return false;
409 
410  if(type.id()!=ID_floatbv &&
411  type.id()!=ID_fixedbv)
412  return false;
413 
414  if(expr.get_bool(ID_C_lvalue))
415  return false;
416 
417  c_qualifierst qual_from;
418 
419  qual_from.read(expr.type());
420  new_expr = typecast_exprt::conditional_cast(expr, type);
421  qual_from.write(new_expr.type());
422 
423  return true;
424 }
425 
459  const exprt &expr,
460  const typet &type,
461  exprt &new_expr)
462 {
463  if(type.id()!=ID_pointer ||
464  is_reference(type))
465  return false;
466 
467  if(expr.get_bool(ID_C_lvalue))
468  return false;
469 
470  // integer 0 to NULL pointer conversion?
471  if(simplify_expr(expr, *this).is_zero() &&
472  expr.type().id()!=ID_pointer)
473  {
474  new_expr=expr;
475  new_expr.set(ID_value, ID_NULL);
476  new_expr.type()=type;
477  return true;
478  }
479 
480  if(type.find(ID_to_member).is_not_nil())
481  return false;
482 
483  if(
484  expr.type().id() != ID_pointer ||
485  expr.type().find(ID_to_member).is_not_nil())
486  {
487  return false;
488  }
489 
490  typet sub_from=follow(expr.type().subtype());
491  typet sub_to=follow(type.subtype());
492 
493  // std::nullptr_t to _any_ pointer type
494  if(sub_from.id()==ID_nullptr)
495  return true;
496 
497  // anything but function pointer to void *
498  if(sub_from.id()!=ID_code && sub_to.id()==ID_empty)
499  {
500  c_qualifierst qual_from;
501  qual_from.read(expr.type().subtype());
502  new_expr = typecast_exprt::conditional_cast(expr, type);
503  qual_from.write(new_expr.type().subtype());
504  return true;
505  }
506 
507  // struct * to struct *
508  if(sub_from.id()==ID_struct && sub_to.id()==ID_struct)
509  {
510  const struct_typet &from_struct=to_struct_type(sub_from);
511  const struct_typet &to_struct=to_struct_type(sub_to);
512  if(subtype_typecast(from_struct, to_struct))
513  {
514  c_qualifierst qual_from;
515  qual_from.read(expr.type().subtype());
516  new_expr=expr;
517  make_ptr_typecast(new_expr, type);
518  qual_from.write(new_expr.type().subtype());
519  return true;
520  }
521  }
522 
523  return false;
524 }
525 
557  const exprt &expr,
558  const typet &type,
559  exprt &new_expr)
560 {
561  if(
562  type.id() != ID_pointer || is_reference(type) ||
563  type.find(ID_to_member).is_nil())
564  {
565  return false;
566  }
567 
568  if(expr.type().id() != ID_pointer || expr.type().find(ID_to_member).is_nil())
569  return false;
570 
571  if(type.subtype()!=expr.type().subtype())
572  {
573  // subtypes different
574  if(type.subtype().id()==ID_code &&
575  expr.type().subtype().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.subtype());
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(expr.get_bool(ID_C_lvalue) || type.subtype().get_bool(ID_C_constant))
1246  {
1247  if(reference_compatible(expr, type, rank))
1248  {
1249  if(!expr.get_bool(ID_C_lvalue))
1250  {
1251  // create temporary object
1252  side_effect_exprt tmp{ID_temporary_object,
1253  {std::move(expr)},
1254  type.subtype(),
1255  expr.source_location()};
1256  tmp.set(ID_mode, ID_cpp);
1257  expr.swap(tmp);
1258  }
1259 
1260  {
1261  address_of_exprt tmp(expr, reference_type(expr.type()));
1262  tmp.add_source_location()=expr.source_location();
1263  new_expr.swap(tmp);
1264  }
1265 
1266  if(expr.type()!=type.subtype())
1267  {
1268  c_qualifierst qual_from;
1269  qual_from.read(expr.type());
1270  new_expr = typecast_exprt::conditional_cast(new_expr, type);
1271  qual_from.write(new_expr.type().subtype());
1272  }
1273 
1274  return true;
1275  }
1276 
1277  rank=backup_rank;
1278  }
1279 
1280  // conversion operators
1281  const typet &from_type = follow(expr.type());
1282  if(from_type.id()==ID_struct)
1283  {
1284  for(const auto &component : to_struct_type(from_type).components())
1285  {
1286  if(component.get_bool(ID_from_base))
1287  continue;
1288 
1289  if(!component.get_bool(ID_is_cast_operator))
1290  continue;
1291 
1292  const code_typet &component_type = to_code_type(component.type());
1293 
1294  // otherwise it cannot bind directly (not an lvalue)
1295  if(!is_reference(component_type.return_type()))
1296  continue;
1297 
1298  assert(component_type.parameters().size()==1);
1299 
1300  typet this_type =
1301  component_type.parameters().front().type();
1302  this_type.set(ID_C_reference, true);
1303 
1304  exprt this_expr(expr);
1305 
1306  this_type.set(ID_C_this, true);
1307 
1308  unsigned tmp_rank=0;
1309 
1310  exprt tmp_expr;
1312  this_expr, this_type, tmp_expr, tmp_rank))
1313  {
1314  // To take care of the possible virtual case,
1315  // we build the function as a member expression.
1316  const cpp_namet cpp_func_name(component.get_base_name());
1317 
1318  exprt member_func(ID_member);
1319  member_func.add(ID_component_cpp_name)=cpp_func_name;
1320  member_func.copy_to_operands(already_typechecked_exprt{expr});
1321 
1323  std::move(member_func),
1324  {},
1326  expr.source_location());
1328 
1329  // let's check if the returned value binds directly
1330  exprt returned_value=func_expr;
1331  add_implicit_dereference(returned_value);
1332 
1333  if(returned_value.get_bool(ID_C_lvalue) &&
1334  reference_compatible(returned_value, type, rank))
1335  {
1336  // returned values are lvalues in case of references only
1338  is_reference(to_dereference_expr(returned_value).op().type()),
1339  "the returned value must be pointer to reference");
1340 
1341  new_expr = to_multi_ary_expr(returned_value).op0();
1342 
1343  if(returned_value.type() != type.subtype())
1344  {
1345  c_qualifierst qual_from;
1346  qual_from.read(returned_value.type());
1347  make_ptr_typecast(new_expr, type);
1348  qual_from.write(new_expr.type().subtype());
1349  }
1350  rank+=4+tmp_rank;
1351  return true;
1352  }
1353  }
1354  }
1355  }
1356 
1357  // No temporary allowed for `this'
1358  if(type.get_bool(ID_C_this))
1359  return false;
1360 
1361  if(!type.subtype().get_bool(ID_C_constant) ||
1362  type.subtype().get_bool(ID_C_volatile))
1363  return false;
1364 
1365  // TODO: handle the case for implicit parameters
1366  if(!type.subtype().get_bool(ID_C_constant) &&
1367  !expr.get_bool(ID_C_lvalue))
1368  return false;
1369 
1370  exprt arg_expr=expr;
1371 
1372  if(arg_expr.type().id() == ID_struct_tag)
1373  {
1374  // required to initialize the temporary
1375  arg_expr.set(ID_C_lvalue, true);
1376  }
1377 
1378  if(user_defined_conversion_sequence(arg_expr, type.subtype(), new_expr, rank))
1379  {
1380  address_of_exprt tmp(new_expr, reference_type(new_expr.type()));
1381  tmp.add_source_location()=new_expr.source_location();
1382  new_expr.swap(tmp);
1383  return true;
1384  }
1385 
1386  rank=backup_rank;
1387  if(standard_conversion_sequence(expr, type.subtype(), new_expr, rank))
1388  {
1389  {
1390  // create temporary object
1391  side_effect_exprt tmp(
1392  ID_temporary_object, type.subtype(), expr.source_location());
1393  tmp.set(ID_mode, ID_cpp);
1394  // tmp.set(ID_C_lvalue, true);
1395  tmp.add_to_operands(std::move(new_expr));
1396  new_expr.swap(tmp);
1397  }
1398 
1399  address_of_exprt tmp(new_expr, pointer_type(new_expr.type()));
1400  tmp.type().set(ID_C_reference, true);
1401  tmp.add_source_location()=new_expr.source_location();
1402 
1403  new_expr=tmp;
1404  return true;
1405  }
1406 
1407  return false;
1408 }
1409 
1417  const exprt &expr,
1418  const typet &type,
1419  exprt &new_expr,
1420  unsigned &rank)
1421 {
1422  unsigned backup_rank=rank;
1423 
1424  exprt e=expr;
1426 
1427  if(is_reference(type))
1428  {
1429  if(!reference_binding(e, type, new_expr, rank))
1430  return false;
1431 
1432  #if 0
1433  simplify_exprt simplify(*this);
1434  simplify.simplify(new_expr);
1435  new_expr.type().set(ID_C_reference, true);
1436  #endif
1437  }
1438  else if(!standard_conversion_sequence(e, type, new_expr, rank))
1439  {
1440  rank=backup_rank;
1441  if(!user_defined_conversion_sequence(e, type, new_expr, rank))
1442  return false;
1443 
1444  #if 0
1445  simplify_exprt simplify(*this);
1446  simplify.simplify(new_expr);
1447  #endif
1448  }
1449 
1450  return true;
1451 }
1452 
1459  const exprt &expr,
1460  const typet &type,
1461  exprt &new_expr)
1462 {
1463  unsigned rank=0;
1464  return implicit_conversion_sequence(expr, type, new_expr, rank);
1465 }
1466 
1473  const exprt &expr,
1474  const typet &type,
1475  unsigned &rank)
1476 {
1477  exprt new_expr;
1478  return implicit_conversion_sequence(expr, type, new_expr, rank);
1479 }
1480 
1482 {
1483  exprt e=expr;
1484 
1485  if(
1486  e.id() == ID_initializer_list && cpp_is_pod(type) &&
1487  e.operands().size() == 1)
1488  {
1489  e = to_unary_expr(expr).op();
1490  }
1491 
1492  if(!implicit_conversion_sequence(e, type, expr))
1493  {
1496  error() << "invalid implicit conversion from '" << to_string(e.type())
1497  << "' to '" << to_string(type) << "'" << eom;
1498 #if 0
1499  str << "\n " << follow(e.type()).pretty() << '\n';
1500  str << "\n " << type.pretty() << '\n';
1501 #endif
1502  throw 0;
1503  }
1504 }
1505 
1549  exprt &expr,
1550  const typet &type)
1551 {
1552  assert(is_reference(type));
1554 
1555  unsigned rank=0;
1556  exprt new_expr;
1557  if(reference_binding(expr, type, new_expr, rank))
1558  {
1559  expr.swap(new_expr);
1560  return;
1561  }
1562 
1564  error() << "bad reference initializer" << eom;
1565  throw 0;
1566 }
1567 
1569  const typet &t1,
1570  const typet &t2) const
1571 {
1572  assert(t1.id()==ID_pointer && t2.id()==ID_pointer);
1573  typet nt1=t1;
1574  typet nt2=t2;
1575 
1576  if(is_reference(nt1))
1577  nt1.remove(ID_C_reference);
1578  nt1.remove(ID_to_member);
1579 
1580  if(is_reference(nt2))
1581  nt2.remove(ID_C_reference);
1582  nt2.remove(ID_to_member);
1583 
1584  // substitute final subtypes
1585  std::vector<typet> snt1;
1586  snt1.push_back(nt1);
1587 
1588  while(snt1.back().has_subtype())
1589  {
1590  snt1.reserve(snt1.size()+1);
1591  snt1.push_back(snt1.back().subtype());
1592  }
1593 
1594  c_qualifierst q1;
1595  q1.read(snt1.back());
1596 
1597  bool_typet newnt1;
1598  q1.write(newnt1);
1599  snt1.back()=newnt1;
1600 
1601  std::vector<typet> snt2;
1602  snt2.push_back(nt2);
1603  while(snt2.back().has_subtype())
1604  {
1605  snt2.reserve(snt2.size()+1);
1606  snt2.push_back(snt2.back().subtype());
1607  }
1608 
1609  c_qualifierst q2;
1610  q2.read(snt2.back());
1611 
1612  bool_typet newnt2;
1613  q2.write(newnt2);
1614  snt2.back()=newnt2;
1615 
1616  const std::size_t k=snt1.size() < snt2.size() ? snt1.size() : snt2.size();
1617 
1618  for(std::size_t i=k; i > 1; i--)
1619  {
1620  snt1[snt1.size()-2].subtype()=snt1[snt1.size()-1];
1621  snt1.pop_back();
1622 
1623  snt2[snt2.size()-2].subtype()=snt2[snt2.size()-1];
1624  snt2.pop_back();
1625  }
1626 
1627  exprt e1("Dummy", snt1.back());
1628  exprt e2;
1629 
1630  return !standard_conversion_qualification(e1, snt2.back(), e2);
1631 }
1632 
1634  const exprt &expr,
1635  const typet &type,
1636  exprt &new_expr)
1637 {
1638  PRECONDITION(!is_reference(expr.type()));
1639 
1640  exprt curr_expr=expr;
1641 
1642  if(curr_expr.type().id()==ID_array)
1643  {
1644  if(type.id()==ID_pointer)
1645  {
1646  if(!standard_conversion_array_to_pointer(curr_expr, new_expr))
1647  return false;
1648  }
1649  }
1650  else if(curr_expr.type().id()==ID_code &&
1651  type.id()==ID_pointer)
1652  {
1653  if(!standard_conversion_function_to_pointer(curr_expr, new_expr))
1654  return false;
1655  }
1656  else if(curr_expr.get_bool(ID_C_lvalue))
1657  {
1658  if(!standard_conversion_lvalue_to_rvalue(curr_expr, new_expr))
1659  return false;
1660  }
1661  else
1662  new_expr=curr_expr;
1663 
1664  if(is_reference(type))
1665  {
1666  if(!expr.get_bool(ID_C_lvalue))
1667  return false;
1668 
1669  if(new_expr.type()!=type.subtype())
1670  return false;
1671 
1672  address_of_exprt address_of(expr, to_pointer_type(type));
1673  add_implicit_dereference(address_of);
1674  new_expr=address_of;
1675  return true;
1676  }
1677  else if(type.id()==ID_pointer)
1678  {
1679  if(type!=new_expr.type())
1680  return false;
1681 
1682  // add proper typecast
1683  typecast_exprt typecast_expr(expr, type);
1684  new_expr.swap(typecast_expr);
1685  return true;
1686  }
1687 
1688  return false;
1689 }
1690 
1692  const exprt &expr,
1693  const typet &type,
1694  exprt &new_expr)
1695 {
1696  exprt e(expr);
1697 
1698  if(type.id()==ID_pointer)
1699  {
1700  if(e.id()==ID_dereference && e.get_bool(ID_C_implicit))
1701  e = to_dereference_expr(expr).pointer();
1702 
1703  if(e.type().id()==ID_pointer &&
1704  cast_away_constness(e.type(), type))
1705  return false;
1706  }
1707 
1709 
1710  if(is_reference(type))
1711  {
1712  if(type.subtype().id() != ID_struct_tag)
1713  return false;
1714  }
1715  else if(type.id()==ID_pointer)
1716  {
1717  if(type.find(ID_to_member).is_not_nil())
1718  return false;
1719 
1720  if(type.subtype().id()==ID_empty)
1721  {
1722  if(!e.get_bool(ID_C_lvalue))
1723  return false;
1724  UNREACHABLE; // currently not supported
1725  }
1726  else if(type.subtype().id() == ID_struct_tag)
1727  {
1728  if(e.get_bool(ID_C_lvalue))
1729  {
1730  exprt tmp(e);
1731 
1733  return false;
1734  }
1735  }
1736  else return false;
1737  }
1738  else return false;
1739 
1740  return static_typecast(e, type, new_expr);
1741 }
1742 
1744  const exprt &expr,
1745  const typet &type,
1746  exprt &new_expr,
1747  bool check_constantness)
1748 {
1749  exprt e=expr;
1750 
1751  if(check_constantness && type.id()==ID_pointer)
1752  {
1753  if(e.id()==ID_dereference && e.get_bool(ID_C_implicit))
1754  e = to_dereference_expr(expr).pointer();
1755 
1756  if(e.type().id()==ID_pointer &&
1757  cast_away_constness(e.type(), type))
1758  return false;
1759  }
1760 
1762 
1763  if(!is_reference(type))
1764  {
1765  exprt tmp;
1766 
1767  if(e.id()==ID_code)
1768  {
1770  e.swap(tmp);
1771  else
1772  return false;
1773  }
1774 
1775  if(e.type().id()==ID_array)
1776  {
1778  e.swap(tmp);
1779  else
1780  return false;
1781  }
1782 
1783  if(e.get_bool(ID_C_lvalue))
1784  {
1786  e.swap(tmp);
1787  else
1788  return false;
1789  }
1790  }
1791 
1792  if(e.type().id()==ID_pointer &&
1793  (type.id()==ID_unsignedbv || type.id()==ID_signedbv))
1794  {
1795  // pointer to integer, always ok
1796  new_expr = typecast_exprt::conditional_cast(e, type);
1797  return true;
1798  }
1799 
1800  if(
1801  (e.type().id() == ID_unsignedbv || e.type().id() == ID_signedbv ||
1802  e.type().id() == ID_c_bool || e.type().id() == ID_bool) &&
1803  type.id() == ID_pointer && !is_reference(type))
1804  {
1805  // integer to pointer
1806  if(simplify_expr(e, *this).is_zero())
1807  {
1808  // NULL
1809  new_expr=e;
1810  new_expr.set(ID_value, ID_NULL);
1811  new_expr.type()=type;
1812  }
1813  else
1814  {
1815  new_expr = typecast_exprt::conditional_cast(e, type);
1816  }
1817  return true;
1818  }
1819 
1820  if(e.type().id()==ID_pointer &&
1821  type.id()==ID_pointer &&
1822  !is_reference(type))
1823  {
1824  // pointer to pointer: we ok it all.
1825  // This is more generous than the standard.
1826  new_expr = typecast_exprt::conditional_cast(expr, type);
1827  return true;
1828  }
1829 
1830  if(is_reference(type) && e.get_bool(ID_C_lvalue))
1831  {
1833  return true;
1834  }
1835 
1836  return false;
1837 }
1838 
1840  const exprt &expr, // source expression
1841  const typet &type, // destination type
1842  exprt &new_expr,
1843  bool check_constantness)
1844 {
1845  exprt e=expr;
1846 
1847  if(check_constantness && type.id()==ID_pointer)
1848  {
1849  if(e.id()==ID_dereference && e.get_bool(ID_C_implicit))
1850  e = to_dereference_expr(expr).pointer();
1851 
1852  if(e.type().id()==ID_pointer &&
1853  cast_away_constness(e.type(), type))
1854  return false;
1855  }
1856 
1858 
1859  if(type.get_bool(ID_C_reference))
1860  {
1861  unsigned rank=0;
1862  if(reference_binding(e, type, new_expr, rank))
1863  return true;
1864 
1865  typet subto=follow(type.subtype());
1866  typet from=follow(e.type());
1867 
1868  if(subto.id()==ID_struct && from.id()==ID_struct)
1869  {
1870  if(!expr.get_bool(ID_C_lvalue))
1871  return false;
1872 
1873  c_qualifierst qual_from;
1874  qual_from.read(e.type());
1875 
1876  c_qualifierst qual_to;
1877  qual_to.read(type.subtype());
1878 
1879  if(!qual_to.is_subset_of(qual_from))
1880  return false;
1881 
1882  const struct_typet &from_struct = to_struct_type(from);
1883  const struct_typet &subto_struct = to_struct_type(subto);
1884 
1885  if(subtype_typecast(subto_struct, from_struct))
1886  {
1887  if(e.id()==ID_dereference)
1888  {
1889  make_ptr_typecast(to_dereference_expr(e).pointer(), type);
1890  new_expr.swap(to_dereference_expr(e).pointer());
1891  return true;
1892  }
1893 
1894  exprt address_of=address_of_exprt(e);
1895  make_ptr_typecast(address_of, type);
1896  new_expr.swap(address_of);
1897  return true;
1898  }
1899  }
1900  return false;
1901  }
1902 
1903  if(type.id()==ID_empty)
1904  {
1905  new_expr = typecast_exprt::conditional_cast(e, type);
1906  return true;
1907  }
1908 
1909  // int/enum to enum
1910  if(type.id()==ID_c_enum_tag &&
1911  (e.type().id()==ID_signedbv ||
1912  e.type().id()==ID_unsignedbv ||
1913  e.type().id()==ID_c_enum_tag))
1914  {
1915  new_expr = typecast_exprt::conditional_cast(e, type);
1916  new_expr.remove(ID_C_lvalue);
1917  return true;
1918  }
1919 
1920  if(implicit_conversion_sequence(e, type, new_expr))
1921  {
1922  if(!cpp_is_pod(type))
1923  {
1924  exprt temporary;
1925  new_temporary(
1926  e.source_location(),
1927  type,
1928  already_typechecked_exprt{new_expr},
1929  temporary);
1930  new_expr.swap(temporary);
1931  }
1932  else
1933  {
1934  // try to avoid temporary
1935  new_expr.set(ID_C_temporary_avoided, true);
1936  if(new_expr.get_bool(ID_C_lvalue))
1937  new_expr.remove(ID_C_lvalue);
1938  }
1939 
1940  return true;
1941  }
1942 
1943  if(type.id()==ID_pointer && e.type().id()==ID_pointer)
1944  {
1945  if(type.find(ID_to_member).is_nil() && e.type().find(ID_to_member).is_nil())
1946  {
1947  typet to=follow(type.subtype());
1948  typet from=follow(e.type().subtype());
1949 
1950  if(from.id()==ID_empty)
1951  {
1952  new_expr = typecast_exprt::conditional_cast(e, type);
1953  return true;
1954  }
1955 
1956  if(to.id()==ID_struct && from.id()==ID_struct)
1957  {
1958  if(e.get_bool(ID_C_lvalue))
1959  {
1960  exprt tmp(e);
1962  return false;
1963  }
1964 
1965  const struct_typet &from_struct = to_struct_type(from);
1966  const struct_typet &to_struct = to_struct_type(to);
1967  if(subtype_typecast(to_struct, from_struct))
1968  {
1969  make_ptr_typecast(e, type);
1970  new_expr.swap(e);
1971  return true;
1972  }
1973  }
1974 
1975  return false;
1976  }
1977  else if(
1978  type.find(ID_to_member).is_not_nil() &&
1979  e.type().find(ID_to_member).is_not_nil())
1980  {
1981  if(type.subtype()!=e.type().subtype())
1982  return false;
1983 
1984  const struct_typet &from_struct = to_struct_type(
1985  follow(static_cast<const typet &>(e.type().find(ID_to_member))));
1986 
1987  const struct_typet &to_struct = to_struct_type(
1988  follow(static_cast<const typet &>(type.find(ID_to_member))));
1989 
1990  if(subtype_typecast(from_struct, to_struct))
1991  {
1992  new_expr = typecast_exprt::conditional_cast(e, type);
1993  return true;
1994  }
1995  }
1996  else if(
1997  type.find(ID_to_member).is_nil() &&
1998  e.type().find(ID_to_member).is_not_nil())
1999  {
2000  if(type.subtype() != e.type().subtype())
2001  return false;
2002 
2003  const struct_typet &from_struct = to_struct_type(
2004  follow(static_cast<const typet &>(e.type().find(ID_to_member))));
2005 
2006  new_expr = e;
2007  new_expr.type().add(ID_to_member) = from_struct;
2008 
2009  return true;
2010  }
2011  else
2012  return false;
2013  }
2014 
2015  return false;
2016 }
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:137
UNREACHABLE
#define UNREACHABLE
This should be used to mark dead code.
Definition: invariant.h:504
to_union_type
const union_typet & to_union_type(const typet &type)
Cast a typet to a union_typet.
Definition: c_types.h:149
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:1788
to_unary_expr
const unary_exprt & to_unary_expr(const exprt &expr)
Cast an exprt to a unary_exprt.
Definition: std_expr.h:328
typet::subtype
const typet & subtype() const
Definition: type.h:47
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:249
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:302
to_dereference_expr
const dereference_exprt & to_dereference_expr(const exprt &expr)
Cast an exprt to a dereference_exprt.
Definition: pointer_expr.h:442
cpp_typecheckt::reference_binding
bool reference_binding(exprt expr, const typet &type, exprt &new_expr, unsigned &rank)
Reference binding.
Definition: cpp_typecheck_conversions.cpp:1214
irept::make_nil
void make_nil()
Definition: irep.h:465
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:93
irept::pretty
std::string pretty(unsigned indent=0, unsigned max_indent=0) const
Definition: irep.cpp:501
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:1743
dereference_exprt
Operator to dereference a pointer.
Definition: pointer_expr.h:386
side_effect_expr_function_callt
A side_effect_exprt representation of a function call side effect.
Definition: std_code.h:2140
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:196
irept::add
irept & add(const irep_namet &name)
Definition: irep.cpp:122
c_bool_type
typet c_bool_type()
Definition: c_types.cpp:108
irept::find
const irept & find(const irep_namet &name) const
Definition: irep.cpp:112
cpp_typecheckt::new_temporary
void new_temporary(const source_locationt &source_location, const typet &, const exprt::operandst &ops, exprt &temporary)
Definition: cpp_constructor.cpp:266
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:47
namespacet::lookup
const symbolt & lookup(const irep_idt &name) const
Lookup a symbol in the namespace.
Definition: namespace.h:44
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:54
from_type
std::string from_type(const namespacet &ns, const irep_idt &identifier, const typet &type)
Definition: language_util.cpp:33
component
auto component(T &struct_expr, const irep_idt &name, const namespacet &ns) -> decltype(struct_expr.op0())
Definition: std_expr.cpp:55
cpp_typecheckt::reference_compatible
bool reference_compatible(const exprt &expr, const typet &type, unsigned &rank) const
Reference-compatible.
Definition: cpp_typecheck_conversions.cpp:1151
bool_typet
The Boolean type.
Definition: std_types.h:36
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:107
index_type
bitvector_typet index_type()
Definition: c_types.cpp:16
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:78
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:82
irept::get_bool
bool get_bool(const irep_namet &name) const
Definition: irep.cpp:64
irept::is_not_nil
bool is_not_nil() const
Definition: irep.h:391
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:401
to_code_type
const code_typet & to_code_type(const typet &type)
Cast a typet to a code_typet.
Definition: std_types.h:738
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:1495
signed_int_type
signedbv_typet signed_int_type()
Definition: c_types.cpp:30
c_qualifierst::is_constant
bool is_constant
Definition: c_qualifiers.h:91
already_typechecked_exprt::make_already_typechecked
static void make_already_typechecked(exprt &expr)
Definition: c_typecheck_base.h:287
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:511
cpp_typecheckt::add_implicit_dereference
void add_implicit_dereference(exprt &)
Definition: cpp_typecheck_expr.cpp:1482
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:1548
PRECONDITION
#define PRECONDITION(CONDITION)
Definition: invariant.h:464
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:192
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:399
std_types.h
Pre-defined types.
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:185
pointer_expr.h
API to expression classes for Pointers.
simplify
bool simplify(exprt &expr, const namespacet &ns)
Definition: simplify_expr.cpp:2552
cpp_typecheckt::make_ptr_typecast
void make_ptr_typecast(exprt &expr, const typet &dest_type)
Definition: cpp_typecheck_compound_type.cpp:1699
to_pointer_type
const pointer_typet & to_pointer_type(const typet &type)
Cast a typet to a pointer_typet.
Definition: pointer_expr.h:62
simplify_expr
exprt simplify_expr(exprt src, const namespacet &ns)
Definition: simplify_expr.cpp:2557
c_qualifierst
Definition: c_qualifiers.h:61
pointer_type
pointer_typet pointer_type(const typet &subtype)
Definition: c_types.cpp:243
simplify_exprt
Definition: simplify_expr_class.h:73
irept::swap
void swap(irept &irep)
Definition: irep.h:453
cpp_typecheckt::subtype_typecast
bool subtype_typecast(const struct_typet &from, const struct_typet &to) const
Definition: cpp_typecheck_compound_type.cpp:1685
code_typet
Base type of functions.
Definition: std_types.h:533
irept::is_nil
bool is_nil() const
Definition: irep.h:387
irept::id
const irep_idt & id() const
Definition: irep.h:407
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:102
irept::remove
void remove(const irep_namet &name)
Definition: irep.cpp:102
unary_exprt::op
const exprt & op() const
Definition: std_expr.h:293
code_typet::parameters
const parameterst & parameters() const
Definition: std_types.h:649
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:556
code_typet::parametert::get_this
bool get_this() const
Definition: std_types.h:594
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:1839
cpp_typecheck.h
C++ Language Type Checking.
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:303
double_type
floatbv_typet double_type()
Definition: c_types.cpp:193
config
configt config
Definition: config.cpp:24
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:837
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:855
cpp_typecheckt::reference_related
bool reference_related(const exprt &expr, const typet &type) const
Reference-related.
Definition: cpp_typecheck_conversions.cpp:1114
reference_type
reference_typet reference_type(const typet &subtype)
Definition: c_types.cpp:248
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:118
is_reference
bool is_reference(const typet &type)
Returns true if the type is a reference.
Definition: std_types.cpp:133
struct_typet
Structure type, corresponds to C style structs.
Definition: std_types.h:225
cpp_typecheckt::const_typecast
bool const_typecast(const exprt &expr, const typet &type, exprt &new_expr)
Definition: cpp_typecheck_conversions.cpp:1633
namespace_baset::follow
const typet & follow(const typet &) const
Resolve type symbol to the type it points to.
Definition: namespace.cpp:52
irept::get
const irep_idt & get(const irep_namet &name) const
Definition: irep.cpp:51
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:100
irept::set
void set(const irep_namet &name, const irep_idt &value)
Definition: irep.h:431
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:1568
c_typecheck_baset::return_type
typet return_type
Definition: c_typecheck_base.h:153
cpp_typecheckt::implicit_typecast
void implicit_typecast(exprt &expr, const typet &type) override
Definition: cpp_typecheck_conversions.cpp:1481
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:458
code_typet::parametert
Definition: std_types.h:550
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:144
already_typechecked_exprt
Definition: c_typecheck_base.h:280
config.h
code_typet::return_type
const typet & return_type() const
Definition: std_types.h:639
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:350
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:1416
cpp_typecheckt::dynamic_typecast
bool dynamic_typecast(const exprt &expr, const typet &type, exprt &new_expr)
Definition: cpp_typecheck_conversions.cpp:1691
cpp_typecheckt::to_string
std::string to_string(const typet &) override
Definition: cpp_typecheck.cpp:84
exprt::operands
operandst & operands()
Definition: expr.h:96
index_exprt
Array index operator.
Definition: std_expr.h:1242
address_of_exprt
Operator to return the address of an object.
Definition: pointer_expr.h:330
INVARIANT
#define INVARIANT(CONDITION, REASON)
This macro uses the wrapper function 'invariant_violated_string'.
Definition: invariant.h:424
configt::ansi_ct::single_width
std::size_t single_width
Definition: config.h:118
exprt::add_source_location
source_locationt & add_source_location()
Definition: expr.h:243
typecast_exprt
Semantic type conversion.
Definition: std_expr.h:1780
pointer_typet
The pointer type These are both 'bitvector_typet' (they have a width) and 'type_with_subtypet' (they ...
Definition: pointer_expr.h:24
uninitialized_typet
Definition: cpp_parse_tree.h:32
multi_ary_exprt::op0
exprt & op0()
Definition: std_expr.h:760
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:815
std_expr.h
API to expression classes.
cpp_namet
Definition: cpp_name.h:17
exprt::source_location
const source_locationt & source_location() const
Definition: expr.h:238
struct_union_typet::is_incomplete
bool is_incomplete() const
A struct/union may be incomplete.
Definition: std_types.h:179
configt::ansi_ct::int_width
std::size_t int_width
Definition: config.h:111
c_types.h
side_effect_exprt
An expression containing a side effect.
Definition: std_code.h:1898