@@ -19,10 +19,13 @@ Author: CM Wintersteiger, 2006
1919#include < sysexits.h>
2020#endif
2121
22+ #include < cstddef>
2223#include < cstdio>
2324#include < iostream>
2425#include < fstream>
2526#include < cstring>
27+ #include < numeric>
28+ #include < sstream>
2629
2730#include < util/string2int.h>
2831#include < util/invariant.h>
@@ -337,10 +340,16 @@ int gcc_modet::doit()
337340 std::cout << " gcc version 3.4.4 (goto-cc " CBMC_VERSION " )\n " ;
338341 }
339342
343+ compilet compiler (cmdline,
344+ gcc_message_handler,
345+ cmdline.isset (" Werror" ) &&
346+ cmdline.isset (" Wextra" ) &&
347+ !cmdline.isset (" Wno-error" ));
348+
340349 if (cmdline.isset (" version" ))
341350 {
342351 if (produce_hybrid_binary)
343- return run_gcc ();
352+ return run_gcc (compiler );
344353
345354 std::cout << ' \n ' <<
346355 " Copyright (C) 2006-2014 Daniel Kroening, Christoph Wintersteiger\n " <<
@@ -354,7 +363,7 @@ int gcc_modet::doit()
354363 if (cmdline.isset (" dumpversion" ))
355364 {
356365 if (produce_hybrid_binary)
357- return run_gcc ();
366+ return run_gcc (compiler );
358367
359368 std::cout << " 3.4.4\n " ;
360369 return EX_OK;
@@ -390,6 +399,24 @@ int gcc_modet::doit()
390399 debug () << " GCC mode" << eom;
391400 }
392401
402+ // determine actions to be undertaken
403+ if (act_as_ld)
404+ compiler.mode =compilet::LINK_LIBRARY;
405+ else if (cmdline.isset (' S' ))
406+ compiler.mode =compilet::ASSEMBLE_ONLY;
407+ else if (cmdline.isset (' c' ))
408+ compiler.mode =compilet::COMPILE_ONLY;
409+ else if (cmdline.isset (' E' ))
410+ {
411+ compiler.mode =compilet::PREPROCESS_ONLY;
412+ UNREACHABLE;
413+ }
414+ else if (cmdline.isset (" shared" ) ||
415+ cmdline.isset (' r' )) // really not well documented
416+ compiler.mode =compilet::COMPILE_LINK;
417+ else
418+ compiler.mode =compilet::COMPILE_LINK_EXECUTABLE;
419+
393420 // In gcc mode, we have just pass on to gcc to handle the following:
394421 // * if -M or -MM is given, we do dependencies only
395422 // * preprocessing (-E)
@@ -402,7 +429,7 @@ int gcc_modet::doit()
402429 cmdline.isset (" MM" ) ||
403430 cmdline.isset (' E' ) ||
404431 !cmdline.have_infile_arg ())
405- return run_gcc (); // exit!
432+ return run_gcc (compiler ); // exit!
406433
407434 // get configuration
408435 config.set (cmdline);
@@ -489,30 +516,6 @@ int gcc_modet::doit()
489516 if (cmdline.isset (" fshort-double" ))
490517 config.ansi_c .double_width =config.ansi_c .single_width ;
491518
492- // determine actions to be undertaken
493- compilet compiler (cmdline,
494- gcc_message_handler,
495- cmdline.isset (" Werror" ) &&
496- cmdline.isset (" Wextra" ) &&
497- !cmdline.isset (" Wno-error" ));
498-
499- if (act_as_ld)
500- compiler.mode =compilet::LINK_LIBRARY;
501- else if (cmdline.isset (' S' ))
502- compiler.mode =compilet::ASSEMBLE_ONLY;
503- else if (cmdline.isset (' c' ))
504- compiler.mode =compilet::COMPILE_ONLY;
505- else if (cmdline.isset (' E' ))
506- {
507- compiler.mode =compilet::PREPROCESS_ONLY;
508- UNREACHABLE;
509- }
510- else if (cmdline.isset (" shared" ) ||
511- cmdline.isset (' r' )) // really not well documented
512- compiler.mode =compilet::COMPILE_LINK;
513- else
514- compiler.mode =compilet::COMPILE_LINK_EXECUTABLE;
515-
516519 switch (compiler.mode )
517520 {
518521 case compilet::LINK_LIBRARY:
@@ -695,10 +698,10 @@ int gcc_modet::doit()
695698
696699 if (compiler.source_files .empty () &&
697700 compiler.object_files .empty ())
698- return run_gcc (); // exit!
701+ return run_gcc (compiler ); // exit!
699702
700703 if (compiler.mode ==compilet::ASSEMBLE_ONLY)
701- return asm_output (act_as_bcc, compiler.source_files );
704+ return asm_output (act_as_bcc, compiler.source_files , compiler );
702705
703706 // do all the rest
704707 if (compiler.doit ())
@@ -707,7 +710,7 @@ int gcc_modet::doit()
707710 // We can generate hybrid ELF and Mach-O binaries
708711 // containing both executable machine code and the goto-binary.
709712 if (produce_hybrid_binary && !act_as_bcc)
710- return gcc_hybrid_binary ();
713+ return gcc_hybrid_binary (compiler );
711714
712715 return EX_OK;
713716}
@@ -791,8 +794,7 @@ int gcc_modet::preprocess(
791794 return run (new_argv[0 ], new_argv, cmdline.stdin_file , stdout_file);
792795}
793796
794- // / run gcc or clang with original command line
795- int gcc_modet::run_gcc ()
797+ int gcc_modet::run_gcc (const compilet &compiler)
796798{
797799 PRECONDITION (!cmdline.parsed_argv .empty ());
798800
@@ -802,6 +804,28 @@ int gcc_modet::run_gcc()
802804 for (const auto &a : cmdline.parsed_argv )
803805 new_argv.push_back (a.arg );
804806
807+ if (compiler.wrote_object_files ())
808+ {
809+ // Undefine all __CPROVER macros for the system compiler
810+ std::map<irep_idt, std::size_t > arities;
811+ compiler.cprover_macro_arities (arities);
812+ for (const auto &pair : arities)
813+ {
814+ std::ostringstream addition;
815+ addition << " -D" << id2string (pair.first ) << " (" ;
816+ std::vector<char > params (pair.second );
817+ std::iota (params.begin (), params.end (), ' a' );
818+ for (std::vector<char >::iterator it=params.begin (); it!=params.end (); ++it)
819+ {
820+ addition << *it;
821+ if (it+1 !=params.end ())
822+ addition << " ," ;
823+ }
824+ addition << " )= " ;
825+ new_argv.push_back (addition.str ());
826+ }
827+ }
828+
805829 // overwrite argv[0]
806830 new_argv[0 ]=native_tool_name;
807831
@@ -813,7 +837,7 @@ int gcc_modet::run_gcc()
813837 return run (new_argv[0 ], new_argv, cmdline.stdin_file , " " );
814838}
815839
816- int gcc_modet::gcc_hybrid_binary ()
840+ int gcc_modet::gcc_hybrid_binary (const compilet &compiler )
817841{
818842 {
819843 bool have_files=false ;
@@ -861,7 +885,7 @@ int gcc_modet::gcc_hybrid_binary()
861885 if (output_files.empty () ||
862886 (output_files.size ()==1 &&
863887 output_files.front ()==" /dev/null" ))
864- return run_gcc () ;
888+ return EX_OK ;
865889
866890 debug () << " Running " << native_tool_name
867891 << " to generate hybrid binary" << eom;
@@ -893,7 +917,7 @@ int gcc_modet::gcc_hybrid_binary()
893917 }
894918 objcopy_cmd+=" objcopy" ;
895919
896- int result=run_gcc ();
920+ int result=run_gcc (compiler );
897921
898922 // merge output from gcc with goto-binaries
899923 // using objcopy, or do cleanup if an earlier call failed
@@ -975,7 +999,8 @@ int gcc_modet::gcc_hybrid_binary()
975999
9761000int gcc_modet::asm_output (
9771001 bool act_as_bcc,
978- const std::list<std::string> &preprocessed_source_files)
1002+ const std::list<std::string> &preprocessed_source_files,
1003+ const compilet &compiler)
9791004{
9801005 {
9811006 bool have_files=false ;
@@ -996,7 +1021,7 @@ int gcc_modet::asm_output(
9961021 debug () << " Running " << native_tool_name
9971022 << " to generate native asm output" << eom;
9981023
999- int result=run_gcc ();
1024+ int result=run_gcc (compiler );
10001025 if (result!=0 )
10011026 // native tool failed
10021027 return result;
0 commit comments