CBMC
c_typecheck_type.cpp
Go to the documentation of this file.
1 /*******************************************************************\
2 
3 Module: C++ Language Type Checking
4 
5 Author: Daniel Kroening, kroening@kroening.com
6 
7 \*******************************************************************/
8 
11 
12 #include "c_typecheck_base.h"
13 
14 #include <unordered_set>
15 
17 
18 #include <util/arith_tools.h>
19 #include <util/c_types.h>
20 #include <util/config.h>
21 #include <util/fresh_symbol.h>
23 #include <util/pointer_expr.h>
25 #include <util/simplify_expr.h>
26 
27 #include "ansi_c_convert_type.h"
28 #include "ansi_c_declaration.h"
29 #include "c_qualifiers.h"
30 #include "gcc_types.h"
31 #include "padding.h"
32 #include "type2name.h"
33 #include "typedef_type.h"
34 
36 {
37  // we first convert, and then check
38  {
39  ansi_c_convert_typet ansi_c_convert_type(get_message_handler());
40 
41  ansi_c_convert_type.read(type);
42  ansi_c_convert_type.write(type);
43  }
44 
45  if(type.id()==ID_already_typechecked)
46  {
47  already_typechecked_typet &already_typechecked =
49 
50  // need to preserve any qualifiers
51  c_qualifierst c_qualifiers(type);
52  c_qualifiers += c_qualifierst(already_typechecked.get_type());
53  bool packed=type.get_bool(ID_C_packed);
54  exprt alignment=static_cast<const exprt &>(type.find(ID_C_alignment));
55  irept _typedef=type.find(ID_C_typedef);
56 
57  type = already_typechecked.get_type();
58 
59  c_qualifiers.write(type);
60  if(packed)
61  type.set(ID_C_packed, true);
62  if(alignment.is_not_nil())
63  type.add(ID_C_alignment, alignment);
64  if(_typedef.is_not_nil())
65  type.add(ID_C_typedef, _typedef);
66 
67  return; // done
68  }
69 
70  // do we have alignment?
71  if(type.find(ID_C_alignment).is_not_nil())
72  {
73  exprt &alignment=static_cast<exprt &>(type.add(ID_C_alignment));
74  if(alignment.id()!=ID_default)
75  {
78  }
79  }
80 
81  if(type.id()==ID_code)
83  else if(type.id()==ID_array)
85  else if(type.id()==ID_pointer)
86  {
87  typecheck_type(to_pointer_type(type).base_type());
88  INVARIANT(
89  to_bitvector_type(type).get_width() > 0, "pointers must have width");
90  }
91  else if(type.id()==ID_struct ||
92  type.id()==ID_union)
94  else if(type.id()==ID_c_enum)
96  else if(type.id()==ID_c_enum_tag)
98  else if(type.id()==ID_c_bit_field)
100  else if(type.id()==ID_typeof)
101  typecheck_typeof_type(type);
102  else if(type.id() == ID_typedef_type)
104  else if(type.id() == ID_struct_tag ||
105  type.id() == ID_union_tag)
106  {
107  // nothing to do, these stay as is
108  }
109  else if(type.id()==ID_vector)
110  {
111  // already done
112  }
113  else if(type.id() == ID_frontend_vector)
114  {
115  typecheck_vector_type(type);
116  }
117  else if(type.id()==ID_custom_unsignedbv ||
118  type.id()==ID_custom_signedbv ||
119  type.id()==ID_custom_floatbv ||
120  type.id()==ID_custom_fixedbv)
121  typecheck_custom_type(type);
122  else if(type.id()==ID_gcc_attribute_mode)
123  {
124  // get that mode
125  const irep_idt gcc_attr_mode = type.get(ID_size);
126 
127  // A list of all modes is at
128  // http://www.delorie.com/gnu/docs/gcc/gccint_53.html
129  typecheck_type(to_type_with_subtype(type).subtype());
130 
131  typet underlying_type = to_type_with_subtype(type).subtype();
132 
133  // gcc allows this, but clang doesn't; it's a compiler hint only,
134  // but we'll try to interpret it the GCC way
135  if(underlying_type.id()==ID_c_enum_tag)
136  {
137  underlying_type =
138  follow_tag(to_c_enum_tag_type(underlying_type)).underlying_type();
139 
140  assert(underlying_type.id()==ID_signedbv ||
141  underlying_type.id()==ID_unsignedbv);
142  }
143 
144  if(underlying_type.id()==ID_signedbv ||
145  underlying_type.id()==ID_unsignedbv)
146  {
147  bool is_signed=underlying_type.id()==ID_signedbv;
148 
149  typet result;
150 
151  if(gcc_attr_mode == "__QI__") // 8 bits
152  {
153  if(is_signed)
155  else
157  }
158  else if(gcc_attr_mode == "__byte__") // 8 bits
159  {
160  if(is_signed)
162  else
164  }
165  else if(gcc_attr_mode == "__HI__") // 16 bits
166  {
167  if(is_signed)
169  else
171  }
172  else if(gcc_attr_mode == "__SI__") // 32 bits
173  {
174  if(is_signed)
176  else
178  }
179  else if(gcc_attr_mode == "__word__") // long int, we think
180  {
181  if(is_signed)
183  else
185  }
186  else if(gcc_attr_mode == "__pointer__") // size_t/ssize_t, we think
187  {
188  if(is_signed)
190  else
191  result=size_type();
192  }
193  else if(gcc_attr_mode == "__DI__") // 64 bits
194  {
196  {
197  if(is_signed)
199  else
201  }
202  else
203  {
204  assert(config.ansi_c.long_long_int_width==64);
205 
206  if(is_signed)
208  else
210  }
211  }
212  else if(gcc_attr_mode == "__TI__") // 128 bits
213  {
214  if(is_signed)
216  else
218  }
219  else if(gcc_attr_mode == "__V2SI__") // vector of 2 ints, deprecated
220  {
221  if(is_signed)
222  {
225  }
226  else
227  {
230  }
231  }
232  else if(gcc_attr_mode == "__V4SI__") // vector of 4 ints, deprecated
233  {
234  if(is_signed)
235  {
238  }
239  else
240  {
243  }
244  }
245  else // give up, just use subtype
247 
248  // save the location
249  result.add_source_location()=type.source_location();
250 
251  if(to_type_with_subtype(type).subtype().id() == ID_c_enum_tag)
252  {
253  const irep_idt &tag_name =
255  .get_identifier();
257  .subtype() = result;
258  }
259 
260  type=result;
261  }
262  else if(underlying_type.id()==ID_floatbv)
263  {
264  typet result;
265 
266  if(gcc_attr_mode == "__SF__") // 32 bits
267  result=float_type();
268  else if(gcc_attr_mode == "__DF__") // 64 bits
270  else if(gcc_attr_mode == "__TF__") // 128 bits
272  else if(gcc_attr_mode == "__V2SF__") // deprecated vector of 2 floats
275  else if(gcc_attr_mode == "__V2DF__") // deprecated vector of 2 doubles
278  else if(gcc_attr_mode == "__V4SF__") // deprecated vector of 4 floats
281  else if(gcc_attr_mode == "__V4DF__") // deprecated vector of 4 doubles
284  else // give up, just use subtype
286 
287  // save the location
288  result.add_source_location()=type.source_location();
289 
290  type=result;
291  }
292  else if(underlying_type.id()==ID_complex)
293  {
294  // gcc allows this, but clang doesn't -- see enums above
295  typet result;
296 
297  if(gcc_attr_mode == "__SC__") // 32 bits
298  result=float_type();
299  else if(gcc_attr_mode == "__DC__") // 64 bits
301  else if(gcc_attr_mode == "__TC__") // 128 bits
303  else // give up, just use subtype
305 
306  // save the location
307  result.add_source_location()=type.source_location();
308 
309  type=complex_typet(result);
310  }
311  else
312  {
314  error() << "attribute mode '" << gcc_attr_mode
315  << "' applied to inappropriate type '" << to_string(type) << "'"
316  << eom;
317  throw 0;
318  }
319  }
320 
321  // do a mild bit of rule checking
322 
323  if(type.get_bool(ID_C_restricted) &&
324  type.id()!=ID_pointer &&
325  type.id()!=ID_array)
326  {
328  error() << "only a pointer can be 'restrict'" << eom;
329  throw 0;
330  }
331 }
332 
334 {
335  // they all have a width
336  exprt size_expr=
337  static_cast<const exprt &>(type.find(ID_size));
338 
339  typecheck_expr(size_expr);
340  source_locationt source_location=size_expr.source_location();
341  make_constant_index(size_expr);
342 
343  mp_integer size_int;
344  if(to_integer(to_constant_expr(size_expr), size_int))
345  {
346  error().source_location=source_location;
347  error() << "failed to convert bit vector width to constant" << eom;
348  throw 0;
349  }
350 
351  if(size_int<1)
352  {
353  error().source_location=source_location;
354  error() << "bit vector width invalid" << eom;
355  throw 0;
356  }
357 
358  type.remove(ID_size);
359  type.set(ID_width, integer2string(size_int));
360 
361  // depending on type, there may be a number of fractional bits
362 
363  if(type.id()==ID_custom_unsignedbv)
364  type.id(ID_unsignedbv);
365  else if(type.id()==ID_custom_signedbv)
366  type.id(ID_signedbv);
367  else if(type.id()==ID_custom_fixedbv)
368  {
369  type.id(ID_fixedbv);
370 
371  exprt f_expr=
372  static_cast<const exprt &>(type.find(ID_f));
373 
374  const source_locationt fraction_source_location =
375  f_expr.find_source_location();
376 
377  typecheck_expr(f_expr);
378 
379  make_constant_index(f_expr);
380 
381  mp_integer f_int;
382  if(to_integer(to_constant_expr(f_expr), f_int))
383  {
384  error().source_location = fraction_source_location;
385  error() << "failed to convert number of fraction bits to constant" << eom;
386  throw 0;
387  }
388 
389  if(f_int<0 || f_int>size_int)
390  {
391  error().source_location = fraction_source_location;
392  error() << "fixedbv fraction width invalid" << eom;
393  throw 0;
394  }
395 
396  type.remove(ID_f);
397  type.set(ID_integer_bits, integer2string(size_int-f_int));
398  }
399  else if(type.id()==ID_custom_floatbv)
400  {
401  type.id(ID_floatbv);
402 
403  exprt f_expr=
404  static_cast<const exprt &>(type.find(ID_f));
405 
406  const source_locationt fraction_source_location =
407  f_expr.find_source_location();
408 
409  typecheck_expr(f_expr);
410 
411  make_constant_index(f_expr);
412 
413  mp_integer f_int;
414  if(to_integer(to_constant_expr(f_expr), f_int))
415  {
416  error().source_location = fraction_source_location;
417  error() << "failed to convert number of fraction bits to constant" << eom;
418  throw 0;
419  }
420 
421  if(f_int<1 || f_int+1>=size_int)
422  {
423  error().source_location = fraction_source_location;
424  error() << "floatbv fraction width invalid" << eom;
425  throw 0;
426  }
427 
428  type.remove(ID_f);
429  type.set(ID_f, integer2string(f_int));
430  }
431  else
432  UNREACHABLE;
433 }
434 
436 {
437  // the return type is still 'subtype()'
438  type.return_type() = to_type_with_subtype(type).subtype();
439  type.remove_subtype();
440 
441  code_typet::parameterst &parameters=type.parameters();
442 
443  // if we don't have any parameters, we assume it's (...)
444  if(parameters.empty())
445  {
446  type.make_ellipsis();
447  }
448  else // we do have parameters
449  {
450  // is the last one ellipsis?
451  if(type.parameters().back().id()==ID_ellipsis)
452  {
453  type.make_ellipsis();
454  type.parameters().pop_back();
455  }
456 
457  parameter_map.clear();
458 
459  for(auto &param : type.parameters())
460  {
461  // turn the declarations into parameters
462  if(param.id()==ID_declaration)
463  {
464  ansi_c_declarationt &declaration=
465  to_ansi_c_declaration(param);
466 
467 
468  // first fix type
469  code_typet::parametert parameter(
470  declaration.full_type(declaration.declarator()));
471  typet &param_type = parameter.type();
472  std::list<codet> tmp_clean_code;
473  tmp_clean_code.swap(clean_code); // ignore side-effects
474  typecheck_type(param_type);
475  tmp_clean_code.swap(clean_code);
476  adjust_function_parameter(param_type);
477 
478  // adjust the identifier
479  irep_idt identifier=declaration.declarator().get_name();
480 
481  // abstract or not?
482  if(identifier.empty())
483  {
484  // abstract
485  parameter.add_source_location()=declaration.type().source_location();
486  }
487  else
488  {
489  // make visible now, later parameters might use it
490  parameter_map[identifier] = param_type;
491  parameter.set_base_name(declaration.declarator().get_base_name());
492  parameter.add_source_location()=
493  declaration.declarator().source_location();
494  }
495 
496  // put the parameter in place of the declaration
497  param.swap(parameter);
498  }
499  }
500 
501  parameter_map.clear();
502 
503  if(parameters.size() == 1 && parameters[0].type().id() == ID_empty)
504  {
505  // if we just have one parameter of type void, remove it
506  parameters.clear();
507  }
508  }
509 
510  typecheck_type(type.return_type());
511 
512  // 6.7.6.3:
513  // "A function declarator shall not specify a return type that
514  // is a function type or an array type."
515 
516  const typet &decl_return_type = type.return_type();
517 
518  if(decl_return_type.id() == ID_array)
519  {
521  error() << "function must not return array" << eom;
522  throw 0;
523  }
524 
525  if(decl_return_type.id() == ID_code)
526  {
528  error() << "function must not return function type" << eom;
529  throw 0;
530  }
531 }
532 
534 {
535  // Typecheck the element type.
537 
538  // We don't allow void as the element type.
539  if(type.element_type().id() == ID_empty)
540  {
542  error() << "array of voids" << eom;
543  throw 0;
544  }
545 
546  // We don't allow incomplete structs or unions as element type.
547  const typet &followed_subtype = follow(type.element_type());
548 
549  if(
550  (followed_subtype.id() == ID_struct || followed_subtype.id() == ID_union) &&
551  to_struct_union_type(followed_subtype).is_incomplete())
552  {
553  // ISO/IEC 9899 6.7.5.2
555  error() << "array has incomplete element type" << eom;
556  throw 0;
557  }
558 
559  // We don't allow functions as element type.
560  if(type.element_type().id() == ID_code)
561  {
562  // ISO/IEC 9899 6.7.5.2
564  error() << "array of function element type" << eom;
565  throw 0;
566  }
567 
568  // We add the index type.
570 
571  // Check the array size, if given.
572  if(type.is_complete())
573  {
574  exprt &size = type.size();
575  const source_locationt size_source_location = size.find_source_location();
576  typecheck_expr(size);
577  make_index_type(size);
578 
579  // The size need not be a constant!
580  // We simplify it, for the benefit of array initialisation.
581 
582  exprt tmp_size=size;
583  add_rounding_mode(tmp_size);
584  simplify(tmp_size, *this);
585 
586  if(tmp_size.is_constant())
587  {
588  mp_integer s;
589  if(to_integer(to_constant_expr(tmp_size), s))
590  {
591  error().source_location = size_source_location;
592  error() << "failed to convert constant: "
593  << tmp_size.pretty() << eom;
594  throw 0;
595  }
596 
597  if(s<0)
598  {
599  error().source_location = size_source_location;
600  error() << "array size must not be negative, "
601  "but got " << s << eom;
602  throw 0;
603  }
604 
605  size=tmp_size;
606  }
607  else if(tmp_size.id()==ID_infinity)
608  {
609  size=tmp_size;
610  }
611  else if(tmp_size.id()==ID_symbol &&
612  tmp_size.type().get_bool(ID_C_constant))
613  {
614  // We allow a constant variable as array size, assuming
615  // it won't change.
616  // This criterion can be tricked:
617  // Of course we can modify a 'const' symbol, e.g.,
618  // using a pointer type cast. Interestingly,
619  // at least gcc 4.2.1 makes the very same mistake!
620  size=tmp_size;
621  }
622  else
623  {
624  // not a constant and not infinity
625 
627 
629  {
631  error() << "array size of static symbol '" << current_symbol.base_name
632  << "' is not constant" << eom;
633  throw 0;
634  }
635 
636  symbolt &new_symbol = get_fresh_aux_symbol(
637  size_type(),
638  id2string(current_symbol.name) + "$array_size",
639  id2string(current_symbol.base_name) + "$array_size",
640  size_source_location,
641  mode,
642  symbol_table);
643  new_symbol.type.set(ID_C_constant, true);
644  new_symbol.value = typecast_exprt::conditional_cast(size, size_type());
645 
646  // produce the code that declares and initializes the symbol
647  symbol_exprt symbol_expr = new_symbol.symbol_expr();
648 
649  code_frontend_declt declaration(symbol_expr);
650  declaration.add_source_location() = size_source_location;
651 
652  code_frontend_assignt assignment;
653  assignment.lhs()=symbol_expr;
654  assignment.rhs() = new_symbol.value;
655  assignment.add_source_location() = size_source_location;
656 
657  // store the code
658  clean_code.push_back(declaration);
659  clean_code.push_back(assignment);
660 
661  // fix type
662  size=symbol_expr;
663  }
664  }
665 }
666 
668 {
669  // This turns the type with ID_frontend_vector into the type
670  // with ID_vector; the difference is that the latter has
671  // a constant as size, which we establish now.
672  exprt size = static_cast<const exprt &>(type.find(ID_size));
673  const source_locationt source_location = size.find_source_location();
674 
675  typecheck_expr(size);
676 
677  typet subtype = to_type_with_subtype(type).subtype();
678  typecheck_type(subtype);
679 
680  // we are willing to combine 'vector' with various
681  // other types, but not everything!
682 
683  if(subtype.id()!=ID_signedbv &&
684  subtype.id()!=ID_unsignedbv &&
685  subtype.id()!=ID_floatbv &&
686  subtype.id()!=ID_fixedbv)
687  {
688  error().source_location=source_location;
689  error() << "cannot make a vector of subtype "
690  << to_string(subtype) << eom;
691  throw 0;
692  }
693 
694  make_constant_index(size);
695 
696  mp_integer s;
697  if(to_integer(to_constant_expr(size), s))
698  {
699  error().source_location=source_location;
700  error() << "failed to convert constant: "
701  << size.pretty() << eom;
702  throw 0;
703  }
704 
705  if(s<=0)
706  {
707  error().source_location=source_location;
708  error() << "vector size must be positive, "
709  "but got " << s << eom;
710  throw 0;
711  }
712 
713  // the subtype must have constant size
714  auto sub_size_expr_opt = size_of_expr(subtype, *this);
715 
716  if(!sub_size_expr_opt.has_value())
717  {
718  error().source_location = source_location;
719  error() << "failed to determine size of vector base type '"
720  << to_string(subtype) << "'" << eom;
721  throw 0;
722  }
723 
724  simplify(sub_size_expr_opt.value(), *this);
725 
726  const auto sub_size = numeric_cast<mp_integer>(sub_size_expr_opt.value());
727 
728  if(!sub_size.has_value())
729  {
730  error().source_location=source_location;
731  error() << "failed to determine size of vector base type '"
732  << to_string(subtype) << "'" << eom;
733  throw 0;
734  }
735 
736  if(*sub_size == 0)
737  {
738  error().source_location=source_location;
739  error() << "type had size 0: '" << to_string(subtype) << "'" << eom;
740  throw 0;
741  }
742 
743  // adjust by width of base type
744  if(s % *sub_size != 0)
745  {
746  error().source_location=source_location;
747  error() << "vector size (" << s
748  << ") expected to be multiple of base type size (" << *sub_size
749  << ")" << eom;
750  throw 0;
751  }
752 
753  s /= *sub_size;
754 
755  // produce the type with ID_vector
756  vector_typet new_type(
757  c_index_type(), subtype, from_integer(s, signed_size_type()));
758  new_type.add_source_location() = source_location;
759  new_type.size().add_source_location() = source_location;
760  type = new_type;
761 }
762 
764 {
765  // These get replaced by symbol types later.
766  irep_idt identifier;
767 
768  bool have_body=type.find(ID_components).is_not_nil();
769 
770  c_qualifierst original_qualifiers(type);
771 
772  // the type symbol, which may get re-used in other declarations, must not
773  // carry any qualifiers (other than transparent_union, which isn't really a
774  // qualifier)
775  c_qualifierst remove_qualifiers;
776  remove_qualifiers.is_transparent_union =
777  original_qualifiers.is_transparent_union;
778  remove_qualifiers.write(type);
779 
780  bool is_packed = type.get_bool(ID_C_packed);
781  irept alignment = type.find(ID_C_alignment);
782 
783  if(type.find(ID_tag).is_nil())
784  {
785  // Anonymous? Must come with body.
786  assert(have_body);
787 
788  // produce symbol
789  symbolt compound_symbol;
790  compound_symbol.is_type=true;
791  compound_symbol.type=type;
792  compound_symbol.location=type.source_location();
793 
795 
796  std::string typestr = type2name(compound_symbol.type, *this);
797  compound_symbol.base_name = "#anon#" + typestr;
798  compound_symbol.name="tag-#anon#"+typestr;
799  identifier=compound_symbol.name;
800 
801  // We might already have the same anonymous union/struct,
802  // and this is simply ok. Note that the C standard treats
803  // these as different types.
804  if(symbol_table.symbols.find(identifier)==symbol_table.symbols.end())
805  {
806  symbolt *new_symbol;
807  move_symbol(compound_symbol, new_symbol);
808  }
809  }
810  else
811  {
812  identifier=type.find(ID_tag).get(ID_identifier);
813 
814  // does it exist already?
815  symbol_tablet::symbolst::const_iterator s_it=
816  symbol_table.symbols.find(identifier);
817 
818  if(s_it==symbol_table.symbols.end())
819  {
820  // no, add new symbol
821  irep_idt base_name=type.find(ID_tag).get(ID_C_base_name);
822  type.remove(ID_tag);
823  type.set(ID_tag, base_name);
824 
825  symbolt compound_symbol;
826  compound_symbol.is_type=true;
827  compound_symbol.name=identifier;
828  compound_symbol.base_name=base_name;
829  compound_symbol.type=type;
830  compound_symbol.location=type.source_location();
831  compound_symbol.pretty_name=id2string(type.id())+" "+id2string(base_name);
832 
833  typet new_type=compound_symbol.type;
834 
835  // mark as incomplete
836  to_struct_union_type(compound_symbol.type).make_incomplete();
837 
838  symbolt *new_symbol;
839  move_symbol(compound_symbol, new_symbol);
840 
841  if(have_body)
842  {
844 
845  new_symbol->type.swap(new_type);
846  }
847  }
848  else
849  {
850  // yes, it exists already
851  if(
852  s_it->second.type.id() == type.id() &&
853  to_struct_union_type(s_it->second.type).is_incomplete())
854  {
855  // Maybe we got a body now.
856  if(have_body)
857  {
858  irep_idt base_name=type.find(ID_tag).get(ID_C_base_name);
859  type.remove(ID_tag);
860  type.set(ID_tag, base_name);
861 
863  symbol_table.get_writeable_ref(s_it->first).type.swap(type);
864  }
865  }
866  else if(s_it->second.type.id() != type.id())
867  {
869  error() << "redefinition of '" << s_it->second.pretty_name << "'"
870  << " as different kind of tag" << eom;
871  throw 0;
872  }
873  else if(have_body)
874  {
876  error() << "redefinition of body of '" << s_it->second.pretty_name
877  << "'" << eom;
878  throw 0;
879  }
880  }
881  }
882 
883  typet tag_type;
884 
885  if(type.id() == ID_union)
886  tag_type = union_tag_typet(identifier);
887  else if(type.id() == ID_struct)
888  tag_type = struct_tag_typet(identifier);
889  else
890  UNREACHABLE;
891 
892  tag_type.add_source_location() = type.source_location();
893  type.swap(tag_type);
894 
895  original_qualifiers.write(type);
896 
897  if(is_packed)
898  type.set(ID_C_packed, true);
899  if(alignment.is_not_nil())
900  type.set(ID_C_alignment, alignment);
901 }
902 
904  struct_union_typet &type)
905 {
906  struct_union_typet::componentst &components=type.components();
907 
908  struct_union_typet::componentst old_components;
909  old_components.swap(components);
910 
911  // We get these as declarations!
912  for(auto &decl : old_components)
913  {
914  // the arguments are member declarations or static assertions
915  assert(decl.id()==ID_declaration);
916 
917  ansi_c_declarationt &declaration=
918  to_ansi_c_declaration(static_cast<exprt &>(decl));
919 
920  if(declaration.get_is_static_assert())
921  {
922  struct_union_typet::componentt new_component;
923  new_component.id(ID_static_assert);
924  new_component.add_source_location()=declaration.source_location();
925  new_component.operands().swap(declaration.operands());
926  assert(new_component.operands().size()==2);
927  components.push_back(new_component);
928  }
929  else
930  {
931  // do first half of type
932  typecheck_type(declaration.type());
934 
935  for(const auto &declarator : declaration.declarators())
936  {
937  struct_union_typet::componentt new_component(
938  declarator.get_base_name(), declaration.full_type(declarator));
939 
940  // There may be a declarator, which we use as location for
941  // the component. Otherwise, use location of the declaration.
942  const source_locationt source_location =
943  declarator.get_name().empty() ? declaration.source_location()
944  : declarator.source_location();
945 
946  new_component.add_source_location() = source_location;
947  new_component.set_pretty_name(declarator.get_base_name());
948 
949  typecheck_type(new_component.type());
950 
951  if(!is_complete_type(new_component.type()) &&
952  (new_component.type().id()!=ID_array ||
953  !to_array_type(new_component.type()).is_incomplete()))
954  {
955  error().source_location = source_location;
956  error() << "incomplete type not permitted here" << eom;
957  throw 0;
958  }
959 
960  if(new_component.type().id() == ID_empty)
961  {
962  error().source_location = source_location;
963  error() << "void-typed member not permitted" << eom;
964  throw 0;
965  }
966 
967  components.push_back(new_component);
968  }
969  }
970  }
971 
972  unsigned anon_member_counter=0;
973 
974  // scan for anonymous members, and name them
975  for(auto &member : components)
976  {
977  if(!member.get_name().empty())
978  continue;
979 
980  member.set_name("$anon"+std::to_string(anon_member_counter++));
981  member.set_anonymous(true);
982  }
983 
984  // scan for duplicate members
985 
986  {
987  std::unordered_set<irep_idt> members;
988 
989  for(const auto &c : components)
990  {
991  if(!members.insert(c.get_name()).second)
992  {
993  error().source_location = c.source_location();
994  error() << "duplicate member '" << c.get_name() << '\'' << eom;
995  throw 0;
996  }
997  }
998  }
999 
1000  // We allow an incomplete (C99) array as _last_ member!
1001  // Zero-length is allowed everywhere.
1002 
1003  if(type.id()==ID_struct ||
1004  type.id()==ID_union)
1005  {
1006  for(struct_union_typet::componentst::iterator
1007  it=components.begin();
1008  it!=components.end();
1009  it++)
1010  {
1011  typet &c_type=it->type();
1012 
1013  if(c_type.id()==ID_array &&
1014  to_array_type(c_type).is_incomplete())
1015  {
1016  // needs to be last member
1017  if(type.id()==ID_struct && it!=--components.end())
1018  {
1019  error().source_location=it->source_location();
1020  error() << "flexible struct member must be last member" << eom;
1021  throw 0;
1022  }
1023 
1024  // make it zero-length
1025  to_array_type(c_type).size() = from_integer(0, c_index_type());
1026  c_type.set(ID_C_flexible_array_member, true);
1027  }
1028  }
1029  }
1030 
1031  // We may add some minimal padding inside and at
1032  // the end of structs and
1033  // as additional member for unions.
1034 
1035  if(type.id()==ID_struct)
1036  add_padding(to_struct_type(type), *this);
1037  else if(type.id()==ID_union)
1038  add_padding(to_union_type(type), *this);
1039 
1040  // Now remove zero-width bit-fields, these are just
1041  // for adjusting alignment.
1042  for(struct_typet::componentst::iterator
1043  it=components.begin();
1044  it!=components.end();
1045  ) // blank
1046  {
1047  if(it->type().id()==ID_c_bit_field &&
1048  to_c_bit_field_type(it->type()).get_width()==0)
1049  it=components.erase(it);
1050  else
1051  it++;
1052  }
1053 
1054  // finally, check _Static_assert inside the compound
1055  for(struct_union_typet::componentst::iterator
1056  it=components.begin();
1057  it!=components.end();
1058  ) // no it++
1059  {
1060  if(it->id()==ID_static_assert)
1061  {
1063  {
1064  error().source_location = it->source_location();
1065  error() << "static_assert not supported in compound body" << eom;
1066  throw 0;
1067  }
1068 
1069  exprt &assertion = to_binary_expr(*it).op0();
1070  typecheck_expr(assertion);
1072  assertion = typecast_exprt(assertion, bool_typet());
1073  make_constant(assertion);
1074 
1075  if(assertion.is_false())
1076  {
1077  error().source_location=it->source_location();
1078  error() << "failed _Static_assert" << eom;
1079  throw 0;
1080  }
1081  else if(!assertion.is_true())
1082  {
1083  // should warn/complain
1084  }
1085 
1086  it=components.erase(it);
1087  }
1088  else
1089  it++;
1090  }
1091 }
1092 
1094  const mp_integer &min_value,
1095  const mp_integer &max_value) const
1096 {
1098  {
1099  return signed_int_type();
1100  }
1101  else
1102  {
1103  // enum constants are at least 'int', but may be made larger.
1104  // 'Packing' has no influence.
1105  if(max_value<(mp_integer(1)<<(config.ansi_c.int_width-1)) &&
1106  min_value>=-(mp_integer(1)<<(config.ansi_c.int_width-1)))
1107  return signed_int_type();
1108  else if(max_value<(mp_integer(1)<<config.ansi_c.int_width) &&
1109  min_value>=0)
1110  return unsigned_int_type();
1111  else if(max_value<(mp_integer(1)<<config.ansi_c.long_int_width) &&
1112  min_value>=0)
1113  return unsigned_long_int_type();
1114  else if(max_value<(mp_integer(1)<<config.ansi_c.long_long_int_width) &&
1115  min_value>=0)
1116  return unsigned_long_long_int_type();
1117  else if(max_value<(mp_integer(1)<<(config.ansi_c.long_int_width-1)) &&
1118  min_value>=-(mp_integer(1)<<(config.ansi_c.long_int_width-1)))
1119  return signed_long_int_type();
1120  else
1121  return signed_long_long_int_type();
1122  }
1123 }
1124 
1126  const mp_integer &min_value,
1127  const mp_integer &max_value,
1128  bool is_packed) const
1129 {
1131  {
1132  return signed_int_type();
1133  }
1134  else
1135  {
1136  if(min_value<0)
1137  {
1138  // We'll want a signed type.
1139 
1140  if(is_packed)
1141  {
1142  // If packed, there are smaller options.
1143  if(max_value<(mp_integer(1)<<(config.ansi_c.char_width-1)) &&
1144  min_value>=-(mp_integer(1)<<(config.ansi_c.char_width-1)))
1145  return signed_char_type();
1146  else if(max_value<(mp_integer(1)<<(config.ansi_c.short_int_width-1)) &&
1147  min_value>=-(mp_integer(1)<<(config.ansi_c.short_int_width-1)))
1148  return signed_short_int_type();
1149  }
1150 
1151  if(max_value<(mp_integer(1)<<(config.ansi_c.int_width-1)) &&
1152  min_value>=-(mp_integer(1)<<(config.ansi_c.int_width-1)))
1153  return signed_int_type();
1154  else if(max_value<(mp_integer(1)<<(config.ansi_c.long_int_width-1)) &&
1155  min_value>=-(mp_integer(1)<<(config.ansi_c.long_int_width-1)))
1156  return signed_long_int_type();
1157  else
1158  return signed_long_long_int_type();
1159  }
1160  else
1161  {
1162  // We'll want an unsigned type.
1163 
1164  if(is_packed)
1165  {
1166  // If packed, there are smaller options.
1167  if(max_value<(mp_integer(1)<<config.ansi_c.char_width))
1168  return unsigned_char_type();
1169  else if(max_value<(mp_integer(1)<<config.ansi_c.short_int_width))
1170  return unsigned_short_int_type();
1171  }
1172 
1173  if(max_value<(mp_integer(1)<<config.ansi_c.int_width))
1174  return unsigned_int_type();
1175  else if(max_value<(mp_integer(1)<<config.ansi_c.long_int_width))
1176  return unsigned_long_int_type();
1177  else
1178  return unsigned_long_long_int_type();
1179  }
1180  }
1181 }
1182 
1184 {
1185  // These come with the declarations
1186  // of the enum constants as operands.
1187 
1188  exprt &as_expr=static_cast<exprt &>(static_cast<irept &>(type));
1189  source_locationt source_location=type.source_location();
1190 
1191  // We allow empty enums in the grammar to get better
1192  // error messages.
1193  if(as_expr.operands().empty())
1194  {
1195  error().source_location=source_location;
1196  error() << "empty enum" << eom;
1197  throw 0;
1198  }
1199 
1200  const bool have_underlying_type =
1201  type.find_type(ID_enum_underlying_type).is_not_nil();
1202 
1203  if(have_underlying_type)
1204  {
1205  typecheck_type(type.add_type(ID_enum_underlying_type));
1206 
1207  const typet &underlying_type =
1208  static_cast<const typet &>(type.find(ID_enum_underlying_type));
1209 
1210  if(!is_signed_or_unsigned_bitvector(underlying_type))
1211  {
1212  std::ostringstream msg;
1213  msg << "non-integral type '" << underlying_type.get(ID_C_c_type)
1214  << "' is an invalid underlying type";
1215  throw invalid_source_file_exceptiont{msg.str(), source_location};
1216  }
1217  }
1218 
1219  // enums start at zero;
1220  // we also track min and max to find a nice base type
1221  mp_integer value=0, min_value=0, max_value=0;
1222 
1223  std::list<c_enum_typet::c_enum_membert> enum_members;
1224 
1225  // We need to determine a width, and a signedness
1226  // to obtain an 'underlying type'.
1227  // We just do int, but gcc might pick smaller widths
1228  // if the type is marked as 'packed'.
1229  // gcc/clang may also pick a larger width. Visual Studio doesn't.
1230 
1231  for(auto &op : as_expr.operands())
1232  {
1233  ansi_c_declarationt &declaration=to_ansi_c_declaration(op);
1234  exprt &v=declaration.declarator().value();
1235 
1236  if(v.is_not_nil()) // value given?
1237  {
1238  exprt tmp_v=v;
1239  typecheck_expr(tmp_v);
1240  add_rounding_mode(tmp_v);
1241  simplify(tmp_v, *this);
1242  if(tmp_v.is_true())
1243  value=1;
1244  else if(tmp_v.is_false())
1245  value=0;
1246  else if(
1247  tmp_v.id() == ID_constant &&
1248  !to_integer(to_constant_expr(tmp_v), value))
1249  {
1250  }
1251  else
1252  {
1254  error() << "enum is not a constant" << eom;
1255  throw 0;
1256  }
1257  }
1258 
1259  if(value<min_value)
1260  min_value=value;
1261  if(value>max_value)
1262  max_value=value;
1263 
1264  typet constant_type;
1265 
1266  if(have_underlying_type)
1267  {
1268  constant_type = type.find_type(ID_enum_underlying_type);
1269  const auto &tmp = to_integer_bitvector_type(constant_type);
1270 
1271  if(value < tmp.smallest() || value > tmp.largest())
1272  {
1273  std::ostringstream msg;
1274  msg << "enumerator value is not representable in the underlying type '"
1275  << constant_type.get(ID_C_c_type) << "'";
1276  throw invalid_source_file_exceptiont{msg.str(), v.source_location()};
1277  }
1278  }
1279  else
1280  {
1281  constant_type = enum_constant_type(min_value, max_value);
1282  }
1283 
1284  v=from_integer(value, constant_type);
1285 
1286  declaration.type()=constant_type;
1287  typecheck_declaration(declaration);
1288 
1289  irep_idt base_name=
1290  declaration.declarator().get_base_name();
1291 
1292  irep_idt identifier=
1293  declaration.declarator().get_name();
1294 
1295  // store
1297  member.set_identifier(identifier);
1298  member.set_base_name(base_name);
1299  // Note: The value will be correctly set to a bv type when we know
1300  // the width of the bitvector
1301  member.set_value(integer2string(value));
1302  enum_members.push_back(member);
1303 
1304  // produce value for next constant
1305  ++value;
1306  }
1307 
1308  // Remove these now; we add them to the
1309  // c_enum symbol later.
1310  as_expr.operands().clear();
1311 
1312  bool is_packed=type.get_bool(ID_C_packed);
1313 
1314  // We use a subtype to store the underlying type.
1315  bitvector_typet underlying_type(ID_nil);
1316 
1317  if(have_underlying_type)
1318  {
1319  underlying_type =
1320  to_bitvector_type(type.find_type(ID_enum_underlying_type));
1321  }
1322  else
1323  {
1324  underlying_type = enum_underlying_type(min_value, max_value, is_packed);
1325  }
1326 
1327  // Get the width to make the values have a bitvector type
1328  std::size_t width = underlying_type.get_width();
1329  for(auto &member : enum_members)
1330  {
1331  // Note: This is inefficient as it first turns integers to strings
1332  // and then turns them back to bvrep
1333  auto value = string2integer(id2string(member.get_value()));
1334  member.set_value(integer2bvrep(value, width));
1335  }
1336 
1337  // tag?
1338  if(type.find(ID_tag).is_nil())
1339  {
1340  // None, it's anonymous. We generate a tag.
1341  std::string anon_identifier="#anon_enum";
1342 
1343  for(const auto &member : enum_members)
1344  {
1345  anon_identifier+='$';
1346  anon_identifier+=id2string(member.get_base_name());
1347  anon_identifier+='=';
1348  anon_identifier+=id2string(member.get_value());
1349  }
1350 
1351  if(is_packed)
1352  anon_identifier+="#packed";
1353 
1354  type.add(ID_tag).set(ID_identifier, anon_identifier);
1355  }
1356 
1357  irept &tag=type.add(ID_tag);
1358  irep_idt base_name=tag.get(ID_C_base_name);
1359  irep_idt identifier=tag.get(ID_identifier);
1360 
1361  // Put into symbol table
1362  symbolt enum_tag_symbol;
1363 
1364  enum_tag_symbol.is_type=true;
1365  enum_tag_symbol.type=type;
1366  enum_tag_symbol.location=source_location;
1367  enum_tag_symbol.is_file_local=true;
1368  enum_tag_symbol.base_name=base_name;
1369  enum_tag_symbol.name=identifier;
1370 
1371  // throw in the enum members as 'body'
1372  irept::subt &body=enum_tag_symbol.type.add(ID_body).get_sub();
1373 
1374  for(const auto &member : enum_members)
1375  body.push_back(member);
1376 
1377  enum_tag_symbol.type.add_subtype() = underlying_type;
1378 
1379  // is it in the symbol table already?
1380  symbol_tablet::symbolst::const_iterator s_it=
1381  symbol_table.symbols.find(identifier);
1382 
1383  if(s_it!=symbol_table.symbols.end())
1384  {
1385  // Yes.
1386  const symbolt &symbol=s_it->second;
1387 
1388  if(symbol.type.id() != ID_c_enum)
1389  {
1390  error().source_location = source_location;
1391  error() << "use of tag that does not match previous declaration" << eom;
1392  throw 0;
1393  }
1394 
1395  if(to_c_enum_type(symbol.type).is_incomplete())
1396  {
1397  // Ok, overwrite the type in the symbol table.
1398  // This gives us the members and the subtype.
1399  symbol_table.get_writeable_ref(symbol.name).type=enum_tag_symbol.type;
1400  }
1401  else
1402  {
1403  // We might already have the same anonymous enum, and this is
1404  // simply ok. Note that the C standard treats these as
1405  // different types.
1406  if(!base_name.empty())
1407  {
1409  error() << "redeclaration of enum tag" << eom;
1410  throw 0;
1411  }
1412  }
1413  }
1414  else
1415  {
1416  symbolt *new_symbol;
1417  move_symbol(enum_tag_symbol, new_symbol);
1418  }
1419 
1420  // We produce a c_enum_tag as the resulting type.
1421  type.id(ID_c_enum_tag);
1422  type.remove(ID_tag);
1423  type.set(ID_identifier, identifier);
1424 }
1425 
1427 {
1428  // It's just a tag.
1429 
1430  if(type.find(ID_tag).is_nil())
1431  {
1433  error() << "anonymous enum tag without members" << eom;
1434  throw 0;
1435  }
1436 
1437  if(type.find(ID_enum_underlying_type).is_not_nil())
1438  {
1440  warning() << "ignoring specification of underlying type for enum" << eom;
1441  }
1442 
1443  source_locationt source_location=type.source_location();
1444 
1445  irept &tag=type.add(ID_tag);
1446  irep_idt base_name=tag.get(ID_C_base_name);
1447  irep_idt identifier=tag.get(ID_identifier);
1448 
1449  // is it in the symbol table?
1450  symbol_tablet::symbolst::const_iterator s_it=
1451  symbol_table.symbols.find(identifier);
1452 
1453  if(s_it!=symbol_table.symbols.end())
1454  {
1455  // Yes.
1456  const symbolt &symbol=s_it->second;
1457 
1458  if(symbol.type.id() != ID_c_enum)
1459  {
1460  error().source_location=source_location;
1461  error() << "use of tag that does not match previous declaration" << eom;
1462  throw 0;
1463  }
1464  }
1465  else
1466  {
1467  // no, add it as an incomplete c_enum
1468  c_enum_typet new_type(signed_int_type()); // default subtype
1469  new_type.add(ID_tag)=tag;
1470  new_type.make_incomplete();
1471 
1472  symbolt enum_tag_symbol;
1473 
1474  enum_tag_symbol.is_type=true;
1475  enum_tag_symbol.type=new_type;
1476  enum_tag_symbol.location=source_location;
1477  enum_tag_symbol.is_file_local=true;
1478  enum_tag_symbol.base_name=base_name;
1479  enum_tag_symbol.name=identifier;
1480 
1481  symbolt *new_symbol;
1482  move_symbol(enum_tag_symbol, new_symbol);
1483  }
1484 
1485  // Clean up resulting type
1486  type.remove(ID_tag);
1487  type.set_identifier(identifier);
1488 }
1489 
1491 {
1493 
1494  mp_integer i;
1495 
1496  {
1497  exprt &width_expr=static_cast<exprt &>(type.add(ID_size));
1498 
1499  typecheck_expr(width_expr);
1500  make_constant_index(width_expr);
1501 
1502  if(to_integer(to_constant_expr(width_expr), i))
1503  {
1505  error() << "failed to convert bit field width" << eom;
1506  throw 0;
1507  }
1508 
1509  if(i<0)
1510  {
1512  error() << "bit field width is negative" << eom;
1513  throw 0;
1514  }
1515 
1516  type.set_width(numeric_cast_v<std::size_t>(i));
1517  type.remove(ID_size);
1518  }
1519 
1520  const typet &underlying_type = type.underlying_type();
1521 
1522  std::size_t sub_width=0;
1523 
1524  if(underlying_type.id() == ID_bool)
1525  {
1526  // This is the 'proper' bool.
1527  sub_width=1;
1528  }
1529  else if(
1530  underlying_type.id() == ID_signedbv ||
1531  underlying_type.id() == ID_unsignedbv || underlying_type.id() == ID_c_bool)
1532  {
1533  sub_width = to_bitvector_type(underlying_type).get_width();
1534  }
1535  else if(underlying_type.id() == ID_c_enum_tag)
1536  {
1537  // These point to an enum, which has a sub-subtype,
1538  // which may be smaller or larger than int, and we thus have
1539  // to check.
1540  const auto &c_enum_type =
1541  to_c_enum_type(follow_tag(to_c_enum_tag_type(underlying_type)));
1542 
1543  if(c_enum_type.is_incomplete())
1544  {
1546  error() << "bit field has incomplete enum type" << eom;
1547  throw 0;
1548  }
1549 
1550  sub_width = to_bitvector_type(c_enum_type.underlying_type()).get_width();
1551  }
1552  else
1553  {
1555  error() << "bit field with non-integer type: " << to_string(underlying_type)
1556  << eom;
1557  throw 0;
1558  }
1559 
1560  if(i>sub_width)
1561  {
1563  error() << "bit field (" << i
1564  << " bits) larger than type (" << sub_width << " bits)"
1565  << eom;
1566  throw 0;
1567  }
1568 }
1569 
1571 {
1572  // save location
1573  source_locationt source_location=type.source_location();
1574 
1575  // retain the qualifiers as is
1576  c_qualifierst c_qualifiers;
1577  c_qualifiers.read(type);
1578 
1579  const auto &as_expr = (const exprt &)type;
1580 
1581  if(!as_expr.has_operands())
1582  {
1583  typet t=static_cast<const typet &>(type.find(ID_type_arg));
1584  typecheck_type(t);
1585  type.swap(t);
1586  }
1587  else
1588  {
1589  exprt expr = to_unary_expr(as_expr).op();
1590  typecheck_expr(expr);
1591 
1592  // undo an implicit address-of
1593  if(expr.id()==ID_address_of &&
1594  expr.get_bool(ID_C_implicit))
1595  {
1596  expr = to_address_of_expr(expr).object();
1597  }
1598 
1599  type.swap(expr.type());
1600  }
1601 
1602  type.add_source_location()=source_location;
1603  c_qualifiers.write(type);
1604 }
1605 
1607 {
1608  const irep_idt &identifier = to_typedef_type(type).get_identifier();
1609 
1610  symbol_tablet::symbolst::const_iterator s_it =
1611  symbol_table.symbols.find(identifier);
1612 
1613  if(s_it == symbol_table.symbols.end())
1614  {
1616  error() << "typedef symbol '" << identifier << "' not found" << eom;
1617  throw 0;
1618  }
1619 
1620  const symbolt &symbol = s_it->second;
1621 
1622  if(!symbol.is_type)
1623  {
1625  error() << "expected type symbol for typedef" << eom;
1626  throw 0;
1627  }
1628 
1629  // overwrite, but preserve (add) any qualifiers and other flags
1630 
1631  c_qualifierst c_qualifiers(type);
1632  bool is_packed = type.get_bool(ID_C_packed);
1633  irept alignment = type.find(ID_C_alignment);
1634 
1635  c_qualifiers += c_qualifierst(symbol.type);
1636  type = symbol.type;
1637  c_qualifiers.write(type);
1638 
1639  if(is_packed)
1640  type.set(ID_C_packed, true);
1641  if(alignment.is_not_nil())
1642  type.set(ID_C_alignment, alignment);
1643 
1644  // CPROVER extensions
1645  if(symbol.base_name == CPROVER_PREFIX "rational")
1646  {
1647  type=rational_typet();
1648  }
1649  else if(symbol.base_name == CPROVER_PREFIX "integer")
1650  {
1651  type=integer_typet();
1652  }
1653 }
1654 
1656 {
1657  if(type.id()==ID_array)
1658  {
1659  source_locationt source_location=type.source_location();
1660  type = pointer_type(to_array_type(type).element_type());
1661  type.add_source_location()=source_location;
1662  }
1663  else if(type.id()==ID_code)
1664  {
1665  // see ISO/IEC 9899:1999 page 199 clause 8,
1666  // may be hidden in typedef
1667  source_locationt source_location=type.source_location();
1668  type=pointer_type(type);
1669  type.add_source_location()=source_location;
1670  }
1671  else if(type.id()==ID_KnR)
1672  {
1673  // any KnR args without type yet?
1674  type=signed_int_type(); // the default is integer!
1675  // no source location
1676  }
1677 }
c_qualifierst::read
virtual void read(const typet &src) override
Definition: c_qualifiers.cpp:62
tag_typet::get_identifier
const irep_idt & get_identifier() const
Definition: std_types.h:410
UNREACHABLE
#define UNREACHABLE
This should be used to mark dead code.
Definition: invariant.h:503
struct_union_typet::components
const componentst & components() const
Definition: std_types.h:147
dstringt
dstringt has one field, an unsigned integer no which is an index into a static table of strings.
Definition: dstring.h:36
pointer_offset_size.h
to_union_type
const union_typet & to_union_type(const typet &type)
Cast a typet to a union_typet.
Definition: c_types.h:162
typecast_exprt::conditional_cast
static exprt conditional_cast(const exprt &expr, const typet &type)
Definition: std_expr.h:2025
to_unary_expr
const unary_exprt & to_unary_expr(const exprt &expr)
Cast an exprt to a unary_exprt.
Definition: std_expr.h:361
tag_typet::set_identifier
void set_identifier(const irep_idt &identifier)
Definition: std_types.h:405
ansi_c_declaration.h
c_typecheck_baset::typecheck_vector_type
virtual void typecheck_vector_type(typet &type)
Definition: c_typecheck_type.cpp:667
c_enum_typet
The type of C enums.
Definition: c_types.h:216
array_typet::is_incomplete
bool is_incomplete() const
Definition: std_types.h:817
mp_integer
BigInt mp_integer
Definition: smt_terms.h:17
ansi_c_declarationt::declarators
const declaratorst & declarators() const
Definition: ansi_c_declaration.h:216
c_enum_typet::c_enum_membert::set_value
void set_value(const irep_idt &value)
Definition: c_types.h:231
c_enum_typet::is_incomplete
bool is_incomplete() const
enum types may be incomplete
Definition: c_types.h:261
c_typecheck_baset::typecheck_array_type
virtual void typecheck_array_type(array_typet &type)
Definition: c_typecheck_type.cpp:533
c_typecheck_baset::current_symbol
symbolt current_symbol
Definition: c_typecheck_base.h:71
arith_tools.h
goto_instruction_code.h
to_struct_type
const struct_typet & to_struct_type(const typet &type)
Cast a typet to a struct_typet.
Definition: std_types.h:308
address_of_exprt::object
exprt & object()
Definition: pointer_expr.h:380
signed_long_long_int_type
signedbv_typet signed_long_long_int_type()
Definition: c_types.cpp:97
signed_char_type
signedbv_typet signed_char_type()
Definition: c_types.cpp:152
ansi_c_declaratort::value
exprt & value()
Definition: ansi_c_declaration.h:26
to_struct_union_type
const struct_union_typet & to_struct_union_type(const typet &type)
Cast a typet to a struct_union_typet.
Definition: std_types.h:214
array_typet::is_complete
bool is_complete() const
Definition: std_types.h:812
rational_typet
Unbounded, signed rational numbers.
Definition: mathematical_types.h:39
typet
The type of an expression, extends irept.
Definition: type.h:28
code_typet::parameterst
std::vector< parametert > parameterst
Definition: std_types.h:541
c_typecheck_baset::enum_constant_type
typet enum_constant_type(const mp_integer &min, const mp_integer &max) const
Definition: c_typecheck_type.cpp:1093
c_typecheck_base.h
fresh_symbol.h
irept::pretty
std::string pretty(unsigned indent=0, unsigned max_indent=0) const
Definition: irep.cpp:495
ansi_c_convert_type.h
c_typecheck_baset::typecheck_declaration
void typecheck_declaration(ansi_c_declarationt &)
Definition: c_typecheck_base.cpp:704
gcc_types.h
c_typecheck_baset::to_string
virtual std::string to_string(const exprt &expr)
Definition: c_typecheck_base.cpp:24
irept::find
const irept & find(const irep_idt &name) const
Definition: irep.cpp:106
struct_union_typet
Base type for structs and unions.
Definition: std_types.h:61
symbolt::type
typet type
Type of symbol.
Definition: symbol.h:31
vector_typet::size
const constant_exprt & size() const
Definition: std_types.cpp:269
to_integer_bitvector_type
const integer_bitvector_typet & to_integer_bitvector_type(const typet &type)
Cast a typet to an integer_bitvector_typet.
Definition: bitvector_types.h:142
ansi_c_convert_typet::write
virtual void write(typet &type)
Definition: ansi_c_convert_type.cpp:292
typedef_type.h
c_typecheck_baset::add_rounding_mode
static void add_rounding_mode(exprt &)
Definition: c_typecheck_expr.cpp:61
is_signed
bool is_signed(const typet &t)
Convenience function – is the type signed?
Definition: util.cpp:45
string2integer
const mp_integer string2integer(const std::string &n, unsigned base)
Definition: mp_arith.cpp:54
configt::ansi_ct::flavourt::VISUAL_STUDIO
@ VISUAL_STUDIO
to_c_enum_type
const c_enum_typet & to_c_enum_type(const typet &type)
Cast a typet to a c_enum_typet.
Definition: c_types.h:302
type2name.h
already_typechecked_typet
Definition: c_typecheck_base.h:328
integer_typet
Unbounded, signed integers (mathematical integers, not bitvectors)
Definition: mathematical_types.h:21
to_type_with_subtype
const type_with_subtypet & to_type_with_subtype(const typet &type)
Definition: type.h:193
code_frontend_declt
A codet representing the declaration of a local variable.
Definition: std_code.h:346
c_typecheck_baset::enum_underlying_type
bitvector_typet enum_underlying_type(const mp_integer &min, const mp_integer &max, bool is_packed) const
Definition: c_typecheck_type.cpp:1125
exprt
Base class for all expressions.
Definition: expr.h:55
struct_union_typet::componentst
std::vector< componentt > componentst
Definition: std_types.h:140
symbolt::base_name
irep_idt base_name
Base (non-scoped) name.
Definition: symbol.h:46
struct_tag_typet
A struct tag type, i.e., struct_typet with an identifier.
Definition: std_types.h:448
namespace_baset::follow_tag
const union_typet & follow_tag(const union_tag_typet &) const
Follow type tag of union type.
Definition: namespace.cpp:63
complex_typet
Complex numbers made of pair of given subtype.
Definition: std_types.h:1076
invalid_source_file_exceptiont
Thrown when we can't handle something in an input source file.
Definition: exception_utils.h:171
c_enum_typet::make_incomplete
void make_incomplete()
enum types may be incomplete
Definition: c_types.h:267
vector_typet
The vector type.
Definition: std_types.h:1007
c_typecheck_baset::move_symbol
void move_symbol(symbolt &symbol, symbolt *&new_symbol)
Definition: c_typecheck_base.cpp:34
to_integer
bool to_integer(const constant_exprt &expr, mp_integer &int_value)
Convert a constant expression expr to an arbitrary-precision integer.
Definition: arith_tools.cpp:20
bool_typet
The Boolean type.
Definition: std_types.h:35
c_typecheck_baset::typecheck_type
virtual void typecheck_type(typet &type)
Definition: c_typecheck_type.cpp:35
struct_union_typet::make_incomplete
void make_incomplete()
A struct/union may be incomplete.
Definition: std_types.h:191
to_string
std::string to_string(const string_not_contains_constraintt &expr)
Used for debug printing.
Definition: string_constraint.cpp:58
messaget::eom
static eomt eom
Definition: message.h:297
unsigned_char_type
unsignedbv_typet unsigned_char_type()
Definition: c_types.cpp:145
exprt::is_true
bool is_true() const
Return whether the expression is a constant representing true.
Definition: expr.cpp:34
c_qualifiers.h
typedef_typet::get_identifier
const irep_idt & get_identifier() const
Definition: typedef_type.h:28
c_typecheck_baset::typecheck_c_bit_field_type
virtual void typecheck_c_bit_field_type(c_bit_field_typet &type)
Definition: c_typecheck_type.cpp:1490
configt::ansi_c
struct configt::ansi_ct ansi_c
to_bitvector_type
const bitvector_typet & to_bitvector_type(const typet &type)
Cast a typet to a bitvector_typet.
Definition: bitvector_types.h:32
symbol_exprt
Expression to hold a symbol (variable)
Definition: std_expr.h:112
ansi_c_declarationt::declarator
const ansi_c_declaratort & declarator() const
Definition: ansi_c_declaration.h:227
gcc_float128_type
floatbv_typet gcc_float128_type()
Definition: gcc_types.cpp:57
ansi_c_convert_typet
Definition: ansi_c_convert_type.h:23
ansi_c_declarationt::get_is_static_assert
bool get_is_static_assert() const
Definition: ansi_c_declaration.h:178
union_tag_typet
A union tag type, i.e., union_typet with an identifier.
Definition: c_types.h:176
unsigned_short_int_type
unsignedbv_typet unsigned_short_int_type()
Definition: c_types.cpp:61
code_frontend_assignt::lhs
exprt & lhs()
Definition: std_code.h:41
exprt::is_false
bool is_false() const
Return whether the expression is a constant representing false.
Definition: expr.cpp:43
c_typecheck_baset::clean_code
std::list< codet > clean_code
Definition: c_typecheck_base.h:266
to_already_typechecked_type
already_typechecked_typet & to_already_typechecked_type(typet &type)
Definition: c_typecheck_base.h:356
ansi_c_declaratort::get_name
irep_idt get_name() const
Definition: ansi_c_declaration.h:41
irept::get
const irep_idt & get(const irep_idt &name) const
Definition: irep.cpp:45
symbolt::pretty_name
irep_idt pretty_name
Language-specific display name.
Definition: symbol.h:52
c_typecheck_baset::make_constant
virtual void make_constant(exprt &expr)
Definition: c_typecheck_expr.cpp:4394
to_binary_expr
const binary_exprt & to_binary_expr(const exprt &expr)
Cast an exprt to a binary_exprt.
Definition: std_expr.h:660
unsigned_long_long_int_type
unsignedbv_typet unsigned_long_long_int_type()
Definition: c_types.cpp:111
configt::ansi_ct::char_width
std::size_t char_width
Definition: config.h:127
mathematical_types.h
unsigned_long_int_type
unsignedbv_typet unsigned_long_int_type()
Definition: c_types.cpp:104
array_typet::size
const exprt & size() const
Definition: std_types.h:800
exprt::type
typet & type()
Return the type of the expression.
Definition: expr.h:84
irept::is_not_nil
bool is_not_nil() const
Definition: irep.h:380
code_frontend_assignt::rhs
exprt & rhs()
Definition: std_code.h:46
to_code_type
const code_typet & to_code_type(const typet &type)
Cast a typet to a code_typet.
Definition: std_types.h:744
messaget::result
mstreamt & result() const
Definition: message.h:409
messaget::error
mstreamt & error() const
Definition: message.h:399
signed_int_type
signedbv_typet signed_int_type()
Definition: c_types.cpp:40
add_padding
void add_padding(struct_typet &type, const namespacet &ns)
Definition: padding.cpp:458
integer2bvrep
irep_idt integer2bvrep(const mp_integer &src, std::size_t width)
convert an integer to bit-vector representation with given width This uses two's complement for negat...
Definition: arith_tools.cpp:380
ansi_c_declaratort::get_base_name
irep_idt get_base_name() const
Definition: ansi_c_declaration.h:46
c_bit_field_typet
Type for C bit fields These are both 'bitvector_typet' (they have a width) and 'type_with_subtypet' (...
Definition: c_types.h:19
symbol_table_baset::get_writeable_ref
symbolt & get_writeable_ref(const irep_idt &name)
Find a symbol in the symbol table for read-write access.
Definition: symbol_table_base.h:121
id2string
const std::string & id2string(const irep_idt &d)
Definition: irep.h:47
messaget::mstreamt::source_location
source_locationt source_location
Definition: message.h:247
to_c_enum_tag_type
const c_enum_tag_typet & to_c_enum_tag_type(const typet &type)
Cast a typet to a c_enum_tag_typet.
Definition: c_types.h:344
gcc_signed_int128_type
signedbv_typet gcc_signed_int128_type()
Definition: gcc_types.cpp:82
type2name
static std::string type2name(const typet &type, const namespacet &ns, symbol_numbert &symbol_number)
Definition: type2name.cpp:81
irept::set
void set(const irep_idt &name, const irep_idt &value)
Definition: irep.h:420
PRECONDITION
#define PRECONDITION(CONDITION)
Definition: invariant.h:463
typet::source_location
const source_locationt & source_location() const
Definition: type.h:90
exprt::find_source_location
const source_locationt & find_source_location() const
Get a source_locationt from the expression or from its operands (non-recursively).
Definition: expr.cpp:165
c_typecheck_baset::is_complete_type
virtual bool is_complete_type(const typet &type) const
Definition: c_typecheck_code.cpp:366
struct_union_typet::componentt::set_pretty_name
void set_pretty_name(const irep_idt &name)
Definition: std_types.h:114
signed_short_int_type
signedbv_typet signed_short_int_type()
Definition: c_types.cpp:47
c_qualifierst::write
virtual void write(typet &src) const override
Definition: c_qualifiers.cpp:89
symbolt::symbol_expr
class symbol_exprt symbol_expr() const
Produces a symbol_exprt for a symbol.
Definition: symbol.cpp:121
float_type
floatbv_typet float_type()
Definition: c_types.cpp:195
pointer_expr.h
c_typecheck_baset::typecheck_c_enum_tag_type
virtual void typecheck_c_enum_tag_type(c_enum_tag_typet &type)
Definition: c_typecheck_type.cpp:1426
signed_size_type
signedbv_typet signed_size_type()
Definition: c_types.cpp:84
simplify
bool simplify(exprt &expr, const namespacet &ns)
Definition: simplify_expr.cpp:2926
configt::ansi_ct::long_long_int_width
std::size_t long_long_int_width
Definition: config.h:129
to_pointer_type
const pointer_typet & to_pointer_type(const typet &type)
Cast a typet to a pointer_typet.
Definition: pointer_expr.h:79
is_signed_or_unsigned_bitvector
bool is_signed_or_unsigned_bitvector(const typet &type)
This method tests, if the given typet is a signed or unsigned bitvector.
Definition: bitvector_types.h:19
c_qualifierst
Definition: c_qualifiers.h:61
c_enum_typet::c_enum_membert::set_identifier
void set_identifier(const irep_idt &identifier)
Definition: c_types.h:239
c_typecheck_baset::symbol_table
symbol_tablet & symbol_table
Definition: c_typecheck_base.h:68
alignment
mp_integer alignment(const typet &type, const namespacet &ns)
Definition: padding.cpp:23
pointer_type
pointer_typet pointer_type(const typet &subtype)
Definition: c_types.cpp:253
typet::remove_subtype
void remove_subtype()
Definition: type.h:87
code_frontend_assignt
A codet representing an assignment in the program.
Definition: std_code.h:23
unsigned_int_type
unsignedbv_typet unsigned_int_type()
Definition: c_types.cpp:54
irept::swap
void swap(irept &irep)
Definition: irep.h:442
code_typet
Base type of functions.
Definition: std_types.h:538
c_typecheck_baset::make_constant_index
virtual void make_constant_index(exprt &expr)
Definition: c_typecheck_expr.cpp:4414
irept::is_nil
bool is_nil() const
Definition: irep.h:376
irept::id
const irep_idt & id() const
Definition: irep.h:396
c_typecheck_baset::typecheck_typedef_type
virtual void typecheck_typedef_type(typet &type)
Definition: c_typecheck_type.cpp:1606
dstringt::empty
bool empty() const
Definition: dstring.h:88
typet::add_type
typet & add_type(const irep_idt &name)
Definition: type.h:100
c_typecheck_baset::typecheck_typeof_type
virtual void typecheck_typeof_type(typet &type)
Definition: c_typecheck_type.cpp:1570
unary_exprt::op
const exprt & op() const
Definition: std_expr.h:326
to_ansi_c_declaration
ansi_c_declarationt & to_ansi_c_declaration(exprt &expr)
Definition: ansi_c_declaration.h:248
code_typet::parameters
const parameterst & parameters() const
Definition: std_types.h:655
typet::add_source_location
source_locationt & add_source_location()
Definition: type.h:95
bitvector_typet::set_width
void set_width(std::size_t width)
Definition: std_types.h:881
to_typedef_type
const typedef_typet & to_typedef_type(const typet &type)
Cast a generic typet to a typedef_typet.
Definition: typedef_type.h:39
c_typecheck_baset::parameter_map
id_type_mapt parameter_map
Definition: c_typecheck_base.h:74
typet::add_subtype
typet & add_subtype()
Definition: type.h:71
already_typechecked_typet::get_type
typet & get_type()
Definition: c_typecheck_base.h:342
sharing_treet< irept, forward_list_as_mapt< irep_idt, irept > >::subt
typename dt::subt subt
Definition: irep.h:160
code_typet::parametert::set_base_name
void set_base_name(const irep_idt &name)
Definition: std_types.h:585
double_type
floatbv_typet double_type()
Definition: c_types.cpp:203
c_typecheck_baset::typecheck_expr
virtual void typecheck_expr(exprt &expr)
Definition: c_typecheck_expr.cpp:46
c_bit_field_typet::underlying_type
const typet & underlying_type() const
Definition: c_types.h:30
config
configt config
Definition: config.cpp:25
source_locationt
Definition: source_location.h:18
simplify_expr.h
bitvector_typet::get_width
std::size_t get_width() const
Definition: std_types.h:876
struct_union_typet::componentt
Definition: std_types.h:68
to_c_bit_field_type
const c_bit_field_typet & to_c_bit_field_type(const typet &type)
Cast a typet to a c_bit_field_typet.
Definition: c_types.h:58
configt::ansi_ct::mode
flavourt mode
Definition: config.h:237
symbolt::value
exprt value
Initial value of symbol.
Definition: symbol.h:34
messaget::get_message_handler
message_handlert & get_message_handler()
Definition: message.h:184
ansi_c_declarationt
Definition: ansi_c_declaration.h:71
irept::add
irept & add(const irep_idt &name)
Definition: irep.cpp:116
c_enum_tag_typet
C enum tag type, i.e., c_enum_typet with an identifier.
Definition: c_types.h:318
array_typet
Arrays with given size.
Definition: std_types.h:762
dstringt::end
std::string::const_iterator end() const
Definition: dstring.h:197
c_enum_typet::c_enum_membert
Definition: c_types.h:224
c_enum_typet::c_enum_membert::set_base_name
void set_base_name(const irep_idt &base_name)
Definition: c_types.h:247
bitvector_typet
Base class of fixed-width bit-vector types.
Definition: std_types.h:864
namespace_baset::follow
const typet & follow(const typet &) const
Resolve type symbol to the type it points to.
Definition: namespace.cpp:49
symbolt::location
source_locationt location
Source code location of definition of symbol.
Definition: symbol.h:37
code_typet::make_ellipsis
void make_ellipsis()
Definition: std_types.h:635
symbolt
Symbol table entry.
Definition: symbol.h:27
array_typet::index_type_nonconst
typet & index_type_nonconst()
The type of the index expressions into any instance of this type.
Definition: std_types.h:777
from_integer
constant_exprt from_integer(const mp_integer &int_value, const typet &type)
Definition: arith_tools.cpp:100
symbol_table_baset::symbols
const symbolst & symbols
Read-only field, used to look up symbols given their names.
Definition: symbol_table_base.h:30
exprt::is_constant
bool is_constant() const
Return whether the expression is a constant.
Definition: expr.cpp:27
symbolt::is_type
bool is_type
Definition: symbol.h:61
CPROVER_PREFIX
#define CPROVER_PREFIX
Definition: cprover_prefix.h:14
irept::get_sub
subt & get_sub()
Definition: irep.h:456
to_array_type
const array_typet & to_array_type(const typet &type)
Cast a typet to an array_typet.
Definition: std_types.h:844
ansi_c_declarationt::full_type
typet full_type(const ansi_c_declaratort &) const
Definition: ansi_c_declaration.cpp:94
gcc_unsigned_int128_type
unsignedbv_typet gcc_unsigned_int128_type()
Definition: gcc_types.cpp:75
code_typet::parametert
Definition: std_types.h:555
symbolt::is_static_lifetime
bool is_static_lifetime
Definition: symbol.h:65
c_typecheck_baset::typecheck_custom_type
virtual void typecheck_custom_type(typet &type)
Definition: c_typecheck_type.cpp:333
typet::find_type
const typet & find_type(const irep_idt &name) const
Definition: type.h:105
config.h
configt::ansi_ct::short_int_width
std::size_t short_int_width
Definition: config.h:128
type_with_subtypet::subtype
const typet & subtype() const
Definition: type.h:172
signed_long_int_type
signedbv_typet signed_long_int_type()
Definition: c_types.cpp:90
already_typechecked_typet::make_already_typechecked
static void make_already_typechecked(typet &type)
Definition: c_typecheck_base.h:336
code_typet::return_type
const typet & return_type() const
Definition: std_types.h:645
size_of_expr
optionalt< exprt > size_of_expr(const typet &type, const namespacet &ns)
Definition: pointer_offset_size.cpp:280
ansi_c_convert_typet::read
virtual void read(const typet &type)
Definition: ansi_c_convert_type.cpp:22
irept
There are a large number of kinds of tree structured or tree-like data in CPROVER.
Definition: irep.h:359
c_typecheck_baset::typecheck_c_enum_type
virtual void typecheck_c_enum_type(typet &type)
Definition: c_typecheck_type.cpp:1183
to_address_of_expr
const address_of_exprt & to_address_of_expr(const exprt &expr)
Cast an exprt to an address_of_exprt.
Definition: pointer_expr.h:408
symbolt::is_file_local
bool is_file_local
Definition: symbol.h:66
exprt::operands
operandst & operands()
Definition: expr.h:94
c_typecheck_baset::typecheck_compound_type
virtual void typecheck_compound_type(struct_union_typet &type)
Definition: c_typecheck_type.cpp:763
irept::remove
void remove(const irep_idt &name)
Definition: irep.cpp:96
exprt::add_source_location
source_locationt & add_source_location()
Definition: expr.h:216
typecast_exprt
Semantic type conversion.
Definition: std_expr.h:2016
size_type
unsignedbv_typet size_type()
Definition: c_types.cpp:68
c_typecheck_baset::typecheck_code_type
virtual void typecheck_code_type(code_typet &type)
Definition: c_typecheck_type.cpp:435
messaget::warning
mstreamt & warning() const
Definition: message.h:404
c_index_type
bitvector_typet c_index_type()
Definition: c_types.cpp:16
binary_exprt::op1
exprt & op1()
Definition: expr.h:128
c_typecheck_baset::mode
const irep_idt mode
Definition: c_typecheck_base.h:70
exprt::source_location
const source_locationt & source_location() const
Definition: expr.h:211
struct_union_typet::is_incomplete
bool is_incomplete() const
A struct/union may be incomplete.
Definition: std_types.h:185
configt::ansi_ct::int_width
std::size_t int_width
Definition: config.h:124
c_types.h
get_fresh_aux_symbol
symbolt & get_fresh_aux_symbol(const typet &type, const std::string &name_prefix, const std::string &basename_prefix, const source_locationt &source_location, const irep_idt &symbol_mode, const namespacet &ns, symbol_table_baset &symbol_table)
Installs a fresh-named symbol with respect to the given namespace ns with the requested name pattern ...
Definition: fresh_symbol.cpp:32
symbolt::name
irep_idt name
The unique identifier.
Definition: symbol.h:40
irept::get_bool
bool get_bool(const irep_idt &name) const
Definition: irep.cpp:58
c_qualifierst::is_transparent_union
bool is_transparent_union
Definition: c_qualifiers.h:98
c_typecheck_baset::typecheck_compound_body
virtual void typecheck_compound_body(struct_union_typet &type)
Definition: c_typecheck_type.cpp:903
configt::ansi_ct::long_int_width
std::size_t long_int_width
Definition: config.h:125
binary_exprt::op0
exprt & op0()
Definition: expr.h:125
validation_modet::INVARIANT
@ INVARIANT
c_typecheck_baset::make_index_type
virtual void make_index_type(exprt &expr)
Definition: c_typecheck_expr.cpp:1250
array_typet::element_type
const typet & element_type() const
The type of the elements of the array.
Definition: std_types.h:785
c_typecheck_baset::adjust_function_parameter
virtual void adjust_function_parameter(typet &type) const
Definition: c_typecheck_type.cpp:1655
padding.h
to_constant_expr
const constant_exprt & to_constant_expr(const exprt &expr)
Cast an exprt to a constant_exprt.
Definition: std_expr.h:2992
integer2string
const std::string integer2string(const mp_integer &n, unsigned base)
Definition: mp_arith.cpp:103