CBMC
ansi_c_internal_additions.cpp
Go to the documentation of this file.
1 /*******************************************************************\
2 
3 Module:
4 
5 Author: Daniel Kroening, kroening@kroening.com
6 
7 \*******************************************************************/
8 
10 
11 #include <util/c_types.h>
12 #include <util/config.h>
13 
15 
17 
18 #include "ansi_c_parser.h"
19 
21  "#line 1 \"gcc_builtin_headers_types.h\"\n"
22 #include "compiler_headers/gcc_builtin_headers_types.inc" // IWYU pragma: keep
23  ; // NOLINT(whitespace/semicolon)
24 
26  "#line 1 \"gcc_builtin_headers_generic.h\"\n"
27 #include "compiler_headers/gcc_builtin_headers_generic.inc" // IWYU pragma: keep
28  ; // NOLINT(whitespace/semicolon)
29 
31  "#line 1 \"gcc_builtin_headers_math.h\"\n"
32 #include "compiler_headers/gcc_builtin_headers_math.inc" // IWYU pragma: keep
33  ; // NOLINT(whitespace/semicolon)
34 
36  "#line 1 \"gcc_builtin_headers_mem_string.h\"\n"
37 // NOLINTNEXTLINE(whitespace/line_length)
38 #include "compiler_headers/gcc_builtin_headers_mem_string.inc" // IWYU pragma: keep
39  ; // NOLINT(whitespace/semicolon)
40 
41 const char gcc_builtin_headers_omp[] = "#line 1 \"gcc_builtin_headers_omp.h\"\n"
42 #include "compiler_headers/gcc_builtin_headers_omp.inc" // IWYU pragma: keep
43  ; // NOLINT(whitespace/semicolon)
44 
45 const char gcc_builtin_headers_tm[] = "#line 1 \"gcc_builtin_headers_tm.h\"\n"
46 #include "compiler_headers/gcc_builtin_headers_tm.inc" // IWYU pragma: keep
47  ; // NOLINT(whitespace/semicolon)
48 
50  "#line 1 \"gcc_builtin_headers_ubsan.h\"\n"
51 #include "compiler_headers/gcc_builtin_headers_ubsan.inc" // IWYU pragma: keep
52  ; // NOLINT(whitespace/semicolon)
53 
55  "#line 1 \"gcc_builtin_headers_ia32.h\"\n"
56 #include "compiler_headers/gcc_builtin_headers_ia32.inc" // IWYU pragma: keep
57  ; // NOLINT(whitespace/semicolon)
59 #include "compiler_headers/gcc_builtin_headers_ia32-2.inc" // IWYU pragma: keep
60  ; // NOLINT(whitespace/semicolon)
62 #include "compiler_headers/gcc_builtin_headers_ia32-3.inc" // IWYU pragma: keep
63  ; // NOLINT(whitespace/semicolon)
65 #include "compiler_headers/gcc_builtin_headers_ia32-4.inc" // IWYU pragma: keep
66  ; // NOLINT(whitespace/semicolon)
68 #include "compiler_headers/gcc_builtin_headers_ia32-5.inc" // IWYU pragma: keep
69  ; // NOLINT(whitespace/semicolon)
71 #include "compiler_headers/gcc_builtin_headers_ia32-6.inc" // IWYU pragma: keep
72  ; // NOLINT(whitespace/semicolon)
74 #include "compiler_headers/gcc_builtin_headers_ia32-7.inc" // IWYU pragma: keep
75  ; // NOLINT(whitespace/semicolon)
77 #include "compiler_headers/gcc_builtin_headers_ia32-8.inc" // IWYU pragma: keep
78  ; // NOLINT(whitespace/semicolon)
80 #include "compiler_headers/gcc_builtin_headers_ia32-9.inc" // IWYU pragma: keep
81  ; // NOLINT(whitespace/semicolon)
82 
84  "#line 1 \"gcc_builtin_headers_alpha.h\"\n"
85 #include "compiler_headers/gcc_builtin_headers_alpha.inc" // IWYU pragma: keep
86  ; // NOLINT(whitespace/semicolon)
87 
88 const char gcc_builtin_headers_arm[] = "#line 1 \"gcc_builtin_headers_arm.h\"\n"
89 #include "compiler_headers/gcc_builtin_headers_arm.inc" // IWYU pragma: keep
90  ; // NOLINT(whitespace/semicolon)
91 
93  "#line 1 \"gcc_builtin_headers_mips.h\"\n"
94 #include "compiler_headers/gcc_builtin_headers_mips.inc" // IWYU pragma: keep
95  ; // NOLINT(whitespace/semicolon)
96 
98  "#line 1 \"gcc_builtin_headers_power.h\"\n"
99 #include "compiler_headers/gcc_builtin_headers_power.inc" // IWYU pragma: keep
100  ; // NOLINT(whitespace/semicolon)
101 
102 const char arm_builtin_headers[] = "#line 1 \"arm_builtin_headers.h\"\n"
103 #include "compiler_headers/arm_builtin_headers.inc" // IWYU pragma: keep
104  ; // NOLINT(whitespace/semicolon)
105 
106 const char cw_builtin_headers[] = "#line 1 \"cw_builtin_headers.h\"\n"
107 #include "compiler_headers/cw_builtin_headers.inc" // IWYU pragma: keep
108  ; // NOLINT(whitespace/semicolon)
109 
110 const char clang_builtin_headers[] = "#line 1 \"clang_builtin_headers.h\"\n"
111 #include "compiler_headers/clang_builtin_headers.inc" // IWYU pragma: keep
112  ; // NOLINT(whitespace/semicolon)
113 
114 const char cprover_builtin_headers[] = "#line 1 \"cprover_builtin_headers.h\"\n"
115 #include "cprover_builtin_headers.inc" // IWYU pragma: keep
116  ; // NOLINT(whitespace/semicolon)
117 
118 const char windows_builtin_headers[] = "#line 1 \"windows_builtin_headers.h\"\n"
119 #include "compiler_headers/windows_builtin_headers.inc" // IWYU pragma: keep
120  ; // NOLINT(whitespace/semicolon)
121 
122 static std::string architecture_string(const std::string &value, const char *s)
123 {
124  return std::string("const char *" CPROVER_PREFIX "architecture_") +
125  std::string(s) + "=\"" + value + "\";\n";
126 }
127 
128 template <typename T>
129 static std::string architecture_string(T value, const char *s)
130 {
131  return std::string("const " CPROVER_PREFIX "integer " CPROVER_PREFIX
132  "architecture_") +
133  std::string(s) + "=" + std::to_string(value) + ";\n";
134 }
135 
136 void ansi_c_internal_additions(std::string &code, bool support_float16_type)
137 {
138  // clang-format off
139  // do the built-in types and variables
140  code+=
141  "#line 1 \"<built-in-additions>\"\n"
142  "typedef __typeof__(sizeof(int)) " CPROVER_PREFIX "size_t;\n"
143  "typedef "+c_type_as_string(signed_size_type().get(ID_C_c_type))+
144  " " CPROVER_PREFIX "ssize_t;\n"
145  "const unsigned " CPROVER_PREFIX "constant_infinity_uint;\n"
146  "typedef void " CPROVER_PREFIX "integer;\n"
147  "typedef void " CPROVER_PREFIX "rational;\n"
148  "extern unsigned char " CPROVER_PREFIX "memory["
149  CPROVER_PREFIX "constant_infinity_uint];\n"
150 
151  // malloc
152  "const void *" CPROVER_PREFIX "deallocated=0;\n"
153  "const void *" CPROVER_PREFIX "dead_object=0;\n"
154  "const void *" CPROVER_PREFIX "memory_leak=0;\n"
155  "void *" CPROVER_PREFIX "allocate("
156  CPROVER_PREFIX "size_t size, " CPROVER_PREFIX "bool zero);\n"
157  "void " CPROVER_PREFIX "deallocate(void *);\n"
158 
159  CPROVER_PREFIX "thread_local " CPROVER_PREFIX "size_t "
160  CPROVER_PREFIX "max_malloc_size="+
163  code += "UL;\n";
165  code += "ULL;\n";
166  else
167  code += "U;\n";
168 
169  code+=
170  // this is ANSI-C
171  "extern " CPROVER_PREFIX "thread_local const char __func__["
172  CPROVER_PREFIX "constant_infinity_uint];\n"
173 
174  // this is GCC
175  "extern " CPROVER_PREFIX "thread_local const char __FUNCTION__["
176  CPROVER_PREFIX "constant_infinity_uint];\n"
177  "extern " CPROVER_PREFIX "thread_local const char __PRETTY_FUNCTION__["
178  CPROVER_PREFIX "constant_infinity_uint];\n"
179 
180  // float stuff
181  "int " CPROVER_PREFIX "thread_local " +
184 
185  // pipes, write, read, close
186  "struct " CPROVER_PREFIX "pipet {\n"
187  " _Bool widowed;\n"
188  " char data[4];\n"
189  " short next_avail;\n"
190  " short next_unread;\n"
191  "};\n"
192  "\n"
193  // This function needs to be declared, or otherwise can't be called
194  // by the entry-point construction.
195  "void " INITIALIZE_FUNCTION "(void);\n"
196  "\n"
197  // frame specifications for contracts
198  // Declares a range of bytes as assignable (internal representation)
199  "void " CPROVER_PREFIX "assignable(void *ptr,\n"
200  " " CPROVER_PREFIX "size_t size,\n"
201  " " CPROVER_PREFIX "bool is_ptr_to_ptr);\n"
202  // Declares a range of bytes as assignable
203  "void " CPROVER_PREFIX "object_upto(void *ptr, \n"
204  " " CPROVER_PREFIX "size_t size);\n"
205  // Declares bytes from ptr to the end of the object as assignable
206  "void " CPROVER_PREFIX "object_from(void *ptr);\n"
207  // Declares the whole object pointed to by ptr as assignable
208  "void " CPROVER_PREFIX "object_whole(void *ptr);\n"
209  // Declares a pointer as freeable
210  "void " CPROVER_PREFIX "freeable(void *ptr);\n"
211  // True iff ptr satisfies the preconditions of the free stdlib function
212  CPROVER_PREFIX "bool " CPROVER_PREFIX "is_freeable(void *ptr);\n"
213  // True iff ptr was freed during function execution or loop execution
214  CPROVER_PREFIX "bool " CPROVER_PREFIX "was_freed(void *ptr);\n"
215  "\n";
216  // clang-format on
217 
218  // GCC junk stuff, also for CLANG and ARM
219  if(
223  {
225  if(support_float16_type)
226  {
227  code +=
228  "typedef _Float16 __gcc_v8hf __attribute__((__vector_size__(16)));\n";
229  code +=
230  "typedef _Float16 __gcc_v16hf __attribute__((__vector_size__(32)));\n";
231  code +=
232  "typedef _Float16 __gcc_v32hf __attribute__((__vector_size__(64)));\n";
233  }
234 
235  // there are many more, e.g., look at
236  // https://developer.apple.com/library/mac/#documentation/developertools/gcc-4.0.1/gcc/Target-Builtins.html
237 
238  if(
239  config.ansi_c.arch == "i386" || config.ansi_c.arch == "x86_64" ||
240  config.ansi_c.arch == "x32" || config.ansi_c.arch == "ia64" ||
241  config.ansi_c.arch == "powerpc" || config.ansi_c.arch == "ppc64")
242  {
243  // https://gcc.gnu.org/onlinedocs/gcc/Floating-Types.html
244  // For clang, __float128 is a keyword.
245  // For gcc, this is a typedef and not a keyword.
246  if(
249  {
250  code += "typedef " CPROVER_PREFIX "Float128 __float128;\n";
251  }
252  }
253  else if(config.ansi_c.arch == "ppc64le")
254  {
255  // https://patchwork.ozlabs.org/patch/792295/
257  code += "typedef " CPROVER_PREFIX "Float128 __ieee128;\n";
258  }
259  else if(config.ansi_c.arch == "hppa")
260  {
261  // https://gcc.gnu.org/onlinedocs/gcc/Floating-Types.html
262  // For clang, __float128 is a keyword.
263  // For gcc, this is a typedef and not a keyword.
264  if(
267  {
268  code+="typedef long double __float128;\n";
269  }
270  }
271 
272  if(
273  config.ansi_c.arch == "i386" || config.ansi_c.arch == "x86_64" ||
274  config.ansi_c.arch == "x32" || config.ansi_c.arch == "ia64")
275  {
276  // clang doesn't do __float80
277  // Note that __float80 is a typedef, and not a keyword.
279  code += "typedef " CPROVER_PREFIX "Float64x __float80;\n";
280  }
281 
282  // On 64-bit systems, gcc has typedefs
283  // __int128_t und __uint128_t -- but not on 32 bit!
285  {
286  code+="typedef signed __int128 __int128_t;\n"
287  "typedef unsigned __int128 __uint128_t;\n";
288  }
289  }
290 
291  // this is Visual C/C++ only
293  code += "int __assume(int);\n";
294 
295  // ARM stuff
297  code+=arm_builtin_headers;
298 
299  // CW stuff
301  code+=cw_builtin_headers;
302 
303  // Architecture strings
305 }
306 
307 void ansi_c_architecture_strings(std::string &code)
308 {
309  // The following are CPROVER-specific.
310  // They allow identifying the architectural settings used
311  // at compile time from a goto-binary.
312 
313  code += "#line 1 \"<builtin-architecture-strings>\"\n";
314 
315  code+=architecture_string(config.ansi_c.int_width, "int_width");
316  code+=architecture_string(config.ansi_c.int_width, "word_size"); // old
317  code+=architecture_string(config.ansi_c.long_int_width, "long_int_width");
318  code+=architecture_string(config.ansi_c.bool_width, "bool_width");
319  code+=architecture_string(config.ansi_c.char_width, "char_width");
320  code+=architecture_string(config.ansi_c.short_int_width, "short_int_width");
321  code+=architecture_string(config.ansi_c.long_long_int_width, "long_long_int_width"); // NOLINT(whitespace/line_length)
322  code+=architecture_string(config.ansi_c.pointer_width, "pointer_width");
323  code+=architecture_string(config.ansi_c.single_width, "single_width");
324  code+=architecture_string(config.ansi_c.double_width, "double_width");
325  code+=architecture_string(config.ansi_c.long_double_width, "long_double_width"); // NOLINT(whitespace/line_length)
326  code+=architecture_string(config.ansi_c.wchar_t_width, "wchar_t_width");
327  code+=architecture_string(config.ansi_c.char_is_unsigned, "char_is_unsigned");
328  code+=architecture_string(config.ansi_c.wchar_t_is_unsigned, "wchar_t_is_unsigned"); // NOLINT(whitespace/line_length)
329  code+=architecture_string(config.ansi_c.alignment, "alignment");
330  code+=architecture_string(config.ansi_c.memory_operand_size, "memory_operand_size"); // NOLINT(whitespace/line_length)
331  code+=architecture_string(static_cast<int>(config.ansi_c.endianness), "endianness"); // NOLINT(whitespace/line_length)
333  code+=architecture_string(configt::ansi_ct::os_to_string(config.ansi_c.os), "os"); // NOLINT(whitespace/line_length)
334  code+=architecture_string(config.ansi_c.NULL_is_zero, "NULL_is_zero");
335 }
irep_idt rounding_mode_identifier()
Return the identifier of the program symbol used to store the current rounding mode.
Symbolic Execution.
const char gcc_builtin_headers_ia32_7[]
static std::string architecture_string(const std::string &value, const char *s)
const char gcc_builtin_headers_types[]
const char cprover_builtin_headers[]
const char gcc_builtin_headers_ia32[]
const char gcc_builtin_headers_ia32_2[]
const char gcc_builtin_headers_ia32_5[]
const char gcc_builtin_headers_ubsan[]
void ansi_c_internal_additions(std::string &code, bool support_float16_type)
const char windows_builtin_headers[]
const char gcc_builtin_headers_ia32_8[]
const char gcc_builtin_headers_mem_string[]
const char gcc_builtin_headers_ia32_4[]
const char gcc_builtin_headers_generic[]
const char gcc_builtin_headers_tm[]
const char gcc_builtin_headers_ia32_9[]
const char cw_builtin_headers[]
const char gcc_builtin_headers_math[]
const char gcc_builtin_headers_arm[]
const char gcc_builtin_headers_ia32_6[]
const char gcc_builtin_headers_mips[]
const char clang_builtin_headers[]
const char gcc_builtin_headers_alpha[]
const char arm_builtin_headers[]
const char gcc_builtin_headers_omp[]
const char gcc_builtin_headers_ia32_3[]
const char gcc_builtin_headers_power[]
void ansi_c_architecture_strings(std::string &code)
configt config
Definition: config.cpp:25
std::string c_type_as_string(const irep_idt &c_type)
Definition: c_types.cpp:251
signedbv_typet signed_size_type()
Definition: c_types.cpp:66
mp_integer max_malloc_size() const
The maximum allocation size is determined by the number of bits that are left in the pointer of width...
Definition: config.cpp:1587
struct configt::ansi_ct ansi_c
#define CPROVER_PREFIX
const std::string & id2string(const irep_idt &d)
Definition: irep.h:44
const std::string integer2string(const mp_integer &n, unsigned base)
Definition: mp_arith.cpp:103
#define INITIALIZE_FUNCTION
std::string to_string(const string_not_contains_constraintt &expr)
Used for debug printing.
std::size_t long_double_width
Definition: config.h:146
endiannesst endianness
Definition: config.h:209
bool wchar_t_is_unsigned
Definition: config.h:150
static std::string os_to_string(ost)
Definition: config.cpp:1268
std::size_t pointer_width
Definition: config.h:143
bool gcc__float128_type
Definition: config.h:153
irep_idt arch
Definition: config.h:223
ieee_floatt::rounding_modet rounding_mode
Definition: config.h:183
std::size_t wchar_t_width
Definition: config.h:147
std::size_t double_width
Definition: config.h:145
bool char_is_unsigned
Definition: config.h:150
std::size_t alignment
Definition: config.h:197
std::size_t bool_width
Definition: config.h:139
std::size_t memory_operand_size
Definition: config.h:201
std::size_t long_long_int_width
Definition: config.h:142
bool NULL_is_zero
Definition: config.h:226
std::size_t long_int_width
Definition: config.h:138
std::size_t single_width
Definition: config.h:144
std::size_t short_int_width
Definition: config.h:141
std::size_t char_width
Definition: config.h:140
flavourt mode
Definition: config.h:256
std::size_t int_width
Definition: config.h:137