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  const dereference_exprt deref(address);
894 
895  // create temporary object
896  side_effect_exprt tmp_object_expr(
897  ID_temporary_object, type, expr.source_location());
898  tmp_object_expr.copy_to_operands(deref);
899  tmp_object_expr.set(ID_C_lvalue, true);
900 
901  new_expr.swap(tmp_object_expr);
902  return true;
903  }
904  }
905  }
906  else
907  {
908  struct_typet from_struct;
909  from_struct.make_nil();
910 
911  if(from.id()==ID_struct)
912  from_struct=to_struct_type(from);
913 
914  struct_typet to_struct=to_struct_type(to);
915 
916  bool found=false;
917 
918  for(struct_typet::componentst::const_iterator
919  it=to_struct.components().begin();
920  it != to_struct.components().end();
921  it++)
922  {
923  const irept &component=*it;
924 
925  if(component.get_bool(ID_from_base))
926  continue;
927 
928  if(component.get_bool("is_explicit"))
929  continue;
930 
931  const typet &comp_type =
932  static_cast<const typet&>(component.find(ID_type));
933 
934  if(comp_type.id() !=ID_code)
935  continue;
936 
937  if(comp_type.find(ID_return_type).id() !=ID_constructor)
938  continue;
939 
940  // TODO: ellipsis
941 
942  const irept &parameters=comp_type.find(ID_parameters);
943 
944  if(parameters.get_sub().size() != 2)
945  continue;
946 
947  exprt curr_arg1=static_cast<const exprt&> (parameters.get_sub()[1]);
948  typet arg1_type=curr_arg1.type();
949 
950  if(is_reference(arg1_type))
951  {
952  typet tmp=arg1_type.subtype();
953  arg1_type.swap(tmp);
954  }
955 
956  struct_typet arg1_struct;
957  arg1_struct.make_nil();
958  {
959  typet tmp=follow(arg1_type);
960  if(tmp.id()==ID_struct)
961  arg1_struct=to_struct_type(tmp);
962  }
963 
964  unsigned tmp_rank=0;
965  if(arg1_struct.is_nil())
966  {
967  exprt tmp_expr;
969  expr, arg1_type, tmp_expr, tmp_rank))
970  {
971  // check if it's ambiguous
972  if(found)
973  return false;
974  found=true;
975 
976  if(expr.get_bool(ID_C_lvalue))
977  tmp_expr.set(ID_C_lvalue, true);
978 
979  tmp_expr.add_source_location()=expr.source_location();
980 
981  exprt func_symb=cpp_symbol_expr(lookup(component.get(ID_name)));
982  func_symb.type()=comp_type;
983  {
984  exprt tmp("already_typechecked");
985  tmp.copy_to_operands(func_symb);
986  func_symb.swap(func_symb);
987  }
988 
989  // create temporary object
991  ctor_expr.add_source_location()=expr.source_location();
992  ctor_expr.function().swap(func_symb);
993  ctor_expr.arguments().push_back(tmp_expr);
995 
996  new_expr.swap(ctor_expr);
997  assert(new_expr.get(ID_statement)==ID_temporary_object);
998 
999  if(to.get_bool(ID_C_constant))
1000  new_expr.type().set(ID_C_constant, true);
1001 
1002  rank += tmp_rank;
1003  }
1004  }
1005  else if(from_struct.is_not_nil() && arg1_struct.is_not_nil())
1006  {
1007  // try derived-to-base conversion
1008  address_of_exprt expr_pfrom(expr, pointer_type(expr.type()));
1009  pointer_typet pto=pointer_type(arg1_type);
1010 
1011  exprt expr_ptmp;
1012  tmp_rank=0;
1014  expr_pfrom, pto, expr_ptmp, tmp_rank))
1015  {
1016  // check if it's ambiguous
1017  if(found)
1018  return false;
1019  found=true;
1020 
1021  rank+=tmp_rank;
1022 
1023  // create temporary object
1024  dereference_exprt expr_deref(expr_ptmp);
1025  expr_deref.set(ID_C_lvalue, true);
1026  expr_deref.add_source_location()=expr.source_location();
1027 
1028  exprt new_object("new_object", type);
1029  new_object.set(ID_C_lvalue, true);
1030  new_object.type().set(ID_C_constant, false);
1031 
1032  exprt func_symb=cpp_symbol_expr(lookup(component.get(ID_name)));
1033  func_symb.type()=comp_type;
1034  {
1035  exprt tmp("already_typechecked");
1036  tmp.copy_to_operands(func_symb);
1037  func_symb.swap(func_symb);
1038  }
1039 
1041  ctor_expr.add_source_location()=expr.source_location();
1042  ctor_expr.function().swap(func_symb);
1043  ctor_expr.arguments().push_back(expr_deref);
1045 
1046  new_expr.swap(ctor_expr);
1047 
1048  INVARIANT(
1049  new_expr.get(ID_statement)==ID_temporary_object,
1050  "statement ID");
1051 
1052  if(to.get_bool(ID_C_constant))
1053  new_expr.type().set(ID_C_constant, true);
1054  }
1055  }
1056  }
1057  if(found)
1058  return true;
1059  }
1060  }
1061 
1062  // conversion operators
1063  if(from.id()==ID_struct)
1064  {
1065  struct_typet from_struct=to_struct_type(from);
1066 
1067  bool found=false;
1068  for(struct_typet::componentst::const_iterator
1069  it=from_struct.components().begin();
1070  it != from_struct.components().end(); it++)
1071  {
1072  const irept &component=*it;
1073  const typet comp_type=static_cast<const typet&>(component.find(ID_type));
1074 
1075  if(component.get_bool(ID_from_base))
1076  continue;
1077 
1078  if(!component.get_bool("is_cast_operator"))
1079  continue;
1080 
1081  assert(component.get(ID_type)==ID_code &&
1082  component.find(ID_type).find(ID_parameters).get_sub().size()==1);
1083 
1084  typet this_type =
1085  static_cast<const typet&>(comp_type.find(ID_parameters)
1086  .get_sub()
1087  .front()
1088  .find(ID_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  irept func_name(ID_name);
1103  func_name.set(ID_identifier, component.get(ID_base_name));
1104  cpp_namet cpp_func_name;
1105  cpp_func_name.get_sub().push_back(func_name);
1106 
1107  exprt member_func(ID_member);
1108  member_func.add(ID_component_cpp_name)=cpp_func_name;
1109  exprt ac("already_typechecked");
1110  ac.copy_to_operands(expr);
1111  member_func.copy_to_operands(ac);
1112 
1114  func_expr.add_source_location()=expr.source_location();
1115  func_expr.function().swap(member_func);
1117 
1118  exprt tmp_expr;
1119  if(standard_conversion_sequence(func_expr, type, tmp_expr, tmp_rank))
1120  {
1121  // check if it's ambiguous
1122  if(found)
1123  return false;
1124  found=true;
1125 
1126  rank+=tmp_rank;
1127  new_expr.swap(tmp_expr);
1128  }
1129  }
1130  }
1131  if(found)
1132  return true;
1133  }
1134 
1135  return new_expr.is_not_nil();
1136 }
1137 
1143  const exprt &expr,
1144  const typet &type) const
1145 {
1146  assert(is_reference(type));
1147  assert(!is_reference(expr.type()));
1148 
1149  typet from=follow(expr.type());
1150  typet to=follow(type.subtype());
1151 
1152  // need to check #c_type
1153  if(from.get(ID_C_c_type)!=to.get(ID_C_c_type))
1154  return false;
1155 
1156  if(from==to)
1157  return true;
1158 
1159  if(from.id()==ID_struct &&
1160  to.id()==ID_struct)
1161  return subtype_typecast(to_struct_type(from),
1162  to_struct_type(to));
1163 
1164  if(from.id()==ID_struct &&
1165  type.get_bool(ID_C_this) &&
1166  type.subtype().id()==ID_empty)
1167  {
1168  // virtual-call case
1169  return true;
1170  }
1171 
1172  return false;
1173 }
1174 
1180  const exprt &expr,
1181  const typet &type,
1182  unsigned &rank) const
1183 {
1184  assert(is_reference(type));
1185  assert(!is_reference(expr.type()));
1186 
1187  if(!reference_related(expr, type))
1188  return false;
1189 
1190  if(expr.type()!=type.subtype())
1191  rank+=3;
1192 
1193  c_qualifierst qual_from;
1194  qual_from.read(expr.type());
1195 
1196  c_qualifierst qual_to;
1197  qual_to.read(type.subtype());
1198 
1199  if(qual_from!=qual_to)
1200  rank+=1;
1201 
1202  if(qual_from.is_subset_of(qual_to))
1203  return true;
1204 
1205  return false;
1206 }
1207 
1243  exprt expr,
1244  const typet &type,
1245  exprt &new_expr,
1246  unsigned &rank)
1247 {
1248  assert(is_reference(type));
1249  assert(!is_reference(expr.type()));
1250 
1251  unsigned backup_rank=rank;
1252 
1253  if(type.get_bool(ID_C_this) &&
1254  !expr.get_bool(ID_C_lvalue))
1255  {
1256  // `this' has to be an lvalue
1257  if(expr.get(ID_statement)==ID_temporary_object)
1258  expr.set(ID_C_lvalue, true);
1259  else if(expr.get(ID_statement)==ID_function_call)
1260  expr.set(ID_C_lvalue, true);
1261  else if(expr.get_bool(ID_C_temporary_avoided))
1262  {
1263  expr.remove(ID_C_temporary_avoided);
1264  exprt temporary;
1265  new_temporary(expr.source_location(), expr.type(), expr, temporary);
1266  expr.swap(temporary);
1267  expr.set(ID_C_lvalue, true);
1268  }
1269  else
1270  return false;
1271  }
1272 
1273  if(expr.get_bool(ID_C_lvalue))
1274  {
1275  if(reference_compatible(expr, type, rank))
1276  {
1277  {
1278  address_of_exprt tmp(expr, reference_type(expr.type()));
1279  tmp.add_source_location()=expr.source_location();
1280  new_expr.swap(tmp);
1281  }
1282 
1283  if(expr.type()!=type.subtype())
1284  {
1285  c_qualifierst qual_from;
1286  qual_from.read(expr.type());
1287  new_expr.make_typecast(type);
1288  qual_from.write(new_expr.type().subtype());
1289  }
1290 
1291  return true;
1292  }
1293 
1294  rank=backup_rank;
1295  }
1296 
1297  // conversion operators
1298  typet from_type=follow(expr.type());
1299  if(from_type.id()==ID_struct)
1300  {
1301  struct_typet from_struct=to_struct_type(from_type);
1302 
1303  for(struct_typet::componentst::const_iterator
1304  it=from_struct.components().begin();
1305  it != from_struct.components().end(); it++)
1306  {
1307  const irept &component=*it;
1308 
1309  if(component.get_bool(ID_from_base))
1310  continue;
1311 
1312  if(!component.get_bool("is_cast_operator"))
1313  continue;
1314 
1315  const code_typet &component_type =
1316  to_code_type(static_cast<const typet&>(component.find(ID_type)));
1317 
1318  // otherwise it cannot bind directly (not an lvalue)
1319  if(!is_reference(component_type.return_type()))
1320  continue;
1321 
1322  assert(component_type.parameters().size()==1);
1323 
1324  typet this_type =
1325  component_type.parameters().front().type();
1326  this_type.set(ID_C_reference, true);
1327 
1328  exprt this_expr(expr);
1329 
1330  this_type.set(ID_C_this, true);
1331 
1332  unsigned tmp_rank=0;
1333 
1334  exprt tmp_expr;
1336  this_expr, this_type, tmp_expr, tmp_rank))
1337  {
1338  // To take care of the possible virtual case,
1339  // we build the function as a member expression.
1340  irept func_name(ID_name);
1341  func_name.set(ID_identifier, component.get(ID_base_name));
1342  cpp_namet cpp_func_name;
1343  cpp_func_name.get_sub().push_back(func_name);
1344 
1345  exprt member_func(ID_member);
1346  member_func.add(ID_component_cpp_name)=cpp_func_name;
1347  exprt ac("already_typechecked");
1348  ac.copy_to_operands(expr);
1349  member_func.copy_to_operands(ac);
1350 
1352  func_expr.add_source_location()=expr.source_location();
1353  func_expr.function().swap(member_func);
1355 
1356  // let's check if the returned value binds directly
1357  exprt returned_value=func_expr;
1358  add_implicit_dereference(returned_value);
1359 
1360  if(returned_value.get_bool(ID_C_lvalue) &&
1361  reference_compatible(returned_value, type, rank))
1362  {
1363  // returned values are lvalues in case of references only
1364  assert(returned_value.id()==ID_dereference &&
1365  is_reference(returned_value.op0().type()));
1366 
1367  new_expr=returned_value.op0();
1368 
1369  if(returned_value.type() != type.subtype())
1370  {
1371  c_qualifierst qual_from;
1372  qual_from.read(returned_value.type());
1373  make_ptr_typecast(new_expr, type);
1374  qual_from.write(new_expr.type().subtype());
1375  }
1376  rank+=4+tmp_rank;
1377  return true;
1378  }
1379  }
1380  }
1381  }
1382 
1383  // No temporary allowed for `this'
1384  if(type.get_bool(ID_C_this))
1385  return false;
1386 
1387  if(!type.subtype().get_bool(ID_C_constant) ||
1388  type.subtype().get_bool(ID_C_volatile))
1389  return false;
1390 
1391  // TODO: handle the case for implicit parameters
1392  if(!type.subtype().get_bool(ID_C_constant) &&
1393  !expr.get_bool(ID_C_lvalue))
1394  return false;
1395 
1396  exprt arg_expr=expr;
1397 
1398  if(follow(arg_expr.type()).id()==ID_struct)
1399  {
1400  // required to initialize the temporary
1401  arg_expr.set(ID_C_lvalue, true);
1402  }
1403 
1404  if(user_defined_conversion_sequence(arg_expr, type.subtype(), new_expr, rank))
1405  {
1406  address_of_exprt tmp(new_expr, reference_type(new_expr.type()));
1407  tmp.add_source_location()=new_expr.source_location();
1408  new_expr.swap(tmp);
1409  return true;
1410  }
1411 
1412  rank=backup_rank;
1413  if(standard_conversion_sequence(expr, type.subtype(), new_expr, rank))
1414  {
1415  {
1416  // create temporary object
1417  exprt tmp=exprt(ID_side_effect, type.subtype());
1418  tmp.set(ID_statement, ID_temporary_object);
1419  tmp.add_source_location()=expr.source_location();
1420  // tmp.set(ID_C_lvalue, true);
1421  tmp.move_to_operands(new_expr);
1422  new_expr.swap(tmp);
1423  }
1424 
1425  address_of_exprt tmp(new_expr, pointer_type(new_expr.type()));
1426  tmp.type().set(ID_C_reference, true);
1427  tmp.add_source_location()=new_expr.source_location();
1428 
1429  new_expr=tmp;
1430  return true;
1431  }
1432 
1433  return false;
1434 }
1435 
1443  const exprt &expr,
1444  const typet &type,
1445  exprt &new_expr,
1446  unsigned &rank)
1447 {
1448  unsigned backup_rank=rank;
1449 
1450  exprt e=expr;
1452 
1453  if(is_reference(type))
1454  {
1455  if(!reference_binding(e, type, new_expr, rank))
1456  return false;
1457 
1458  #if 0
1459  simplify_exprt simplify(*this);
1460  simplify.simplify(new_expr);
1461  new_expr.type().set(ID_C_reference, true);
1462  #endif
1463  }
1464  else if(!standard_conversion_sequence(e, type, new_expr, rank))
1465  {
1466  rank=backup_rank;
1467  if(!user_defined_conversion_sequence(e, type, new_expr, rank))
1468  return false;
1469 
1470  #if 0
1471  simplify_exprt simplify(*this);
1472  simplify.simplify(new_expr);
1473  #endif
1474  }
1475 
1476  return true;
1477 }
1478 
1485  const exprt &expr,
1486  const typet &type,
1487  exprt &new_expr)
1488 {
1489  unsigned rank=0;
1490  return implicit_conversion_sequence(expr, type, new_expr, rank);
1491 }
1492 
1499  const exprt &expr,
1500  const typet &type,
1501  unsigned &rank)
1502 {
1503  exprt new_expr;
1504  return implicit_conversion_sequence(expr, type, new_expr, rank);
1505 }
1506 
1508 {
1509  exprt e=expr;
1510 
1511  if(
1512  e.id() == ID_initializer_list && cpp_is_pod(type) &&
1513  e.operands().size() == 1)
1514  {
1515  e = expr.op0();
1516  }
1517 
1518  if(!implicit_conversion_sequence(e, type, expr))
1519  {
1522  error() << "invalid implicit conversion from `"
1523  << to_string(e.type()) << "' to `"
1524  << to_string(type) << "'" << eom;
1525  #if 0
1526  str << "\n " << follow(e.type()).pretty() << '\n';
1527  str << "\n " << type.pretty() << '\n';
1528  #endif
1529  throw 0;
1530  }
1531 }
1532 
1576  exprt &expr,
1577  const typet &type)
1578 {
1579  assert(is_reference(type));
1581 
1582  unsigned rank=0;
1583  exprt new_expr;
1584  if(reference_binding(expr, type, new_expr, rank))
1585  {
1586  expr.swap(new_expr);
1587  return;
1588  }
1589 
1591  error() << "bad reference initializer" << eom;
1592  throw 0;
1593 }
1594 
1596  const typet &t1,
1597  const typet &t2) const
1598 {
1599  assert(t1.id()==ID_pointer && t2.id()==ID_pointer);
1600  typet nt1=t1;
1601  typet nt2=t2;
1602 
1603  if(is_reference(nt1))
1604  nt1.remove(ID_C_reference);
1605  nt1.remove("to-member");
1606 
1607  if(is_reference(nt2))
1608  nt2.remove(ID_C_reference);
1609  nt2.remove("to-member");
1610 
1611  // substitute final subtypes
1612  std::vector<typet> snt1;
1613  snt1.push_back(nt1);
1614 
1615  while(snt1.back().has_subtype())
1616  {
1617  snt1.reserve(snt1.size()+1);
1618  snt1.push_back(snt1.back().subtype());
1619  }
1620 
1621  c_qualifierst q1;
1622  q1.read(snt1.back());
1623 
1624  bool_typet newnt1;
1625  q1.write(newnt1);
1626  snt1.back()=newnt1;
1627 
1628  std::vector<typet> snt2;
1629  snt2.push_back(nt2);
1630  while(snt2.back().has_subtype())
1631  {
1632  snt2.reserve(snt2.size()+1);
1633  snt2.push_back(snt2.back().subtype());
1634  }
1635 
1636  c_qualifierst q2;
1637  q2.read(snt2.back());
1638 
1639  bool_typet newnt2;
1640  q2.write(newnt2);
1641  snt2.back()=newnt2;
1642 
1643  const std::size_t k=snt1.size() < snt2.size() ? snt1.size() : snt2.size();
1644 
1645  for(std::size_t i=k; i > 1; i--)
1646  {
1647  snt1[snt1.size()-2].subtype()=snt1[snt1.size()-1];
1648  snt1.pop_back();
1649 
1650  snt2[snt2.size()-2].subtype()=snt2[snt2.size()-1];
1651  snt2.pop_back();
1652  }
1653 
1654  exprt e1("Dummy", snt1.back());
1655  exprt e2;
1656 
1657  return !standard_conversion_qualification(e1, snt2.back(), e2);
1658 }
1659 
1661  const exprt &expr,
1662  const typet &type,
1663  exprt &new_expr)
1664 {
1665  assert(is_reference(expr.type())==false);
1666 
1667  exprt curr_expr=expr;
1668 
1669  if(curr_expr.type().id()==ID_array)
1670  {
1671  if(type.id()==ID_pointer)
1672  {
1673  if(!standard_conversion_array_to_pointer(curr_expr, new_expr))
1674  return false;
1675  }
1676  }
1677  else if(curr_expr.type().id()==ID_code &&
1678  type.id()==ID_pointer)
1679  {
1680  if(!standard_conversion_function_to_pointer(curr_expr, new_expr))
1681  return false;
1682  }
1683  else if(curr_expr.get_bool(ID_C_lvalue))
1684  {
1685  if(!standard_conversion_lvalue_to_rvalue(curr_expr, new_expr))
1686  return false;
1687  }
1688  else
1689  new_expr=curr_expr;
1690 
1691  if(is_reference(type))
1692  {
1693  if(!expr.get_bool(ID_C_lvalue))
1694  return false;
1695 
1696  if(new_expr.type()!=type.subtype())
1697  return false;
1698 
1699  address_of_exprt address_of(expr, to_pointer_type(type));
1700  add_implicit_dereference(address_of);
1701  new_expr=address_of;
1702  return true;
1703  }
1704  else if(type.id()==ID_pointer)
1705  {
1706  if(type!=new_expr.type())
1707  return false;
1708 
1709  // add proper typecast
1710  typecast_exprt typecast_expr(expr, type);
1711  new_expr.swap(typecast_expr);
1712  return true;
1713  }
1714 
1715  return false;
1716 }
1717 
1719  const exprt &expr,
1720  const typet &type,
1721  exprt &new_expr)
1722 {
1723  exprt e(expr);
1724 
1725  if(type.id()==ID_pointer)
1726  {
1727  if(e.id()==ID_dereference && e.get_bool(ID_C_implicit))
1728  e=expr.op0();
1729 
1730  if(e.type().id()==ID_pointer &&
1731  cast_away_constness(e.type(), type))
1732  return false;
1733  }
1734 
1736 
1737  if(is_reference(type))
1738  {
1739  if(follow(type.subtype()).id() != ID_struct)
1740  return false;
1741  }
1742  else if(type.id()==ID_pointer)
1743  {
1744  if(type.find("to-member").is_not_nil())
1745  return false;
1746 
1747  if(type.subtype().id()==ID_empty)
1748  {
1749  if(!e.get_bool(ID_C_lvalue))
1750  return false;
1751  UNREACHABLE; // currently not supported
1752  }
1753  else if(follow(type.subtype()).id()==ID_struct)
1754  {
1755  if(e.get_bool(ID_C_lvalue))
1756  {
1757  exprt tmp(e);
1758 
1760  return false;
1761  }
1762  }
1763  else return false;
1764  }
1765  else return false;
1766 
1767  return static_typecast(e, type, new_expr);
1768 }
1769 
1771  const exprt &expr,
1772  const typet &type,
1773  exprt &new_expr,
1774  bool check_constantness)
1775 {
1776  exprt e=expr;
1777 
1778  if(check_constantness && type.id()==ID_pointer)
1779  {
1780  if(e.id()==ID_dereference && e.get_bool(ID_C_implicit))
1781  e=expr.op0();
1782 
1783  if(e.type().id()==ID_pointer &&
1784  cast_away_constness(e.type(), type))
1785  return false;
1786  }
1787 
1789 
1790  if(!is_reference(type))
1791  {
1792  exprt tmp;
1793 
1794  if(e.id()==ID_code)
1795  {
1797  e.swap(tmp);
1798  else
1799  return false;
1800  }
1801 
1802  if(e.type().id()==ID_array)
1803  {
1805  e.swap(tmp);
1806  else
1807  return false;
1808  }
1809 
1810  if(e.get_bool(ID_C_lvalue))
1811  {
1813  e.swap(tmp);
1814  else
1815  return false;
1816  }
1817  }
1818 
1819  if(e.type().id()==ID_pointer &&
1820  (type.id()==ID_unsignedbv || type.id()==ID_signedbv))
1821  {
1822  // pointer to integer, always ok
1823  new_expr=e;
1824  new_expr.make_typecast(type);
1825  return true;
1826  }
1827 
1828  if((e.type().id()==ID_unsignedbv ||
1829  e.type().id()==ID_signedbv ||
1830  e.type().id()==ID_bool) &&
1831  type.id()==ID_pointer &&
1832  !is_reference(type))
1833  {
1834  // integer to pointer
1835  if(simplify_expr(e, *this).is_zero())
1836  {
1837  // NULL
1838  new_expr=e;
1839  new_expr.set(ID_value, ID_NULL);
1840  new_expr.type()=type;
1841  }
1842  else
1843  {
1844  new_expr=e;
1845  new_expr.make_typecast(type);
1846  }
1847  return true;
1848  }
1849 
1850  if(e.type().id()==ID_pointer &&
1851  type.id()==ID_pointer &&
1852  !is_reference(type))
1853  {
1854  // pointer to pointer: we ok it all.
1855  // This is more generous than the standard.
1856  new_expr=expr;
1857  new_expr.make_typecast(type);
1858  return true;
1859  }
1860 
1861  if(is_reference(type) && e.get_bool(ID_C_lvalue))
1862  {
1863  exprt tmp=address_of_exprt(e);
1864  tmp.make_typecast(type);
1865  new_expr.swap(tmp);
1866  return true;
1867  }
1868 
1869  return false;
1870 }
1871 
1873  const exprt &expr, // source expression
1874  const typet &type, // destination type
1875  exprt &new_expr,
1876  bool check_constantness)
1877 {
1878  exprt e=expr;
1879 
1880  if(check_constantness && type.id()==ID_pointer)
1881  {
1882  if(e.id()==ID_dereference && e.get_bool(ID_C_implicit))
1883  e=expr.op0();
1884 
1885  if(e.type().id()==ID_pointer &&
1886  cast_away_constness(e.type(), type))
1887  return false;
1888  }
1889 
1891 
1892  if(type.get_bool(ID_C_reference))
1893  {
1894  unsigned rank=0;
1895  if(reference_binding(e, type, new_expr, rank))
1896  return true;
1897 
1898  typet subto=follow(type.subtype());
1899  typet from=follow(e.type());
1900 
1901  if(subto.id()==ID_struct && from.id()==ID_struct)
1902  {
1903  if(!expr.get_bool(ID_C_lvalue))
1904  return false;
1905 
1906  c_qualifierst qual_from;
1907  qual_from.read(e.type());
1908 
1909  c_qualifierst qual_to;
1910  qual_to.read(type.subtype());
1911 
1912  if(!qual_to.is_subset_of(qual_from))
1913  return false;
1914 
1915  struct_typet from_struct=to_struct_type(from);
1916  struct_typet subto_struct=to_struct_type(subto);
1917 
1918  if(subtype_typecast(subto_struct, from_struct))
1919  {
1920  if(e.id()==ID_dereference)
1921  {
1922  make_ptr_typecast(e.op0(), type);
1923  new_expr.swap(e.op0());
1924  return true;
1925  }
1926 
1927  exprt address_of=address_of_exprt(e);
1928  make_ptr_typecast(address_of, type);
1929  new_expr.swap(address_of);
1930  return true;
1931  }
1932  }
1933  return false;
1934  }
1935 
1936  if(type.id()==ID_empty)
1937  {
1938  new_expr=e;
1939  new_expr.make_typecast(type);
1940  return true;
1941  }
1942 
1943  // int/enum to enum
1944  if(type.id()==ID_c_enum_tag &&
1945  (e.type().id()==ID_signedbv ||
1946  e.type().id()==ID_unsignedbv ||
1947  e.type().id()==ID_c_enum_tag))
1948  {
1949  new_expr=e;
1950  new_expr.make_typecast(type);
1951  new_expr.remove(ID_C_lvalue);
1952  return true;
1953  }
1954 
1955  if(implicit_conversion_sequence(e, type, new_expr))
1956  {
1957  if(!cpp_is_pod(type))
1958  {
1959  exprt tc(ID_already_typechecked);
1960  tc.copy_to_operands(new_expr);
1961  exprt temporary;
1962  new_temporary(e.source_location(), type, tc, temporary);
1963  new_expr.swap(temporary);
1964  }
1965  else
1966  {
1967  // try to avoid temporary
1968  new_expr.set(ID_C_temporary_avoided, true);
1969  if(new_expr.get_bool(ID_C_lvalue))
1970  new_expr.remove(ID_C_lvalue);
1971  }
1972 
1973  return true;
1974  }
1975 
1976  if(type.id()==ID_pointer && e.type().id()==ID_pointer)
1977  {
1978  if(type.find("to-member").is_nil()
1979  && e.type().find("to-member").is_nil())
1980  {
1981  typet to=follow(type.subtype());
1982  typet from=follow(e.type().subtype());
1983 
1984  if(from.id()==ID_empty)
1985  {
1986  e.make_typecast(type);
1987  new_expr.swap(e);
1988  return true;
1989  }
1990 
1991  if(to.id()==ID_struct && from.id()==ID_struct)
1992  {
1993  if(e.get_bool(ID_C_lvalue))
1994  {
1995  exprt tmp(e);
1997  return false;
1998  }
1999 
2000  struct_typet from_struct=to_struct_type(from);
2001  struct_typet to_struct=to_struct_type(to);
2002  if(subtype_typecast(to_struct, from_struct))
2003  {
2004  make_ptr_typecast(e, type);
2005  new_expr.swap(e);
2006  return true;
2007  }
2008  }
2009 
2010  return false;
2011  }
2012  else if(type.find("to-member").is_not_nil() &&
2013  e.type().find("to-member").is_not_nil())
2014  {
2015  if(type.subtype()!=e.type().subtype())
2016  return false;
2017 
2018  struct_typet from_struct=
2020  follow(static_cast<const typet&>(e.type().find("to-member"))));
2021 
2022  struct_typet to_struct=
2024  follow(static_cast<const typet&>(type.find("to-member"))));
2025 
2026  if(subtype_typecast(from_struct, to_struct))
2027  {
2028  new_expr=e;
2029  new_expr.make_typecast(type);
2030  return true;
2031  }
2032  }
2033  else if(
2034  type.find("to-member").is_nil() &&
2035  e.type().find("to-member").is_not_nil())
2036  {
2037  if(type.subtype() != e.type().subtype())
2038  return false;
2039 
2040  struct_typet from_struct = to_struct_type(
2041  follow(static_cast<const typet &>(e.type().find("to-member"))));
2042 
2043  new_expr = e;
2044  new_expr.type().add("to-member") = from_struct;
2045 
2046  return true;
2047  }
2048  else
2049  return false;
2050  }
2051 
2052  return false;
2053 }
The type of an expression.
Definition: type.h:22
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:2111
bool reference_binding(exprt expr, const typet &type, exprt &new_expr, unsigned &rank)
Reference binding.
Base type of functions.
Definition: std_types.h:764
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 generic typet to a signedbv_typet.
Definition: std_types.h:1296
exprt & op0()
Definition: expr.h:72
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.
const code_typet & to_code_type(const typet &type)
Cast a generic typet to a code_typet.
Definition: std_types.h:993
std::size_t single_width
Definition: config.h:37
void copy_to_operands(const exprt &expr)
Definition: expr.cpp:55
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:22
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:245
bitvector_typet double_type()
Definition: c_types.cpp:193
typet & type()
Definition: expr.h:56
virtual void implicit_typecast(exprt &expr, const typet &type)
The proper Booleans.
Definition: std_types.h:34
static mstreamt & eom(mstreamt &m)
Definition: message.h:272
Structure type.
Definition: std_types.h:297
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:23
bool standard_conversion_integral_promotion(const exprt &expr, exprt &new_expr) const
Integral-promotion conversion.
#define INVARIANT(CONDITION, REASON)
Definition: invariant.h:204
subt & get_sub()
Definition: irep.h:317
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
bitvector_typet float_type()
Definition: c_types.cpp:185
reference_typet reference_type(const typet &subtype)
Definition: c_types.cpp:248
The pointer type.
Definition: std_types.h:1435
const source_locationt & find_source_location() const
Definition: expr.cpp:246
source_locationt source_location
Definition: message.h:214
bool cpp_is_pod(const typet &type) const
Definition: cpp_is_pod.cpp:14
Operator to dereference a pointer.
Definition: std_expr.h:3282
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)
TO_BE_DOCUMENTED.
Definition: std_types.cpp:105
const irep_idt & get(const irep_namet &name) const
Definition: irep.cpp:213
mstreamt & error() const
Definition: message.h:302
virtual void read(const typet &src) override
std::size_t int_width
Definition: config.h:30
Base class for tree-like data structures with sharing.
Definition: irep.h:156
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
Definition: namespace.cpp:55
bitvector_typet index_type()
Definition: c_types.cpp:16
const struct_typet & to_struct_type(const typet &type)
Cast a generic typet to a struct_typet.
Definition: std_types.h:318
Operator to return the address of an object.
Definition: std_expr.h:3168
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 generic typet to an unsignedbv_typet.
Definition: std_types.h:1254
A function call side effect.
Definition: std_code.h:1395
bool const_typecast(const exprt &expr, const typet &type, exprt &new_expr)
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.
const floatbv_typet & to_floatbv_type(const typet &type)
Cast a generic typet to a floatbv_typet.
Definition: std_types.h:1382
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:42
const parameterst & parameters() const
Definition: std_types.h:905
const source_locationt & source_location() const
Definition: expr.h:125
#define UNREACHABLE
Definition: invariant.h:271
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:1453
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
Definition: expr.cpp:161
source_locationt & add_source_location()
Definition: expr.h:130
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 generic typet to a pointer_typet.
Definition: std_types.h:1459
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
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:33
An expression containing a side effect.
Definition: std_code.h:1271
bool implicit_conversion_sequence(const exprt &expr, const typet &type, exprt &new_expr, unsigned &rank)
implicit conversion sequence
operandst & operands()
Definition: expr.h:66
constant_exprt from_integer(const mp_integer &int_value, const typet &type)
void make_typecast(const typet &_type)
Definition: expr.cpp:84
const irept & find(const irep_namet &name) const
Definition: irep.cpp:285
const typet & return_type() const
Definition: std_types.h:895
bool lookup(const irep_idt &name, const symbolt *&symbol) const override
See namespace_baset::lookup().
Definition: namespace.cpp:136
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:1462