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  expr.type().id()==ID_incomplete_struct ||
54  expr.type().id()==ID_incomplete_union)
55  return false;
56 
57  new_expr=expr;
58  new_expr.remove(ID_C_lvalue);
59 
60  return true;
61 }
62 
72  const exprt &expr,
73  exprt &new_expr) const
74 {
75  assert(expr.type().id()==ID_array);
76 
77  index_exprt index(
78  expr,
79  from_integer(0, index_type()));
80 
81  index.set(ID_C_lvalue, true);
82 
83  new_expr=address_of_exprt(index);
84 
85  return true;
86 }
87 
96  const exprt &expr, exprt &new_expr) const
97 {
98  if(!expr.get_bool(ID_C_lvalue))
99  return false;
100 
101  new_expr=address_of_exprt(expr);
102 
103  return true;
104 }
105 
112  const exprt &expr,
113  const typet &type,
114  exprt &new_expr) const
115 {
116  if(expr.type().id()!=ID_pointer ||
117  is_reference(expr.type()))
118  return false;
119 
120  if(expr.get_bool(ID_C_lvalue))
121  return false;
122 
123  if(expr.type()!=type)
124  return false;
125 
126  typet sub_from=expr.type().subtype();
127  typet sub_to=type.subtype();
128  bool const_to=true;
129 
130  while(sub_from.id()==ID_pointer)
131  {
132  c_qualifierst qual_from(sub_from);
133  c_qualifierst qual_to(sub_to);
134 
135  if(!qual_to.is_constant)
136  const_to=false;
137 
138  if(qual_from.is_constant && !qual_to.is_constant)
139  return false;
140 
141  if(qual_from!=qual_to && !const_to)
142  return false;
143 
144  typet tmp1=sub_from.subtype();
145  sub_from.swap(tmp1);
146 
147  typet tmp2=sub_to.subtype();
148  sub_to.swap(tmp2);
149  }
150 
151  c_qualifierst qual_from(sub_from);
152  c_qualifierst qual_to(sub_to);
153 
154  if(qual_from.is_subset_of(qual_to))
155  {
156  new_expr=expr;
157  new_expr.type()=type;
158  return true;
159  }
160 
161  return false;
162 }
163 
190  const exprt &expr,
191  exprt &new_expr) const
192 {
193  if(expr.get_bool(ID_C_lvalue))
194  return false;
195 
196  c_qualifierst qual_from;
197  qual_from.read(expr.type());
198 
199  typet int_type=signed_int_type();
200  qual_from.write(int_type);
201 
202  if(expr.type().id()==ID_signedbv)
203  {
204  std::size_t width=to_signedbv_type(expr.type()).get_width();
205  if(width >= config.ansi_c.int_width)
206  return false;
207  new_expr=expr;
208  new_expr.make_typecast(int_type);
209  return true;
210  }
211 
212  if(expr.type().id()==ID_unsignedbv)
213  {
214  std::size_t width=to_unsignedbv_type(expr.type()).get_width();
215  if(width >= config.ansi_c.int_width)
216  return false;
217  new_expr=expr;
218  if(width==config.ansi_c.int_width)
219  int_type.id(ID_unsignedbv);
220  new_expr.make_typecast(int_type);
221  return true;
222  }
223 
224  if(expr.type().id() == ID_bool || expr.type().id() == ID_c_bool)
225  {
226  new_expr = expr;
227  new_expr.make_typecast(int_type);
228  return true;
229  }
230 
231  if(expr.type().id()==ID_c_enum_tag)
232  {
233  new_expr=expr;
234  new_expr.make_typecast(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=expr;
269  new_expr.make_typecast(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=expr;
326  new_expr.make_typecast(type);
327  qual_from.write(new_expr.type());
328 
329  return true;
330 }
331 
352  const exprt &expr,
353  const typet &type,
354  exprt &new_expr) const
355 {
356  if(expr.get_bool(ID_C_lvalue))
357  return false;
358 
359  if(expr.type().id()==ID_floatbv ||
360  expr.type().id()==ID_fixedbv)
361  {
362  if(type.id()!=ID_signedbv &&
363  type.id()!=ID_unsignedbv)
364  return false;
365  }
366  else if(expr.type().id()==ID_signedbv ||
367  expr.type().id()==ID_unsignedbv ||
368  expr.type().id()==ID_c_enum_tag)
369  {
370  if(type.id()!=ID_fixedbv &&
371  type.id()!=ID_floatbv)
372  return false;
373  }
374  else
375  return false;
376 
377  c_qualifierst qual_from;
378  qual_from.read(expr.type());
379  new_expr=expr;
380  new_expr.make_typecast(type);
381  qual_from.write(new_expr.type());
382 
383  return true;
384 }
385 
386 
404  const exprt &expr,
405  const typet &type,
406  exprt &new_expr) const
407 {
408  if(expr.type().id()!=ID_floatbv &&
409  expr.type().id()!=ID_fixedbv)
410  return false;
411 
412  if(type.id()!=ID_floatbv &&
413  type.id()!=ID_fixedbv)
414  return false;
415 
416  if(expr.get_bool(ID_C_lvalue))
417  return false;
418 
419  c_qualifierst qual_from;
420 
421  qual_from.read(expr.type());
422  new_expr=expr;
423  new_expr.make_typecast(type);
424  qual_from.write(new_expr.type());
425 
426  return true;
427 }
428 
462  const exprt &expr,
463  const typet &type,
464  exprt &new_expr)
465 {
466  if(type.id()!=ID_pointer ||
467  is_reference(type))
468  return false;
469 
470  if(expr.get_bool(ID_C_lvalue))
471  return false;
472 
473  // integer 0 to NULL pointer conversion?
474  if(simplify_expr(expr, *this).is_zero() &&
475  expr.type().id()!=ID_pointer)
476  {
477  new_expr=expr;
478  new_expr.set(ID_value, ID_NULL);
479  new_expr.type()=type;
480  return true;
481  }
482 
483  if(type.find("to-member").is_not_nil())
484  return false;
485 
486  if(expr.type().id() != ID_pointer ||
487  expr.type().find("to-member").is_not_nil())
488  return false;
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=expr;
503  new_expr.make_typecast(type);
504  qual_from.write(new_expr.type().subtype());
505  return true;
506  }
507 
508  // struct * to struct *
509  if(sub_from.id()==ID_struct && sub_to.id()==ID_struct)
510  {
511  const struct_typet &from_struct=to_struct_type(sub_from);
512  const struct_typet &to_struct=to_struct_type(sub_to);
513  if(subtype_typecast(from_struct, to_struct))
514  {
515  c_qualifierst qual_from;
516  qual_from.read(expr.type().subtype());
517  new_expr=expr;
518  make_ptr_typecast(new_expr, type);
519  qual_from.write(new_expr.type().subtype());
520  return true;
521  }
522  }
523 
524  return false;
525 }
526 
558  const exprt &expr,
559  const typet &type,
560  exprt &new_expr)
561 {
562  if(type.id()!=ID_pointer ||
563  is_reference(type) ||
564  type.find("to-member").is_nil())
565  return false;
566 
567  if(expr.type().id() != ID_pointer ||
568  expr.type().find("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  assert(this1.get(ID_C_base_name)==ID_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  assert(this2.get(ID_C_base_name)==ID_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=expr;
608  new_expr.make_typecast(type);
609  return true;
610  }
611 
612  struct_typet from_struct =
613  to_struct_type(follow(static_cast<const typet &>
614  (expr.type().find("to-member"))));
615 
616  struct_typet to_struct =
617  to_struct_type(follow(static_cast<const typet &>
618  (type.find("to-member"))));
619 
620  if(subtype_typecast(to_struct, from_struct))
621  {
622  new_expr=expr;
623  new_expr.make_typecast(type);
624  return true;
625  }
626 
627  return false;
628 }
629 
640  const exprt &expr, exprt &new_expr) const
641 {
642  if(expr.get_bool(ID_C_lvalue))
643  return false;
644 
645  if(
646  expr.type().id() != ID_signedbv && expr.type().id() != ID_unsignedbv &&
647  expr.type().id() != ID_pointer && expr.type().id() != ID_bool &&
648  expr.type().id() != ID_c_enum_tag)
649  {
650  return false;
651  }
652 
653  c_qualifierst qual_from;
654  qual_from.read(expr.type());
655 
656  typet Bool = c_bool_type();
657  qual_from.write(Bool);
658 
659  new_expr=expr;
660  new_expr.make_typecast(Bool);
661  return true;
662 }
663 
685  const exprt &expr,
686  const typet &type,
687  exprt &new_expr,
688  unsigned &rank)
689 {
690  assert(!is_reference(expr.type()) && !is_reference(type));
691 
692  exprt curr_expr=expr;
693 
694  // bit fields are converted like their underlying type
695  if(type.id()==ID_c_bit_field)
696  return standard_conversion_sequence(expr, type.subtype(), new_expr, rank);
697 
698  // we turn bit fields into their underlying type
699  if(curr_expr.type().id()==ID_c_bit_field)
700  curr_expr.make_typecast(curr_expr.type().subtype());
701 
702  if(curr_expr.type().id()==ID_array)
703  {
704  if(type.id()==ID_pointer)
705  {
706  if(!standard_conversion_array_to_pointer(curr_expr, new_expr))
707  return false;
708  }
709  }
710  else if(curr_expr.type().id()==ID_code &&
711  type.id()==ID_pointer)
712  {
713  if(!standard_conversion_function_to_pointer(curr_expr, new_expr))
714  return false;
715  }
716  else if(curr_expr.get_bool(ID_C_lvalue))
717  {
718  if(!standard_conversion_lvalue_to_rvalue(curr_expr, new_expr))
719  return false;
720  }
721  else
722  new_expr=curr_expr;
723 
724  curr_expr.swap(new_expr);
725 
726  // two enums are the same if the tag is the same,
727  // even if the width differs (enum bit-fields!)
728  if(follow(type).id()==ID_c_enum &&
729  follow(curr_expr.type()).id()==ID_c_enum)
730  {
731  if(follow(type).find(ID_tag)==
732  follow(curr_expr.type()).find(ID_tag))
733  return true;
734  else
735  {
736  // In contrast to C, we simply don't allow implicit conversions
737  // between enums.
738  return false;
739  }
740  }
741 
742  // need to consider #c_type
743  if(follow(curr_expr.type())!=follow(type) ||
744  curr_expr.type().get(ID_C_c_type)!=type.get(ID_C_c_type))
745  {
746  if(type.id()==ID_signedbv ||
747  type.id()==ID_unsignedbv ||
748  follow(type).id()==ID_c_enum)
749  {
750  if(!standard_conversion_integral_promotion(curr_expr, new_expr) ||
751  new_expr.type() != type)
752  {
753  if(!standard_conversion_integral_conversion(curr_expr, type, new_expr))
754  {
756  curr_expr, type, new_expr))
757  return false;
758  }
759 
760  rank+=3;
761  }
762  else
763  rank+=2;
764  }
765  else if(type.id()==ID_floatbv || type.id()==ID_fixedbv)
766  {
767  if(!standard_conversion_floating_point_promotion(curr_expr, new_expr) ||
768  new_expr.type() != type)
769  {
771  curr_expr, type, new_expr) &&
773  curr_expr, type, new_expr))
774  return false;
775 
776  rank += 3;
777  }
778  else
779  rank += 2;
780  }
781  else if(type.id()==ID_pointer)
782  {
783  if(expr.type().subtype().id()==ID_nullptr)
784  {
785  // std::nullptr_t to _any_ pointer type is ok
786  new_expr.make_typecast(type);
787  }
788  else if(!standard_conversion_pointer(curr_expr, type, new_expr))
789  {
790  if(!standard_conversion_pointer_to_member(curr_expr, type, new_expr))
791  return false;
792  }
793 
794  rank += 3;
795  }
796  else if(type.id() == ID_c_bool)
797  {
798  if(!standard_conversion_boolean(curr_expr, new_expr))
799  return false;
800 
801  rank += 3;
802  }
803  else if(type.id() == ID_bool)
804  {
805  new_expr = is_not_zero(curr_expr, *this);
806 
807  rank += 3;
808  }
809  else
810  return false;
811  }
812  else
813  new_expr=curr_expr;
814 
815  curr_expr.swap(new_expr);
816 
817  if(curr_expr.type().id()==ID_pointer)
818  {
819  typet sub_from=curr_expr.type();
820  typet sub_to=type;
821 
822  do
823  {
824  typet tmp_from=sub_from.subtype();
825  sub_from.swap(tmp_from);
826  typet tmp_to=sub_to.subtype();
827  sub_to.swap(tmp_to);
828 
829  c_qualifierst qual_from;
830  qual_from.read(sub_from);
831 
832  c_qualifierst qual_to;
833  qual_to.read(sub_to);
834 
835  if(qual_from!=qual_to)
836  {
837  rank+=1;
838  break;
839  }
840  }
841  while(sub_from.id()==ID_pointer);
842 
843  if(!standard_conversion_qualification(curr_expr, type, new_expr))
844  return false;
845  }
846  else
847  {
848  new_expr=curr_expr;
849  new_expr.type()=type;
850  }
851 
852  return true;
853 }
854 
861  const exprt &expr,
862  const typet &type,
863  exprt &new_expr,
864  unsigned &rank)
865 {
866  assert(!is_reference(expr.type()));
867  assert(!is_reference(type));
868 
869  const typet &from=follow(expr.type());
870  const typet &to=follow(type);
871 
872  new_expr.make_nil();
873 
874  // special case:
875  // A conversion from a type to the same type is given an exact
876  // match rank even though a user-defined conversion is used
877 
878  if(from==to)
879  rank+=0;
880  else
881  rank+=4; // higher than all the standard conversions
882 
883  if(to.id()==ID_struct)
884  {
885  std::string err_msg;
886 
887  if(cpp_is_pod(to))
888  {
889  if(from.id()==ID_struct)
890  {
891  const struct_typet &from_struct=to_struct_type(from);
892  const struct_typet &to_struct=to_struct_type(to);
893 
894  // potentially requires
895  // expr.get_bool(ID_C_lvalue) ??
896 
897  if(subtype_typecast(from_struct, to_struct))
898  {
899  exprt address=address_of_exprt(expr);
900 
901  // simplify address
902  if(expr.id()==ID_dereference)
903  address=expr.op0();
904 
905  pointer_typet ptr_sub=pointer_type(type);
906  c_qualifierst qual_from;
907  qual_from.read(expr.type());
908  qual_from.write(ptr_sub.subtype());
909  make_ptr_typecast(address, ptr_sub);
910 
911  const dereference_exprt deref(address);
912 
913  // create temporary object
914  side_effect_exprt tmp_object_expr(
915  ID_temporary_object, type, expr.source_location());
916  tmp_object_expr.copy_to_operands(deref);
917  tmp_object_expr.set(ID_C_lvalue, true);
918 
919  new_expr.swap(tmp_object_expr);
920  return true;
921  }
922  }
923  }
924  else
925  {
926  struct_typet from_struct;
927  from_struct.make_nil();
928 
929  if(from.id()==ID_struct)
930  from_struct=to_struct_type(from);
931 
932  bool found=false;
933 
934  for(const auto &component : to_struct_type(to).components())
935  {
936  if(component.get_bool(ID_from_base))
937  continue;
938 
939  if(component.get_bool(ID_is_explicit))
940  continue;
941 
942  const typet &comp_type = component.type();
943 
944  if(comp_type.id() !=ID_code)
945  continue;
946 
947  if(to_code_type(comp_type).return_type().id() != ID_constructor)
948  continue;
949 
950  // TODO: ellipsis
951 
952  const auto &parameters = to_code_type(comp_type).parameters();
953 
954  if(parameters.size() != 2)
955  continue;
956 
957  exprt curr_arg1 = parameters[1];
958  typet arg1_type=curr_arg1.type();
959 
960  if(is_reference(arg1_type))
961  {
962  typet tmp=arg1_type.subtype();
963  arg1_type.swap(tmp);
964  }
965 
966  struct_typet arg1_struct;
967  arg1_struct.make_nil();
968  {
969  typet tmp=follow(arg1_type);
970  if(tmp.id()==ID_struct)
971  arg1_struct=to_struct_type(tmp);
972  }
973 
974  unsigned tmp_rank=0;
975  if(arg1_struct.is_nil())
976  {
977  exprt tmp_expr;
979  expr, arg1_type, tmp_expr, tmp_rank))
980  {
981  // check if it's ambiguous
982  if(found)
983  return false;
984  found=true;
985 
986  if(expr.get_bool(ID_C_lvalue))
987  tmp_expr.set(ID_C_lvalue, true);
988 
989  tmp_expr.add_source_location()=expr.source_location();
990 
991  exprt func_symb = cpp_symbol_expr(lookup(component.get_name()));
992  func_symb.type()=comp_type;
993  {
994  exprt tmp(ID_already_typechecked);
995  tmp.copy_to_operands(func_symb);
996  func_symb.swap(func_symb);
997  }
998 
999  // create temporary object
1001  ctor_expr.add_source_location()=expr.source_location();
1002  ctor_expr.function().swap(func_symb);
1003  ctor_expr.arguments().push_back(tmp_expr);
1005 
1006  new_expr.swap(ctor_expr);
1007  assert(new_expr.get(ID_statement)==ID_temporary_object);
1008 
1009  if(to.get_bool(ID_C_constant))
1010  new_expr.type().set(ID_C_constant, true);
1011 
1012  rank += tmp_rank;
1013  }
1014  }
1015  else if(from_struct.is_not_nil() && arg1_struct.is_not_nil())
1016  {
1017  // try derived-to-base conversion
1018  address_of_exprt expr_pfrom(expr, pointer_type(expr.type()));
1019  pointer_typet pto=pointer_type(arg1_type);
1020 
1021  exprt expr_ptmp;
1022  tmp_rank=0;
1024  expr_pfrom, pto, expr_ptmp, tmp_rank))
1025  {
1026  // check if it's ambiguous
1027  if(found)
1028  return false;
1029  found=true;
1030 
1031  rank+=tmp_rank;
1032 
1033  // create temporary object
1034  dereference_exprt expr_deref(expr_ptmp);
1035  expr_deref.set(ID_C_lvalue, true);
1036  expr_deref.add_source_location()=expr.source_location();
1037 
1038  exprt new_object(ID_new_object, type);
1039  new_object.set(ID_C_lvalue, true);
1040  new_object.type().set(ID_C_constant, false);
1041 
1042  exprt func_symb = cpp_symbol_expr(lookup(component.get_name()));
1043  func_symb.type()=comp_type;
1044  {
1045  exprt tmp(ID_already_typechecked);
1046  tmp.copy_to_operands(func_symb);
1047  func_symb.swap(func_symb);
1048  }
1049 
1051  ctor_expr.add_source_location()=expr.source_location();
1052  ctor_expr.function().swap(func_symb);
1053  ctor_expr.arguments().push_back(expr_deref);
1055 
1056  new_expr.swap(ctor_expr);
1057 
1058  INVARIANT(
1059  new_expr.get(ID_statement)==ID_temporary_object,
1060  "statement ID");
1061 
1062  if(to.get_bool(ID_C_constant))
1063  new_expr.type().set(ID_C_constant, true);
1064  }
1065  }
1066  }
1067  if(found)
1068  return true;
1069  }
1070  }
1071 
1072  // conversion operators
1073  if(from.id()==ID_struct)
1074  {
1075  bool found=false;
1076  for(const auto &component : to_struct_type(from).components())
1077  {
1078  if(component.get_bool(ID_from_base))
1079  continue;
1080 
1081  if(!component.get_bool(ID_is_cast_operator))
1082  continue;
1083 
1084  const code_typet &comp_type = to_code_type(component.type());
1086  comp_type.parameters().size() == 1, "expected exactly one parameter");
1087 
1088  typet this_type = comp_type.parameters().front().type();
1089  this_type.set(ID_C_reference, true);
1090 
1091  exprt this_expr(expr);
1092  this_type.set(ID_C_this, true);
1093 
1094  unsigned tmp_rank=0;
1095  exprt tmp_expr;
1096 
1098  this_expr, this_type, tmp_expr, tmp_rank))
1099  {
1100  // To take care of the possible virtual case,
1101  // we build the function as a member expression.
1102  const cpp_namet cpp_func_name(component.get_base_name());
1103 
1104  exprt member_func(ID_member);
1105  member_func.add(ID_component_cpp_name)=cpp_func_name;
1106  exprt ac(ID_already_typechecked);
1107  ac.copy_to_operands(expr);
1108  member_func.copy_to_operands(ac);
1109 
1111  func_expr.add_source_location()=expr.source_location();
1112  func_expr.function().swap(member_func);
1114 
1115  if(standard_conversion_sequence(func_expr, type, tmp_expr, tmp_rank))
1116  {
1117  // check if it's ambiguous
1118  if(found)
1119  return false;
1120  found=true;
1121 
1122  rank+=tmp_rank;
1123  new_expr.swap(tmp_expr);
1124  }
1125  }
1126  }
1127  if(found)
1128  return true;
1129  }
1130 
1131  return new_expr.is_not_nil();
1132 }
1133 
1139  const exprt &expr,
1140  const typet &type) const
1141 {
1142  assert(is_reference(type));
1143  assert(!is_reference(expr.type()));
1144 
1145  typet from=follow(expr.type());
1146  typet to=follow(type.subtype());
1147 
1148  // need to check #c_type
1149  if(from.get(ID_C_c_type)!=to.get(ID_C_c_type))
1150  return false;
1151 
1152  if(from==to)
1153  return true;
1154 
1155  if(from.id()==ID_struct &&
1156  to.id()==ID_struct)
1157  return subtype_typecast(to_struct_type(from),
1158  to_struct_type(to));
1159 
1160  if(from.id()==ID_struct &&
1161  type.get_bool(ID_C_this) &&
1162  type.subtype().id()==ID_empty)
1163  {
1164  // virtual-call case
1165  return true;
1166  }
1167 
1168  return false;
1169 }
1170 
1176  const exprt &expr,
1177  const typet &type,
1178  unsigned &rank) const
1179 {
1180  assert(is_reference(type));
1181  assert(!is_reference(expr.type()));
1182 
1183  if(!reference_related(expr, type))
1184  return false;
1185 
1186  if(expr.type()!=type.subtype())
1187  rank+=3;
1188 
1189  c_qualifierst qual_from;
1190  qual_from.read(expr.type());
1191 
1192  c_qualifierst qual_to;
1193  qual_to.read(type.subtype());
1194 
1195  if(qual_from!=qual_to)
1196  rank+=1;
1197 
1198  if(qual_from.is_subset_of(qual_to))
1199  return true;
1200 
1201  return false;
1202 }
1203 
1239  exprt expr,
1240  const typet &type,
1241  exprt &new_expr,
1242  unsigned &rank)
1243 {
1244  assert(is_reference(type));
1245  assert(!is_reference(expr.type()));
1246 
1247  unsigned backup_rank=rank;
1248 
1249  if(type.get_bool(ID_C_this) &&
1250  !expr.get_bool(ID_C_lvalue))
1251  {
1252  // `this' has to be an lvalue
1253  if(expr.get(ID_statement)==ID_temporary_object)
1254  expr.set(ID_C_lvalue, true);
1255  else if(expr.get(ID_statement)==ID_function_call)
1256  expr.set(ID_C_lvalue, true);
1257  else if(expr.get_bool(ID_C_temporary_avoided))
1258  {
1259  expr.remove(ID_C_temporary_avoided);
1260  exprt temporary;
1261  new_temporary(expr.source_location(), expr.type(), expr, temporary);
1262  expr.swap(temporary);
1263  expr.set(ID_C_lvalue, true);
1264  }
1265  else
1266  return false;
1267  }
1268 
1269  if(expr.get_bool(ID_C_lvalue))
1270  {
1271  if(reference_compatible(expr, type, rank))
1272  {
1273  {
1274  address_of_exprt tmp(expr, reference_type(expr.type()));
1275  tmp.add_source_location()=expr.source_location();
1276  new_expr.swap(tmp);
1277  }
1278 
1279  if(expr.type()!=type.subtype())
1280  {
1281  c_qualifierst qual_from;
1282  qual_from.read(expr.type());
1283  new_expr.make_typecast(type);
1284  qual_from.write(new_expr.type().subtype());
1285  }
1286 
1287  return true;
1288  }
1289 
1290  rank=backup_rank;
1291  }
1292 
1293  // conversion operators
1294  const typet &from_type = follow(expr.type());
1295  if(from_type.id()==ID_struct)
1296  {
1297  for(const auto &component : to_struct_type(from_type).components())
1298  {
1299  if(component.get_bool(ID_from_base))
1300  continue;
1301 
1302  if(!component.get_bool(ID_is_cast_operator))
1303  continue;
1304 
1305  const code_typet &component_type = to_code_type(component.type());
1306 
1307  // otherwise it cannot bind directly (not an lvalue)
1308  if(!is_reference(component_type.return_type()))
1309  continue;
1310 
1311  assert(component_type.parameters().size()==1);
1312 
1313  typet this_type =
1314  component_type.parameters().front().type();
1315  this_type.set(ID_C_reference, true);
1316 
1317  exprt this_expr(expr);
1318 
1319  this_type.set(ID_C_this, true);
1320 
1321  unsigned tmp_rank=0;
1322 
1323  exprt tmp_expr;
1325  this_expr, this_type, tmp_expr, tmp_rank))
1326  {
1327  // To take care of the possible virtual case,
1328  // we build the function as a member expression.
1329  const cpp_namet cpp_func_name(component.get_base_name());
1330 
1331  exprt member_func(ID_member);
1332  member_func.add(ID_component_cpp_name)=cpp_func_name;
1333  exprt ac(ID_already_typechecked);
1334  ac.copy_to_operands(expr);
1335  member_func.copy_to_operands(ac);
1336 
1338  func_expr.add_source_location()=expr.source_location();
1339  func_expr.function().swap(member_func);
1341 
1342  // let's check if the returned value binds directly
1343  exprt returned_value=func_expr;
1344  add_implicit_dereference(returned_value);
1345 
1346  if(returned_value.get_bool(ID_C_lvalue) &&
1347  reference_compatible(returned_value, type, rank))
1348  {
1349  // returned values are lvalues in case of references only
1350  assert(returned_value.id()==ID_dereference &&
1351  is_reference(returned_value.op0().type()));
1352 
1353  new_expr=returned_value.op0();
1354 
1355  if(returned_value.type() != type.subtype())
1356  {
1357  c_qualifierst qual_from;
1358  qual_from.read(returned_value.type());
1359  make_ptr_typecast(new_expr, type);
1360  qual_from.write(new_expr.type().subtype());
1361  }
1362  rank+=4+tmp_rank;
1363  return true;
1364  }
1365  }
1366  }
1367  }
1368 
1369  // No temporary allowed for `this'
1370  if(type.get_bool(ID_C_this))
1371  return false;
1372 
1373  if(!type.subtype().get_bool(ID_C_constant) ||
1374  type.subtype().get_bool(ID_C_volatile))
1375  return false;
1376 
1377  // TODO: handle the case for implicit parameters
1378  if(!type.subtype().get_bool(ID_C_constant) &&
1379  !expr.get_bool(ID_C_lvalue))
1380  return false;
1381 
1382  exprt arg_expr=expr;
1383 
1384  if(follow(arg_expr.type()).id()==ID_struct)
1385  {
1386  // required to initialize the temporary
1387  arg_expr.set(ID_C_lvalue, true);
1388  }
1389 
1390  if(user_defined_conversion_sequence(arg_expr, type.subtype(), new_expr, rank))
1391  {
1392  address_of_exprt tmp(new_expr, reference_type(new_expr.type()));
1393  tmp.add_source_location()=new_expr.source_location();
1394  new_expr.swap(tmp);
1395  return true;
1396  }
1397 
1398  rank=backup_rank;
1399  if(standard_conversion_sequence(expr, type.subtype(), new_expr, rank))
1400  {
1401  {
1402  // create temporary object
1403  exprt tmp=exprt(ID_side_effect, type.subtype());
1404  tmp.set(ID_statement, ID_temporary_object);
1405  tmp.add_source_location()=expr.source_location();
1406  // tmp.set(ID_C_lvalue, true);
1407  tmp.move_to_operands(new_expr);
1408  new_expr.swap(tmp);
1409  }
1410 
1411  address_of_exprt tmp(new_expr, pointer_type(new_expr.type()));
1412  tmp.type().set(ID_C_reference, true);
1413  tmp.add_source_location()=new_expr.source_location();
1414 
1415  new_expr=tmp;
1416  return true;
1417  }
1418 
1419  return false;
1420 }
1421 
1429  const exprt &expr,
1430  const typet &type,
1431  exprt &new_expr,
1432  unsigned &rank)
1433 {
1434  unsigned backup_rank=rank;
1435 
1436  exprt e=expr;
1438 
1439  if(is_reference(type))
1440  {
1441  if(!reference_binding(e, type, new_expr, rank))
1442  return false;
1443 
1444  #if 0
1445  simplify_exprt simplify(*this);
1446  simplify.simplify(new_expr);
1447  new_expr.type().set(ID_C_reference, true);
1448  #endif
1449  }
1450  else if(!standard_conversion_sequence(e, type, new_expr, rank))
1451  {
1452  rank=backup_rank;
1453  if(!user_defined_conversion_sequence(e, type, new_expr, rank))
1454  return false;
1455 
1456  #if 0
1457  simplify_exprt simplify(*this);
1458  simplify.simplify(new_expr);
1459  #endif
1460  }
1461 
1462  return true;
1463 }
1464 
1471  const exprt &expr,
1472  const typet &type,
1473  exprt &new_expr)
1474 {
1475  unsigned rank=0;
1476  return implicit_conversion_sequence(expr, type, new_expr, rank);
1477 }
1478 
1485  const exprt &expr,
1486  const typet &type,
1487  unsigned &rank)
1488 {
1489  exprt new_expr;
1490  return implicit_conversion_sequence(expr, type, new_expr, rank);
1491 }
1492 
1494 {
1495  exprt e=expr;
1496 
1497  if(
1498  e.id() == ID_initializer_list && cpp_is_pod(type) &&
1499  e.operands().size() == 1)
1500  {
1501  e = expr.op0();
1502  }
1503 
1504  if(!implicit_conversion_sequence(e, type, expr))
1505  {
1508  error() << "invalid implicit conversion from `"
1509  << to_string(e.type()) << "' to `"
1510  << to_string(type) << "'" << eom;
1511  #if 0
1512  str << "\n " << follow(e.type()).pretty() << '\n';
1513  str << "\n " << type.pretty() << '\n';
1514  #endif
1515  throw 0;
1516  }
1517 }
1518 
1562  exprt &expr,
1563  const typet &type)
1564 {
1565  assert(is_reference(type));
1567 
1568  unsigned rank=0;
1569  exprt new_expr;
1570  if(reference_binding(expr, type, new_expr, rank))
1571  {
1572  expr.swap(new_expr);
1573  return;
1574  }
1575 
1577  error() << "bad reference initializer" << eom;
1578  throw 0;
1579 }
1580 
1582  const typet &t1,
1583  const typet &t2) const
1584 {
1585  assert(t1.id()==ID_pointer && t2.id()==ID_pointer);
1586  typet nt1=t1;
1587  typet nt2=t2;
1588 
1589  if(is_reference(nt1))
1590  nt1.remove(ID_C_reference);
1591  nt1.remove("to-member");
1592 
1593  if(is_reference(nt2))
1594  nt2.remove(ID_C_reference);
1595  nt2.remove("to-member");
1596 
1597  // substitute final subtypes
1598  std::vector<typet> snt1;
1599  snt1.push_back(nt1);
1600 
1601  while(snt1.back().has_subtype())
1602  {
1603  snt1.reserve(snt1.size()+1);
1604  snt1.push_back(snt1.back().subtype());
1605  }
1606 
1607  c_qualifierst q1;
1608  q1.read(snt1.back());
1609 
1610  bool_typet newnt1;
1611  q1.write(newnt1);
1612  snt1.back()=newnt1;
1613 
1614  std::vector<typet> snt2;
1615  snt2.push_back(nt2);
1616  while(snt2.back().has_subtype())
1617  {
1618  snt2.reserve(snt2.size()+1);
1619  snt2.push_back(snt2.back().subtype());
1620  }
1621 
1622  c_qualifierst q2;
1623  q2.read(snt2.back());
1624 
1625  bool_typet newnt2;
1626  q2.write(newnt2);
1627  snt2.back()=newnt2;
1628 
1629  const std::size_t k=snt1.size() < snt2.size() ? snt1.size() : snt2.size();
1630 
1631  for(std::size_t i=k; i > 1; i--)
1632  {
1633  snt1[snt1.size()-2].subtype()=snt1[snt1.size()-1];
1634  snt1.pop_back();
1635 
1636  snt2[snt2.size()-2].subtype()=snt2[snt2.size()-1];
1637  snt2.pop_back();
1638  }
1639 
1640  exprt e1("Dummy", snt1.back());
1641  exprt e2;
1642 
1643  return !standard_conversion_qualification(e1, snt2.back(), e2);
1644 }
1645 
1647  const exprt &expr,
1648  const typet &type,
1649  exprt &new_expr)
1650 {
1651  PRECONDITION(!is_reference(expr.type()));
1652 
1653  exprt curr_expr=expr;
1654 
1655  if(curr_expr.type().id()==ID_array)
1656  {
1657  if(type.id()==ID_pointer)
1658  {
1659  if(!standard_conversion_array_to_pointer(curr_expr, new_expr))
1660  return false;
1661  }
1662  }
1663  else if(curr_expr.type().id()==ID_code &&
1664  type.id()==ID_pointer)
1665  {
1666  if(!standard_conversion_function_to_pointer(curr_expr, new_expr))
1667  return false;
1668  }
1669  else if(curr_expr.get_bool(ID_C_lvalue))
1670  {
1671  if(!standard_conversion_lvalue_to_rvalue(curr_expr, new_expr))
1672  return false;
1673  }
1674  else
1675  new_expr=curr_expr;
1676 
1677  if(is_reference(type))
1678  {
1679  if(!expr.get_bool(ID_C_lvalue))
1680  return false;
1681 
1682  if(new_expr.type()!=type.subtype())
1683  return false;
1684 
1685  address_of_exprt address_of(expr, to_pointer_type(type));
1686  add_implicit_dereference(address_of);
1687  new_expr=address_of;
1688  return true;
1689  }
1690  else if(type.id()==ID_pointer)
1691  {
1692  if(type!=new_expr.type())
1693  return false;
1694 
1695  // add proper typecast
1696  typecast_exprt typecast_expr(expr, type);
1697  new_expr.swap(typecast_expr);
1698  return true;
1699  }
1700 
1701  return false;
1702 }
1703 
1705  const exprt &expr,
1706  const typet &type,
1707  exprt &new_expr)
1708 {
1709  exprt e(expr);
1710 
1711  if(type.id()==ID_pointer)
1712  {
1713  if(e.id()==ID_dereference && e.get_bool(ID_C_implicit))
1714  e=expr.op0();
1715 
1716  if(e.type().id()==ID_pointer &&
1717  cast_away_constness(e.type(), type))
1718  return false;
1719  }
1720 
1722 
1723  if(is_reference(type))
1724  {
1725  if(follow(type.subtype()).id() != ID_struct)
1726  return false;
1727  }
1728  else if(type.id()==ID_pointer)
1729  {
1730  if(type.find("to-member").is_not_nil())
1731  return false;
1732 
1733  if(type.subtype().id()==ID_empty)
1734  {
1735  if(!e.get_bool(ID_C_lvalue))
1736  return false;
1737  UNREACHABLE; // currently not supported
1738  }
1739  else if(follow(type.subtype()).id()==ID_struct)
1740  {
1741  if(e.get_bool(ID_C_lvalue))
1742  {
1743  exprt tmp(e);
1744 
1746  return false;
1747  }
1748  }
1749  else return false;
1750  }
1751  else return false;
1752 
1753  return static_typecast(e, type, new_expr);
1754 }
1755 
1757  const exprt &expr,
1758  const typet &type,
1759  exprt &new_expr,
1760  bool check_constantness)
1761 {
1762  exprt e=expr;
1763 
1764  if(check_constantness && type.id()==ID_pointer)
1765  {
1766  if(e.id()==ID_dereference && e.get_bool(ID_C_implicit))
1767  e=expr.op0();
1768 
1769  if(e.type().id()==ID_pointer &&
1770  cast_away_constness(e.type(), type))
1771  return false;
1772  }
1773 
1775 
1776  if(!is_reference(type))
1777  {
1778  exprt tmp;
1779 
1780  if(e.id()==ID_code)
1781  {
1783  e.swap(tmp);
1784  else
1785  return false;
1786  }
1787 
1788  if(e.type().id()==ID_array)
1789  {
1791  e.swap(tmp);
1792  else
1793  return false;
1794  }
1795 
1796  if(e.get_bool(ID_C_lvalue))
1797  {
1799  e.swap(tmp);
1800  else
1801  return false;
1802  }
1803  }
1804 
1805  if(e.type().id()==ID_pointer &&
1806  (type.id()==ID_unsignedbv || type.id()==ID_signedbv))
1807  {
1808  // pointer to integer, always ok
1809  new_expr=e;
1810  new_expr.make_typecast(type);
1811  return true;
1812  }
1813 
1814  if(
1815  (e.type().id() == ID_unsignedbv || e.type().id() == ID_signedbv ||
1816  e.type().id() == ID_c_bool || e.type().id() == ID_bool) &&
1817  type.id() == ID_pointer && !is_reference(type))
1818  {
1819  // integer to pointer
1820  if(simplify_expr(e, *this).is_zero())
1821  {
1822  // NULL
1823  new_expr=e;
1824  new_expr.set(ID_value, ID_NULL);
1825  new_expr.type()=type;
1826  }
1827  else
1828  {
1829  new_expr=e;
1830  new_expr.make_typecast(type);
1831  }
1832  return true;
1833  }
1834 
1835  if(e.type().id()==ID_pointer &&
1836  type.id()==ID_pointer &&
1837  !is_reference(type))
1838  {
1839  // pointer to pointer: we ok it all.
1840  // This is more generous than the standard.
1841  new_expr=expr;
1842  new_expr.make_typecast(type);
1843  return true;
1844  }
1845 
1846  if(is_reference(type) && e.get_bool(ID_C_lvalue))
1847  {
1848  exprt tmp=address_of_exprt(e);
1849  tmp.make_typecast(type);
1850  new_expr.swap(tmp);
1851  return true;
1852  }
1853 
1854  return false;
1855 }
1856 
1858  const exprt &expr, // source expression
1859  const typet &type, // destination type
1860  exprt &new_expr,
1861  bool check_constantness)
1862 {
1863  exprt e=expr;
1864 
1865  if(check_constantness && type.id()==ID_pointer)
1866  {
1867  if(e.id()==ID_dereference && e.get_bool(ID_C_implicit))
1868  e=expr.op0();
1869 
1870  if(e.type().id()==ID_pointer &&
1871  cast_away_constness(e.type(), type))
1872  return false;
1873  }
1874 
1876 
1877  if(type.get_bool(ID_C_reference))
1878  {
1879  unsigned rank=0;
1880  if(reference_binding(e, type, new_expr, rank))
1881  return true;
1882 
1883  typet subto=follow(type.subtype());
1884  typet from=follow(e.type());
1885 
1886  if(subto.id()==ID_struct && from.id()==ID_struct)
1887  {
1888  if(!expr.get_bool(ID_C_lvalue))
1889  return false;
1890 
1891  c_qualifierst qual_from;
1892  qual_from.read(e.type());
1893 
1894  c_qualifierst qual_to;
1895  qual_to.read(type.subtype());
1896 
1897  if(!qual_to.is_subset_of(qual_from))
1898  return false;
1899 
1900  struct_typet from_struct=to_struct_type(from);
1901  struct_typet subto_struct=to_struct_type(subto);
1902 
1903  if(subtype_typecast(subto_struct, from_struct))
1904  {
1905  if(e.id()==ID_dereference)
1906  {
1907  make_ptr_typecast(e.op0(), type);
1908  new_expr.swap(e.op0());
1909  return true;
1910  }
1911 
1912  exprt address_of=address_of_exprt(e);
1913  make_ptr_typecast(address_of, type);
1914  new_expr.swap(address_of);
1915  return true;
1916  }
1917  }
1918  return false;
1919  }
1920 
1921  if(type.id()==ID_empty)
1922  {
1923  new_expr=e;
1924  new_expr.make_typecast(type);
1925  return true;
1926  }
1927 
1928  // int/enum to enum
1929  if(type.id()==ID_c_enum_tag &&
1930  (e.type().id()==ID_signedbv ||
1931  e.type().id()==ID_unsignedbv ||
1932  e.type().id()==ID_c_enum_tag))
1933  {
1934  new_expr=e;
1935  new_expr.make_typecast(type);
1936  new_expr.remove(ID_C_lvalue);
1937  return true;
1938  }
1939 
1940  if(implicit_conversion_sequence(e, type, new_expr))
1941  {
1942  if(!cpp_is_pod(type))
1943  {
1944  exprt tc(ID_already_typechecked);
1945  tc.copy_to_operands(new_expr);
1946  exprt temporary;
1947  new_temporary(e.source_location(), type, tc, temporary);
1948  new_expr.swap(temporary);
1949  }
1950  else
1951  {
1952  // try to avoid temporary
1953  new_expr.set(ID_C_temporary_avoided, true);
1954  if(new_expr.get_bool(ID_C_lvalue))
1955  new_expr.remove(ID_C_lvalue);
1956  }
1957 
1958  return true;
1959  }
1960 
1961  if(type.id()==ID_pointer && e.type().id()==ID_pointer)
1962  {
1963  if(type.find("to-member").is_nil()
1964  && e.type().find("to-member").is_nil())
1965  {
1966  typet to=follow(type.subtype());
1967  typet from=follow(e.type().subtype());
1968 
1969  if(from.id()==ID_empty)
1970  {
1971  e.make_typecast(type);
1972  new_expr.swap(e);
1973  return true;
1974  }
1975 
1976  if(to.id()==ID_struct && from.id()==ID_struct)
1977  {
1978  if(e.get_bool(ID_C_lvalue))
1979  {
1980  exprt tmp(e);
1982  return false;
1983  }
1984 
1985  struct_typet from_struct=to_struct_type(from);
1986  struct_typet to_struct=to_struct_type(to);
1987  if(subtype_typecast(to_struct, from_struct))
1988  {
1989  make_ptr_typecast(e, type);
1990  new_expr.swap(e);
1991  return true;
1992  }
1993  }
1994 
1995  return false;
1996  }
1997  else if(type.find("to-member").is_not_nil() &&
1998  e.type().find("to-member").is_not_nil())
1999  {
2000  if(type.subtype()!=e.type().subtype())
2001  return false;
2002 
2003  struct_typet from_struct=
2005  follow(static_cast<const typet&>(e.type().find("to-member"))));
2006 
2007  struct_typet to_struct=
2009  follow(static_cast<const typet&>(type.find("to-member"))));
2010 
2011  if(subtype_typecast(from_struct, to_struct))
2012  {
2013  new_expr=e;
2014  new_expr.make_typecast(type);
2015  return true;
2016  }
2017  }
2018  else if(
2019  type.find("to-member").is_nil() &&
2020  e.type().find("to-member").is_not_nil())
2021  {
2022  if(type.subtype() != e.type().subtype())
2023  return false;
2024 
2025  struct_typet from_struct = to_struct_type(
2026  follow(static_cast<const typet &>(e.type().find("to-member"))));
2027 
2028  new_expr = e;
2029  new_expr.type().add("to-member") = from_struct;
2030 
2031  return true;
2032  }
2033  else
2034  return false;
2035  }
2036 
2037  return false;
2038 }
The type of an expression, extends irept.
Definition: type.h:27
struct configt::ansi_ct ansi_c
Semantic type conversion.
Definition: std_expr.h:2277
bool reference_binding(exprt expr, const typet &type, exprt &new_expr, unsigned &rank)
Reference binding.
Base type of functions.
Definition: std_types.h:751
bool is_nil() const
Definition: irep.h:172
bool is_not_nil() const
Definition: irep.h:173
pointer_typet pointer_type(const typet &subtype)
Definition: c_types.cpp:243
void new_temporary(const source_locationt &source_location, const typet &, const exprt::operandst &ops, exprt &temporary)
bool standard_conversion_floating_point_conversion(const exprt &expr, const typet &type, exprt &new_expr) const
Floating-point conversion.
const signedbv_typet & to_signedbv_type(const typet &type)
Cast a typet to a signedbv_typet.
Definition: std_types.h:1316
exprt & op0()
Definition: expr.h:84
std::string pretty(unsigned indent=0, unsigned max_indent=0) const
Definition: irep.cpp:640
exprt simplify_expr(const exprt &src, const namespacet &ns)
bool static_typecast(const exprt &expr, const typet &type, exprt &new_expr, bool check_constantness=true)
bool standard_conversion_integral_conversion(const exprt &expr, const typet &type, exprt &new_expr) const
Integral conversion.
Deprecated expression utility functions.
const code_typet & to_code_type(const typet &type)
Cast a typet to a code_typet.
Definition: std_types.h:982
std::size_t single_width
Definition: config.h:37
void copy_to_operands(const exprt &expr)
Copy the given argument to the end of exprt&#39;s operands.
Definition: expr.h:123
auto component(T &struct_expr, const irep_idt &name, const namespacet &ns) -> decltype(struct_expr.op0())
Definition: std_expr.cpp:173
bool user_defined_conversion_sequence(const exprt &expr, const typet &type, exprt &new_expr, unsigned &rank)
User-defined conversion sequence.
void move_to_operands(exprt &expr)
Move the given argument to the end of exprt&#39;s operands.
Definition: expr.cpp:29
bool standard_conversion_qualification(const exprt &expr, const typet &, exprt &new_expr) const
Qualification conversion.
bool standard_conversion_floating_point_promotion(const exprt &expr, exprt &new_expr) const
Floating-point-promotion conversion.
void show_instantiation_stack(std::ostream &)
const componentst & components() const
Definition: std_types.h:205
typet & type()
Return the type of the expression.
Definition: expr.h:68
The Boolean type.
Definition: std_types.h:28
Structure type, corresponds to C style structs.
Definition: std_types.h:276
bool standard_conversion_function_to_pointer(const exprt &expr, exprt &new_expr) const
Function-to-pointer conversion.
bool get_bool(const irep_namet &name) const
Definition: irep.cpp:239
bool cast_away_constness(const typet &t1, const typet &t2) const
configt config
Definition: config.cpp:24
bool standard_conversion_integral_promotion(const exprt &expr, exprt &new_expr) const
Integral-promotion conversion.
bool reference_compatible(const exprt &expr, const typet &type, unsigned &rank) const
Reference-compatible.
bool dynamic_typecast(const exprt &expr, const typet &type, exprt &new_expr)
bool standard_conversion_floating_integral_conversion(const exprt &expr, const typet &type, exprt &new_expr) const
Floating-integral conversion.
bool reference_related(const exprt &expr, const typet &type) const
Reference-related.
const irep_idt & id() const
Definition: irep.h:259
exprt is_not_zero(const exprt &src, const namespacet &ns)
converts a scalar/float expression to C/C++ Booleans
Definition: expr_util.cpp:98
reference_typet reference_type(const typet &subtype)
Definition: c_types.cpp:248
The pointer type These are both &#39;bitvector_typet&#39; (they have a width) and &#39;type_with_subtypet&#39; (they ...
Definition: std_types.h:1507
const source_locationt & find_source_location() const
Get a source_locationt from the expression or from its operands (non-recursively).
Definition: expr.cpp:229
source_locationt source_location
Definition: message.h:236
bool cpp_is_pod(const typet &type) const
Definition: cpp_is_pod.cpp:14
Operator to dereference a pointer.
Definition: std_expr.h:3355
bool reinterpret_typecast(const exprt &expr, const typet &type, exprt &new_expr, bool check_constantness=true)
API to expression classes.
bool is_reference(const typet &type)
Returns true if the type is a reference.
Definition: std_types.cpp:132
void implicit_typecast(exprt &expr, const typet &type) override
const irep_idt & get(const irep_namet &name) const
Definition: irep.cpp:212
mstreamt & error() const
Definition: message.h:386
virtual void read(const typet &src) override
#define PRECONDITION(CONDITION)
Definition: invariant.h:438
std::size_t int_width
Definition: config.h:30
bool standard_conversion_pointer_to_member(const exprt &expr, const typet &type, exprt &new_expr)
Pointer-to-member conversion.
C++ Language Type Checking.
const typet & follow(const typet &) const
Resolve type symbol to the type it points to.
Definition: namespace.cpp:62
bitvector_typet index_type()
Definition: c_types.cpp:16
const struct_typet & to_struct_type(const typet &type)
Cast a typet to a struct_typet.
Definition: std_types.h:349
symbol_exprt cpp_symbol_expr(const symbolt &symbol)
Definition: cpp_util.cpp:14
Operator to return the address of an object.
Definition: std_expr.h:3255
std::string from_type(const namespacet &ns, const irep_idt &identifier, const typet &type)
void make_ptr_typecast(exprt &expr, const typet &dest_type)
const unsignedbv_typet & to_unsignedbv_type(const typet &type)
Cast a typet to an unsignedbv_typet.
Definition: std_types.h:1262
A side_effect_exprt representation of a function call side effect.
Definition: std_code.h:1691
bool const_typecast(const exprt &expr, const typet &type, exprt &new_expr)
static eomt eom
Definition: message.h:284
floatbv_typet float_type()
Definition: c_types.cpp:185
Pre-defined types.
bool subtype_typecast(const struct_typet &from, const struct_typet &to) const
bool standard_conversion_lvalue_to_rvalue(const exprt &expr, exprt &new_expr) const
Lvalue-to-rvalue conversion.
const floatbv_typet & to_floatbv_type(const typet &type)
Cast a typet to a floatbv_typet.
Definition: std_types.h:1442
virtual bool is_subset_of(const qualifierst &other) const override
Definition: c_qualifiers.h:107
bool standard_conversion_sequence(const exprt &expr, const typet &type, exprt &new_expr, unsigned &rank)
Standard Conversion Sequence.
Base class for all expressions.
Definition: expr.h:54
floatbv_typet double_type()
Definition: c_types.cpp:193
const parameterst & parameters() const
Definition: std_types.h:893
const source_locationt & source_location() const
Definition: expr.h:228
#define UNREACHABLE
This should be used to mark dead code.
Definition: invariant.h:478
irept & add(const irep_namet &name)
Definition: irep.cpp:305
exprt::operandst & arguments()
Definition: std_code.h:1754
void make_nil()
Definition: irep.h:315
void swap(irept &irep)
Definition: irep.h:303
virtual void write(typet &src) const override
bool is_zero() const
Return whether the expression is a constant representing 0.
Definition: expr.cpp:130
source_locationt & add_source_location()
Definition: expr.h:233
bool standard_conversion_array_to_pointer(const exprt &expr, exprt &new_expr) const
Array-to-pointer conversion.
const pointer_typet & to_pointer_type(const typet &type)
Cast a typet to a pointer_typet.
Definition: std_types.h:1544
bool standard_conversion_pointer(const exprt &expr, const typet &type, exprt &new_expr)
Pointer conversion.
signedbv_typet signed_int_type()
Definition: c_types.cpp:30
void remove(const irep_namet &name)
Definition: irep.cpp:269
const typet & subtype() const
Definition: type.h:38
#define DATA_INVARIANT(CONDITION, REASON)
This condition should be used to document that assumptions that are made on goto_functions, goto_programs, exprts, etc.
Definition: invariant.h:485
An expression containing a side effect.
Definition: std_code.h:1560
bool implicit_conversion_sequence(const exprt &expr, const typet &type, exprt &new_expr, unsigned &rank)
implicit conversion sequence
operandst & operands()
Definition: expr.h:78
constant_exprt from_integer(const mp_integer &int_value, const typet &type)
void typecheck_side_effect_function_call(side_effect_expr_function_callt &) override
std::string to_string(const typet &) override
typet c_bool_type()
Definition: c_types.cpp:108
void make_typecast(const typet &_type)
Create a typecast_exprt to the given type.
Definition: expr.cpp:74
const irept & find(const irep_namet &name) const
Definition: irep.cpp:284
const typet & return_type() const
Definition: std_types.h:883
bool lookup(const irep_idt &name, const symbolt *&symbol) const override
See documentation for namespace_baset::lookup().
Definition: namespace.cpp:166
void add_implicit_dereference(exprt &)
void set(const irep_namet &name, const irep_idt &value)
Definition: irep.h:286
void reference_initializer(exprt &expr, const typet &type)
A reference to type "cv1 T1" is initialized by an expression of type "cv2 T2" as follows: ...
bool standard_conversion_boolean(const exprt &expr, exprt &new_expr) const
Boolean conversion.
bool simplify(exprt &expr, const namespacet &ns)
Array index operator.
Definition: std_expr.h:1595