[PATCH] Bulletproofing -fsyntax-only, round 2 (extra armour plate)

Nix nix@esperi.demon.co.uk
Mon Jun 12 10:44:00 GMT 2000


As promised, here is a -fsyntax-only patch (against the 20000605
snapshot) which is a little more general than the last one. It provides
a new #define, HOST_BIT_BUCKET, which system.h defines to point at
/dev/null, but which xm-* files may override for specific host
platforms.

The patch sets HOST_BIT_BUCKET to "NUL:" on *-*-winnt* and DOS hosts,
but not on cygwin or mingw hosts, because they both provide
/dev/null. (At least, I *think* mingw does...) I'm not sure whether
xm-dos.h is actually used by anything, but if it is it's using NUL: as
the bit bucket, too.

Platform maintainers should probably define HOST_BIT_BUCKET for their
platforms if their platforms have a bit bucket and it is not /dev/null,
but I'm not sure what the bit buckets are on any other platforms, so I
cannot do this. gcc -fsyntax-only will work by way of a temporary file
if the HOST_BIT_BUCKET is not accessible (as it will be om VMS until
someone fixes xm-vms.h, for instance), but protoize may well not work if
it is not accessible.

I spotted and fixed more breakage in -fsyntax-only since the last patch;
the default specs in gcc.c *always* run the assembler, even if no output
is generated, and certain vendor assemblers, like that on DEC OSF/1
4.0d, die in flames if no input is provided. GCC then displays that
error rather than the syntax-checking output from cc1* ;) so I've
wrapped a %{!fsyntax-only:...} around the appropriate parts of the
specs, to block the assembler from running when we know it hasn't got
anything useful to do. Richard Kenner checked in something similar a few
months ago for C++, but it only did half the job, as it didn't kick in
if you compiled a .ii file with -fsyntax-only, so I reexpressed his
existing work to look the same as what's turned up in all the other
lang-specs files, and in gcc.c itself. (This `reexpression' was a matter
of moving one line ;) )

(This change is perhaps slightly questionable, as it means `-o foo' is
totally ignored with -fsyntax-only; i.e. you don't even get an empty
output file, or even a temporary. But ISTM that this is what the user
expected, even if it's not what gcc has been doing up to now...)

While I was in gcc.c I killed MKTEMP_EACH_FILE and the false parts of
the code paths in question; that code has been dead for years, and looks
like a massive predictable-/tmp-names security hole if it is ever
enabled, so killing it completely is probably a good thing.


Kludges to perhaps fix: I haven't bothered catering for the case where
the temporary file can't be created; no other parts of GCC that create
temporaries bother to check, so it can't be especially harmful to not
bother here either.

I assumed that access() is always present, even though it is not ISO C;
parts of GCC already use it, so I haven't broken things worse than they
already are, I hope.

If gcc has to use a temporary file rather than another method of
bit-bucketing its data, deleting that file is difficult. The way I'm
doing it right now is quite ugly, and I expect everyone to scream in
horror and throw it back in my face. Probably a replacement mkstemp() in
libiberty, using a single atexit() and a linked list of files for
deletion, is in order; I'll probably implement that soon, but I'm coming
down with a cold right now, and my mind is shutting down :(

I'm not so sure about my changes to the bottom of gcc/f/lang-specs.h,
because it's structured to always run `as' and `ld', and then run the
binary (!!), but never via a pipe. I've just killed all of that from
`as' onwards if -fsyntax-only is on; this may be wrong, although it
passes its tests. What is that `@f77-version' part of that specs file
for?


Bootstrapped and tested on i586-pc-linux-gnu, once normally and once
with a changed system.h with /dev/null misspelled to force a temporary
file to be used instead. Also ran the non-execute parts of the C
testsuite with -fsyntax-only (and the compiler never sig11ed, although
every test `failed' because the output file didn't exist). The changes
to the chill lang-specs file are still totally untested, and some bits
of the other lang-specs files elsewhere will probably be untested too
(.ii, for instance). But all those changes are very similar... except
for the weird Fortran run-the-binary-at-the-end spec entry. I'm not sure
*what* that's doing, so I'm not sure when it's used... maybe that's been
tested, maybe not ;)

The tiny change to protoize.c is untested.

A backport of this to 2.95.2 has been tested on alphaev56-dec-osf4.0d,
hppa2.0-hp-hpux10.20 and sparc-sun-solaris2.5.1 (there's no space for
the snapshots at the site where I did this).


(The copyright assignment form will be in the post as soon as I get
access to a printer with some ink left in it :) when my cold has faded
I'll get it done.)


2000-06-11  Nix  <nix@esperi.demon.co.uk>

	* system.h (HOST_BIT_BUCKET): Default to "/dev/null".
	* config/i386/xm-djgpp.h (HOST_BIT_BUCKET): Define as "NUL:".
	* config/i386/xm-dos.h, config/i386/xm-os2.h,
	config/winnt/winnt.h: Likewise.

	* toplev.c: (ax_delete_temporaries): New function.
	(main): Register it with atexit().
	(compile_file): Point the asm_out_file at HOST_BIT_BUCKET (if
	accessible) or a temporary file when -fsyntax-only is on, not at
	NULL.  Close it even if -fsyntax-only is on.
	* protoize.c (munge_compile_params): Use HOST_BIT_BUCKET instead
	of hardcoded value.

	* gcc.c, config/i386/xm-dos.h, config/i386/xm-os2.h: Kill
	MKTEMP_EACH_FILE.

	* gcc.c, ch/lang-specs.h, cp/lang-specs.h, f/lang-specs.h,
	java/lang-specs.h, objc/lang-specs.h: Do not process -o or
	run the assembler if -fsyntax-only.

diff -uprN egcs/gcc/ch/lang-specs.h egcs-hacking/gcc/ch/lang-specs.h
--- egcs/gcc/ch/lang-specs.h	Sat Apr  8 18:33:05 2000
+++ egcs-hacking/gcc/ch/lang-specs.h	Sat Jun 10 18:45:11 2000
@@ -38,7 +38,7 @@ Boston, MA 02111-1307, USA.  */
 		   %{v:-version} %{pg:-p} %{p} %{f*} %{I*} \
 		   %{aux-info*} %{Qn:-fno-ident} %X \
 		   %{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\
-		   %{S:%W{o*}%{!o*:-o %b.s}}%{!S:-o %{|!pipe:%g.s}} |\n\
+		   %{!fsyntax-only:%{S:%W{o*}%{!o*:-o %b.s}}%{!S:-o %{|!pipe:%g.s}} |\n\
               %{!S:as %a %Y \
 		      %{c:%W{o*}%{!o*:-o %w%b%O}}%{!c:-o %d%w%u%O}\
-                      %{!pipe:%g.s} %A\n }}"}},
+                      %{!pipe:%g.s} %A\n }}}"}},
diff -uprN egcs/gcc/config/i386/xm-djgpp.h egcs-hacking/gcc/config/i386/xm-djgpp.h
--- egcs/gcc/config/i386/xm-djgpp.h	Sun May 28 23:18:42 2000
+++ egcs-hacking/gcc/config/i386/xm-djgpp.h	Sat Jun 10 16:38:21 2000
@@ -34,6 +34,10 @@ Boston, MA 02111-1307, USA.  */
 /* Allow test for DOS drive names.  */
 #define HAVE_DOS_BASED_FILE_SYSTEM
 
+/* Tell GCC about DOS's bit bucket. */
+
+#define HOST_BIT_BUCKET "NUL:"
+
 /* System dependant initialization for collect2
    to tell system() to act like Unix.  */
 #define COLLECT2_HOST_INITIALIZATION \
diff -uprN egcs/gcc/config/i386/xm-dos.h egcs-hacking/gcc/config/i386/xm-dos.h
--- egcs/gcc/config/i386/xm-dos.h	Mon Apr 12 00:59:24 1999
+++ egcs-hacking/gcc/config/i386/xm-dos.h	Sat Jun 10 16:39:11 2000
@@ -33,6 +33,8 @@ Boston, MA 02111-1307, USA.  */
 /* Suffix for executable file names.  */
 #define EXECUTABLE_SUFFIX ".exe"
 
-#define MKTEMP_EACH_FILE 1
+/* Tell GCC about DOS's bit bucket. */
+
+#define HOST_BIT_BUCKET "NUL:"
 
 #define NO_PRECOMPILES 1
diff -uprN egcs/gcc/config/i386/xm-os2.h egcs-hacking/gcc/config/i386/xm-os2.h
--- egcs/gcc/config/i386/xm-os2.h	Thu May 25 20:07:33 2000
+++ egcs-hacking/gcc/config/i386/xm-os2.h	Sat Jun 10 17:02:37 2000
@@ -67,8 +67,8 @@ int spawnvp (int modeflag, char *path, c
 #define OBJECT_SUFFIX ".obj"
 #endif
 
-/* This is required to make temporary file names unique on file
-   systems which severely restrict the length of file names. */
-#define MKTEMP_EACH_FILE
+/* Tell GCC about OS/2's bit bucket. */
+
+#define HOST_BIT_BUCKET "NUL:"
 
 #include "i386/xm-i386.h"
diff -uprN egcs/gcc/config/winnt/xm-winnt.h egcs-hacking/gcc/config/winnt/xm-winnt.h
--- egcs/gcc/config/winnt/xm-winnt.h	Mon Feb  7 19:46:20 2000
+++ egcs-hacking/gcc/config/winnt/xm-winnt.h	Sat Jun 10 16:38:33 2000
@@ -53,6 +53,10 @@ Boston, MA 02111-1307, USA.  */
 /* Allows checks for drive names.  */
 #define HAVE_DOS_BASED_FILE_SYSTEM
 
+/* Tell GCC about NT's bit bucket. */
+
+#define HOST_BIT_BUCKET "NUL:"
+
 #define S_IRUSR 0000400
 #define S_IWUSR 0000200
 #define S_IXUSR 0000100
diff -uprN egcs/gcc/cp/lang-specs.h egcs-hacking/gcc/cp/lang-specs.h
--- egcs/gcc/cp/lang-specs.h	Sat Apr  8 18:33:23 2000
+++ egcs-hacking/gcc/cp/lang-specs.h	Sat Jun 10 18:46:55 2000
@@ -62,8 +62,8 @@ Boston, MA 02111-1307, USA.  */
 			    %{v:-version} %{pg:-p} %{p}\
 			    %{f*} %{+e*} %{aux-info*} %{Qn:-fno-ident}\
 			    %{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\
-			    %{S:%W{o*}%{!o*:-o %b.s}}%{!S:-o %{|!pipe:%g.s}}|\n\
-              %{!S:%{!fsyntax-only:as %a %Y\
+			    %{!fsyntax-only:%{S:%W{o*}%{!o*:-o %b.s}}%{!S:-o %{|!pipe:%g.s}}|\n\
+              %{!S:as %a %Y\
 		      %{c:%W{o*}%{!o*:-o %w%b%O}}%{!c:-o %d%w%u%O}\
                       %{!pipe:%g.s} %A\n }}}}}"}},
 #else /* ! USE_CPPLIB */
@@ -87,8 +87,8 @@ Boston, MA 02111-1307, USA.  */
 			    %{v:-version} %{pg:-p} %{p}\
 			    %{f*} %{+e*} %{aux-info*} %{Qn:-fno-ident}\
 			    %{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\
-			    %{S:%W{o*}%{!o*:-o %b.s}}%{!S:-o %{|!pipe:%g.s}}|\n\
-              %{!S:%{!fsyntax-only:as %a %Y\
+			    %{!fsyntax-only:%{S:%W{o*}%{!o*:-o %b.s}}%{!S:-o %{|!pipe:%g.s}}|\n\
+              %{!S:as %a %Y\
 		      %{c:%W{o*}%{!o*:-o %w%b%O}}%{!c:-o %d%w%u%O}\
                       %{!pipe:%g.s} %A\n }}}}}"}},
 #endif /* ! USE_CPPLIB */
@@ -99,7 +99,7 @@ Boston, MA 02111-1307, USA.  */
 			    %{v:-version} %{pg:-p} %{p} -fpreprocessed\
 			    %{f*} %{+e*} %{aux-info*} %{Qn:-fno-ident}\
 			    %{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\
-			    %{S:%W{o*}%{!o*:-o %b.s}}%{!S:-o %{|!pipe:%g.s}} |\n\
+			    %{!fsyntax-only:%{S:%W{o*}%{!o*:-o %b.s}}%{!S:-o %{|!pipe:%g.s}} |\n\
 	            %{!S:as %a %Y\
 			    %{c:%W{o*}%{!o*:-o %w%b%O}}%{!c:-o %d%w%u%O}\
-			    %{!pipe:%g.s} %A\n }}}}"}},
+			    %{!pipe:%g.s} %A\n }}}}}"}},
diff -uprN egcs/gcc/f/lang-specs.h egcs-hacking/gcc/f/lang-specs.h
--- egcs/gcc/f/lang-specs.h	Sat Apr  8 18:33:54 2000
+++ egcs-hacking/gcc/f/lang-specs.h	Sat Jun 10 18:53:50 2000
@@ -52,10 +52,10 @@ the Free Software Foundation, 59 Temple 
 		   %{v:-version -fversion} %{pg:-p} %{p} %{f*} %{I*}\
 		   %{aux-info*} %{Qn:-fno-ident}\
 		   %{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\
-		   %{S:%W{o*}%{!o*:-o %b.s}}%{!S:-o %{|!pipe:%g.s}} |\n\
+		   %{!fsyntax-only:%{S:%W{o*}%{!o*:-o %b.s}}%{!S:-o %{|!pipe:%g.s}} |\n\
 	      %{!S:as %a %Y\
 		      %{c:%W{o*}%{!o*:-o %w%b%O}}%{!c:-o %d%w%u%O}\
-		      %{!pipe:%g.s} %A\n }}}}"}},
+		      %{!pipe:%g.s} %A\n }}}}}"}},
   {".r", {"@ratfor"}},
   {"@ratfor",
    {"ratfor %{C} %{v}\
@@ -81,10 +81,10 @@ the Free Software Foundation, 59 Temple 
 		   %{v:-version -fversion} %{pg:-p} %{p} %{f*} %{I*}\
 		   %{aux-info*} %{Qn:-fno-ident}\
 		   %{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\
-		   %{S:%W{o*}%{!o*:-o %b.s}}%{!S:-o %{|!pipe:%g.s}} |\n\
+		   %{!fsyntax-only:%{S:%W{o*}%{!o*:-o %b.s}}%{!S:-o %{|!pipe:%g.s}} |\n\
 	      %{!S:as %a %Y\
 		      %{c:%W{o*}%{!o*:-o %w%b%O}}%{!c:-o %d%w%u%O}\
-		      %{!pipe:%g.s} %A\n }}}}"}},
+		      %{!pipe:%g.s} %A\n }}}}}"}},
   {"@f77-version",
    {"cpp -lang-fortran %{nostdinc*} %{C} %{v} %{A*} %{I*} %{P} %{$} %I \
       %{C:%{!E:%eGNU C does not support -C without using -E}} \
@@ -99,8 +99,8 @@ the Free Software Foundation, 59 Temple 
      f771 -fnull-version %1 %(f771) \
       %{!Q:-quiet} -dumpbase g77-version.f %{d*} %{m*} %{a*} \
       %{g*} %{O*} %{W*} %{w} %{pedantic*} \
-      -version -fversion %{f*} %{I*} -o %g.s /dev/null \n\
-     as %a %Y -o %g%O %g.s %A \n\
+      -version -fversion %{f*} %{I*} %{!fsyntax-only:-o %g.s} /dev/null \n\
+     %{!fsyntax-only:as %a %Y -o %g%O %g.s %A \n\
      ld %l %X -o %g %g%O %{A} %{d} %{e*} %{m} %{N} %{n} \
       %{r} %{s} %{t} %{u*} %{x} %{z} %{Z} \
       %{!A:%{!nostdlib:%{!nostartfiles:%S}}} \
@@ -108,4 +108,4 @@ the Free Software Foundation, 59 Temple 
       %{!nostdlib:%{!nodefaultlibs:%G %L %G}} \
       %{!A:%{!nostdlib:%{!nostartfiles:%E}}} \
       %{T*} \n\
-     %g \n"}},
+     %g \n}"}},
diff -uprN egcs/gcc/gcc.c egcs-hacking/gcc/gcc.c
--- egcs/gcc/gcc.c	Sun May 28 23:18:03 2000
+++ egcs-hacking/gcc/gcc.c	Sat Jun 10 18:10:20 2000
@@ -655,10 +655,10 @@ static struct compiler default_compilers
 		  %{--help:--help}\
 		  %{g*} %{O*} %{W*} %{w} %{pedantic*}\
 		  %{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\
-		  %{S:%W{o*}%{!o*:-o %b.s}}%{!S:-o %{|!pipe:%g.s}} |\n\
+		  %{!fsyntax-only:%{S:%W{o*}%{!o*:-o %b.s}}%{!S:-o %{|!pipe:%g.s}} |\n\
                   %{!S:as %a %Y\
 		     %{c:%W{o*}%{!o*:-o %w%b%O}}%{!c:-o %d%w%u%O}\
-                     %{!pipe:%g.s} %A\n }}}}"
+                     %{!pipe:%g.s} %A\n }}}}}"
 #else /* ! USE_CPPLIB */
     "cpp -lang-c %{ansi:-std=c89} %{std*} %{nostdinc*}\
 	%{C} %{v} %{A*} %{I*} %{P} %{$} %I\
@@ -682,10 +682,10 @@ static struct compiler default_compilers
 		   %{aux-info*} %{Qn:-fno-ident}\
 		   %{--help:--help} \
 		   %{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\
-		   %{S:%W{o*}%{!o*:-o %b.s}}%{!S:-o %{|!pipe:%g.s}} |\n\
+		   %{!fsyntax-only:%{S:%W{o*}%{!o*:-o %b.s}}%{!S:-o %{|!pipe:%g.s}} |\n\
               %{!S:as %a %Y\
 		      %{c:%W{o*}%{!o*:-o %w%b%O}}%{!c:-o %d%w%u%O}\
-                      %{!pipe:%g.s} %A\n }}}}"
+                      %{!pipe:%g.s} %A\n }}}}}"
 #endif /* ! USE_CPPLIB */
   }},
   {"-",
@@ -730,10 +730,10 @@ static struct compiler default_compilers
 			%{traditional} %{v:-version} %{pg:-p} %{p} %{f*}\
 			%{aux-info*} %{Qn:-fno-ident} -fpreprocessed\
 			%{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\
-			%{S:%W{o*}%{!o*:-o %b.s}}%{!S:-o %{|!pipe:%g.s}} |\n\
+			%{!fsyntax-only:%{S:%W{o*}%{!o*:-o %b.s}}%{!S:-o %{|!pipe:%g.s}} |\n\
 		     %{!S:as %a %Y\
 			     %{c:%W{o*}%{!o*:-o %w%b%O}}%{!c:-o %d%w%u%O}\
-			     %{!pipe:%g.s} %A\n }}}}"}},
+			     %{!pipe:%g.s} %A\n }}}}}"}},
   {".s", {"@assembler"}},
   {"@assembler",
    {"%{!M:%{!MM:%{!E:%{!S:as %a %Y\
@@ -1300,11 +1300,6 @@ static int argbuf_length;
 
 static int argbuf_index;
 
-/* We want this on by default all the time now.  */
-#define MKTEMP_EACH_FILE
-
-#ifdef MKTEMP_EACH_FILE
-
 /* This is the list of suffixes and codes (%g/%u/%U) and the associated
    temp file.  */
 
@@ -1316,8 +1311,6 @@ static struct temp_name {
   int filename_length;	/* strlen (filename).  */
   struct temp_name *next;
 } *temp_names;
-#endif
-
 
 /* Number of commands executed so far.  */
 
@@ -4024,7 +4017,6 @@ do_spec_1 (spec, inswitch, soft_matched_
 	      }
 	    else
 	      {
-#ifdef MKTEMP_EACH_FILE
 		/* ??? This has a problem: the total number of
 		   values mktemp can return is limited.
 		   That matters for the names of object files.
@@ -4088,18 +4080,6 @@ do_spec_1 (spec, inswitch, soft_matched_
 
 		obstack_grow (&obstack, t->filename, t->filename_length);
 		delete_this_arg = 1;
-#else
-		obstack_grow (&obstack, temp_filename, temp_filename_length);
-		if (c == 'u' || c == 'U')
-		  {
-		    static int unique;
-		    char buff[9];
-		    if (c == 'u')
-		      unique++;
-		    sprintf (buff, "%d", unique);
-		    obstack_grow (&obstack, buff, strlen (buff));
-		  }
-#endif
 		delete_this_arg = 1;
 	      }
 	    arg_going = 1;
@@ -5232,13 +5212,6 @@ main (argc, argv)
   putenv (INIT_ENVIRONMENT);
 #endif
 
-  /* Choose directory for temp files.  */
-
-#ifndef MKTEMP_EACH_FILE
-  temp_filename = choose_temp_base ();
-  temp_filename_length = strlen (temp_filename);
-#endif
-
   /* Make a table of what switches there are (switches, n_switches).
      Make a table of specified input files (infiles, n_infiles).
      Decode switches that are handled locally.  */
diff -uprN egcs/gcc/java/lang-specs.h egcs-hacking/gcc/java/lang-specs.h
--- egcs/gcc/java/lang-specs.h	Thu May 25 20:10:38 2000
+++ egcs-hacking/gcc/java/lang-specs.h	Sat Jun 10 18:54:30 2000
@@ -38,7 +38,7 @@ The Free Software Foundation is independ
 		    %{MD} %{MMD} %{M} %{MM}\
                     %{fjni:%{femit-class-file:%e-fjni and -femit-class-file are incompatible}}\
 		    %{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\
-		    %{S:%W{o*}%{!o*:-o %b.s}}%{!S:-o %{|!pipe:%g.s}} |\n\
+		    %{!fsyntax-only:%{S:%W{o*}%{!o*:-o %b.s}}%{!S:-o %{|!pipe:%g.s}} |\n\
             %{!S:as %a %Y\
 		    %{c:%W{o*}%{!o*:-o %w%b%O}}%{!c:-o %d%w%u%O}\
-		    %{!pipe:%g.s} %A\n }}"}},
+		    %{!pipe:%g.s} %A\n }}}"}},
diff -uprN egcs/gcc/objc/lang-specs.h egcs-hacking/gcc/objc/lang-specs.h
--- egcs/gcc/objc/lang-specs.h	Sat Apr  8 18:34:55 2000
+++ egcs-hacking/gcc/objc/lang-specs.h	Sat Jun 10 18:55:17 2000
@@ -52,10 +52,10 @@ Boston, MA 02111-1307, USA.  */
     		   -lang-objc %{gen-decls} \
 		   %{aux-info*} %{Qn:-fno-ident}\
 		   %{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\
-		   %{S:%W{o*}%{!o*:-o %b.s}}%{!S:-o %{|!pipe:%g.s}} |\n\
+		   %{!fsyntax-only:%{S:%W{o*}%{!o*:-o %b.s}}%{!S:-o %{|!pipe:%g.s}} |\n\
      %{!S:as %a %Y\
 	%{c:%W{o*}%{!o*:-o %w%b%O}}%{!c:-o %d%w%u%O}\
-        %{!pipe:%g.s} %A\n }}}}"}
+        %{!pipe:%g.s} %A\n }}}}}"}
 #else /* ! USE_CPPLIB */
    {"cpp -lang-objc %{nostdinc*} %{C} %{v} %{A*} %{I*} %{P} %{$} %I\
 	%{C:%{!E:%eGNU C does not support -C without using -E}}\
@@ -79,10 +79,10 @@ Boston, MA 02111-1307, USA.  */
     		   -lang-objc %{gen-decls} \
 		   %{aux-info*} %{Qn:-fno-ident}\
 		   %{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\
-		   %{S:%W{o*}%{!o*:-o %b.s}}%{!S:-o %{|!pipe:%g.s}} |\n\
+		   %{!fsyntax-only:%{S:%W{o*}%{!o*:-o %b.s}}%{!S:-o %{|!pipe:%g.s}} |\n\
               %{!S:as %a %Y\
 		      %{c:%W{o*}%{!o*:-o %w%b%O}}%{!c:-o %d%w%u%O}\
-                      %{!pipe:%g.s} %A\n }}}}"}
+                      %{!pipe:%g.s} %A\n }}}}}"}
 #endif /* ! USE_CPPLIB */
   },
   {".mi", {"@objc-cpp-output"}},
@@ -94,7 +94,7 @@ Boston, MA 02111-1307, USA.  */
     		   -lang-objc %{gen-decls} \
 		   %{aux-info*} %{Qn:-fno-ident}\
 		   %{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\
-		   %{S:%W{o*}%{!o*:-o %b.s}}%{!S:-o %{|!pipe:%g.s}} |\n",
+		   %{!fsyntax-only:%{S:%W{o*}%{!o*:-o %b.s}}%{!S:-o %{|!pipe:%g.s}} |\n",
     "%{!S:as %a %Y\
 	%{c:%W{o*}%{!o*:-o %w%b%O}}%{!c:-o %d%w%u%O}\
-        %{!pipe:%g.s} %A\n }}}}"}},
+        %{!pipe:%g.s} %A\n }}}}}"}},
diff -uprN egcs/gcc/protoize.c egcs-hacking/gcc/protoize.c
--- egcs/gcc/protoize.c	Thu May 25 20:04:02 2000
+++ egcs-hacking/gcc/protoize.c	Sat Jun 10 17:16:31 2000
@@ -1998,11 +1998,7 @@ munge_compile_params (params_list)
 
   temp_params[param_count++] = "-S";
   temp_params[param_count++] = "-o";
-#if defined (_WIN32) && ! defined (__CYGWIN__) && ! defined (_UWIN)
-  temp_params[param_count++] = "NUL";
-#else
-  temp_params[param_count++] = "/dev/null";
-#endif
+  temp_params[param_count++] = HOST_BIT_BUCKET;
 
   /* Leave room for the input file name argument.  */
   input_file_name_index = param_count;
diff -uprN egcs/gcc/system.h egcs-hacking/gcc/system.h
--- egcs/gcc/system.h	Sun May 28 23:18:17 2000
+++ egcs-hacking/gcc/system.h	Sun Jun 11 21:59:12 2000
@@ -589,6 +589,13 @@ extern void abort PARAMS ((void));
 #define ONLY_INT_FIELDS 0
 #endif 
 
+/* Provide a default for the HOST_BIT_BUCKET.
+   This suffices for POSIX-like hosts.  */
+
+#ifndef HOST_BIT_BUCKET
+#define HOST_BIT_BUCKET "/dev/nill"
+#endif
+  
 /* Enumerated bitfields are safe to use unless we've been explictly told
    otherwise or if they are signed. */
  
diff -uprN egcs/gcc/toplev.c egcs-hacking/gcc/toplev.c
--- egcs/gcc/toplev.c	Sat Jun 10 15:05:48 2000
+++ egcs-hacking/gcc/toplev.c	Sun Jun 11 23:12:42 2000
@@ -204,6 +204,12 @@ const char *input_filename;
 
 const char *main_input_filename;
 
+/* The name of a single temporary file to delete on exit, or NULL if none.
+   This file is used to put compiler output when -fsyntax-only is used, and
+   there is no accessible bit bucket. */
+
+char *temporary_delete_on_exit = NULL;
+
 /* Current line number in real source file.  */
 
 int lineno;
@@ -1810,6 +1816,16 @@ close_dump_file (index, func, insns)
   timevar_pop (TV_DUMP);
 }
 
+/* Routine registered by atexit() to delete the temporary file
+   `temporary_delete_on_exit', if non-NULL.  */
+
+static void
+ax_delete_temporaries (void)
+{
+  if (temporary_delete_on_exit)
+    unlink (temporary_delete_on_exit);
+}
+
 /* Do any final processing required for the declarations in VEC, of
    which there are LEN.  We write out inline functions and variables
    that have been deferred until this point, but which are required.
@@ -2123,35 +2139,50 @@ compile_file (name)
   /* Open assembler code output file.  */
 
   if (flag_syntax_only)
-    asm_out_file = NULL;
+    {
+      /* If no assembler is to be generated, we generate it anyway and throw
+         it away, in a bit bucket if that is accessible, otherwise in a
+         temporary file.  This ensures that all semantic and syntactic checks
+         happen, even those that are mixed up with producing output.  */
+
+      if (access (HOST_BIT_BUCKET, W_OK) == 0)
+        {
+          asm_file_name = (char *) xmalloc (strlen (HOST_BIT_BUCKET) + 1);
+          strcpy (asm_file_name, HOST_BIT_BUCKET);
+        }
+      else
+        {
+          asm_file_name = make_temp_file (NULL);
+          temporary_delete_on_exit = asm_file_name;
+        }
+      name_specified = 1;
+    }
+
+  if (! name_specified && asm_file_name == 0)
+    asm_out_file = stdout;
   else
     {
-      if (! name_specified && asm_file_name == 0)
-	asm_out_file = stdout;
+      if (asm_file_name == 0)
+        {
+          int len = strlen (dump_base_name);
+          char *dumpname = (char *) xmalloc (len + 6);
+          memcpy (dumpname, dump_base_name, len + 1);
+          strip_off_ending (dumpname, len);
+          strcat (dumpname, ".s");
+          asm_file_name = dumpname;
+        }
+      if (!strcmp (asm_file_name, "-"))
+        asm_out_file = stdout;
       else
-	{
-	  if (asm_file_name == 0)
-	    {
-	      int len = strlen (dump_base_name);
-	      char *dumpname = (char *) xmalloc (len + 6);
-	      memcpy (dumpname, dump_base_name, len + 1);
-	      strip_off_ending (dumpname, len);
-	      strcat (dumpname, ".s");
-	      asm_file_name = dumpname;
-	    }
-	  if (!strcmp (asm_file_name, "-"))
-	    asm_out_file = stdout;
-	  else
-	    asm_out_file = fopen (asm_file_name, "w");
-	  if (asm_out_file == 0)
-	    pfatal_with_name (asm_file_name);
-	}
+        asm_out_file = fopen (asm_file_name, "w");
+      if (asm_out_file == 0)
+        pfatal_with_name (asm_file_name);
+    }
 
 #ifdef IO_BUFFER_SIZE
-      setvbuf (asm_out_file, (char *) xmalloc (IO_BUFFER_SIZE),
-	       _IOFBF, IO_BUFFER_SIZE);
+  setvbuf (asm_out_file, (char *) xmalloc (IO_BUFFER_SIZE),
+           _IOFBF, IO_BUFFER_SIZE);
 #endif
-    }
 
   if (ggc_p && name != 0)
     name = ggc_alloc_string (name, strlen (name));
@@ -2420,8 +2451,7 @@ compile_file (name)
 
   finish_parse ();
 
-  if (! flag_syntax_only
-      && (ferror (asm_out_file) != 0 || fclose (asm_out_file) != 0))
+  if (ferror (asm_out_file) != 0 || fclose (asm_out_file) != 0)
     fatal_io_error (asm_file_name);
 
   /* Do whatever is necessary to finish printing the graphs.  */
@@ -2452,6 +2482,16 @@ compile_file (name)
 
   if (! quiet_flag)
     timevar_print (stderr);
+
+  /* If the output file was a temporary, delete it and turn off the
+     associated atexitery.  */
+  
+  if (temporary_delete_on_exit)
+    {
+      unlink (temporary_delete_on_exit);
+      free (temporary_delete_on_exit);
+      temporary_delete_on_exit = NULL;
+    }
 }
 
 /* This is called from various places for FUNCTION_DECL, VAR_DECL,
@@ -4690,6 +4730,10 @@ main (argc, argv)
 		 flag_leading_underscore ? "" : "no-");
     }
 
+  /* Register the function that deletes any temporary files on exit.  */
+
+  atexit (ax_delete_temporaries);
+  
   /* If we are in verbose mode, write out the version and maybe all the
      option flags in use.  */
   if (version_flag)


-- 
> ... knowing the alignment of Orcs in AD&D.
Doubleword.
  --- David Jacoby and Greg Andrews in the Monastery


More information about the Gcc-patches mailing list