CBMC
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
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 "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="+
162 if(config.ansi_c.pointer_width==config.ansi_c.long_int_width)
163 code += "UL;\n";
164 else if(config.ansi_c.pointer_width==config.ansi_c.long_long_int_width)
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 " +
183 std::to_string(config.ansi_c.rounding_mode)+";\n"
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(
248 config.ansi_c.gcc__float128_type)
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(
266 config.ansi_c.gcc__float128_type)
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!
284 if(config.ansi_c.long_int_width>=64)
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
298
299 // CW stuff
301 code+=cw_builtin_headers;
302
303 // Architecture strings
305}
306
307void 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)
332 code+=architecture_string(id2string(config.ansi_c.arch), "arch");
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
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:1597
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:1278