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/config.h>
17 #include <util/arith_tools.h>
18 #include <util/std_types.h>
19 #include <util/std_expr.h>
20 #include <util/simplify_expr.h>
21 
22 #include <ansi-c/c_qualifiers.h>
23 #include <util/c_types.h>
24 
46  const exprt &expr,
47  exprt &new_expr) const
48 {
49  assert(expr.get_bool(ID_C_lvalue));
50 
51  if(expr.type().id()==ID_code ||
52  expr.type().id()==ID_incomplete_struct ||
53  expr.type().id()==ID_incomplete_union)
54  return false;
55 
56  new_expr=expr;
57  new_expr.remove(ID_C_lvalue);
58 
59  return true;
60 }
61 
71  const exprt &expr,
72  exprt &new_expr) const
73 {
74  assert(expr.type().id()==ID_array);
75 
76  index_exprt index(
77  expr,
78  from_integer(0, index_type()));
79 
80  index.set(ID_C_lvalue, true);
81 
82  new_expr=address_of_exprt(index);
83 
84  return true;
85 }
86 
95  const exprt &expr, exprt &new_expr) const
96 {
97  if(!expr.get_bool(ID_C_lvalue))
98  return false;
99 
100  new_expr=address_of_exprt(expr);
101 
102  return true;
103 }
104 
111  const exprt &expr,
112  const typet &type,
113  exprt &new_expr) const
114 {
115  if(expr.type().id()!=ID_pointer ||
116  is_reference(expr.type()))
117  return false;
118 
119  if(expr.get_bool(ID_C_lvalue))
120  return false;
121 
122  if(expr.type()!=type)
123  return false;
124 
125  typet sub_from=expr.type().subtype();
126  typet sub_to=type.subtype();
127  bool const_to=true;
128 
129  while(sub_from.id()==ID_pointer)
130  {
131  c_qualifierst qual_from(sub_from);
132  c_qualifierst qual_to(sub_to);
133 
134  if(!qual_to.is_constant)
135  const_to=false;
136 
137  if(qual_from.is_constant && !qual_to.is_constant)
138  return false;
139 
140  if(qual_from!=qual_to && !const_to)
141  return false;
142 
143  typet tmp1=sub_from.subtype();
144  sub_from.swap(tmp1);
145 
146  typet tmp2=sub_to.subtype();
147  sub_to.swap(tmp2);
148  }
149 
150  c_qualifierst qual_from(sub_from);
151  c_qualifierst qual_to(sub_to);
152 
153  if(qual_from.is_subset_of(qual_to))
154  {
155  new_expr=expr;
156  new_expr.type()=type;
157  return true;
158  }
159 
160  return false;
161 }
162 
189  const exprt &expr,
190  exprt &new_expr) const
191 {
192  if(expr.get_bool(ID_C_lvalue))
193  return false;
194 
195  c_qualifierst qual_from;
196  qual_from.read(expr.type());
197 
198  typet int_type=signed_int_type();
199  qual_from.write(int_type);
200 
201  if(expr.type().id()==ID_signedbv)
202  {
203  std::size_t width=to_signedbv_type(expr.type()).get_width();
204  if(width >= config.ansi_c.int_width)
205  return false;
206  new_expr=expr;
207  new_expr.make_typecast(int_type);
208  return true;
209  }
210 
211  if(expr.type().id()==ID_unsignedbv)
212  {
213  std::size_t width=to_unsignedbv_type(expr.type()).get_width();
214  if(width >= config.ansi_c.int_width)
215  return false;
216  new_expr=expr;
217  if(width==config.ansi_c.int_width)
218  int_type.id(ID_unsignedbv);
219  new_expr.make_typecast(int_type);
220  return true;
221  }
222 
223  if(expr.type().id()==ID_c_enum_tag)
224  {
225  new_expr=expr;
226  new_expr.make_typecast(int_type);
227  return true;
228  }
229 
230  return false;
231 }
232 
241  const exprt &expr,
242  exprt &new_expr) const
243 {
244  if(expr.get_bool(ID_C_lvalue))
245  return false;
246 
247  // we only do that with 'float',
248  // not with 'double' or 'long double'
249  if(expr.type()!=float_type())
250  return false;
251 
252  std::size_t width=to_floatbv_type(expr.type()).get_width();
253 
254  if(width!=config.ansi_c.single_width)
255  return false;
256 
257  c_qualifierst qual_from;
258  qual_from.read(expr.type());
259 
260  new_expr=expr;
261  new_expr.make_typecast(double_type());
262  qual_from.write(new_expr.type());
263 
264  return true;
265 }
266 
296  const exprt &expr,
297  const typet &type,
298  exprt &new_expr) const
299 {
300  if(type.id()!=ID_signedbv &&
301  type.id()!=ID_unsignedbv)
302  return false;
303 
304  if(expr.type().id()!=ID_signedbv &&
305  expr.type().id()!=ID_unsignedbv &&
306  expr.type().id()!=ID_bool &&
307  expr.type().id()!=ID_c_enum_tag)
308  return false;
309 
310  if(expr.get_bool(ID_C_lvalue))
311  return false;
312 
313  c_qualifierst qual_from;
314  qual_from.read(expr.type());
315  new_expr=expr;
316  new_expr.make_typecast(type);
317  qual_from.write(new_expr.type());
318 
319  return true;
320 }
321 
342  const exprt &expr,
343  const typet &type,
344  exprt &new_expr) const
345 {
346  if(expr.get_bool(ID_C_lvalue))
347  return false;
348 
349  if(expr.type().id()==ID_floatbv ||
350  expr.type().id()==ID_fixedbv)
351  {
352  if(type.id()!=ID_signedbv &&
353  type.id()!=ID_unsignedbv)
354  return false;
355  }
356  else if(expr.type().id()==ID_signedbv ||
357  expr.type().id()==ID_unsignedbv ||
358  expr.type().id()==ID_c_enum_tag)
359  {
360  if(type.id()!=ID_fixedbv &&
361  type.id()!=ID_floatbv)
362  return false;
363  }
364  else
365  return false;
366 
367  c_qualifierst qual_from;
368  qual_from.read(expr.type());
369  new_expr=expr;
370  new_expr.make_typecast(type);
371  qual_from.write(new_expr.type());
372 
373  return true;
374 }
375 
376 
394  const exprt &expr,
395  const typet &type,
396  exprt &new_expr) const
397 {
398  if(expr.type().id()!=ID_floatbv &&
399  expr.type().id()!=ID_fixedbv)
400  return false;
401 
402  if(type.id()!=ID_floatbv &&
403  type.id()!=ID_fixedbv)
404  return false;
405 
406  if(expr.get_bool(ID_C_lvalue))
407  return false;
408 
409  c_qualifierst qual_from;
410 
411  qual_from.read(expr.type());
412  new_expr=expr;
413  new_expr.make_typecast(type);
414  qual_from.write(new_expr.type());
415 
416  return true;
417 }
418 
452  const exprt &expr,
453  const typet &type,
454  exprt &new_expr)
455 {
456  if(type.id()!=ID_pointer ||
457  is_reference(type))
458  return false;
459 
460  if(expr.get_bool(ID_C_lvalue))
461  return false;
462 
463  // integer 0 to NULL pointer conversion?
464  if(simplify_expr(expr, *this).is_zero() &&
465  expr.type().id()!=ID_pointer)
466  {
467  new_expr=expr;
468  new_expr.set(ID_value, ID_NULL);
469  new_expr.type()=type;
470  return true;
471  }
472 
473  if(type.find("to-member").is_not_nil())
474  return false;
475 
476  if(expr.type().id() != ID_pointer ||
477  expr.type().find("to-member").is_not_nil())
478  return false;
479 
480  typet sub_from=follow(expr.type().subtype());
481  typet sub_to=follow(type.subtype());
482 
483  // std::nullptr_t to _any_ pointer type
484  if(sub_from.id()==ID_nullptr)
485  return true;
486 
487  // anything but function pointer to void *
488  if(sub_from.id()!=ID_code && sub_to.id()==ID_empty)
489  {
490  c_qualifierst qual_from;
491  qual_from.read(expr.type().subtype());
492  new_expr=expr;
493  new_expr.make_typecast(type);
494  qual_from.write(new_expr.type().subtype());
495  return true;
496  }
497 
498  // struct * to struct *
499  if(sub_from.id()==ID_struct && sub_to.id()==ID_struct)
500  {
501  const struct_typet &from_struct=to_struct_type(sub_from);
502  const struct_typet &to_struct=to_struct_type(sub_to);
503  if(subtype_typecast(from_struct, to_struct))
504  {
505  c_qualifierst qual_from;
506  qual_from.read(expr.type().subtype());
507  new_expr=expr;
508  make_ptr_typecast(new_expr, type);
509  qual_from.write(new_expr.type().subtype());
510  return true;
511  }
512  }
513 
514  return false;
515 }
516 
548  const exprt &expr,
549  const typet &type,
550  exprt &new_expr)
551 {
552  if(type.id()!=ID_pointer ||
553  is_reference(type) ||
554  type.find("to-member").is_nil())
555  return false;
556 
557  if(expr.type().id() != ID_pointer ||
558  expr.type().find("to-member").is_nil())
559  return false;
560 
561  if(type.subtype()!=expr.type().subtype())
562  {
563  // subtypes different
564  if(type.subtype().id()==ID_code &&
565  expr.type().subtype().id()==ID_code)
566  {
567  code_typet code1=to_code_type(expr.type().subtype());
568  assert(!code1.parameters().empty());
569  code_typet::parametert this1=code1.parameters()[0];
570  assert(this1.get(ID_C_base_name)==ID_this);
571  code1.parameters().erase(code1.parameters().begin());
572 
573  code_typet code2=to_code_type(type.subtype());
574  assert(!code2.parameters().empty());
575  code_typet::parametert this2=code2.parameters()[0];
576  assert(this2.get(ID_C_base_name)==ID_this);
577  code2.parameters().erase(code2.parameters().begin());
578 
579  if(this2.type().subtype().get_bool(ID_C_constant) &&
580  !this1.type().subtype().get_bool(ID_C_constant))
581  return false;
582 
583  // give a second chance ignoring `this'
584  if(code1!=code2)
585  return false;
586  }
587  else
588  return false;
589  }
590 
591  if(expr.get_bool(ID_C_lvalue))
592  return false;
593 
594  if(expr.id()==ID_constant &&
595  expr.get(ID_value)==ID_NULL)
596  {
597  new_expr=expr;
598  new_expr.make_typecast(type);
599  return true;
600  }
601 
602  struct_typet from_struct =
603  to_struct_type(follow(static_cast<const typet &>
604  (expr.type().find("to-member"))));
605 
606  struct_typet to_struct =
607  to_struct_type(follow(static_cast<const typet &>
608  (type.find("to-member"))));
609 
610  if(subtype_typecast(to_struct, from_struct))
611  {
612  new_expr=expr;
613  new_expr.make_typecast(type);
614  return true;
615  }
616 
617  return false;
618 }
619 
630  const exprt &expr, exprt &new_expr) const
631 {
632  if(expr.get_bool(ID_C_lvalue))
633  return false;
634 
635  if(expr.type().id()!=ID_signedbv &&
636  expr.type().id()!=ID_unsignedbv &&
637  expr.type().id()!=ID_pointer &&
638  expr.type().id()!=ID_c_enum_tag)
639  return false;
640 
641  c_qualifierst qual_from;
642  qual_from.read(expr.type());
643 
644  bool_typet Bool;
645  qual_from.write(Bool);
646 
647  new_expr=expr;
648  new_expr.make_typecast(Bool);
649  return true;
650 }
651 
673  const exprt &expr,
674  const typet &type,
675  exprt &new_expr,
676  unsigned &rank)
677 {
678  assert(!is_reference(expr.type()) && !is_reference(type));
679 
680  exprt curr_expr=expr;
681 
682  // bit fields are converted like their underlying type
683  if(type.id()==ID_c_bit_field)
684  return standard_conversion_sequence(expr, type.subtype(), new_expr, rank);
685 
686  // we turn bit fields into their underlying type
687  if(curr_expr.type().id()==ID_c_bit_field)
688  curr_expr.make_typecast(curr_expr.type().subtype());
689 
690  if(curr_expr.type().id()==ID_array)
691  {
692  if(type.id()==ID_pointer)
693  {
694  if(!standard_conversion_array_to_pointer(curr_expr, new_expr))
695  return false;
696  }
697  }
698  else if(curr_expr.type().id()==ID_code &&
699  type.id()==ID_pointer)
700  {
701  if(!standard_conversion_function_to_pointer(curr_expr, new_expr))
702  return false;
703  }
704  else if(curr_expr.get_bool(ID_C_lvalue))
705  {
706  if(!standard_conversion_lvalue_to_rvalue(curr_expr, new_expr))
707  return false;
708  }
709  else
710  new_expr=curr_expr;
711 
712  curr_expr.swap(new_expr);
713 
714  // two enums are the same if the tag is the same,
715  // even if the width differs (enum bit-fields!)
716  if(follow(type).id()==ID_c_enum &&
717  follow(curr_expr.type()).id()==ID_c_enum)
718  {
719  if(follow(type).find(ID_tag)==
720  follow(curr_expr.type()).find(ID_tag))
721  return true;
722  else
723  {
724  // In contrast to C, we simply don't allow implicit conversions
725  // between enums.
726  return false;
727  }
728  }
729 
730  // need to consider #c_type
731  if(follow(curr_expr.type())!=follow(type) ||
732  curr_expr.type().get(ID_C_c_type)!=type.get(ID_C_c_type))
733  {
734  if(type.id()==ID_signedbv ||
735  type.id()==ID_unsignedbv ||
736  follow(type).id()==ID_c_enum)
737  {
738  if(!standard_conversion_integral_promotion(curr_expr, new_expr) ||
739  new_expr.type() != type)
740  {
741  if(!standard_conversion_integral_conversion(curr_expr, type, new_expr))
742  {
744  curr_expr, type, new_expr))
745  return false;
746  }
747 
748  rank+=3;
749  }
750  else
751  rank+=2;
752  }
753  else if(type.id()==ID_floatbv || type.id()==ID_fixedbv)
754  {
755  if(!standard_conversion_floating_point_promotion(curr_expr, new_expr) ||
756  new_expr.type() != type)
757  {
759  curr_expr, type, new_expr) &&
761  curr_expr, type, new_expr))
762  return false;
763 
764  rank += 3;
765  }
766  else
767  rank += 2;
768  }
769  else if(type.id()==ID_pointer)
770  {
771  if(expr.type().subtype().id()==ID_nullptr)
772  {
773  // std::nullptr_t to _any_ pointer type is ok
774  new_expr.make_typecast(type);
775  }
776  else if(!standard_conversion_pointer(curr_expr, type, new_expr))
777  {
778  if(!standard_conversion_pointer_to_member(curr_expr, type, new_expr))
779  return false;
780  }
781 
782  rank += 3;
783  }
784  else if(type.id()==ID_bool)
785  {
786  if(!standard_conversion_boolean(curr_expr, new_expr))
787  return false;
788 
789  rank += 3;
790  }
791  else
792  return false;
793  }
794  else
795  new_expr=curr_expr;
796 
797  curr_expr.swap(new_expr);
798 
799  if(curr_expr.type().id()==ID_pointer)
800  {
801  typet sub_from=curr_expr.type();
802  typet sub_to=type;
803 
804  do
805  {
806  typet tmp_from=sub_from.subtype();
807  sub_from.swap(tmp_from);
808  typet tmp_to=sub_to.subtype();
809  sub_to.swap(tmp_to);
810 
811  c_qualifierst qual_from;
812  qual_from.read(sub_from);
813 
814  c_qualifierst qual_to;
815  qual_to.read(sub_to);
816 
817  if(qual_from!=qual_to)
818  {
819  rank+=1;
820  break;
821  }
822  }
823  while(sub_from.id()==ID_pointer);
824 
825  if(!standard_conversion_qualification(curr_expr, type, new_expr))
826  return false;
827  }
828  else
829  {
830  new_expr=curr_expr;
831  new_expr.type()=type;
832  }
833 
834  return true;
835 }
836 
843  const exprt &expr,
844  const typet &type,
845  exprt &new_expr,
846  unsigned &rank)
847 {
848  assert(!is_reference(expr.type()));
849  assert(!is_reference(type));
850 
851  const typet &from=follow(expr.type());
852  const typet &to=follow(type);
853 
854  new_expr.make_nil();
855 
856  // special case:
857  // A conversion from a type to the same type is given an exact
858  // match rank even though a user-defined conversion is used
859 
860  if(from==to)
861  rank+=0;
862  else
863  rank+=4; // higher than all the standard conversions
864 
865  if(to.id()==ID_struct)
866  {
867  std::string err_msg;
868 
869  if(cpp_is_pod(to))
870  {
871  if(from.id()==ID_struct)
872  {
873  const struct_typet &from_struct=to_struct_type(from);
874  const struct_typet &to_struct=to_struct_type(to);
875 
876  // potentially requires
877  // expr.get_bool(ID_C_lvalue) ??
878 
879  if(subtype_typecast(from_struct, to_struct))
880  {
881  exprt address=address_of_exprt(expr);
882 
883  // simplify address
884  if(expr.id()==ID_dereference)
885  address=expr.op0();
886 
887  pointer_typet ptr_sub=pointer_type(type);
888  c_qualifierst qual_from;
889  qual_from.read(expr.type());
890  qual_from.write(ptr_sub.subtype());
891  make_ptr_typecast(address, ptr_sub);
892 
893  exprt deref(ID_dereference);
894  deref.copy_to_operands(address);
895  deref.type()=address.type().subtype();
896 
897  // create temporary object
898  exprt tmp_object_expr=exprt(ID_side_effect, type);
899  tmp_object_expr.set(ID_statement, ID_temporary_object);
900  tmp_object_expr.add_source_location()=expr.source_location();
901  tmp_object_expr.copy_to_operands(deref);
902  tmp_object_expr.set(ID_C_lvalue, true);
903 
904  new_expr.swap(tmp_object_expr);
905  return true;
906  }
907  }
908  }
909  else
910  {
911  struct_typet from_struct;
912  from_struct.make_nil();
913 
914  if(from.id()==ID_struct)
915  from_struct=to_struct_type(from);
916 
917  struct_typet to_struct=to_struct_type(to);
918 
919  bool found=false;
920 
921  for(struct_typet::componentst::const_iterator
922  it=to_struct.components().begin();
923  it != to_struct.components().end();
924  it++)
925  {
926  const irept &component=*it;
927 
928  if(component.get_bool(ID_from_base))
929  continue;
930 
931  if(component.get_bool("is_explicit"))
932  continue;
933 
934  const typet &comp_type =
935  static_cast<const typet&>(component.find(ID_type));
936 
937  if(comp_type.id() !=ID_code)
938  continue;
939 
940  if(comp_type.find(ID_return_type).id() !=ID_constructor)
941  continue;
942 
943  // TODO: ellipsis
944 
945  const irept &parameters=comp_type.find(ID_parameters);
946 
947  if(parameters.get_sub().size() != 2)
948  continue;
949 
950  exprt curr_arg1=static_cast<const exprt&> (parameters.get_sub()[1]);
951  typet arg1_type=curr_arg1.type();
952 
953  if(is_reference(arg1_type))
954  {
955  typet tmp=arg1_type.subtype();
956  arg1_type.swap(tmp);
957  }
958 
959  struct_typet arg1_struct;
960  arg1_struct.make_nil();
961  {
962  typet tmp=follow(arg1_type);
963  if(tmp.id()==ID_struct)
964  arg1_struct=to_struct_type(tmp);
965  }
966 
967  unsigned tmp_rank=0;
968  if(arg1_struct.is_nil())
969  {
970  exprt tmp_expr;
972  expr, arg1_type, tmp_expr, tmp_rank))
973  {
974  // check if it's ambiguous
975  if(found)
976  return false;
977  found=true;
978 
979  if(expr.get_bool(ID_C_lvalue))
980  tmp_expr.set(ID_C_lvalue, true);
981 
982  tmp_expr.add_source_location()=expr.source_location();
983 
984  exprt func_symb=cpp_symbol_expr(lookup(component.get(ID_name)));
985  func_symb.type()=comp_type;
986  {
987  exprt tmp("already_typechecked");
988  tmp.copy_to_operands(func_symb);
989  func_symb.swap(func_symb);
990  }
991 
992  // create temporary object
994  ctor_expr.add_source_location()=expr.source_location();
995  ctor_expr.function().swap(func_symb);
996  ctor_expr.arguments().push_back(tmp_expr);
998 
999  new_expr.swap(ctor_expr);
1000  assert(new_expr.get(ID_statement)==ID_temporary_object);
1001 
1002  if(to.get_bool(ID_C_constant))
1003  new_expr.type().set(ID_C_constant, true);
1004 
1005  rank += tmp_rank;
1006  }
1007  }
1008  else if(from_struct.is_not_nil() && arg1_struct.is_not_nil())
1009  {
1010  // try derived-to-base conversion
1011  address_of_exprt expr_pfrom(expr, pointer_type(expr.type()));
1012  pointer_typet pto=pointer_type(arg1_type);
1013 
1014  exprt expr_ptmp;
1015  tmp_rank=0;
1017  expr_pfrom, pto, expr_ptmp, tmp_rank))
1018  {
1019  // check if it's ambiguous
1020  if(found)
1021  return false;
1022  found=true;
1023 
1024  rank+=tmp_rank;
1025 
1026  // create temporary object
1027  exprt expr_deref=
1028  exprt(ID_dereference, expr_ptmp.type().subtype());
1029  expr_deref.set(ID_C_lvalue, true);
1030  expr_deref.copy_to_operands(expr_ptmp);
1031  expr_deref.add_source_location()=expr.source_location();
1032 
1033  exprt new_object("new_object", type);
1034  new_object.set(ID_C_lvalue, true);
1035  new_object.type().set(ID_C_constant, false);
1036 
1037  exprt func_symb=cpp_symbol_expr(lookup(component.get(ID_name)));
1038  func_symb.type()=comp_type;
1039  {
1040  exprt tmp("already_typechecked");
1041  tmp.copy_to_operands(func_symb);
1042  func_symb.swap(func_symb);
1043  }
1044 
1046  ctor_expr.add_source_location()=expr.source_location();
1047  ctor_expr.function().swap(func_symb);
1048  ctor_expr.arguments().push_back(expr_deref);
1050 
1051  new_expr.swap(ctor_expr);
1052 
1053  INVARIANT(
1054  new_expr.get(ID_statement)==ID_temporary_object,
1055  "statement ID");
1056 
1057  if(to.get_bool(ID_C_constant))
1058  new_expr.type().set(ID_C_constant, true);
1059  }
1060  }
1061  }
1062  if(found)
1063  return true;
1064  }
1065  }
1066 
1067  // conversion operators
1068  if(from.id()==ID_struct)
1069  {
1070  struct_typet from_struct=to_struct_type(from);
1071 
1072  bool found=false;
1073  for(struct_typet::componentst::const_iterator
1074  it=from_struct.components().begin();
1075  it != from_struct.components().end(); it++)
1076  {
1077  const irept &component=*it;
1078  const typet comp_type=static_cast<const typet&>(component.find(ID_type));
1079 
1080  if(component.get_bool(ID_from_base))
1081  continue;
1082 
1083  if(!component.get_bool("is_cast_operator"))
1084  continue;
1085 
1086  assert(component.get(ID_type)==ID_code &&
1087  component.find(ID_type).find(ID_parameters).get_sub().size()==1);
1088 
1089  typet this_type =
1090  static_cast<const typet&>(comp_type.find(ID_parameters)
1091  .get_sub()
1092  .front()
1093  .find(ID_type));
1094  this_type.set(ID_C_reference, true);
1095 
1096  exprt this_expr(expr);
1097  this_type.set(ID_C_this, true);
1098 
1099  unsigned tmp_rank=0;
1100  exprt tmp_expr;
1101 
1103  this_expr, this_type, tmp_expr, tmp_rank))
1104  {
1105  // To take care of the possible virtual case,
1106  // we build the function as a member expression.
1107  irept func_name(ID_name);
1108  func_name.set(ID_identifier, component.get(ID_base_name));
1109  cpp_namet cpp_func_name;
1110  cpp_func_name.get_sub().push_back(func_name);
1111 
1112  exprt member_func(ID_member);
1113  member_func.add(ID_component_cpp_name)=cpp_func_name;
1114  exprt ac("already_typechecked");
1115  ac.copy_to_operands(expr);
1116  member_func.copy_to_operands(ac);
1117 
1119  func_expr.add_source_location()=expr.source_location();
1120  func_expr.function().swap(member_func);
1122 
1123  exprt tmp_expr;
1124  if(standard_conversion_sequence(func_expr, type, tmp_expr, tmp_rank))
1125  {
1126  // check if it's ambiguous
1127  if(found)
1128  return false;
1129  found=true;
1130 
1131  rank+=tmp_rank;
1132  new_expr.swap(tmp_expr);
1133  }
1134  }
1135  }
1136  if(found)
1137  return true;
1138  }
1139 
1140  return new_expr.is_not_nil();
1141 }
1142 
1148  const exprt &expr,
1149  const typet &type) const
1150 {
1151  assert(is_reference(type));
1152  assert(!is_reference(expr.type()));
1153 
1154  typet from=follow(expr.type());
1155  typet to=follow(type.subtype());
1156 
1157  // need to check #c_type
1158  if(from.get(ID_C_c_type)!=to.get(ID_C_c_type))
1159  return false;
1160 
1161  if(from==to)
1162  return true;
1163 
1164  if(from.id()==ID_struct &&
1165  to.id()==ID_struct)
1166  return subtype_typecast(to_struct_type(from),
1167  to_struct_type(to));
1168 
1169  if(from.id()==ID_struct &&
1170  type.get_bool(ID_C_this) &&
1171  type.subtype().id()==ID_empty)
1172  {
1173  // virtual-call case
1174  return true;
1175  }
1176 
1177  return false;
1178 }
1179 
1185  const exprt &expr,
1186  const typet &type,
1187  unsigned &rank) const
1188 {
1189  assert(is_reference(type));
1190  assert(!is_reference(expr.type()));
1191 
1192  if(!reference_related(expr, type))
1193  return false;
1194 
1195  if(expr.type()!=type.subtype())
1196  rank+=3;
1197 
1198  c_qualifierst qual_from;
1199  qual_from.read(expr.type());
1200 
1201  c_qualifierst qual_to;
1202  qual_to.read(type.subtype());
1203 
1204  if(qual_from!=qual_to)
1205  rank+=1;
1206 
1207  if(qual_from.is_subset_of(qual_to))
1208  return true;
1209 
1210  return false;
1211 }
1212 
1248  exprt expr,
1249  const typet &type,
1250  exprt &new_expr,
1251  unsigned &rank)
1252 {
1253  assert(is_reference(type));
1254  assert(!is_reference(expr.type()));
1255 
1256  unsigned backup_rank=rank;
1257 
1258  if(type.get_bool(ID_C_this) &&
1259  !expr.get_bool(ID_C_lvalue))
1260  {
1261  // `this' has to be an lvalue
1262  if(expr.get(ID_statement)==ID_temporary_object)
1263  expr.set(ID_C_lvalue, true);
1264  else if(expr.get(ID_statement)==ID_function_call)
1265  expr.set(ID_C_lvalue, true);
1266  else if(expr.get_bool("#temporary_avoided"))
1267  {
1268  expr.remove("#temporary_avoided");
1269  exprt temporary;
1270  new_temporary(expr.source_location(), expr.type(), expr, temporary);
1271  expr.swap(temporary);
1272  expr.set(ID_C_lvalue, true);
1273  }
1274  else
1275  return false;
1276  }
1277 
1278  if(expr.get_bool(ID_C_lvalue))
1279  {
1280  if(reference_compatible(expr, type, rank))
1281  {
1282  {
1283  address_of_exprt tmp;
1284  tmp.add_source_location()=expr.source_location();
1285  tmp.object()=expr;
1286  tmp.type()=pointer_type(tmp.op0().type());
1287  tmp.type().set(ID_C_reference, true);
1288  new_expr.swap(tmp);
1289  }
1290 
1291  if(expr.type()!=type.subtype())
1292  {
1293  c_qualifierst qual_from;
1294  qual_from.read(expr.type());
1295  new_expr.make_typecast(type);
1296  qual_from.write(new_expr.type().subtype());
1297  }
1298 
1299  return true;
1300  }
1301 
1302  rank=backup_rank;
1303  }
1304 
1305  // conversion operators
1306  typet from_type=follow(expr.type());
1307  if(from_type.id()==ID_struct)
1308  {
1309  struct_typet from_struct=to_struct_type(from_type);
1310 
1311  for(struct_typet::componentst::const_iterator
1312  it=from_struct.components().begin();
1313  it != from_struct.components().end(); it++)
1314  {
1315  const irept &component=*it;
1316 
1317  if(component.get_bool(ID_from_base))
1318  continue;
1319 
1320  if(!component.get_bool("is_cast_operator"))
1321  continue;
1322 
1323  const code_typet &component_type =
1324  to_code_type(static_cast<const typet&>(component.find(ID_type)));
1325 
1326  // otherwise it cannot bind directly (not an lvalue)
1327  if(!is_reference(component_type.return_type()))
1328  continue;
1329 
1330  assert(component_type.parameters().size()==1);
1331 
1332  typet this_type =
1333  component_type.parameters().front().type();
1334  this_type.set(ID_C_reference, true);
1335 
1336  exprt this_expr(expr);
1337 
1338  this_type.set(ID_C_this, true);
1339 
1340  unsigned tmp_rank=0;
1341 
1342  exprt tmp_expr;
1344  this_expr, this_type, tmp_expr, tmp_rank))
1345  {
1346  // To take care of the possible virtual case,
1347  // we build the function as a member expression.
1348  irept func_name(ID_name);
1349  func_name.set(ID_identifier, component.get(ID_base_name));
1350  cpp_namet cpp_func_name;
1351  cpp_func_name.get_sub().push_back(func_name);
1352 
1353  exprt member_func(ID_member);
1354  member_func.add(ID_component_cpp_name)=cpp_func_name;
1355  exprt ac("already_typechecked");
1356  ac.copy_to_operands(expr);
1357  member_func.copy_to_operands(ac);
1358 
1360  func_expr.add_source_location()=expr.source_location();
1361  func_expr.function().swap(member_func);
1363 
1364  // let's check if the returned value binds directly
1365  exprt returned_value=func_expr;
1366  add_implicit_dereference(returned_value);
1367 
1368  if(returned_value.get_bool(ID_C_lvalue) &&
1369  reference_compatible(returned_value, type, rank))
1370  {
1371  // returned values are lvalues in case of references only
1372  assert(returned_value.id()==ID_dereference &&
1373  is_reference(returned_value.op0().type()));
1374 
1375  new_expr=returned_value.op0();
1376 
1377  if(returned_value.type() != type.subtype())
1378  {
1379  c_qualifierst qual_from;
1380  qual_from.read(returned_value.type());
1381  make_ptr_typecast(new_expr, type);
1382  qual_from.write(new_expr.type().subtype());
1383  }
1384  rank+=4+tmp_rank;
1385  return true;
1386  }
1387  }
1388  }
1389  }
1390 
1391  // No temporary allowed for `this'
1392  if(type.get_bool(ID_C_this))
1393  return false;
1394 
1395  if(!type.subtype().get_bool(ID_C_constant) ||
1396  type.subtype().get_bool(ID_C_volatile))
1397  return false;
1398 
1399  // TODO: handle the case for implicit parameters
1400  if(!type.subtype().get_bool(ID_C_constant) &&
1401  !expr.get_bool(ID_C_lvalue))
1402  return false;
1403 
1404  exprt arg_expr=expr;
1405 
1406  if(follow(arg_expr.type()).id()==ID_struct)
1407  {
1408  // required to initialize the temporary
1409  arg_expr.set(ID_C_lvalue, true);
1410  }
1411 
1412  if(user_defined_conversion_sequence(arg_expr, type.subtype(), new_expr, rank))
1413  {
1414  address_of_exprt tmp;
1415  tmp.type()=pointer_type(new_expr.type());
1416  tmp.object()=new_expr;
1417  tmp.type().set(ID_C_reference, true);
1418  tmp.add_source_location()=new_expr.source_location();
1419  new_expr.swap(tmp);
1420  return true;
1421  }
1422 
1423  rank=backup_rank;
1424  if(standard_conversion_sequence(expr, type.subtype(), new_expr, rank))
1425  {
1426  {
1427  // create temporary object
1428  exprt tmp=exprt(ID_side_effect, type.subtype());
1429  tmp.set(ID_statement, ID_temporary_object);
1430  tmp.add_source_location()=expr.source_location();
1431  // tmp.set(ID_C_lvalue, true);
1432  tmp.move_to_operands(new_expr);
1433  new_expr.swap(tmp);
1434  }
1435 
1436  address_of_exprt tmp(new_expr, pointer_type(new_expr.type()));
1437  tmp.type().set(ID_C_reference, true);
1438  tmp.add_source_location()=new_expr.source_location();
1439 
1440  new_expr=tmp;
1441  return true;
1442  }
1443 
1444  return false;
1445 }
1446 
1454  const exprt &expr,
1455  const typet &type,
1456  exprt &new_expr,
1457  unsigned &rank)
1458 {
1459  unsigned backup_rank=rank;
1460 
1461  exprt e=expr;
1463 
1464  if(is_reference(type))
1465  {
1466  if(!reference_binding(e, type, new_expr, rank))
1467  return false;
1468 
1469  #if 0
1470  simplify_exprt simplify(*this);
1471  simplify.simplify(new_expr);
1472  new_expr.type().set(ID_C_reference, true);
1473  #endif
1474  }
1475  else if(!standard_conversion_sequence(e, type, new_expr, rank))
1476  {
1477  rank=backup_rank;
1478  if(!user_defined_conversion_sequence(e, type, new_expr, rank))
1479  return false;
1480 
1481  #if 0
1482  simplify_exprt simplify(*this);
1483  simplify.simplify(new_expr);
1484  #endif
1485  }
1486 
1487  return true;
1488 }
1489 
1496  const exprt &expr,
1497  const typet &type,
1498  exprt &new_expr)
1499 {
1500  unsigned rank=0;
1501  return implicit_conversion_sequence(expr, type, new_expr, rank);
1502 }
1503 
1510  const exprt &expr,
1511  const typet &type,
1512  unsigned &rank)
1513 {
1514  exprt new_expr;
1515  return implicit_conversion_sequence(expr, type, new_expr, rank);
1516 }
1517 
1519 {
1520  exprt e=expr;
1521 
1522  if(!implicit_conversion_sequence(e, type, expr))
1523  {
1526  error() << "invalid implicit conversion from `"
1527  << to_string(e.type()) << "' to `"
1528  << to_string(type) << "'" << eom;
1529  #if 0
1530  str << "\n " << follow(e.type()).pretty() << '\n';
1531  str << "\n " << type.pretty() << '\n';
1532  #endif
1533  throw 0;
1534  }
1535 }
1536 
1580  exprt &expr,
1581  const typet &type)
1582 {
1583  assert(is_reference(type));
1585 
1586  unsigned rank=0;
1587  exprt new_expr;
1588  if(reference_binding(expr, type, new_expr, rank))
1589  {
1590  expr.swap(new_expr);
1591  return;
1592  }
1593 
1595  error() << "bad reference initializer" << eom;
1596  throw 0;
1597 }
1598 
1600  const typet &t1,
1601  const typet &t2) const
1602 {
1603  assert(t1.id()==ID_pointer && t2.id()==ID_pointer);
1604  typet nt1=t1;
1605  typet nt2=t2;
1606 
1607  if(is_reference(nt1))
1608  nt1.remove(ID_C_reference);
1609 
1610  if(is_reference(nt2))
1611  nt2.remove(ID_C_reference);
1612 
1613  // substitute final subtypes
1614  std::vector<typet> snt1;
1615  snt1.push_back(nt1);
1616 
1617  while(snt1.back().has_subtype())
1618  {
1619  snt1.reserve(snt1.size()+1);
1620  snt1.push_back(snt1.back().subtype());
1621  }
1622 
1623  c_qualifierst q1;
1624  q1.read(snt1.back());
1625 
1626  bool_typet newnt1;
1627  q1.write(newnt1);
1628  snt1.back()=newnt1;
1629 
1630  std::vector<typet> snt2;
1631  snt2.push_back(nt2);
1632  while(snt2.back().has_subtype())
1633  {
1634  snt2.reserve(snt2.size()+1);
1635  snt2.push_back(snt2.back().subtype());
1636  }
1637 
1638  c_qualifierst q2;
1639  q2.read(snt2.back());
1640 
1641  bool_typet newnt2;
1642  q2.write(newnt2);
1643  snt2.back()=newnt2;
1644 
1645  const std::size_t k=snt1.size() < snt2.size() ? snt1.size() : snt2.size();
1646 
1647  for(std::size_t i=k; i > 1; i--)
1648  {
1649  snt1[snt1.size()-2].subtype()=snt1[snt1.size()-1];
1650  snt1.pop_back();
1651 
1652  snt2[snt2.size()-2].subtype()=snt2[snt2.size()-1];
1653  snt2.pop_back();
1654  }
1655 
1656  exprt e1("Dummy", snt1.back());
1657  exprt e2;
1658 
1659  return !standard_conversion_qualification(e1, snt2.back(), e2);
1660 }
1661 
1663  const exprt &expr,
1664  const typet &type,
1665  exprt &new_expr)
1666 {
1667  assert(is_reference(expr.type())==false);
1668 
1669  exprt curr_expr=expr;
1670 
1671  if(curr_expr.type().id()==ID_array)
1672  {
1673  if(type.id()==ID_pointer)
1674  {
1675  if(!standard_conversion_array_to_pointer(curr_expr, new_expr))
1676  return false;
1677  }
1678  }
1679  else if(curr_expr.type().id()==ID_code &&
1680  type.id()==ID_pointer)
1681  {
1682  if(!standard_conversion_function_to_pointer(curr_expr, new_expr))
1683  return false;
1684  }
1685  else if(curr_expr.get_bool(ID_C_lvalue))
1686  {
1687  if(!standard_conversion_lvalue_to_rvalue(curr_expr, new_expr))
1688  return false;
1689  }
1690  else
1691  new_expr=curr_expr;
1692 
1693  if(is_reference(type))
1694  {
1695  if(!expr.get_bool(ID_C_lvalue))
1696  return false;
1697 
1698  if(new_expr.type()!=type.subtype())
1699  return false;
1700 
1701  exprt address_of=address_of_exprt(expr, to_pointer_type(type));
1702  add_implicit_dereference(address_of);
1703  new_expr=address_of;
1704  return true;
1705  }
1706  else if(type.id()==ID_pointer)
1707  {
1708  if(type!=new_expr.type())
1709  return false;
1710 
1711  // add proper typecast
1712  typecast_exprt typecast_expr(expr, type);
1713  new_expr.swap(typecast_expr);
1714  return true;
1715  }
1716 
1717  return false;
1718 }
1719 
1721  const exprt &expr,
1722  const typet &type,
1723  exprt &new_expr)
1724 {
1725  exprt e(expr);
1726 
1727  if(type.id()==ID_pointer)
1728  {
1729  if(e.id()==ID_dereference && e.get_bool(ID_C_implicit))
1730  e=expr.op0();
1731 
1732  if(e.type().id()==ID_pointer &&
1733  cast_away_constness(e.type(), type))
1734  return false;
1735  }
1736 
1738 
1739  if(is_reference(type))
1740  {
1741  if(follow(type.subtype()).id() != ID_struct)
1742  return false;
1743  }
1744  else if(type.id()==ID_pointer)
1745  {
1746  if(type.find("to-member").is_not_nil())
1747  return false;
1748 
1749  if(type.subtype().id()==ID_empty)
1750  {
1751  if(!e.get_bool(ID_C_lvalue))
1752  return false;
1753  assert(0); // currently not supported
1754  }
1755  else if(follow(type.subtype()).id()==ID_struct)
1756  {
1757  if(e.get_bool(ID_C_lvalue))
1758  {
1759  exprt tmp(e);
1760 
1762  return false;
1763  }
1764  }
1765  else return false;
1766  }
1767  else return false;
1768 
1769  return static_typecast(e, type, new_expr);
1770 }
1771 
1773  const exprt &expr,
1774  const typet &type,
1775  exprt &new_expr,
1776  bool check_constantness)
1777 {
1778  exprt e=expr;
1779 
1780  if(check_constantness && type.id()==ID_pointer)
1781  {
1782  if(e.id()==ID_dereference && e.get_bool(ID_C_implicit))
1783  e=expr.op0();
1784 
1785  if(e.type().id()==ID_pointer &&
1786  cast_away_constness(e.type(), type))
1787  return false;
1788  }
1789 
1791 
1792  if(!is_reference(type))
1793  {
1794  exprt tmp;
1795 
1796  if(e.id()==ID_code)
1797  {
1799  e.swap(tmp);
1800  else
1801  return false;
1802  }
1803 
1804  if(e.type().id()==ID_array)
1805  {
1807  e.swap(tmp);
1808  else
1809  return false;
1810  }
1811 
1812  if(e.get_bool(ID_C_lvalue))
1813  {
1815  e.swap(tmp);
1816  else
1817  return false;
1818  }
1819  }
1820 
1821  if(e.type().id()==ID_pointer &&
1822  (type.id()==ID_unsignedbv || type.id()==ID_signedbv))
1823  {
1824  // pointer to integer, always ok
1825  new_expr=e;
1826  new_expr.make_typecast(type);
1827  return true;
1828  }
1829 
1830  if((e.type().id()==ID_unsignedbv ||
1831  e.type().id()==ID_signedbv ||
1832  e.type().id()==ID_bool) &&
1833  type.id()==ID_pointer &&
1834  !is_reference(type))
1835  {
1836  // integer to pointer
1837  if(simplify_expr(e, *this).is_zero())
1838  {
1839  // NULL
1840  new_expr=e;
1841  new_expr.set(ID_value, ID_NULL);
1842  new_expr.type()=type;
1843  }
1844  else
1845  {
1846  new_expr=e;
1847  new_expr.make_typecast(type);
1848  }
1849  return true;
1850  }
1851 
1852  if(e.type().id()==ID_pointer &&
1853  type.id()==ID_pointer &&
1854  !is_reference(type))
1855  {
1856  // pointer to pointer: we ok it all.
1857  // This is more generous than the standard.
1858  new_expr=expr;
1859  new_expr.make_typecast(type);
1860  return true;
1861  }
1862 
1863  if(is_reference(type) && e.get_bool(ID_C_lvalue))
1864  {
1865  exprt tmp=address_of_exprt(e);
1866  tmp.make_typecast(type);
1867  new_expr.swap(tmp);
1868  return true;
1869  }
1870 
1871  return false;
1872 }
1873 
1875  const exprt &expr, // source expression
1876  const typet &type, // destination type
1877  exprt &new_expr,
1878  bool check_constantness)
1879 {
1880  exprt e=expr;
1881 
1882  if(check_constantness && type.id()==ID_pointer)
1883  {
1884  if(e.id()==ID_dereference && e.get_bool(ID_C_implicit))
1885  e=expr.op0();
1886 
1887  if(e.type().id()==ID_pointer &&
1888  cast_away_constness(e.type(), type))
1889  return false;
1890  }
1891 
1893 
1894  if(type.get_bool(ID_C_reference))
1895  {
1896  unsigned rank=0;
1897  if(reference_binding(e, type, new_expr, rank))
1898  return true;
1899 
1900  typet subto=follow(type.subtype());
1901  typet from=follow(e.type());
1902 
1903  if(subto.id()==ID_struct && from.id()==ID_struct)
1904  {
1905  if(!expr.get_bool(ID_C_lvalue))
1906  return false;
1907 
1908  c_qualifierst qual_from;
1909  qual_from.read(e.type());
1910 
1911  c_qualifierst qual_to;
1912  qual_to.read(type.subtype());
1913 
1914  if(!qual_to.is_subset_of(qual_from))
1915  return false;
1916 
1917  struct_typet from_struct=to_struct_type(from);
1918  struct_typet subto_struct=to_struct_type(subto);
1919 
1920  if(subtype_typecast(subto_struct, from_struct))
1921  {
1922  if(e.id()==ID_dereference)
1923  {
1924  make_ptr_typecast(e.op0(), type);
1925  new_expr.swap(e.op0());
1926  return true;
1927  }
1928 
1929  exprt address_of=address_of_exprt(e);
1930  make_ptr_typecast(address_of, type);
1931  new_expr.swap(address_of);
1932  return true;
1933  }
1934  }
1935  return false;
1936  }
1937 
1938  if(type.id()==ID_empty)
1939  {
1940  new_expr=e;
1941  new_expr.make_typecast(type);
1942  return true;
1943  }
1944 
1945  // int/enum to enum
1946  if(type.id()==ID_c_enum_tag &&
1947  (e.type().id()==ID_signedbv ||
1948  e.type().id()==ID_unsignedbv ||
1949  e.type().id()==ID_c_enum_tag))
1950  {
1951  new_expr=e;
1952  new_expr.make_typecast(type);
1953  new_expr.remove(ID_C_lvalue);
1954  return true;
1955  }
1956 
1957  if(implicit_conversion_sequence(e, type, new_expr))
1958  {
1959  if(!cpp_is_pod(type))
1960  {
1961  exprt tc(ID_already_typechecked);
1962  tc.copy_to_operands(new_expr);
1963  exprt temporary;
1964  new_temporary(e.source_location(), type, tc, temporary);
1965  new_expr.swap(temporary);
1966  }
1967  else
1968  {
1969  // try to avoid temporary
1970  new_expr.set("#temporary_avoided", true);
1971  if(new_expr.get_bool(ID_C_lvalue))
1972  new_expr.remove(ID_C_lvalue);
1973  }
1974 
1975  return true;
1976  }
1977 
1978  if(type.id()==ID_pointer && e.type().id()==ID_pointer)
1979  {
1980  if(type.find("to-member").is_nil()
1981  && e.type().find("to-member").is_nil())
1982  {
1983  typet to=follow(type.subtype());
1984  typet from=follow(e.type().subtype());
1985 
1986  if(from.id()==ID_empty)
1987  {
1988  e.make_typecast(type);
1989  new_expr.swap(e);
1990  return true;
1991  }
1992 
1993  if(to.id()==ID_struct && from.id()==ID_struct)
1994  {
1995  if(e.get_bool(ID_C_lvalue))
1996  {
1997  exprt tmp(e);
1999  return false;
2000  }
2001 
2002  struct_typet from_struct=to_struct_type(from);
2003  struct_typet to_struct=to_struct_type(to);
2004  if(subtype_typecast(to_struct, from_struct))
2005  {
2006  make_ptr_typecast(e, type);
2007  new_expr.swap(e);
2008  return true;
2009  }
2010  }
2011 
2012  return false;
2013  }
2014  else if(type.find("to-member").is_not_nil() &&
2015  e.type().find("to-member").is_not_nil())
2016  {
2017  if(type.subtype()!=e.type().subtype())
2018  return false;
2019 
2020  struct_typet from_struct=
2022  follow(static_cast<const typet&>(e.type().find("to-member"))));
2023 
2024  struct_typet to_struct=
2026  follow(static_cast<const typet&>(type.find("to-member"))));
2027 
2028  if(subtype_typecast(from_struct, to_struct))
2029  {
2030  new_expr=e;
2031  new_expr.make_typecast(type);
2032  return true;
2033  }
2034  }
2035  else
2036  return false;
2037  }
2038 
2039  return false;
2040 }
The type of an expression.
Definition: type.h:20
const typet & follow(const typet &src) const
Definition: namespace.cpp:66
struct configt::ansi_ct ansi_c
void typecheck_side_effect_function_call(side_effect_expr_function_callt &expr)
semantic type conversion
Definition: std_expr.h:1725
virtual bool lookup(const irep_idt &name, const symbolt *&symbol) const
Definition: namespace.cpp:139
bool reference_binding(exprt expr, const typet &type, exprt &new_expr, unsigned &rank)
Reference binding.
Base type of functions.
Definition: std_types.h:734
bool is_nil() const
Definition: irep.h:103
bool is_not_nil() const
Definition: irep.h:104
pointer_typet pointer_type(const typet &subtype)
Definition: c_types.cpp:296
unsigned int_width
Definition: config.h:30
exprt & object()
Definition: std_expr.h:2608
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.
unsigned single_width
Definition: config.h:37
exprt & op0()
Definition: expr.h:84
std::string pretty(unsigned indent=0, unsigned max_indent=0) const
Definition: irep.cpp:641
exprt simplify_expr(const exprt &src, const namespacet &ns)
void add_implicit_dereference(exprt &expr)
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.
void copy_to_operands(const exprt &expr)
Definition: expr.cpp:61
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)
Definition: expr.cpp:28
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:242
bitvector_typet double_type()
Definition: c_types.cpp:203
typet & type()
Definition: expr.h:60
virtual void implicit_typecast(exprt &expr, const typet &type)
The proper Booleans.
Definition: std_types.h:33
static mstreamt & eom(mstreamt &m)
Definition: message.h:193
Structure type.
Definition: std_types.h:296
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:240
bool cast_away_constness(const typet &t1, const typet &t2) const
configt config
Definition: config.cpp:21
bool standard_conversion_integral_promotion(const exprt &expr, exprt &new_expr) const
Integral-promotion conversion.
const floatbv_typet & to_floatbv_type(const typet &type)
Cast a generic typet to a floatbv_typet.
Definition: std_types.h:1286
#define INVARIANT(CONDITION, REASON)
Definition: invariant.h:202
subt & get_sub()
Definition: irep.h:245
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.
void read(const typet &src)
bool reference_related(const exprt &expr, const typet &type) const
Reference-related.
const irep_idt & id() const
Definition: irep.h:189
bitvector_typet float_type()
Definition: c_types.cpp:184
The pointer type.
Definition: std_types.h:1343
const source_locationt & find_source_location() const
Definition: expr.cpp:466
source_locationt source_location
Definition: message.h:175
bool cpp_is_pod(const typet &type) const
Definition: cpp_is_pod.cpp:14
bool reinterpret_typecast(const exprt &expr, const typet &type, exprt &new_expr, bool check_constantness=true)
void write(typet &src) const
API to expression classes.
bool is_reference(const typet &type)
TO_BE_DOCUMENTED.
Definition: std_types.cpp:105
const irep_idt & get(const irep_namet &name) const
Definition: irep.cpp:213
Base class for tree-like data structures with sharing.
Definition: irep.h:87
bool standard_conversion_pointer_to_member(const exprt &expr, const typet &type, exprt &new_expr)
Pointer-to-member conversion.
C++ Language Type Checking.
bitvector_typet index_type()
Definition: c_types.cpp:15
const unsignedbv_typet & to_unsignedbv_type(const typet &type)
Cast a generic typet to an unsignedbv_typet.
Definition: std_types.h:1154
Operator to return the address of an object.
Definition: std_expr.h:2593
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 struct_typet & to_struct_type(const typet &type)
Cast a generic typet to a struct_typet.
Definition: std_types.h:317
A function call side effect.
Definition: std_code.h:1052
bool const_typecast(const exprt &expr, const typet &type, exprt &new_expr)
const pointer_typet & to_pointer_type(const typet &type)
Cast a generic typet to a pointer_typet.
Definition: std_types.h:1377
API to type classes.
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.
bool is_subset_of(const c_qualifierst &q) const
Definition: c_qualifiers.h:59
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:46
const parameterst & parameters() const
Definition: std_types.h:841
const signedbv_typet & to_signedbv_type(const typet &type)
Cast a generic typet to a signedbv_typet.
Definition: std_types.h:1200
const source_locationt & source_location() const
Definition: expr.h:142
irept & add(const irep_namet &name)
Definition: irep.cpp:306
virtual std::string to_string(const typet &type)
exprt::operandst & arguments()
Definition: std_code.h:1071
const code_typet & to_code_type(const typet &type)
Cast a generic typet to a code_typet.
Definition: std_types.h:884
void make_nil()
Definition: irep.h:243
void swap(irept &irep)
Definition: irep.h:231
virtual bool simplify(exprt &expr)
mstreamt & error()
Definition: message.h:223
bool is_zero() const
Definition: expr.cpp:236
source_locationt & add_source_location()
Definition: expr.h:147
bool standard_conversion_array_to_pointer(const exprt &expr, exprt &new_expr) const
Array-to-pointer conversion.
bool standard_conversion_pointer(const exprt &expr, const typet &type, exprt &new_expr)
Pointer conversion.
signedbv_typet signed_int_type()
Definition: c_types.cpp:29
exprt cpp_symbol_expr(const symbolt &symbol)
Definition: cpp_util.cpp:14
void remove(const irep_namet &name)
Definition: irep.cpp:270
const typet & subtype() const
Definition: type.h:31
bool implicit_conversion_sequence(const exprt &expr, const typet &type, exprt &new_expr, unsigned &rank)
implicit conversion sequence
constant_exprt from_integer(const mp_integer &int_value, const typet &type)
void make_typecast(const typet &_type)
Definition: expr.cpp:90
const irept & find(const irep_namet &name) const
Definition: irep.cpp:285
const typet & return_type() const
Definition: std_types.h:831
void set(const irep_namet &name, const irep_idt &value)
Definition: irep.h:214
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:1170