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