CBMC
gcc_mode.cpp
Go to the documentation of this file.
1 /*******************************************************************\
2 
3 Module: GCC Mode
4 
5 Author: CM Wintersteiger, 2006
6 
7 \*******************************************************************/
8 
11 
12 #include "gcc_mode.h"
13 
14 #ifdef _WIN32
15 #define EX_OK 0
16 #define EX_USAGE 64
17 #define EX_SOFTWARE 70
18 #else
19 #include <sysexits.h>
20 #endif
21 
22 #include <iostream>
23 #include <fstream>
24 #include <numeric>
25 
26 #include <util/cmdline.h>
27 #include <util/config.h>
28 #include <util/file_util.h>
29 #include <util/get_base_name.h>
30 #include <util/invariant.h>
31 #include <util/prefix.h>
32 #include <util/run.h>
33 #include <util/suffix.h>
34 #include <util/tempdir.h>
35 #include <util/version.h>
36 
37 #include "compile.h"
38 #include "goto_cc_cmdline.h"
39 #include "hybrid_binary.h"
40 #include "linker_script_merge.h"
41 
42 static std::string compiler_name(
43  const cmdlinet &cmdline,
44  const std::string &base_name)
45 {
46  if(cmdline.isset("native-compiler"))
47  return cmdline.get_value("native-compiler");
48 
49  if(base_name=="bcc" ||
50  base_name.find("goto-bcc")!=std::string::npos)
51  return "bcc";
52 
53  if(base_name=="goto-clang")
54  return "clang";
55 
56  std::string::size_type pos=base_name.find("goto-gcc");
57 
58  if(pos==std::string::npos ||
59  base_name=="goto-gcc" ||
60  base_name=="goto-ld")
61  {
62  #ifdef __FreeBSD__
63  return "clang";
64  #else
65  return "gcc";
66  #endif
67  }
68 
69  std::string result=base_name;
70  result.replace(pos, 8, "gcc");
71 
72  return result;
73 }
74 
75 static std::string linker_name(
76  const cmdlinet &cmdline,
77  const std::string &base_name)
78 {
79  if(cmdline.isset("native-linker"))
80  return cmdline.get_value("native-linker");
81 
82  std::string::size_type pos=base_name.find("goto-ld");
83 
84  if(pos==std::string::npos ||
85  base_name=="goto-gcc" ||
86  base_name=="goto-ld")
87  return "ld";
88 
89  std::string result=base_name;
90  result.replace(pos, 7, "ld");
91 
92  return result;
93 }
94 
96  goto_cc_cmdlinet &_cmdline,
97  const std::string &_base_name,
98  bool _produce_hybrid_binary):
99  goto_cc_modet(_cmdline, _base_name, gcc_message_handler),
100  produce_hybrid_binary(_produce_hybrid_binary),
101  goto_binary_tmp_suffix(".goto-cc-saved"),
102 
103  // Keys are architectures specified in configt::set_arch().
104  // Values are lists of GCC architectures that can be supplied as
105  // arguments to the -march, -mcpu, and -mtune flags (see the GCC
106  // manual https://gcc.gnu.org/onlinedocs/).
107  arch_map(
108  {
109  // ARM information taken from the following:
110  //
111  // the "ARM core timeline" table on this page:
112  // https://en.wikipedia.org/wiki/List_of_ARM_microarchitectures
113  //
114  // articles on particular core groups, e.g.
115  // https://en.wikipedia.org/wiki/ARM9
116  //
117  // The "Cores" table on this page:
118  // https://en.wikipedia.org/wiki/ARM_architecture
119  // NOLINTNEXTLINE(whitespace/braces)
120  {"arm", {
121  "strongarm", "strongarm110", "strongarm1100", "strongarm1110",
122  "arm2", "arm250", "arm3", "arm6", "arm60", "arm600", "arm610",
123  "arm620", "fa526", "fa626", "fa606te", "fa626te", "fmp626",
124  "xscale", "iwmmxt", "iwmmxt2", "xgene1"
125  }}, // NOLINTNEXTLINE(whitespace/braces)
126  {"armhf", {
127  "armv7", "arm7m", "arm7d", "arm7dm", "arm7di", "arm7dmi",
128  "arm70", "arm700", "arm700i", "arm710", "arm710c", "arm7100",
129  "arm720", "arm7500", "arm7500fe", "arm7tdmi", "arm7tdmi-s",
130  "arm710t", "arm720t", "arm740t", "mpcore", "mpcorenovfp",
131  "arm8", "arm810", "arm9", "arm9e", "arm920", "arm920t",
132  "arm922t", "arm946e-s", "arm966e-s", "arm968e-s", "arm926ej-s",
133  "arm940t", "arm9tdmi", "arm10tdmi", "arm1020t", "arm1026ej-s",
134  "arm10e", "arm1020e", "arm1022e", "arm1136j-s", "arm1136jf-s",
135  "arm1156t2-s", "arm1156t2f-s", "arm1176jz-s", "arm1176jzf-s",
136  "cortex-a5", "cortex-a7", "cortex-a8", "cortex-a9",
137  "cortex-a12", "cortex-a15", "cortex-a53", "cortex-r4",
138  "cortex-r4f", "cortex-r5", "cortex-r7", "cortex-m7",
139  "cortex-m4", "cortex-m3", "cortex-m1", "cortex-m0",
140  "cortex-m0plus", "cortex-m1.small-multiply",
141  "cortex-m0.small-multiply", "cortex-m0plus.small-multiply",
142  "marvell-pj4", "ep9312", "fa726te",
143  }}, // NOLINTNEXTLINE(whitespace/braces)
144  {"arm64", {
145  "cortex-a57", "cortex-a72", "exynos-m1"
146  }}, // NOLINTNEXTLINE(whitespace/braces)
147  {"hppa", {"1.0", "1.1", "2.0"}}, // NOLINTNEXTLINE(whitespace/braces)
148  // PowerPC
149  // https://en.wikipedia.org/wiki/List_of_PowerPC_processors
150  // NOLINTNEXTLINE(whitespace/braces)
151  {"powerpc", {
152  "powerpc", "601", "602", "603", "603e", "604", "604e", "630",
153  // PowerPC G3 == 7xx series
154  "G3", "740", "750",
155  // PowerPC G4 == 74xx series
156  "G4", "7400", "7450",
157  // SoC and low power: https://en.wikipedia.org/wiki/PowerPC_400
158  "401", "403", "405", "405fp", "440", "440fp", "464", "464fp",
159  "476", "476fp",
160  // e series. x00 are 32-bit, x50 are 64-bit. See e.g.
161  // https://en.wikipedia.org/wiki/PowerPC_e6500
162  "e300c2", "e300c3", "e500mc", "ec603e",
163  // https://en.wikipedia.org/wiki/Titan_(microprocessor)
164  "titan",
165  }},
166  // NOLINTNEXTLINE(whitespace/braces)
167  {"powerpc64", {
168  "powerpc64",
169  // First IBM 64-bit processor
170  "620",
171  "970", "G5"
172  // All IBM POWER processors are 64 bit, but POWER 8 is
173  // little-endian so not in this list.
174  // https://en.wikipedia.org/wiki/Ppc64
175  "power3", "power4", "power5", "power5+", "power6", "power6x",
176  "power7", "rs64",
177  // e series SoC chips. x00 are 32-bit, x50 are 64-bit. See e.g.
178  // https://en.wikipedia.org/wiki/PowerPC_e6500
179  "e500mc64", "e5500", "e6500",
180  // https://en.wikipedia.org/wiki/IBM_A2
181  "a2",
182  }},
183  // The latest Power processors are little endian.
184  {"powerpc64le", {"powerpc64le", "power8"}},
185  // There are two MIPS architecture series. The 'old' one comprises
186  // MIPS I - MIPS V (where MIPS I and MIPS II are 32-bit
187  // architectures, and the III, IV and V are 64-bit). The 'new'
188  // architecture series comprises MIPS32 and MIPS64. Source: [0].
189  //
190  // CPROVER's names for these are in configt::this_architecture(),
191  // in particular note the preprocessor variable names. MIPS
192  // processors can run in little-endian or big-endian mode; [1]
193  // gives more information on particular processors. Particular
194  // processors and their architectures are at [2]. This means that
195  // we cannot use the processor flags alone to decide which CPROVER
196  // name to use; we also need to check for the -EB or -EL flags to
197  // decide whether little- or big-endian code should be generated.
198  // Therefore, the keys in this part of the map don't directly map
199  // to CPROVER architectures.
200  //
201  // [0] https://en.wikipedia.org/wiki/MIPS_architecture
202  // [1] https://www.debian.org/ports/mips/
203  // [2] https://en.wikipedia.org/wiki/List_of_MIPS_architecture_processors
204  // NOLINTNEXTLINE(whitespace/braces)
205  {"mips64n", {
206  "loongson2e", "loongson2f", "loongson3a", "mips64", "mips64r2",
207  "mips64r3", "mips64r5", "mips64r6 4kc", "5kc", "5kf", "20kc",
208  "octeon", "octeon+", "octeon2", "octeon3", "sb1", "vr4100",
209  "vr4111", "vr4120", "vr4130", "vr4300", "vr5000", "vr5400",
210  "vr5500", "sr71000", "xlp",
211  }}, // NOLINTNEXTLINE(whitespace/braces)
212  {"mips32n", {
213  "mips32", "mips32r2", "mips32r3", "mips32r5", "mips32r6",
214  // https://www.imgtec.com/mips/classic/
215  "4km", "4kp", "4ksc", "4kec", "4kem", "4kep", "4ksd", "24kc",
216  "24kf2_1", "24kf1_1", "24kec", "24kef2_1", "24kef1_1", "34kc",
217  "34kf2_1", "34kf1_1", "34kn", "74kc", "74kf2_1", "74kf1_1",
218  "74kf3_2", "1004kc", "1004kf2_1", "1004kf1_1", "m4k", "m14k",
219  "m14kc", "m14ke", "m14kec",
220  // https://en.wikipedia.org/wiki/List_of_MIPS_architecture_processors
221  "p5600", "xlr",
222  }}, // NOLINTNEXTLINE(whitespace/braces)
223  {"mips32o", {
224  "mips1", "mips2", "r2000", "r3000",
225  "r6000", // Not a mistake, r4000 came out _after_ this
226  }}, // NOLINTNEXTLINE(whitespace/braces)
227  {"mips64o", {
228  "mips3", "mips4", "r4000", "r4400", "r4600", "r4650", "r4700",
229  "r8000", "rm7000", "rm9000", "r10000", "r12000", "r14000",
230  "r16000",
231  }},
232  // These are IBM mainframes. s390 is 32-bit; s390x is 64-bit [0].
233  // Search that page for s390x and note that 32-bit refers to
234  // everything "prior to 2000's z900 model". The list of model
235  // numbers is at [1].
236  // [0] https://en.wikipedia.org/wiki/Linux_on_z_Systems
237  // [1] https://en.wikipedia.org/wiki/IBM_System_z
238  // NOLINTNEXTLINE(whitespace/braces)
239  {"s390", {
240  "z900", "z990", "g5", "g6",
241  }}, // NOLINTNEXTLINE(whitespace/braces)
242  {"s390x", {
243  "z9-109", "z9-ec", "z10", "z196", "zEC12", "z13"
244  }},
245  // SPARC
246  // In the "Implementations" table of [0], everything with an arch
247  // version up to V8 is 32-bit. V9 and onward are 64-bit.
248  // [0] https://en.wikipedia.org/wiki/SPARC
249  // NOLINTNEXTLINE(whitespace/braces)
250  {"sparc", {
251  "v7", "v8", "leon", "leon3", "leon3v7", "cypress", "supersparc",
252  "hypersparc", "sparclite", "f930", "f934", "sparclite86x",
253  "tsc701",
254  }}, // NOLINTNEXTLINE(whitespace/braces)
255  {"sparc64", {
256  "v9", "ultrasparc", "ultrasparc3", "niagara", "niagara2",
257  "niagara3", "niagara4",
258  }}, // NOLINTNEXTLINE(whitespace/braces)
259  {"ia64", {
260  "itanium", "itanium1", "merced", "itanium2", "mckinley"
261  }}, // NOLINTNEXTLINE(whitespace/braces)
262  // x86 and x86_64. See
263  // https://en.wikipedia.org/wiki/List_of_AMD_microprocessors
264  // https://en.wikipedia.org/wiki/List_of_Intel_microprocessors
265  {"i386", {
266  // Intel generic
267  "i386", "i486", "i586", "i686",
268  // AMD
269  "k6", "k6-2", "k6-3", "athlon" "athlon-tbird", "athlon-4",
270  "athlon-xp", "athlon-mp",
271  // Everything called "pentium" by GCC is 32 bits; the only 64-bit
272  // Pentium flag recognized by GCC is "nocona".
273  "pentium", "pentium-mmx", "pentiumpro" "pentium2", "pentium3",
274  "pentium3m", "pentium-m" "pentium4", "pentium4m", "prescott",
275  // Misc
276  "winchip-c6", "winchip2", "c3", "c3-2", "geode",
277  }}, // NOLINTNEXTLINE(whitespace/braces)
278  {"x86_64", {
279  // Intel
280  "nocona", "core2", "nehalem" "westmere", "sandybridge", "knl",
281  "ivybridge", "haswell", "broadwell" "bonnell", "silvermont",
282  // AMD generic
283  "k8", "k8-sse3", "opteron", "athlon64", "athlon-fx",
284  "opteron-sse3" "athlon64-sse3", "amdfam10", "barcelona",
285  // AMD "bulldozer" (high power, family 15h)
286  "bdver1", "bdver2" "bdver3", "bdver4",
287  // AMD "bobcat" (low power, family 14h)
288  "btver1", "btver2",
289  }},
290  })
291 {
292 }
293 
294 bool gcc_modet::needs_preprocessing(const std::string &file)
295 {
296  if(has_suffix(file, ".c") ||
297  has_suffix(file, ".cc") ||
298  has_suffix(file, ".cp") ||
299  has_suffix(file, ".cpp") ||
300  has_suffix(file, ".CPP") ||
301  has_suffix(file, ".c++") ||
302  has_suffix(file, ".C"))
303  return true;
304  else
305  return false;
306 }
307 
310 {
311  if(cmdline.isset('?') ||
312  cmdline.isset("help"))
313  {
314  help();
315  return EX_OK;
316  }
317 
320 
321  auto default_verbosity = (cmdline.isset("Wall") || cmdline.isset("Wextra")) ?
324  cmdline.get_value("verbosity"), default_verbosity, gcc_message_handler);
325 
326  bool act_as_bcc=
327  base_name=="bcc" ||
328  base_name.find("goto-bcc")!=std::string::npos;
329 
330  // if we are gcc or bcc, then get the version number
332 
333  if((cmdline.isset('v') && cmdline.have_infile_arg()) ||
334  (cmdline.isset("version") && !produce_hybrid_binary))
335  {
336  // "-v" a) prints the version and b) increases verbosity.
337  // Compilation continues, don't exit!
338 
339  if(act_as_bcc)
340  std::cout << "bcc: version " << gcc_version << " (goto-cc "
341  << CBMC_VERSION << ")\n";
342  else
343  {
345  std::cout << "clang version " << gcc_version << " (goto-cc "
346  << CBMC_VERSION << ")\n";
347  else
348  std::cout << "gcc (goto-cc " << CBMC_VERSION << ") " << gcc_version
349  << '\n';
350  }
351  }
352 
353  compilet compiler(cmdline,
355  cmdline.isset("Werror") &&
356  !cmdline.isset("Wno-error"));
357 
358  if(cmdline.isset("version"))
359  {
361  return run_gcc(compiler);
362 
363  std::cout
364  << '\n'
365  << "Copyright (C) 2006-2018 Daniel Kroening, Christoph Wintersteiger\n"
366  << "CBMC version: " << CBMC_VERSION << '\n'
367  << "Architecture: " << config.this_architecture() << '\n'
368  << "OS: " << config.this_operating_system() << '\n';
369 
371  std::cout << "clang: " << gcc_version << '\n';
372  else
373  std::cout << "gcc: " << gcc_version << '\n';
374 
375  return EX_OK; // Exit!
376  }
377 
378  if(
379  cmdline.isset("dumpmachine") || cmdline.isset("dumpspecs") ||
380  cmdline.isset("dumpversion") || cmdline.isset("print-sysroot") ||
381  cmdline.isset("print-sysroot-headers-suffix"))
382  {
384  return run_gcc(compiler);
385 
386  // GCC will only print one of these, even when multiple arguments are
387  // passed, so we do the same
388  if(cmdline.isset("dumpmachine"))
389  std::cout << config.this_architecture() << '\n';
390  else if(cmdline.isset("dumpversion"))
391  std::cout << gcc_version << '\n';
392 
393  // we don't have any meaningful output for the other options, and GCC
394  // doesn't necessarily produce non-empty output either
395 
396  return EX_OK;
397  }
398 
400 
401  if(act_as_bcc)
402  {
404  log.debug() << "BCC mode (hybrid)" << messaget::eom;
405  else
406  log.debug() << "BCC mode" << messaget::eom;
407  }
408  else
409  {
411  log.debug() << "GCC mode (hybrid)" << messaget::eom;
412  else
413  log.debug() << "GCC mode" << messaget::eom;
414  }
415 
416  // model validation
417  compiler.validate_goto_model = cmdline.isset("validate-goto-model");
418 
419  // determine actions to be undertaken
420  if(cmdline.isset('S'))
421  compiler.mode=compilet::ASSEMBLE_ONLY;
422  else if(cmdline.isset('c'))
423  compiler.mode=compilet::COMPILE_ONLY;
424  else if(cmdline.isset('E'))
426  else if(cmdline.isset("shared") ||
427  cmdline.isset('r')) // really not well documented
428  compiler.mode=compilet::COMPILE_LINK;
429  else
431 
432  // In gcc mode, we have just pass on to gcc to handle the following:
433  // * if -M or -MM is given, we do dependencies only
434  // * preprocessing (-E)
435  // * no input files given
436 
437  if(cmdline.isset('M') ||
438  cmdline.isset("MM") ||
439  cmdline.isset('E') ||
441  return run_gcc(compiler); // exit!
442 
443  // get configuration
444  config.set(cmdline);
445 
446  // Intel-specific
447  // in GCC, m16 is 32-bit (!), as documented here:
448  // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59672
449  if(cmdline.isset("m16") ||
450  cmdline.isset("m32") || cmdline.isset("mx32"))
451  {
452  config.ansi_c.arch="i386";
454  }
455  else if(cmdline.isset("m64"))
456  {
457  config.ansi_c.arch="x86_64";
459  }
460 
461  // ARM-specific
462  if(cmdline.isset("mbig-endian") || cmdline.isset("mbig"))
464  else if(cmdline.isset("little-endian") || cmdline.isset("mlittle"))
466 
467  if(cmdline.isset("mthumb") || cmdline.isset("mthumb-interwork"))
469 
470  // -mcpu sets both the arch and tune, but should only be used if
471  // neither -march nor -mtune are passed on the command line.
472  std::string target_cpu=
473  cmdline.isset("march") ? cmdline.get_value("march") :
474  cmdline.isset("mtune") ? cmdline.get_value("mtune") :
475  cmdline.isset("mcpu") ? cmdline.get_value("mcpu") : "";
476 
477  if(!target_cpu.empty())
478  {
479  // Work out what CPROVER architecture we should target.
480  for(auto &pair : arch_map)
481  for(auto &processor : pair.second)
482  if(processor==target_cpu)
483  {
484  if(pair.first.find("mips")==std::string::npos)
485  config.set_arch(pair.first);
486  else
487  {
488  // Targeting a MIPS processor. MIPS is special; we also need
489  // to know the endianness. -EB (big-endian) is the default.
490  if(cmdline.isset("EL"))
491  {
492  if(pair.first=="mips32o")
493  config.set_arch("mipsel");
494  else if(pair.first=="mips32n")
495  config.set_arch("mipsn32el");
496  else
497  config.set_arch("mips64el");
498  }
499  else
500  {
501  if(pair.first=="mips32o")
502  config.set_arch("mips");
503  else if(pair.first=="mips32n")
504  config.set_arch("mipsn32");
505  else
506  config.set_arch("mips64");
507  }
508  }
509  }
510  }
511 
512  // clang supports -target <arch-quadruple> and --target=<arch-quadruple>
513  if(cmdline.isset("target"))
514  {
515  // list of targets supported by LLVM 10.0, found using llc --version
516  static const std::map<std::string, std::string> target_map = {
517  {"aarch64", "arm64" /* AArch64 (little endian) */},
518  {"aarch64_32", "arm" /* AArch64 (little endian ILP32) */},
519  {"aarch64_be", "none" /* AArch64 (big endian) */},
520  {"amdgcn", "none" /* AMD GCN GPUs */},
521  {"arm", "arm" /* ARM */},
522  {"arm64", "arm64" /* ARM64 (little endian) */},
523  {"arm64_32", "arm" /* ARM64 (little endian ILP32) */},
524  {"armeb", "none" /* ARM (big endian) */},
525  {"avr", "none" /* Atmel AVR Microcontroller */},
526  {"bpf", "none" /* BPF (host endian) */},
527  {"bpfeb", "none" /* BPF (big endian) */},
528  {"bpfel", "none" /* BPF (little endian) */},
529  {"hexagon", "none" /* Hexagon */},
530  {"i386", "i386" /* (not in llc's list: 32-bit x86) */},
531  {"lanai", "none" /* Lanai */},
532  {"mips", "mips" /* MIPS (32-bit big endian) */},
533  {"mips64", "mips64" /* MIPS (64-bit big endian) */},
534  {"mips64el", "mips64el" /* MIPS (64-bit little endian) */},
535  {"mipsel", "mipsel" /* MIPS (32-bit little endian) */},
536  {"msp430", "none" /* MSP430 [experimental] */},
537  {"nvptx", "none" /* NVIDIA PTX 32-bit */},
538  {"nvptx64", "none" /* NVIDIA PTX 64-bit */},
539  {"ppc32", "powerpc" /* PowerPC 32 */},
540  {"ppc64", "ppc64" /* PowerPC 64 */},
541  {"ppc64le", "ppc64le" /* PowerPC 64 LE */},
542  {"r600", "none" /* AMD GPUs HD2XXX-HD6XXX */},
543  {"riscv32", "none" /* 32-bit RISC-V */},
544  {"riscv64", "riscv64" /* 64-bit RISC-V */},
545  {"sparc", "sparc" /* Sparc */},
546  {"sparcel", "none" /* Sparc LE */},
547  {"sparcv9", "sparc64" /* Sparc V9 */},
548  {"systemz", "none" /* SystemZ */},
549  {"thumb", "armhf" /* Thumb */},
550  {"thumbeb", "none" /* Thumb (big endian) */},
551  {"wasm32", "none" /* WebAssembly 32-bit */},
552  {"wasm64", "none" /* WebAssembly 64-bit */},
553  {"x86", "i386" /* 32-bit X86: Pentium-Pro and above */},
554  {"x86_64", "x86_64" /* 64-bit X86: EM64T and AMD64 */},
555  {"xcore", "none" /* XCore */},
556  };
557  std::string arch_quadruple = cmdline.get_value("target");
558  auto it =
559  target_map.find(arch_quadruple.substr(0, arch_quadruple.find('-')));
560  if(it == target_map.end())
561  config.set_arch("none");
562  else
563  config.set_arch(it->second);
564  }
565 
566  // -fshort-wchar makes wchar_t "short unsigned int"
567  if(cmdline.isset("fshort-wchar"))
568  {
571  }
572 
573  // -fsingle-precision-constant makes floating-point constants "float"
574  // instead of double
575  if(cmdline.isset("-fsingle-precision-constant"))
577 
578  // -fshort-double makes double the same as float
579  if(cmdline.isset("fshort-double"))
581 
582  // configure version-specific gcc settings
584 
585  switch(compiler.mode)
586  {
588  log.debug() << "Linking a library only" << messaget::eom;
589  break;
591  log.debug() << "Compiling only" << messaget::eom;
592  break;
594  log.debug() << "Assembling only" << messaget::eom;
595  break;
597  log.debug() << "Preprocessing only" << messaget::eom;
598  break;
600  log.debug() << "Compiling and linking a library" << messaget::eom;
601  break;
603  log.debug() << "Compiling and linking an executable" << messaget::eom;
604  break;
605  }
606 
607  if(cmdline.isset("i386-win32") ||
608  cmdline.isset("winx64"))
609  {
610  // We may wish to reconsider the below.
612  log.debug() << "Enabling Visual Studio syntax" << messaget::eom;
613  }
614  else
615  {
618  else
620  }
621 
622  if(compiler.mode==compilet::ASSEMBLE_ONLY)
623  compiler.object_file_extension="s";
624  else
625  compiler.object_file_extension="o";
626 
627  if(cmdline.isset("std"))
628  {
629  std::string std_string=cmdline.get_value("std");
630 
631  if(std_string=="gnu89" || std_string=="c89")
633 
634  if(std_string=="gnu99" || std_string=="c99" || std_string=="iso9899:1999" ||
635  std_string=="gnu9x" || std_string=="c9x" || std_string=="iso9899:199x")
637 
638  if(std_string=="gnu11" || std_string=="c11" ||
639  std_string=="gnu1x" || std_string=="c1x")
641 
642  if(std_string=="c++11" || std_string=="c++1x" ||
643  std_string=="gnu++11" || std_string=="gnu++1x" ||
644  std_string=="c++1y" ||
645  std_string=="gnu++1y")
646  config.cpp.set_cpp11();
647 
648  if(std_string=="gnu++14" || std_string=="c++14")
649  config.cpp.set_cpp14();
650 
651  if(std_string == "gnu++17" || std_string == "c++17")
652  config.cpp.set_cpp17();
653  }
654  else
655  {
658  }
659 
660  // gcc's default is 32 bits for wchar_t
661  if(cmdline.isset("short-wchar"))
663 
664  // gcc's default is 64 bits for double
665  if(cmdline.isset("short-double"))
667 
668  // gcc's default is signed chars on most architectures
669  if(cmdline.isset("funsigned-char"))
671 
672  if(cmdline.isset("fsigned-char"))
674 
675  if(cmdline.isset('U'))
677 
678  if(cmdline.isset("undef"))
679  config.ansi_c.preprocessor_options.push_back("-undef");
680 
681  if(cmdline.isset("nostdinc"))
682  config.ansi_c.preprocessor_options.push_back("-nostdinc");
683 
684  if(cmdline.isset('L'))
685  compiler.library_paths=cmdline.get_values('L');
686  // Don't add the system paths!
687 
688  if(cmdline.isset('l'))
689  compiler.libraries=cmdline.get_values('l');
690 
691  if(cmdline.isset("static"))
692  compiler.libraries.push_back("c");
693 
694  if(cmdline.isset("pthread"))
695  compiler.libraries.push_back("pthread");
696 
697  if(cmdline.isset('o'))
698  {
699  // given gcc -o file1 -o file2,
700  // gcc will output to file2, not file1
701  compiler.output_file_object=cmdline.get_values('o').back();
702  compiler.output_file_executable=cmdline.get_values('o').back();
703  }
704  else
705  {
706  compiler.output_file_object.clear();
707  compiler.output_file_executable="a.out";
708  }
709 
710  // We now iterate over any input files
711 
712  std::vector<temp_dirt> temp_dirs;
713 
714  {
715  std::string language;
716 
717  for(goto_cc_cmdlinet::parsed_argvt::iterator
718  arg_it=cmdline.parsed_argv.begin();
719  arg_it!=cmdline.parsed_argv.end();
720  arg_it++)
721  {
722  if(arg_it->is_infile_name)
723  {
724  // do any preprocessing needed
725 
726  if(language=="cpp-output" || language=="c++-cpp-output")
727  {
728  compiler.add_input_file(arg_it->arg);
729  }
730  else if(
731  language == "c" || language == "c++" ||
732  (language.empty() && needs_preprocessing(arg_it->arg)))
733  {
734  std::string new_suffix;
735 
736  if(language=="c")
737  new_suffix=".i";
738  else if(language=="c++")
739  new_suffix=".ii";
740  else
741  new_suffix=has_suffix(arg_it->arg, ".c")?".i":".ii";
742 
743  std::string new_name=
744  get_base_name(arg_it->arg, true)+new_suffix;
745 
746  temp_dirs.emplace_back("goto-cc-XXXXXX");
747  std::string dest = temp_dirs.back()(new_name);
748 
749  int exit_code=
750  preprocess(language, arg_it->arg, dest, act_as_bcc);
751 
752  if(exit_code!=0)
753  {
754  log.error() << "preprocessing has failed" << messaget::eom;
755  return exit_code;
756  }
757 
758  compiler.add_input_file(dest);
759  }
760  else
761  compiler.add_input_file(arg_it->arg);
762  }
763  else if(arg_it->arg=="-x")
764  {
765  arg_it++;
766  if(arg_it!=cmdline.parsed_argv.end())
767  {
768  language=arg_it->arg;
769  if(language=="none")
770  language.clear();
771  }
772  }
773  else if(has_prefix(arg_it->arg, "-x"))
774  {
775  language=std::string(arg_it->arg, 2, std::string::npos);
776  if(language=="none")
777  language.clear();
778  }
779  }
780  }
781 
782  if(
783  cmdline.isset('o') && cmdline.isset('c') &&
784  compiler.source_files.size() >= 2)
785  {
786  log.error() << "cannot specify -o with -c with multiple files"
787  << messaget::eom;
788  return 1; // to match gcc's behaviour
789  }
790 
791  // Revert to gcc in case there is no source to compile
792  // and no binary to link.
793 
794  if(compiler.source_files.empty() &&
795  compiler.object_files.empty())
796  return run_gcc(compiler); // exit!
797 
798  if(compiler.mode==compilet::ASSEMBLE_ONLY)
799  return asm_output(act_as_bcc, compiler.source_files, compiler);
800 
801  // do all the rest
802  if(compiler.doit())
803  return 1; // GCC exit code for all kinds of errors
804 
805  // We can generate hybrid ELF and Mach-O binaries
806  // containing both executable machine code and the goto-binary.
807  if(produce_hybrid_binary && !act_as_bcc)
808  return gcc_hybrid_binary(compiler);
809 
810  return EX_OK;
811 }
812 
815  const std::string &language,
816  const std::string &src,
817  const std::string &dest,
818  bool act_as_bcc)
819 {
820  // build new argv
821  std::vector<std::string> new_argv;
822 
823  new_argv.reserve(cmdline.parsed_argv.size());
824 
825  bool skip_next=false;
826 
827  for(goto_cc_cmdlinet::parsed_argvt::const_iterator
828  it=cmdline.parsed_argv.begin();
829  it!=cmdline.parsed_argv.end();
830  it++)
831  {
832  if(skip_next)
833  {
834  // skip
835  skip_next=false;
836  }
837  else if(it->is_infile_name)
838  {
839  // skip
840  }
841  else if(it->arg=="-c" || it->arg=="-E" || it->arg=="-S")
842  {
843  // skip
844  }
845  else if(it->arg=="-o")
846  {
847  skip_next=true;
848  }
849  else if(has_prefix(it->arg, "-o"))
850  {
851  // ignore
852  }
853  else
854  new_argv.push_back(it->arg);
855  }
856 
857  // We just want to preprocess.
858  new_argv.push_back("-E");
859 
860  // destination file
861  std::string stdout_file;
862  if(act_as_bcc)
863  stdout_file=dest;
864  else
865  {
866  new_argv.push_back("-o");
867  new_argv.push_back(dest);
868  }
869 
870  // language, if given
871  if(!language.empty())
872  {
873  new_argv.push_back("-x");
874  new_argv.push_back(language);
875  }
876 
877  // source file
878  new_argv.push_back(src);
879 
880  // overwrite argv[0]
881  INVARIANT(new_argv.size()>=1, "No program name in argv");
882  new_argv[0]=native_tool_name.c_str();
883 
885  log.debug() << "RUN:";
886  for(std::size_t i=0; i<new_argv.size(); i++)
887  log.debug() << " " << new_argv[i];
888  log.debug() << messaget::eom;
889 
890  return run(new_argv[0], new_argv, cmdline.stdin_file, stdout_file, "");
891 }
892 
893 int gcc_modet::run_gcc(const compilet &compiler)
894 {
895  PRECONDITION(!cmdline.parsed_argv.empty());
896 
897  // build new argv
898  std::vector<std::string> new_argv;
899  new_argv.reserve(cmdline.parsed_argv.size());
900  for(const auto &a : cmdline.parsed_argv)
901  new_argv.push_back(a.arg);
902 
903  if(compiler.wrote_object_files())
904  {
905  // Undefine all __CPROVER macros for the system compiler
906  std::map<irep_idt, std::size_t> arities;
907  compiler.cprover_macro_arities(arities);
908  for(const auto &pair : arities)
909  {
910  std::ostringstream addition;
911  addition << "-D" << id2string(pair.first) << "(";
912  std::vector<char> params(pair.second);
913  std::iota(params.begin(), params.end(), 'a');
914  for(std::vector<char>::iterator it=params.begin(); it!=params.end(); ++it)
915  {
916  addition << *it;
917  if(it+1!=params.end())
918  addition << ",";
919  }
920  addition << ")= ";
921  new_argv.push_back(addition.str());
922  }
923  }
924 
925  // overwrite argv[0]
926  new_argv[0]=native_tool_name;
927 
929  log.debug() << "RUN:";
930  for(std::size_t i=0; i<new_argv.size(); i++)
931  log.debug() << " " << new_argv[i];
932  log.debug() << messaget::eom;
933 
934  return run(new_argv[0], new_argv, cmdline.stdin_file, "", "");
935 }
936 
938 {
939  {
940  bool have_files=false;
941 
942  for(goto_cc_cmdlinet::parsed_argvt::const_iterator
943  it=cmdline.parsed_argv.begin();
944  it!=cmdline.parsed_argv.end();
945  it++)
946  if(it->is_infile_name)
947  have_files=true;
948 
949  if(!have_files)
950  return EX_OK;
951  }
952 
953  std::list<std::string> output_files;
954 
955  if(cmdline.isset('c'))
956  {
957  if(cmdline.isset('o'))
958  {
959  // there should be only one input file
960  output_files.push_back(cmdline.get_value('o'));
961  }
962  else
963  {
964  for(goto_cc_cmdlinet::parsed_argvt::const_iterator
965  i_it=cmdline.parsed_argv.begin();
966  i_it!=cmdline.parsed_argv.end();
967  i_it++)
968  if(i_it->is_infile_name &&
969  needs_preprocessing(i_it->arg))
970  output_files.push_back(get_base_name(i_it->arg, true)+".o");
971  }
972  }
973  else
974  {
975  // -c is not given
976  if(cmdline.isset('o'))
977  output_files.push_back(cmdline.get_value('o'));
978  else
979  output_files.push_back("a.out");
980  }
981 
982  if(output_files.empty() ||
983  (output_files.size()==1 &&
984  output_files.front()=="/dev/null"))
985  return run_gcc(compiler);
986 
988  log.debug() << "Running " << native_tool_name << " to generate hybrid binary"
989  << messaget::eom;
990 
991  // save the goto-cc output files
992  std::list<std::string> goto_binaries;
993  for(std::list<std::string>::const_iterator
994  it=output_files.begin();
995  it!=output_files.end();
996  it++)
997  {
998  std::string bin_name=*it+goto_binary_tmp_suffix;
999 
1000  try
1001  {
1002  file_rename(*it, bin_name);
1003  }
1004  catch(const cprover_exception_baset &e)
1005  {
1006  log.error() << "Rename failed: " << e.what() << messaget::eom;
1007  return 1;
1008  }
1009 
1010  goto_binaries.push_back(bin_name);
1011  }
1012 
1013  int result=run_gcc(compiler);
1014 
1015  if(result==0 &&
1016  cmdline.isset('T') &&
1017  goto_binaries.size()==1 &&
1018  output_files.size()==1)
1019  {
1020  linker_script_merget ls_merge(
1021  output_files.front(),
1022  goto_binaries.front(),
1023  cmdline,
1025  result=ls_merge.add_linker_script_definitions();
1026  }
1027 
1028  std::string native_tool;
1029 
1030  if(has_suffix(linker_name(cmdline, base_name), "-ld"))
1031  native_tool=linker_name(cmdline, base_name);
1032  else if(has_suffix(compiler_name(cmdline, base_name), "-gcc"))
1033  native_tool=compiler_name(cmdline, base_name);
1034 
1035  // merge output from gcc with goto-binaries
1036  // using objcopy, or do cleanup if an earlier call failed
1037  for(std::list<std::string>::const_iterator
1038  it=output_files.begin();
1039  it!=output_files.end();
1040  it++)
1041  {
1042  std::string goto_binary=*it+goto_binary_tmp_suffix;
1043 
1044  if(result==0)
1045  result = hybrid_binary(
1046  native_tool,
1047  goto_binary,
1048  *it,
1051  }
1052 
1053  return result;
1054 }
1055 
1057  bool act_as_bcc,
1058  const std::list<std::string> &preprocessed_source_files,
1059  const compilet &compiler)
1060 {
1061  {
1062  bool have_files=false;
1063 
1064  for(goto_cc_cmdlinet::parsed_argvt::const_iterator
1065  it=cmdline.parsed_argv.begin();
1066  it!=cmdline.parsed_argv.end();
1067  it++)
1068  if(it->is_infile_name)
1069  have_files=true;
1070 
1071  if(!have_files)
1072  return EX_OK;
1073  }
1074 
1076 
1078  {
1079  log.debug() << "Running " << native_tool_name
1080  << " to generate native asm output" << messaget::eom;
1081 
1082  int result=run_gcc(compiler);
1083  if(result!=0)
1084  // native tool failed
1085  return result;
1086  }
1087 
1088  std::map<std::string, std::string> output_files;
1089 
1090  if(cmdline.isset('o'))
1091  {
1092  // GCC --combine supports more than one source file
1093  for(const auto &s : preprocessed_source_files)
1094  output_files.insert(std::make_pair(s, cmdline.get_value('o')));
1095  }
1096  else
1097  {
1098  for(const std::string &s : preprocessed_source_files)
1099  output_files.insert(
1100  std::make_pair(s, get_base_name(s, true)+".s"));
1101  }
1102 
1103  if(output_files.empty() ||
1104  (output_files.size()==1 &&
1105  output_files.begin()->second=="/dev/null"))
1106  return EX_OK;
1107 
1108  log.debug() << "Appending preprocessed sources to generate hybrid asm output"
1109  << messaget::eom;
1110 
1111  for(const auto &so : output_files)
1112  {
1113  std::ifstream is(so.first);
1114  if(!is.is_open())
1115  {
1116  log.error() << "Failed to open input source " << so.first
1117  << messaget::eom;
1118  return 1;
1119  }
1120 
1121  std::ofstream os(so.second, std::ios::app);
1122  if(!os.is_open())
1123  {
1124  log.error() << "Failed to open output file " << so.second
1125  << messaget::eom;
1126  return 1;
1127  }
1128 
1129  const char comment=act_as_bcc ? ':' : '#';
1130 
1131  os << comment << comment << " GOTO-CC" << '\n';
1132 
1133  std::string line;
1134 
1135  while(std::getline(is, line))
1136  {
1137  os << comment << comment << line << '\n';
1138  }
1139  }
1140 
1141  return EX_OK;
1142 }
1143 
1146 {
1147  std::cout << "goto-cc understands the options of "
1148  << "gcc plus the following.\n\n";
1149 }
messaget
Class that provides messages with a built-in verbosity 'level'.
Definition: message.h:154
gcc_modet::gcc_hybrid_binary
int gcc_hybrid_binary(compilet &compiler)
Definition: gcc_mode.cpp:937
get_base_name
std::string get_base_name(const std::string &in, bool strip_suffix)
cleans a filename from path and extension
Definition: get_base_name.cpp:16
configt::ansi_ct::set_c99
void set_c99()
Definition: config.h:155
gcc_versiont::get
void get(const std::string &executable)
Definition: gcc_version.cpp:18
linker_script_merge.h
Merge linker script-defined symbols into a goto-program.
goto_cc_cmdlinet::parsed_argv
parsed_argvt parsed_argv
Definition: goto_cc_cmdline.h:64
cmdlinet::isset
virtual bool isset(char option) const
Definition: cmdline.cpp:30
compilet::source_files
std::list< std::string > source_files
Definition: compile.h:46
goto_cc_cmdlinet::stdin_file
std::string stdin_file
Definition: goto_cc_cmdline.h:68
configt::ansi_ct::wchar_t_width
std::size_t wchar_t_width
Definition: config.h:134
configt::cppt::set_cpp17
void set_cpp17()
Definition: config.h:311
gcc_modet::doit
int doit() final
does it.
Definition: gcc_mode.cpp:309
pos
literalt pos(literalt a)
Definition: literal.h:194
file_util.h
compiler_name
static std::string compiler_name(const cmdlinet &cmdline, const std::string &base_name)
Definition: gcc_mode.cpp:42
linker_script_merget::add_linker_script_definitions
int add_linker_script_definitions()
Add values of linkerscript-defined symbols to the goto-binary.
Definition: linker_script_merge.cpp:34
gcc_modet::help_mode
void help_mode() final
display command line help
Definition: gcc_mode.cpp:1145
gcc_modet::gcc_version
gcc_versiont gcc_version
Definition: gcc_mode.h:68
configt::ansi_ct::flavourt::VISUAL_STUDIO
@ VISUAL_STUDIO
prefix.h
compilet::doit
bool doit()
reads and source and object files, compiles and links them into goto program objects.
Definition: compile.cpp:60
invariant.h
configure_gcc
void configure_gcc(const gcc_versiont &gcc_version)
Definition: gcc_version.cpp:147
gcc_versiont::flavor
enum gcc_versiont::flavort flavor
configt::ansi_ct::set_arch_spec_i386
void set_arch_spec_i386()
Definition: config.cpp:150
run
int run(const std::string &what, const std::vector< std::string > &argv)
Definition: run.cpp:48
compilet::libraries
std::list< std::string > libraries
Definition: compile.h:48
linker_script_merget
Synthesise definitions of symbols that are defined in linker scripts.
Definition: linker_script_merge.h:67
goto_cc_modet::base_name
const std::string base_name
Definition: goto_cc_mode.h:39
messaget::eom
static eomt eom
Definition: message.h:297
gcc_modet::native_tool_name
std::string native_tool_name
Definition: gcc_mode.h:43
configt::ansi_ct::undefines
std::list< std::string > undefines
Definition: config.h:251
configt::ansi_c
struct configt::ansi_ct ansi_c
run.h
version.h
tempdir.h
has_suffix
bool has_suffix(const std::string &s, const std::string &suffix)
Definition: suffix.h:17
compilet::validate_goto_model
bool validate_goto_model
Definition: compile.h:35
gcc_modet::needs_preprocessing
static bool needs_preprocessing(const std::string &)
Definition: gcc_mode.cpp:294
gcc_versiont::default_cxx_standard
configt::cppt::cpp_standardt default_cxx_standard
Definition: gcc_version.h:40
configt::ansi_ct::flavourt::CLANG
@ CLANG
compilet::wrote_object_files
bool wrote_object_files() const
Has this compiler written any object files?
Definition: compile.h:86
compilet::COMPILE_LINK
@ COMPILE_LINK
Definition: compile.h:41
goto_cc_cmdline.h
configt::ansi_ct::endiannesst::IS_LITTLE_ENDIAN
@ IS_LITTLE_ENDIAN
configt::cppt::set_cpp14
void set_cpp14()
Definition: config.h:307
cmdlinet
Definition: cmdline.h:20
CBMC_VERSION
const char * CBMC_VERSION
compilet::output_file_object
std::string output_file_object
Definition: compile.h:54
compilet::mode
enum compilet::@3 mode
compilet::object_files
std::list< std::string > object_files
Definition: compile.h:47
configt::ansi_ct::set_arch_spec_arm
void set_arch_spec_arm(const irep_idt &subarch)
Definition: config.cpp:281
has_prefix
bool has_prefix(const std::string &s, const std::string &prefix)
Definition: converter.cpp:13
configt::ansi_ct::wchar_t_is_unsigned
bool wchar_t_is_unsigned
Definition: config.h:137
id2string
const std::string & id2string(const irep_idt &d)
Definition: irep.h:47
configt::ansi_ct::double_width
std::size_t double_width
Definition: config.h:132
gcc_modet::run_gcc
int run_gcc(const compilet &compiler)
call gcc with original command line
Definition: gcc_mode.cpp:893
compilet::COMPILE_LINK_EXECUTABLE
@ COMPILE_LINK_EXECUTABLE
Definition: compile.h:42
compilet::output_file_executable
std::string output_file_executable
Definition: compile.h:51
gcc_modet::arch_map
const std::map< std::string, std::set< std::string > > arch_map
Associate CBMC architectures with processor names.
Definition: gcc_mode.h:48
PRECONDITION
#define PRECONDITION(CONDITION)
Definition: invariant.h:463
configt::cppt::set_cpp11
void set_cpp11()
Definition: config.h:303
messaget::M_ERROR
@ M_ERROR
Definition: message.h:170
cmdlinet::get_value
std::string get_value(char option) const
Definition: cmdline.cpp:48
gcc_modet::goto_binary_tmp_suffix
const std::string goto_binary_tmp_suffix
Definition: gcc_mode.h:45
compilet::library_paths
std::list< std::string > library_paths
Definition: compile.h:45
compile.h
configt::this_operating_system
static irep_idt this_operating_system()
Definition: config.cpp:1450
gcc_modet::produce_hybrid_binary
const bool produce_hybrid_binary
Definition: gcc_mode.h:41
configt::ansi_ct::arch
irep_idt arch
Definition: config.h:206
compilet::object_file_extension
std::string object_file_extension
Definition: compile.h:50
get_base_name.h
goto_cc_modet::cmdline
goto_cc_cmdlinet & cmdline
Definition: goto_cc_mode.h:38
gcc_modet::asm_output
int asm_output(bool act_as_bcc, const std::list< std::string > &preprocessed_source_files, const compilet &compiler)
Definition: gcc_mode.cpp:1056
configt::ansi_ct::preprocessor_options
std::list< std::string > preprocessor_options
Definition: config.h:252
compilet::ASSEMBLE_ONLY
@ ASSEMBLE_ONLY
Definition: compile.h:39
goto_cc_cmdlinet::have_infile_arg
bool have_infile_arg() const
Definition: goto_cc_cmdline.cpp:121
gcc_modet::gcc_message_handler
gcc_message_handlert gcc_message_handler
Definition: gcc_mode.h:39
compilet::add_input_file
bool add_input_file(const std::string &)
puts input file names into a list and does preprocessing for libraries.
Definition: compile.cpp:173
config
configt config
Definition: config.cpp:25
gcc_versiont::flavort::CLANG
@ CLANG
hybrid_binary.h
configt::ansi_ct::set_c11
void set_c11()
Definition: config.h:160
configt::this_architecture
static irep_idt this_architecture()
Definition: config.cpp:1350
gcc_modet::preprocess
int preprocess(const std::string &language, const std::string &src, const std::string &dest, bool act_as_bcc)
call gcc for preprocessing
Definition: gcc_mode.cpp:814
configt::ansi_ct::mode
flavourt mode
Definition: config.h:237
configt::ansi_ct::set_c89
void set_c89()
Definition: config.h:150
compilet::COMPILE_ONLY
@ COMPILE_ONLY
Definition: compile.h:38
messaget::M_WARNING
@ M_WARNING
Definition: message.h:170
configt::ansi_ct::endiannesst::IS_BIG_ENDIAN
@ IS_BIG_ENDIAN
suffix.h
cmdline.h
configt::set
bool set(const cmdlinet &cmdline)
Definition: config.cpp:798
configt::ansi_ct::c_standard
enum configt::ansi_ct::c_standardt c_standard
cprover_exception_baset::what
virtual std::string what() const
A human readable description of what went wrong.
Definition: exception_utils.cpp:12
goto_cc_modet
Definition: goto_cc_mode.h:22
gcc_versiont::default_c_standard
configt::ansi_ct::c_standardt default_c_standard
Definition: gcc_version.h:39
compilet::LINK_LIBRARY
@ LINK_LIBRARY
Definition: compile.h:40
config.h
configt::ansi_ct::short_int_width
std::size_t short_int_width
Definition: config.h:128
configt::ansi_ct::char_is_unsigned
bool char_is_unsigned
Definition: config.h:137
configt::ansi_ct::flavourt::GCC
@ GCC
configt::ansi_ct::set_arch_spec_x86_64
void set_arch_spec_x86_64()
Definition: config.cpp:182
hybrid_binary
int hybrid_binary(const std::string &compiler_or_linker, const std::string &goto_binary_file, const std::string &output_file, bool building_executable, message_handlert &message_handler, bool linking_efi)
Merges a goto binary into an object file (e.g.
Definition: hybrid_binary.cpp:39
goto_cc_modet::help
void help()
display command line help
Definition: goto_cc_mode.cpp:47
configt::ansi_ct::single_width
std::size_t single_width
Definition: config.h:131
compilet::PREPROCESS_ONLY
@ PREPROCESS_ONLY
Definition: compile.h:37
configt::cpp
struct configt::cppt cpp
compilet
Definition: compile.h:30
size_type
unsignedbv_typet size_type()
Definition: c_types.cpp:68
messaget::eval_verbosity
static unsigned eval_verbosity(const std::string &user_input, const message_levelt default_verbosity, message_handlert &dest)
Parse a (user-)provided string as a verbosity level and set it as the verbosity of dest.
Definition: message.cpp:105
configt::ansi_ct::single_precision_constant
bool single_precision_constant
Definition: config.h:141
cmdlinet::get_values
const std::list< std::string > & get_values(const std::string &option) const
Definition: cmdline.cpp:109
comment
static std::string comment(const rw_set_baset::entryt &entry, bool write)
Definition: race_check.cpp:109
linker_name
static std::string linker_name(const cmdlinet &cmdline, const std::string &base_name)
Definition: gcc_mode.cpp:75
goto_cc_cmdlinet
Definition: goto_cc_cmdline.h:19
configt::set_arch
void set_arch(const irep_idt &)
Definition: config.cpp:702
compilet::cprover_macro_arities
void cprover_macro_arities(std::map< irep_idt, std::size_t > &cprover_macros) const
__CPROVER_... macros written to object files and their arities
Definition: compile.h:93
configt::ansi_ct::endianness
endiannesst endianness
Definition: config.h:192
validation_modet::INVARIANT
@ INVARIANT
cprover_exception_baset
Base class for exceptions thrown in the cprover project.
Definition: exception_utils.h:24
gcc_mode.h
file_rename
void file_rename(const std::string &old_path, const std::string &new_path)
Rename a file.
Definition: file_util.cpp:240
gcc_modet::gcc_modet
gcc_modet(goto_cc_cmdlinet &_cmdline, const std::string &_base_name, bool _produce_hybrid_binary)
Definition: gcc_mode.cpp:95
configt::cppt::cpp_standard
enum configt::cppt::cpp_standardt cpp_standard