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)
73 
75  "#line 1 \"gcc_builtin_headers_alpha.h\"\n"
76 #include "compiler_headers/gcc_builtin_headers_alpha.inc" // IWYU pragma: keep
77  ; // NOLINT(whitespace/semicolon)
78 
79 const char gcc_builtin_headers_arm[] = "#line 1 \"gcc_builtin_headers_arm.h\"\n"
80 #include "compiler_headers/gcc_builtin_headers_arm.inc" // IWYU pragma: keep
81  ; // NOLINT(whitespace/semicolon)
82 
84  "#line 1 \"gcc_builtin_headers_mips.h\"\n"
85 #include "compiler_headers/gcc_builtin_headers_mips.inc" // IWYU pragma: keep
86  ; // NOLINT(whitespace/semicolon)
87 
89  "#line 1 \"gcc_builtin_headers_power.h\"\n"
90 #include "compiler_headers/gcc_builtin_headers_power.inc" // IWYU pragma: keep
91  ; // NOLINT(whitespace/semicolon)
92 
93 const char arm_builtin_headers[] = "#line 1 \"arm_builtin_headers.h\"\n"
94 #include "compiler_headers/arm_builtin_headers.inc" // IWYU pragma: keep
95  ; // NOLINT(whitespace/semicolon)
96 
97 const char cw_builtin_headers[] = "#line 1 \"cw_builtin_headers.h\"\n"
98 #include "compiler_headers/cw_builtin_headers.inc" // IWYU pragma: keep
99  ; // NOLINT(whitespace/semicolon)
100 
101 const char clang_builtin_headers[] = "#line 1 \"clang_builtin_headers.h\"\n"
102 #include "compiler_headers/clang_builtin_headers.inc" // IWYU pragma: keep
103  ; // NOLINT(whitespace/semicolon)
104 
105 const char cprover_builtin_headers[] = "#line 1 \"cprover_builtin_headers.h\"\n"
106 #include "cprover_builtin_headers.inc" // IWYU pragma: keep
107  ; // NOLINT(whitespace/semicolon)
108 
109 const char windows_builtin_headers[] = "#line 1 \"windows_builtin_headers.h\"\n"
110 #include "compiler_headers/windows_builtin_headers.inc" // IWYU pragma: keep
111  ; // NOLINT(whitespace/semicolon)
112 
113 static std::string architecture_string(const std::string &value, const char *s)
114 {
115  return std::string("const char *" CPROVER_PREFIX "architecture_") +
116  std::string(s) + "=\"" + value + "\";\n";
117 }
118 
119 template <typename T>
120 static std::string architecture_string(T value, const char *s)
121 {
122  return std::string("const " CPROVER_PREFIX "integer " CPROVER_PREFIX
123  "architecture_") +
124  std::string(s) + "=" + std::to_string(value) + ";\n";
125 }
126 
127 void ansi_c_internal_additions(std::string &code, bool support_float16_type)
128 {
129  // clang-format off
130  // do the built-in types and variables
131  code+=
132  "#line 1 \"<built-in-additions>\"\n"
133  "typedef __typeof__(sizeof(int)) " CPROVER_PREFIX "size_t;\n"
134  "typedef "+c_type_as_string(signed_size_type().get(ID_C_c_type))+
135  " " CPROVER_PREFIX "ssize_t;\n"
136  "const unsigned " CPROVER_PREFIX "constant_infinity_uint;\n"
137  "typedef void " CPROVER_PREFIX "integer;\n"
138  "typedef void " CPROVER_PREFIX "rational;\n"
139  "extern unsigned char " CPROVER_PREFIX "memory["
140  CPROVER_PREFIX "constant_infinity_uint];\n"
141 
142  // malloc
143  "const void *" CPROVER_PREFIX "deallocated=0;\n"
144  "const void *" CPROVER_PREFIX "dead_object=0;\n"
145  "const void *" CPROVER_PREFIX "memory_leak=0;\n"
146  "void *" CPROVER_PREFIX "allocate("
147  CPROVER_PREFIX "size_t size, " CPROVER_PREFIX "bool zero);\n"
148  "void " CPROVER_PREFIX "deallocate(void *);\n"
149 
150  CPROVER_PREFIX "thread_local " CPROVER_PREFIX "size_t "
151  CPROVER_PREFIX "max_malloc_size="+
154  code += "UL;\n";
156  code += "ULL;\n";
157  else
158  code += "U;\n";
159 
160  code+=
161  // this is ANSI-C
162  "extern " CPROVER_PREFIX "thread_local const char __func__["
163  CPROVER_PREFIX "constant_infinity_uint];\n"
164 
165  // this is GCC
166  "extern " CPROVER_PREFIX "thread_local const char __FUNCTION__["
167  CPROVER_PREFIX "constant_infinity_uint];\n"
168  "extern " CPROVER_PREFIX "thread_local const char __PRETTY_FUNCTION__["
169  CPROVER_PREFIX "constant_infinity_uint];\n"
170 
171  // float stuff
172  "int " CPROVER_PREFIX "thread_local " +
175 
176  // pipes, write, read, close
177  "struct " CPROVER_PREFIX "pipet {\n"
178  " _Bool widowed;\n"
179  " char data[4];\n"
180  " short next_avail;\n"
181  " short next_unread;\n"
182  "};\n"
183  "\n"
184  // This function needs to be declared, or otherwise can't be called
185  // by the entry-point construction.
186  "void " INITIALIZE_FUNCTION "(void);\n"
187  "\n"
188  // frame specifications for contracts
189  // Declares a range of bytes as assignable (internal representation)
190  "void " CPROVER_PREFIX "assignable(void *ptr,\n"
191  " " CPROVER_PREFIX "size_t size,\n"
192  " " CPROVER_PREFIX "bool is_ptr_to_ptr);\n"
193  // Declares a range of bytes as assignable
194  "void " CPROVER_PREFIX "object_upto(void *ptr, \n"
195  " " CPROVER_PREFIX "size_t size);\n"
196  // Declares bytes from ptr to the end of the object as assignable
197  "void " CPROVER_PREFIX "object_from(void *ptr);\n"
198  // Declares the whole object pointed to by ptr as assignable
199  "void " CPROVER_PREFIX "object_whole(void *ptr);\n"
200  // Declares a pointer as freeable
201  "void " CPROVER_PREFIX "freeable(void *ptr);\n"
202  // True iff ptr satisfies the preconditions of the free stdlib function
203  CPROVER_PREFIX "bool " CPROVER_PREFIX "is_freeable(void *ptr);\n"
204  // True iff ptr was freed during function execution or loop execution
205  CPROVER_PREFIX "bool " CPROVER_PREFIX "was_freed(void *ptr);\n"
206  "\n";
207  // clang-format on
208 
209  // GCC junk stuff, also for CLANG and ARM
210  if(
214  {
216  if(support_float16_type)
217  {
218  code +=
219  "typedef _Float16 __gcc_v8hf __attribute__((__vector_size__(16)));\n";
220  code +=
221  "typedef _Float16 __gcc_v16hf __attribute__((__vector_size__(32)));\n";
222  code +=
223  "typedef _Float16 __gcc_v32hf __attribute__((__vector_size__(64)));\n";
224  }
225 
226  // there are many more, e.g., look at
227  // https://developer.apple.com/library/mac/#documentation/developertools/gcc-4.0.1/gcc/Target-Builtins.html
228 
229  if(
230  config.ansi_c.arch == "i386" || config.ansi_c.arch == "x86_64" ||
231  config.ansi_c.arch == "x32" || config.ansi_c.arch == "ia64" ||
232  config.ansi_c.arch == "powerpc" || config.ansi_c.arch == "ppc64")
233  {
234  // https://gcc.gnu.org/onlinedocs/gcc/Floating-Types.html
235  // For clang, __float128 is a keyword.
236  // For gcc, this is a typedef and not a keyword.
237  if(
240  {
241  code += "typedef " CPROVER_PREFIX "Float128 __float128;\n";
242  }
243  }
244  else if(config.ansi_c.arch == "ppc64le")
245  {
246  // https://patchwork.ozlabs.org/patch/792295/
248  code += "typedef " CPROVER_PREFIX "Float128 __ieee128;\n";
249  }
250  else if(config.ansi_c.arch == "hppa")
251  {
252  // https://gcc.gnu.org/onlinedocs/gcc/Floating-Types.html
253  // For clang, __float128 is a keyword.
254  // For gcc, this is a typedef and not a keyword.
255  if(
258  {
259  code+="typedef long double __float128;\n";
260  }
261  }
262 
263  if(
264  config.ansi_c.arch == "i386" || config.ansi_c.arch == "x86_64" ||
265  config.ansi_c.arch == "x32" || config.ansi_c.arch == "ia64")
266  {
267  // clang doesn't do __float80
268  // Note that __float80 is a typedef, and not a keyword.
270  code += "typedef " CPROVER_PREFIX "Float64x __float80;\n";
271  }
272 
273  // On 64-bit systems, gcc has typedefs
274  // __int128_t und __uint128_t -- but not on 32 bit!
276  {
277  code+="typedef signed __int128 __int128_t;\n"
278  "typedef unsigned __int128 __uint128_t;\n";
279  }
280  }
281 
282  // this is Visual C/C++ only
284  code += "int __assume(int);\n";
285 
286  // ARM stuff
288  code+=arm_builtin_headers;
289 
290  // CW stuff
292  code+=cw_builtin_headers;
293 
294  // Architecture strings
296 }
297 
298 void ansi_c_architecture_strings(std::string &code)
299 {
300  // The following are CPROVER-specific.
301  // They allow identifying the architectural settings used
302  // at compile time from a goto-binary.
303 
304  code += "#line 1 \"<builtin-architecture-strings>\"\n";
305 
306  code+=architecture_string(config.ansi_c.int_width, "int_width");
307  code+=architecture_string(config.ansi_c.int_width, "word_size"); // old
308  code+=architecture_string(config.ansi_c.long_int_width, "long_int_width");
309  code+=architecture_string(config.ansi_c.bool_width, "bool_width");
310  code+=architecture_string(config.ansi_c.char_width, "char_width");
311  code+=architecture_string(config.ansi_c.short_int_width, "short_int_width");
312  code+=architecture_string(config.ansi_c.long_long_int_width, "long_long_int_width"); // NOLINT(whitespace/line_length)
313  code+=architecture_string(config.ansi_c.pointer_width, "pointer_width");
314  code+=architecture_string(config.ansi_c.single_width, "single_width");
315  code+=architecture_string(config.ansi_c.double_width, "double_width");
316  code+=architecture_string(config.ansi_c.long_double_width, "long_double_width"); // NOLINT(whitespace/line_length)
317  code+=architecture_string(config.ansi_c.wchar_t_width, "wchar_t_width");
318  code+=architecture_string(config.ansi_c.char_is_unsigned, "char_is_unsigned");
319  code+=architecture_string(config.ansi_c.wchar_t_is_unsigned, "wchar_t_is_unsigned"); // NOLINT(whitespace/line_length)
320  code+=architecture_string(config.ansi_c.alignment, "alignment");
321  code+=architecture_string(config.ansi_c.memory_operand_size, "memory_operand_size"); // NOLINT(whitespace/line_length)
322  code+=architecture_string(static_cast<int>(config.ansi_c.endianness), "endianness"); // NOLINT(whitespace/line_length)
324  code+=architecture_string(configt::ansi_ct::os_to_string(config.ansi_c.os), "os"); // NOLINT(whitespace/line_length)
325  code+=architecture_string(config.ansi_c.NULL_is_zero, "NULL_is_zero");
326 }
irep_idt rounding_mode_identifier()
Return the identifier of the program symbol used to store the current rounding mode.
Symbolic Execution.
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_mem_string[]
const char gcc_builtin_headers_ia32_4[]
const char gcc_builtin_headers_generic[]
const char gcc_builtin_headers_tm[]
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:1533
struct configt::ansi_ct ansi_c
#define CPROVER_PREFIX
const std::string & id2string(const irep_idt &d)
Definition: irep.h:40
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:207
bool wchar_t_is_unsigned
Definition: config.h:150
static std::string os_to_string(ost)
Definition: config.cpp:1218
std::size_t pointer_width
Definition: config.h:143
bool gcc__float128_type
Definition: config.h:153
irep_idt arch
Definition: config.h:221
ieee_floatt::rounding_modet rounding_mode
Definition: config.h:181
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:195
std::size_t bool_width
Definition: config.h:139
std::size_t memory_operand_size
Definition: config.h:199
std::size_t long_long_int_width
Definition: config.h:142
bool NULL_is_zero
Definition: config.h:224
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:253
std::size_t int_width
Definition: config.h:137