I just found a behavior change of driver on multiple input assembly files. Previously (before r164357), for the command line

gcc -o t t1.s t2.s

, the driver will call assembler twice, once for t1.s and once for t2.s. After r164357, the driver will only call assembler once for t1.s and t2.s. Then if t1.s and t2.s have same symbol, assembler will report an error, like:

t2.s: Assembler messages:
t2.s:1: Error: symbol `.L1' is already defined

I read the discussion on the mailing list starting by the patch email of r164357.[1] It seems that this behavior change is not the intention of that patch. And I think the previous behavior is more useful than the current behavior. So it's good to restore the previous behavior, isn't?

For a minimal fix, I propose to change combinable fields of assembly languages in default_compilers[] to 0. See the attached patch "gcc-not-combine-assembly-inputs.diff". I don't know why the combinable fields were set to 1 when --combine option was introduced. There is no explanation about that in that patch email.[2] Does anyone still remember?

For an aggressive fix, how about removing the combinable field from "struct compiler"? If we change combinable fields of assembly languages in default_compilers[] to 0, only ".go" and "@cpp-output" set combinable to 1. I don't see any reason for difference between "@cpp-output" and ".i". So if we can set combinable to 0 for ".go", we have 0 for all compilers in default_compilers[], thus we can remove that field. Is there a reason to set 1 for ".go"?

I also attached the aggressive patch "gcc-remove-combinable-field.diff". Either patch is not tested. Which way should we go?

[1] http://gcc.gnu.org/ml/gcc-patches/2010-09/msg01322.html
[2] http://gcc.gnu.org/ml/gcc-patches/2004-03/msg01880.html


Regards,
--
Jie Zhang


	* gcc.c (default_compilers[]): Set combinable field to 0
	for all assembly languages.

Index: gcc.c
===================================================================
--- gcc.c	(revision 168362)
+++ gcc.c	(working copy)
@@ -935,11 +935,11 @@ static const struct compiler default_com
   {".i", "@cpp-output", 0, 0, 0},
   {"@cpp-output",
    "%{!M:%{!MM:%{!E:cc1 -fpreprocessed %i %(cc1_options) %{!fsyntax-only:%(invoke_as)}}}}", 0, 1, 0},
-  {".s", "@assembler", 0, 1, 0},
+  {".s", "@assembler", 0, 0, 0},
   {"@assembler",
-   "%{!M:%{!MM:%{!E:%{!S:as %(asm_debug) %(asm_options) %i %A }}}}", 0, 1, 0},
-  {".sx", "@assembler-with-cpp", 0, 1, 0},
-  {".S", "@assembler-with-cpp", 0, 1, 0},
+   "%{!M:%{!MM:%{!E:%{!S:as %(asm_debug) %(asm_options) %i %A }}}}", 0, 0, 0},
+  {".sx", "@assembler-with-cpp", 0, 0, 0},
+  {".S", "@assembler-with-cpp", 0, 0, 0},
   {"@assembler-with-cpp",
 #ifdef AS_NEEDS_DASH_FOR_PIPED_INPUT
    "%(trad_capable_cpp) -lang-asm %(cpp_options) -fno-directives-only\
@@ -952,7 +952,7 @@ static const struct compiler default_com
       %{!M:%{!MM:%{!E:%{!S:-o %|.s |\n\
        as %(asm_debug) %(asm_options) %m.s %A }}}}"
 #endif
-   , 0, 1, 0},
+   , 0, 0, 0},
 
 #include "specs.h"
   /* Mark end of table.  */
Index: gcc.c
===================================================================
--- gcc.c	(revision 168362)
+++ gcc.c	(working copy)
@@ -847,8 +847,6 @@ struct compiler
   const char *cpp_spec;         /* If non-NULL, substitute this spec
 				   for `%C', rather than the usual
 				   cpp_spec.  */
-  const int combinable;          /* If nonzero, compiler can deal with
-				    multiple source files at once (IMA).  */
   const int needs_preprocessing; /* If nonzero, source files need to
 				    be run through a preprocessor.  */
 };
@@ -876,29 +874,29 @@ static const struct compiler default_com
      were not present when we built the driver, we will hit these copies
      and be given a more meaningful error than "file not used since
      linking is not done".  */
-  {".m",  "#Objective-C", 0, 0, 0}, {".mi",  "#Objective-C", 0, 0, 0},
-  {".mm", "#Objective-C++", 0, 0, 0}, {".M", "#Objective-C++", 0, 0, 0},
-  {".mii", "#Objective-C++", 0, 0, 0},
-  {".cc", "#C++", 0, 0, 0}, {".cxx", "#C++", 0, 0, 0},
-  {".cpp", "#C++", 0, 0, 0}, {".cp", "#C++", 0, 0, 0},
-  {".c++", "#C++", 0, 0, 0}, {".C", "#C++", 0, 0, 0},
-  {".CPP", "#C++", 0, 0, 0}, {".ii", "#C++", 0, 0, 0},
-  {".ads", "#Ada", 0, 0, 0}, {".adb", "#Ada", 0, 0, 0},
-  {".f", "#Fortran", 0, 0, 0}, {".F", "#Fortran", 0, 0, 0},
-  {".for", "#Fortran", 0, 0, 0}, {".FOR", "#Fortran", 0, 0, 0},
-  {".ftn", "#Fortran", 0, 0, 0}, {".FTN", "#Fortran", 0, 0, 0},
-  {".fpp", "#Fortran", 0, 0, 0}, {".FPP", "#Fortran", 0, 0, 0},
-  {".f90", "#Fortran", 0, 0, 0}, {".F90", "#Fortran", 0, 0, 0},
-  {".f95", "#Fortran", 0, 0, 0}, {".F95", "#Fortran", 0, 0, 0},
-  {".f03", "#Fortran", 0, 0, 0}, {".F03", "#Fortran", 0, 0, 0},
-  {".f08", "#Fortran", 0, 0, 0}, {".F08", "#Fortran", 0, 0, 0},
-  {".r", "#Ratfor", 0, 0, 0},
-  {".p", "#Pascal", 0, 0, 0}, {".pas", "#Pascal", 0, 0, 0},
-  {".java", "#Java", 0, 0, 0}, {".class", "#Java", 0, 0, 0},
-  {".zip", "#Java", 0, 0, 0}, {".jar", "#Java", 0, 0, 0},
-  {".go", "#Go", 0, 1, 0},
+  {".m",  "#Objective-C", 0, 0}, {".mi",  "#Objective-C", 0, 0},
+  {".mm", "#Objective-C++", 0, 0}, {".M", "#Objective-C++", 0, 0},
+  {".mii", "#Objective-C++", 0, 0},
+  {".cc", "#C++", 0, 0}, {".cxx", "#C++", 0, 0},
+  {".cpp", "#C++", 0, 0}, {".cp", "#C++", 0, 0},
+  {".c++", "#C++", 0, 0}, {".C", "#C++", 0, 0},
+  {".CPP", "#C++", 0, 0}, {".ii", "#C++", 0, 0},
+  {".ads", "#Ada", 0, 0}, {".adb", "#Ada", 0, 0},
+  {".f", "#Fortran", 0, 0}, {".F", "#Fortran", 0, 0},
+  {".for", "#Fortran", 0, 0}, {".FOR", "#Fortran", 0, 0},
+  {".ftn", "#Fortran", 0, 0}, {".FTN", "#Fortran", 0, 0},
+  {".fpp", "#Fortran", 0, 0}, {".FPP", "#Fortran", 0, 0},
+  {".f90", "#Fortran", 0, 0}, {".F90", "#Fortran", 0, 0},
+  {".f95", "#Fortran", 0, 0}, {".F95", "#Fortran", 0, 0},
+  {".f03", "#Fortran", 0, 0}, {".F03", "#Fortran", 0, 0},
+  {".f08", "#Fortran", 0, 0}, {".F08", "#Fortran", 0, 0},
+  {".r", "#Ratfor", 0, 0},
+  {".p", "#Pascal", 0, 0}, {".pas", "#Pascal", 0, 0},
+  {".java", "#Java", 0, 0}, {".class", "#Java", 0, 0},
+  {".zip", "#Java", 0, 0}, {".jar", "#Java", 0, 0},
+  {".go", "#Go", 0, 0},
   /* Next come the entries for C.  */
-  {".c", "@c", 0, 0, 1},
+  {".c", "@c", 0, 1},
   {"@c",
    /* cc1 has an integrated ISO C preprocessor.  We should invoke the
       external preprocessor if -save-temps is given.  */
@@ -912,11 +910,11 @@ static const struct compiler default_com
 	  %(cc1_options)}\
       %{!save-temps*:%{!traditional-cpp:%{!no-integrated-cpp:\
 	  cc1 %(cpp_unique_options) %(cc1_options)}}}\
-      %{!fsyntax-only:%(invoke_as)}}}}", 0, 0, 1},
+      %{!fsyntax-only:%(invoke_as)}}}}", 0, 1},
   {"-",
    "%{!E:%e-E or -x required when input is from standard input}\
-    %(trad_capable_cpp) %(cpp_options) %(cpp_debug_options)", 0, 0, 0},
-  {".h", "@c-header", 0, 0, 0},
+    %(trad_capable_cpp) %(cpp_options) %(cpp_debug_options)", 0, 0},
+  {".h", "@c-header", 0, 0},
   {"@c-header",
    /* cc1 has an integrated ISO C preprocessor.  We should invoke the
       external preprocessor if -save-temps is given.  */
@@ -931,15 +929,15 @@ static const struct compiler default_com
 	  %{!save-temps*:%{!traditional-cpp:%{!no-integrated-cpp:\
 		cc1 %(cpp_unique_options) %(cc1_options)\
                     %{!fdump-ada-spec*:-o %g.s %{!o*:--output-pch=%i.gch}\
-                    %W{o*:--output-pch=%*}}%V}}}}}}", 0, 0, 0},
-  {".i", "@cpp-output", 0, 0, 0},
+                    %W{o*:--output-pch=%*}}%V}}}}}}", 0, 0},
+  {".i", "@cpp-output", 0, 0},
   {"@cpp-output",
-   "%{!M:%{!MM:%{!E:cc1 -fpreprocessed %i %(cc1_options) %{!fsyntax-only:%(invoke_as)}}}}", 0, 1, 0},
-  {".s", "@assembler", 0, 1, 0},
+   "%{!M:%{!MM:%{!E:cc1 -fpreprocessed %i %(cc1_options) %{!fsyntax-only:%(invoke_as)}}}}", 0, 0},
+  {".s", "@assembler", 0, 0},
   {"@assembler",
-   "%{!M:%{!MM:%{!E:%{!S:as %(asm_debug) %(asm_options) %i %A }}}}", 0, 1, 0},
-  {".sx", "@assembler-with-cpp", 0, 1, 0},
-  {".S", "@assembler-with-cpp", 0, 1, 0},
+   "%{!M:%{!MM:%{!E:%{!S:as %(asm_debug) %(asm_options) %i %A }}}}", 0, 0},
+  {".sx", "@assembler-with-cpp", 0, 0},
+  {".S", "@assembler-with-cpp", 0, 0},
   {"@assembler-with-cpp",
 #ifdef AS_NEEDS_DASH_FOR_PIPED_INPUT
    "%(trad_capable_cpp) -lang-asm %(cpp_options) -fno-directives-only\
@@ -952,11 +950,11 @@ static const struct compiler default_com
       %{!M:%{!MM:%{!E:%{!S:-o %|.s |\n\
        as %(asm_debug) %(asm_options) %m.s %A }}}}"
 #endif
-   , 0, 1, 0},
+   , 0, 0},
 
 #include "specs.h"
   /* Mark end of table.  */
-  {0, 0, 0, 0, 0}
+  {0, 0, 0, 0}
 };
 
 /* Number of elements in default_compilers, not counting the terminator.  */
@@ -2812,11 +2810,6 @@ int n_infiles;
 
 static int n_infiles_alloc;
 
-/* True if multiple input files are being compiled to a single
-   assembly file.  */
-
-static bool combine_inputs;
-
 /* This counts the number of libraries added by lang_specific_driver, so that
    we can tell if there were any user supplied any files or libraries.  */
 
@@ -4756,50 +4749,9 @@ do_spec_1 (const char *spec, int inswitc
 	    break;
 
 	  case 'i':
-	    if (combine_inputs)
-	      {
-		if (at_file_supplied)
-		  {
-		    /* We are going to expand `%i' to `...@file', where FILE
-		       is a newly-created temporary filename.  The filenames
-		       that would usually be expanded in place of %o will be
-		       written to the temporary file.  */
-		    char **argv;
-		    int n_files = 0;
-		    int j;
-
-		    for (i = 0; i < n_infiles; i++)
-		      if (compile_input_file_p (&infiles[i]))
-			n_files++;
-
-		    argv = (char **) alloca (sizeof (char *) * (n_files + 1));
-
-		    /* Copy the strings over.  */
-		    for (i = 0, j = 0; i < n_infiles; i++)
-		      if (compile_input_file_p (&infiles[i]))
-			{
-			  argv[j] = CONST_CAST (char *, infiles[i].name);
-			  infiles[i].compiled = true;
-			  j++;
-			}
-		    argv[j] = NULL;
-
-		    create_at_file (argv);
-		  }
-		else
-		  for (i = 0; (int) i < n_infiles; i++)
-		    if (compile_input_file_p (&infiles[i]))
-		      {
-			store_arg (infiles[i].name, 0, 0);
-			infiles[i].compiled = true;
-		      }
-	      }
-	    else
-	      {
-		obstack_grow (&obstack, gcc_input_filename,
-			      input_filename_length);
-		arg_going = 1;
-	      }
+	    obstack_grow (&obstack, gcc_input_filename,
+			  input_filename_length);
+	    arg_going = 1;
 	    break;
 
 	  case 'I':
@@ -6582,8 +6534,6 @@ warranty; not even for MERCHANTABILITY o
 
   explicit_link_files = XCNEWVEC (char, n_infiles);
 
-  combine_inputs = have_o || flag_wpa;
-
   for (i = 0; (int) i < n_infiles; i++)
     {
       const char *name = infiles[i].name;
@@ -6591,9 +6541,6 @@ warranty; not even for MERCHANTABILITY o
 						   strlen (name),
 						   infiles[i].language);
 
-      if (compiler && !(compiler->combinable))
-	combine_inputs = false;
-
       if (lang_n_infiles > 0 && compiler != input_file_compiler
 	  && infiles[i].language && infiles[i].language[0] != '*')
 	infiles[i].incompiler = compiler;
@@ -6614,7 +6561,7 @@ warranty; not even for MERCHANTABILITY o
       infiles[i].preprocessed = false;
     }
 
-  if (!combine_inputs && have_c && have_o && lang_n_infiles > 1)
+  if (have_c && have_o && lang_n_infiles > 1)
     fatal_error ("cannot specify -o with -c, -S or -E with multiple files");
 
   for (i = 0; (int) i < n_infiles; i++)

Reply via email to