CBMC
Loading...
Searching...
No Matches
ansi_c_internal_additions.cpp
Go to the documentation of this file.
1/*******************************************************************\
2
3Module:
4
5Author: 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
41const 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
45const 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
88const 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
102const 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
106const 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
110const 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
114const 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
118const 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
122static 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
128template <typename T>
129static 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
136void 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"
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 "natural;\n"
148 "typedef void " CPROVER_PREFIX "rational;\n"
149 "typedef void " CPROVER_PREFIX "real;\n"
150 "extern unsigned char " CPROVER_PREFIX "memory["
151 CPROVER_PREFIX "constant_infinity_uint];\n"
152
153 // malloc
154 "const void *" CPROVER_PREFIX "deallocated=0;\n"
155 "const void *" CPROVER_PREFIX "dead_object=0;\n"
156 "const void *" CPROVER_PREFIX "memory_leak=0;\n"
157 "void *" CPROVER_PREFIX "allocate("
158 CPROVER_PREFIX "size_t size, " CPROVER_PREFIX "bool zero);\n"
159 "void " CPROVER_PREFIX "deallocate(void *);\n"
160
161 CPROVER_PREFIX "thread_local " CPROVER_PREFIX "size_t "
162 CPROVER_PREFIX "max_malloc_size="+
164 if(config.ansi_c.pointer_width==config.ansi_c.long_int_width)
165 code += "UL;\n";
166 else if(config.ansi_c.pointer_width==config.ansi_c.long_long_int_width)
167 code += "ULL;\n";
168 else
169 code += "U;\n";
170
171 code+=
172 // this is ANSI-C
173 "extern " CPROVER_PREFIX "thread_local const char __func__["
174 CPROVER_PREFIX "constant_infinity_uint];\n"
175
176 // this is GCC
177 "extern " CPROVER_PREFIX "thread_local const char __FUNCTION__["
178 CPROVER_PREFIX "constant_infinity_uint];\n"
179 "extern " CPROVER_PREFIX "thread_local const char __PRETTY_FUNCTION__["
180 CPROVER_PREFIX "constant_infinity_uint];\n"
181
182 // float stuff
183 "int " CPROVER_PREFIX "thread_local " +
185 std::to_string(config.ansi_c.rounding_mode)+";\n"
186
187 // pipes, write, read, close
188 "struct " CPROVER_PREFIX "pipet {\n"
189 " _Bool widowed;\n"
190 " char data[4];\n"
191 " short next_avail;\n"
192 " short next_unread;\n"
193 "};\n"
194 "\n"
195 // This function needs to be declared, or otherwise can't be called
196 // by the entry-point construction.
197 "void " INITIALIZE_FUNCTION "(void);\n"
198 "\n"
199 // frame specifications for contracts
200 // Declares a range of bytes as assignable (internal representation)
201 "void " CPROVER_PREFIX "assignable(void *ptr,\n"
202 " " CPROVER_PREFIX "size_t size,\n"
203 " " CPROVER_PREFIX "bool is_ptr_to_ptr);\n"
204 // Declares a range of bytes as assignable
205 "void " CPROVER_PREFIX "object_upto(void *ptr, \n"
206 " " CPROVER_PREFIX "size_t size);\n"
207 // Declares bytes from ptr to the end of the object as assignable
208 "void " CPROVER_PREFIX "object_from(void *ptr);\n"
209 // Declares the whole object pointed to by ptr as assignable
210 "void " CPROVER_PREFIX "object_whole(void *ptr);\n"
211 // Declares a pointer as freeable
212 "void " CPROVER_PREFIX "freeable(void *ptr);\n"
213 // True iff ptr satisfies the preconditions of the free stdlib function
214 CPROVER_PREFIX "bool " CPROVER_PREFIX "is_freeable(void *ptr);\n"
215 // True iff ptr was freed during function execution or loop execution
216 CPROVER_PREFIX "bool " CPROVER_PREFIX "was_freed(void *ptr);\n"
217 "\n";
218 // clang-format on
219
220 // GCC junk stuff, also for CLANG and ARM
221 if(
225 {
227 if(support_float16_type)
228 {
229 code +=
230 "typedef _Float16 __gcc_v8hf __attribute__((__vector_size__(16)));\n";
231 code +=
232 "typedef _Float16 __gcc_v16hf __attribute__((__vector_size__(32)));\n";
233 code +=
234 "typedef _Float16 __gcc_v32hf __attribute__((__vector_size__(64)));\n";
235 }
236
237 // there are many more, e.g., look at
238 // https://developer.apple.com/library/mac/#documentation/developertools/gcc-4.0.1/gcc/Target-Builtins.html
239
240 if(
241 config.ansi_c.arch == "i386" || config.ansi_c.arch == "x86_64" ||
242 config.ansi_c.arch == "x32" || config.ansi_c.arch == "ia64" ||
243 config.ansi_c.arch == "powerpc" || config.ansi_c.arch == "ppc64")
244 {
245 // https://gcc.gnu.org/onlinedocs/gcc/Floating-Types.html
246 // For clang, __float128 is a keyword.
247 // For gcc, this is a typedef and not a keyword.
248 if(
250 config.ansi_c.gcc__float128_type)
251 {
252 code += "typedef " CPROVER_PREFIX "Float128 __float128;\n";
253 }
254 }
255 else if(config.ansi_c.arch == "ppc64le")
256 {
257 // https://patchwork.ozlabs.org/patch/792295/
259 code += "typedef " CPROVER_PREFIX "Float128 __ieee128;\n";
260 }
261 else if(config.ansi_c.arch == "hppa")
262 {
263 // https://gcc.gnu.org/onlinedocs/gcc/Floating-Types.html
264 // For clang, __float128 is a keyword.
265 // For gcc, this is a typedef and not a keyword.
266 if(
268 config.ansi_c.gcc__float128_type)
269 {
270 code+="typedef long double __float128;\n";
271 }
272 }
273
274 if(
275 config.ansi_c.arch == "i386" || config.ansi_c.arch == "x86_64" ||
276 config.ansi_c.arch == "x32" || config.ansi_c.arch == "ia64")
277 {
278 // clang doesn't do __float80
279 // Note that __float80 is a typedef, and not a keyword.
281 code += "typedef " CPROVER_PREFIX "Float64x __float80;\n";
282 }
283
284 // On 64-bit systems, gcc has typedefs
285 // __int128_t und __uint128_t -- but not on 32 bit!
286 if(config.ansi_c.long_int_width>=64)
287 {
288 code+="typedef signed __int128 __int128_t;\n"
289 "typedef unsigned __int128 __uint128_t;\n";
290 }
291
292 if(
293 config.ansi_c.arch == "arm64" &&
295 {
296 code += "typedef struct __va_list {";
297 code += "void *__stack;";
298 code += "void *__gr_top;";
299 code += "void *__vr_top;";
300 code += "int __gr_offs;";
301 code += "int __vr_offs;";
302 code += " } __builtin_va_list;\n";
303 }
304 else
305 {
306 code += "typedef void ** __builtin_va_list;\n";
307 }
308 }
309
310 // this is Visual C/C++ only
312 code += "int __assume(int);\n";
313
314 // ARM stuff
317
318 // CW stuff
320 code+=cw_builtin_headers;
321
322 // Architecture strings
324}
325
326void ansi_c_architecture_strings(std::string &code)
327{
328 // The following are CPROVER-specific.
329 // They allow identifying the architectural settings used
330 // at compile time from a goto-binary.
331
332 code += "#line 1 \"<builtin-architecture-strings>\"\n";
333
334 code+=architecture_string(config.ansi_c.int_width, "int_width");
335 code+=architecture_string(config.ansi_c.int_width, "word_size"); // old
336 code+=architecture_string(config.ansi_c.long_int_width, "long_int_width");
337 code+=architecture_string(config.ansi_c.bool_width, "bool_width");
338 code+=architecture_string(config.ansi_c.char_width, "char_width");
339 code+=architecture_string(config.ansi_c.short_int_width, "short_int_width");
340 code+=architecture_string(config.ansi_c.long_long_int_width, "long_long_int_width"); // NOLINT(whitespace/line_length)
341 code+=architecture_string(config.ansi_c.pointer_width, "pointer_width");
342 code+=architecture_string(config.ansi_c.single_width, "single_width");
343 code+=architecture_string(config.ansi_c.double_width, "double_width");
344 code+=architecture_string(config.ansi_c.long_double_width, "long_double_width"); // NOLINT(whitespace/line_length)
345 code+=architecture_string(config.ansi_c.wchar_t_width, "wchar_t_width");
346 code+=architecture_string(config.ansi_c.char_is_unsigned, "char_is_unsigned");
347 code+=architecture_string(config.ansi_c.wchar_t_is_unsigned, "wchar_t_is_unsigned"); // NOLINT(whitespace/line_length)
348 code+=architecture_string(config.ansi_c.alignment, "alignment");
349 code+=architecture_string(config.ansi_c.memory_operand_size, "memory_operand_size"); // NOLINT(whitespace/line_length)
350 code+=architecture_string(static_cast<int>(config.ansi_c.endianness), "endianness"); // NOLINT(whitespace/line_length)
351 code+=architecture_string(id2string(config.ansi_c.arch), "arch");
352 code+=architecture_string(configt::ansi_ct::os_to_string(config.ansi_c.os), "os"); // NOLINT(whitespace/line_length)
353 code+=architecture_string(config.ansi_c.NULL_is_zero, "NULL_is_zero");
354}
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
ait supplies three of the four components needed: an abstract interpreter (in this case handling func...
Definition ai.h:562
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:1603
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
static std::string os_to_string(ost)
Definition config.cpp:1284