[3.0 critical] Make fixproto deal with assert.h

Zack Weinberg zackw@stanford.edu
Wed May 9 23:50:00 GMT 2001


There's a long-standing problem where GCC overrides the system
assert.h unless specifically prevented.  Most modern systems have a
perfectly good assert.h which we should use.  This is particularly
important because GCC's assert.h depends on a libgcc routine which
perhaps ought to go away.  If we use our assert.h on any system which
supports shared libgcc (all of which certainly have C89 compliant
libc, therefore a functional assert.h) we'll be stuck with it forever.

This patch changes it so that, instead of installing it always,
fixproto checks for a system assert.h and copies over our version if
there is none.  If there is a system assert.h, it does not bother
checking whether it works; that's for fixincludes to deal with.

As a consequence, any target that disables fixproto will never install
assert.h.

This bootstraps, passes testsuite, and installs correctly on
i686-pc-linux-gnu, with 'correct installation' being defined as
'assert.h was not installed'.  I also verified that, with a completely
built tree for the same target, if I hid the system assert.h and then
ran 'make stmp-fixproto', GCC's assert.h was copied into gcc/include
of the object tree.  I was not able to do a complete bootstrap with
assert.h hidden.  autoconf 2.13 generates scripts that intrinsically
assume assert.h exists!  If it doesn't, all AC_CHECK_FUNC probes fail,
and the bootstrap fails because the configuration doesn't match the
system.

If anyone would care to give this patch a spin on a genuine pre-C89
system I'd appreciate it.

The patch does not remove __eprintf from libgcc, because it will still
be used on old old targets.  However, it should never be referenced on
most machines, anymore.  I can look into excluding it conditionally,
as a follow-on patch, or perhaps replacing it with something cleaner.

assert.h moves to ginclude so that we don't pick it up in gcc
bootstraps when it's unwanted.  I added a proper copyright and license
notice while I was at it.

-- 
zw     Well, there's another triumph for clean hands, a pure heart, a good
       soul...and vastly superior technology.
       	-- _Undocumented Features: Out in the Cold_


	* Makefile.in: Exterminate all references to assert.h.
	* cross-make: Likewise.
	* configure.in: Update commentary.

	* fixproto: If there is no system assert.h, then copy the one
	from ginclude into the target directory.

	* config/t-freebsd, config/t-linux, config/t-linux-aout,
	config/t-netbsd, config/t-rtems, config/x-linux,
	config/i386/t-beos, config/mcore/t-mcore,
	config/mcore/t-mcore-pe: No need to override INSTALL_ASSERT_H.

	* fixinc/fixinc.dgux, fixinc/fixinc.interix, fixinc/fixinc.ptx, 
	fixinc/fixinc.svr4, fixinc/fixinc.winnt, fixinc/fixinc.wrap,
	fixinc/fixincl.sh: Don't copy assert.h into target directory.

	* assert.h: Move...
	* ginclude/assert.h: ...here.  #error if not processed by GCC;
	remove logic for non-GCC.  Add proper copyright and license
	notice (GPL+special exception, as stdarg.h).

===================================================================
Index: Makefile.in
--- Makefile.in	2001/05/09 14:19:59	1.602.2.16
+++ Makefile.in	2001/05/10 06:40:05
@@ -182,10 +182,6 @@ USER_H = $(srcdir)/ginclude/stdarg.h $(s
     $(srcdir)/ginclude/stdbool.h $(srcdir)/ginclude/iso646.h \
     $(EXTRA_HEADERS) $(LANG_EXTRA_HEADERS)
 
-# Target to use whe installing assert.h.  Some systems may
-# want to set this empty.
-INSTALL_ASSERT_H = install-assert-h
-
 # The GCC to use for compiling libgcc.a, enquire, and libgcc1-test.
 # Usually the one we just built.
 # Don't use this as a dependency--use $(GCC_PASSES) or $(GCC_PARTS).
@@ -320,9 +316,6 @@ build_tooldir = $(exec_prefix)/$(target_
 gcc_gxx_include_dir = @gcc_gxx_include_dir@
 # Directory to search for site-specific includes.
 includedir = $(local_prefix)/include
-# assertdir is overridden in cross-make.
-# (But this currently agrees with what is in cross-make.)
-assertdir = $(gcc_tooldir)/include
 # where the info files go
 infodir = @infodir@
 # Where cpp should go besides $prefix/bin if necessary
@@ -2107,8 +2100,8 @@ stmp-fixinc: fixinc.sh gsyslimits.h
 	rm -rf include; mkdir include
 	-chmod a+rx include
 	(TARGET_MACHINE=$(target); srcdir=`cd $(srcdir); pwd`; \
-	INSTALL_ASSERT_H=$(INSTALL_ASSERT_H); SHELL=$(SHELL) ;\
-	export TARGET_MACHINE srcdir INSTALL_ASSERT_H SHELL ; \
+	SHELL=$(SHELL) ;\
+	export TARGET_MACHINE srcdir SHELL ; \
 	$(SHELL) ./fixinc.sh `pwd`/include $(SYSTEM_HEADER_DIR) $(OTHER_FIXINCLUDES_DIRS); \
 	rm -f include/syslimits.h; \
 	if [ -f include/limits.h ]; then \
@@ -2486,7 +2479,6 @@ installdirs:
 	-if [ -d $(bindir) ] ; then true ; else mkdir $(bindir) ; chmod a+rx $(bindir) ; fi
 	-if [ -d $(includedir) ] ; then true ; else mkdir $(includedir) ; chmod a+rx $(includedir) ; fi
 	-if [ -d $(gcc_tooldir) ] ; then true ; else mkdir $(gcc_tooldir) ; chmod a+rx $(gcc_tooldir) ; fi
-	-if [ -d $(assertdir) ] ; then true ; else mkdir $(assertdir) ; chmod a+rx $(assertdir) ; fi
 	-if [ -d $(infodir) ] ; then true ; else mkdir $(infodir) ; chmod a+rx $(infodir) ; fi
 	-if [ -d $(slibdir) ] ; then true ; else mkdir $(slibdir) ; chmod a+rx $(slibdir) ; fi
 # We don't use mkdir -p to create the parents of man1dir,
@@ -2670,7 +2662,7 @@ install-multilib: stmp-multilib installd
 	  -f libgcc.mk install
 
 # Install all the header files built in the include subdirectory.
-install-headers: install-include-dir $(INSTALL_HEADERS_DIR) $(INSTALL_ASSERT_H)
+install-headers: install-include-dir $(INSTALL_HEADERS_DIR)
 # Fix symlinks to absolute paths in the installed include directory to
 # point to the installed directory, not the build directory.
 # Don't need to use LN_S here since we really do need ln -s and no substitutes.
@@ -2709,29 +2701,6 @@ install-headers-cpio: stmp-int-hdrs $(ST
 # See discussion about the use of `pwd` above
 	cd `pwd`/include ; \
 	find . -print | cpio -pdum $(libsubdir)/include
-
-# Put assert.h where it won't override GNU libc's assert.h.
-# It goes in a dir that is searched after GNU libc's headers;
-# thus, the following conditionals are no longer needed.
-# But it's not worth deleting them now.
-## Don't replace the assert.h already there if it is not from GCC.
-## This code would be simpler if it tested for -f ... && ! grep ...
-## but supposedly the ! operator is missing in sh on some systems.
-install-assert-h: assert.h installdirs
-	if [ -f $(assertdir)/assert.h ]; \
-	then \
-	  if grep "__eprintf" $(assertdir)/assert.h >/dev/null; \
-	    then \
-	    rm -f $(assertdir)/assert.h; \
-	    $(INSTALL_DATA) $(srcdir)/assert.h $(assertdir)/assert.h; \
-	    chmod a-x $(assertdir)/assert.h; \
-	  else true; \
-	  fi; \
-	else \
-	  rm -f $(assertdir)/assert.h; \
-	  $(INSTALL_DATA) $(srcdir)/assert.h $(assertdir)/assert.h; \
-	  chmod a-x $(assertdir)/assert.h; \
-	fi
 
 # Use this target to install the program `collect2' under the name `collect2'.
 install-collect2: collect2 installdirs
===================================================================
Index: assert.h
--- assert.h	Wed May  9 23:40:09 2001
+++ assert.h	Tue May  5 13:32:27 1998
@@ -1,54 +0,0 @@
-/* Allow this file to be included multiple times
-   with different settings of NDEBUG.  */
-#undef assert
-#undef __assert
-
-#ifdef NDEBUG
-#define assert(ignore) ((void) 0)
-#else
-
-#ifndef __GNUC__
-
-#define assert(expression)  \
-  ((void) ((expression) ? 0 : __assert (expression, __FILE__, __LINE__)))
-
-#define __assert(expression, file, lineno)  \
-  (printf ("%s:%u: failed assertion\n", file, lineno),	\
-   abort (), 0)
-
-#else
-
-#if defined(__STDC__) || defined (__cplusplus)
-
-/* Defined in libgcc.a */
-#ifdef __cplusplus
-extern "C" {
-extern void __eprintf (const char *, const char *, unsigned, const char *)
-    __attribute__ ((noreturn));
-}
-#else
-extern void __eprintf (const char *, const char *, unsigned, const char *)
-    __attribute__ ((noreturn));
-#endif
-
-#define assert(expression)  \
-  ((void) ((expression) ? 0 : __assert (#expression, __FILE__, __LINE__)))
-
-#define __assert(expression, file, line)  \
-  (__eprintf ("%s:%u: failed assertion `%s'\n",		\
-	      file, line, expression), 0)
-
-#else /* no __STDC__ and not C++; i.e. -traditional.  */
-
-extern void __eprintf () __attribute__ ((noreturn)); /* Defined in libgcc.a */
-
-#define assert(expression)  \
-  ((void) ((expression) ? 0 : __assert (expression, __FILE__, __LINE__)))
-
-#define __assert(expression, file, lineno)  \
-  (__eprintf ("%s:%u: failed assertion `%s'\n",		\
-	      file, lineno, "expression"), 0)
-
-#endif /* no __STDC__ and not C++; i.e. -traditional.  */
-#endif /* no __GNU__; i.e., /bin/cc.  */
-#endif
===================================================================
Index: configure.in
--- configure.in	2001/04/26 04:32:10	1.483.2.11
+++ configure.in	2001/05/10 06:40:06
@@ -1033,10 +1033,9 @@ fi
 # have its own set of headers then define
 # inhibit_libc
 
-# If this is using newlib, then define inhibit_libc in
-# LIBGCC2_CFLAGS.  This will cause __eprintf to be left out of
-# libgcc.a, but that's OK because newlib should have its own version of
-# assert.h.
+# If this is using newlib, then define inhibit_libc in LIBGCC2_CFLAGS.
+# This prevents libgcc2 from containing any code which requires libc
+# support.
 inhibit_libc=
 if [test x$host != x$target] && [test x$with_headers = x]; then
        inhibit_libc=-Dinhibit_libc
===================================================================
Index: cross-make
--- cross-make	2000/01/13 00:37:05	1.7
+++ cross-make	2001/05/10 06:40:06
@@ -9,6 +9,3 @@ SYSTEM_HEADER_DIR = $(CROSS_SYSTEM_HEADE
 
 # Don't try to compile the things we can't compile.
 ALL = all.cross
-
-# Don't install assert.h in /usr/local/include.
-assertdir = $(tooldir)/include
===================================================================
Index: fixproto
--- fixproto	2001/01/27 21:07:57	1.11
+++ fixproto	2001/05/10 06:40:07
@@ -319,6 +319,18 @@ EOF
   fi
 done
 
+# If there is no assert.h on this system, then we should use GCC's.
+# If there is an assert.h, and it's broken, deal with that in fixincludes.
+if grep assert.h fixproto.list >/dev/null
+then :
+elif test -f $src_dir_all/assert.h
+then :
+elif test -f $src_dir_std/assert.h
+then :
+else
+    cp $dirname/ginclude/assert.h $abs_target_dir/assert.h
+fi
+
 # Remove any directories that we made that are still empty.
 rmdir $subdirs_made 2>/dev/null
 
===================================================================
Index: config/t-freebsd
--- config/t-freebsd	2001/05/03 21:27:34	1.3.14.1
+++ config/t-freebsd	2001/05/10 06:40:08
@@ -1,8 +1,5 @@
 # Don't run fixproto
 STMP_FIXPROTO =
 
-# Don't install "assert.h" in gcc.  We use the system one.
-INSTALL_ASSERT_H =
-
 # Compile crtbeginS.o and crtendS.o with pic.
 CRTSTUFF_T_CFLAGS_S = -fPIC
===================================================================
Index: config/t-linux
--- config/t-linux	2001/01/07 21:55:09	1.8
+++ config/t-linux	2001/05/10 06:40:08
@@ -1,9 +1,6 @@
 # Don't run fixproto
 STMP_FIXPROTO =
 
-# Don't install "assert.h" in gcc. We use the one in glibc.
-INSTALL_ASSERT_H =
-
 # Compile crtbeginS.o and crtendS.o with pic.
 CRTSTUFF_T_CFLAGS_S = -fPIC
 # Compile libgcc2.a with pic.
===================================================================
Index: config/t-linux-aout
--- config/t-linux-aout	1998/12/16 21:00:10	1.3
+++ config/t-linux-aout	2001/05/10 06:40:08
@@ -1,9 +1,6 @@
 # Don't run fixproto
 STMP_FIXPROTO =
 
-# Don't install "assert.h" in gcc. We use the one in glibc.
-INSTALL_ASSERT_H =
-
 # Do not build libgcc1. Let gcc generate those functions. The GNU/Linux
 # C library can handle them.
 LIBGCC1 = 
===================================================================
Index: config/t-netbsd
--- config/t-netbsd	1998/12/16 21:00:12	1.3
+++ config/t-netbsd	2001/05/10 06:40:08
@@ -4,6 +4,3 @@ LIBGCC1_TEST=
 
 # Don't run fixproto
 STMP_FIXPROTO =
-
-# Don't install "assert.h" in gcc. We use the one in glibc.
-INSTALL_ASSERT_H =
===================================================================
Index: config/t-rtems
--- config/t-rtems	1999/03/31 00:50:40	1.4
+++ config/t-rtems	2001/05/10 06:40:08
@@ -1,9 +1,6 @@
 # RTEMS uses newlib which does not require prototype fixing
 STMP_FIXPROTO =
 
-# Don't install "assert.h" in gcc.  RTEMS uses the one in newlib.
-INSTALL_ASSERT_H =
-
 # RTEMS always has limits.h.
 LIMITS_H_TEST = true
 
===================================================================
Index: config/x-linux
--- config/x-linux	1998/12/16 21:00:15	1.2
+++ config/x-linux	2001/05/10 06:40:08
@@ -1,5 +1,2 @@
 # Don't run fixproto
 STMP_FIXPROTO =
-
-# Don't install "assert.h" in gcc. We use the one in glibc.
-INSTALL_ASSERT_H =
===================================================================
Index: config/i386/t-beos
--- config/i386/t-beos	2000/08/02 07:04:33	1.2
+++ config/i386/t-beos	2001/05/10 06:40:08
@@ -6,6 +6,3 @@ CROSS_LIBGCC1 =
 # we are most likely to want to apply any fixes to.
 SYSTEM_HEADER_DIR = /boot/develop/headers/posix
 CROSS_SYSTEM_HEADER_DIR = $(tooldir)/sys-include/posix
-
-# Use the system assert.h
-INSTALL_ASSERT_H =
===================================================================
Index: config/mcore/t-mcore
--- config/mcore/t-mcore	2000/02/14 22:51:36	1.1
+++ config/mcore/t-mcore	2001/05/10 06:40:08
@@ -38,9 +38,6 @@ TARGET_LIBGCC2_CFLAGS=-O3 -DNO_FLOATLIB_
 # We have values for float.h.
 CROSS_FLOAT_H = $(srcdir)/config/mcore/gfloat.h
 
-# let the library provider supply an <assert.h>
-INSTALL_ASSERT_H=
-
 # If support for -m4align is ever re-enabled then comment out the
 # following line and uncomment the mutlilib lines below.
 
===================================================================
Index: config/mcore/t-mcore-pe
--- config/mcore/t-mcore-pe	2000/02/14 22:51:36	1.1
+++ config/mcore/t-mcore-pe	2001/05/10 06:40:08
@@ -29,9 +29,6 @@ TARGET_LIBGCC2_CFLAGS=-O3 -DNO_FLOATLIB_
 # We have values for float.h.
 CROSS_FLOAT_H = $(srcdir)/config/mcore/gfloat.h
 
-# let the library provider supply an <assert.h>
-INSTALL_ASSERT_H=
-
 MULTILIB_OPTIONS     = mbig-endian/mlittle-endian m210/m340
 MULTILIB_DIRNAMES    = big little m210 m340
 MULTILIB_MATCHES     = 
===================================================================
Index: fixinc/fixinc.dgux
--- fixinc/fixinc.dgux	1999/05/28 21:33:05	1.6
+++ fixinc/fixinc.dgux	2001/05/10 06:40:08
@@ -221,12 +221,4 @@ fi
 
 done
 
-if [ x${INSTALL_ASSERT_H} != x ]
-then
-  cd ${ORIG_DIR}
-  rm -f include/assert.h
-  cp ${srcdir}/assert.h include/assert.h || exit 1
-  chmod a+r include/assert.h
-fi
-
 exit 0
===================================================================
Index: fixinc/fixinc.interix
--- fixinc/fixinc.interix	1999/04/11 11:35:44	1.2
+++ fixinc/fixinc.interix	2001/05/10 06:40:08
@@ -162,12 +162,4 @@ done
 
 done # for include directory list
 
-if [ x${INSTALL_ASSERT_H} != x ]
-then
-  cd ${ORIG_DIR}
-  rm -f include/assert.h
-  cp ${srcdir}/assert.h include/assert.h || exit 1
-  chmod a+r include/assert.h
-fi
-
 exit 0
===================================================================
Index: fixinc/fixinc.ptx
--- fixinc/fixinc.ptx	2000/02/01 21:42:05	1.6
+++ fixinc/fixinc.ptx	2001/05/10 06:40:08
@@ -263,12 +263,4 @@ fi
 
 done
 
-if [ x${INSTALL_ASSERT_H} != x ]
-then
-  cd ${ORIG_DIR}
-  rm -f include/assert.h
-  cp ${srcdir}/assert.h include/assert.h || exit 1
-  chmod a+r include/assert.h
-fi
-
 exit 0
===================================================================
Index: fixinc/fixinc.svr4
--- fixinc/fixinc.svr4	2000/02/17 00:32:50	1.9
+++ fixinc/fixinc.svr4	2001/05/10 06:40:08
@@ -1806,12 +1806,4 @@ chmod a+r ${LIB}/sys/byteorder.h
 
 done
 
-if [ x${INSTALL_ASSERT_H} != x ]
-then
-  cd ${ORIG_DIR}
-  rm -f include/assert.h
-  cp ${srcdir}/assert.h include/assert.h || exit 1
-  chmod a+r include/assert.h
-fi
-
 exit 0
===================================================================
Index: fixinc/fixinc.winnt
--- fixinc/fixinc.winnt	2000/02/01 21:42:05	1.6
+++ fixinc/fixinc.winnt	2001/05/10 06:40:08
@@ -229,12 +229,4 @@ for file in $files; do
   rmdir $LIB/$file > NUL 2>&1
 done
 
-if [ x${INSTALL_ASSERT_H} != x ]
-then
-  cd ${ORIG_DIR}
-  rm -f include/assert.h
-  cp ${srcdir}/assert.h include/assert.h || exit 1
-  chmod a+r include/assert.h
-fi
-
 exit 0
===================================================================
Index: fixinc/fixinc.wrap
--- fixinc/fixinc.wrap	2000/04/02 22:50:55	1.6
+++ fixinc/fixinc.wrap	2001/05/10 06:40:08
@@ -133,12 +133,4 @@ fi
 
 done
 
-if [ x${INSTALL_ASSERT_H} != x ]
-then
-  cd ${ORIG_DIR}
-  rm -f include/assert.h
-  cp ${srcdir}/assert.h include/assert.h || exit 1
-  chmod a+r include/assert.h
-fi
-
 exit 0
===================================================================
Index: fixinc/fixincl.sh
--- fixinc/fixincl.sh	2000/12/27 15:46:42	1.34
+++ fixinc/fixincl.sh	2001/05/10 06:40:08
@@ -470,11 +470,3 @@ then echo fixincludes is done ; fi
 done
 #
 # # # # # # # # # # # # # # # # # # # # #
-
-if [ x${INSTALL_ASSERT_H} != x ] && [ -f ${srcdir}/assert.h ]
-then
-  cd $ORIGDIR
-  rm -f include/assert.h
-  cp ${srcdir}/assert.h include/assert.h || exit 1
-  chmod a+r include/assert.h
-fi
===================================================================
Index: ginclude/assert.h
--- ginclude/assert.h	Tue May  5 13:32:27 1998
+++ ginclude/assert.h	Wed May  9 23:40:08 2001
@@ -0,0 +1,76 @@
+/* Copyright (C) 1995, 1997, 2001 Free Software Foundation, Inc.
+
+This file is part of GNU CC.
+
+GNU CC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU CC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU CC; see the file COPYING.  If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
+
+/* As a special exception, if you include this header file into source
+   files compiled by GCC, this header file does not by itself cause
+   the resulting executable to be covered by the GNU General Public
+   License.  This exception does not however invalidate any other
+   reasons why the executable file might be covered by the GNU General
+   Public License.  */
+
+/*
+ * ISO C Standard:  7.2  Diagnostics  <assert.h>
+ */
+
+/* Allow this file to be included multiple times
+   with different settings of NDEBUG.  */
+#undef assert
+#undef __assert
+
+#ifndef __GNUC__
+#error "This <assert.h> must be used with GNU CC."
+#endif
+
+#ifdef NDEBUG
+#define assert(ignore) ((void) 0)
+#else
+
+#if defined(__STDC__) || defined (__cplusplus)
+
+/* Defined in libgcc.a */
+#ifdef __cplusplus
+extern "C" {
+extern void __eprintf (const char *, const char *, unsigned, const char *)
+    __attribute__ ((noreturn));
+}
+#else
+extern void __eprintf (const char *, const char *, unsigned, const char *)
+    __attribute__ ((noreturn));
+#endif
+
+#define assert(expression)  \
+  ((void) ((expression) ? 0 : __assert (#expression, __FILE__, __LINE__)))
+
+#define __assert(expression, file, line)  \
+  (__eprintf ("%s:%u: failed assertion `%s'\n",		\
+	      file, line, expression), 0)
+
+#else /* no __STDC__ and not C++; i.e. -traditional.  */
+
+extern void __eprintf () __attribute__ ((noreturn)); /* Defined in libgcc.a */
+
+#define assert(expression)  \
+  ((void) ((expression) ? 0 : __assert (expression, __FILE__, __LINE__)))
+
+#define __assert(expression, file, lineno)  \
+  (__eprintf ("%s:%u: failed assertion `%s'\n",		\
+	      file, lineno, "expression"), 0)
+
+#endif /* no __STDC__ and not C++; i.e. -traditional.  */
+#endif /* no NDEBUG.  */



More information about the Gcc-patches mailing list