Patchwork Defining C99 predefined macros for whole translation unit

login
register
mail settings
Submitter Joseph S. Myers
Date Sept. 28, 2012, 3:59 p.m.
Message ID <Pine.LNX.4.64.1209281557330.3465@digraph.polyomino.org.uk>
Download mbox | patch
Permalink /patch/187825/
State New
Headers show

Comments

Joseph S. Myers - Sept. 28, 2012, 3:59 p.m.
On Fri, 24 Apr 2009, Ian Lance Taylor wrote:

> This patch to gcc is OK if the patch to glibc is OK.

Now that the corresponding glibc patch is in glibc 2.16, I've updated
the GCC patch (original submission
<http://gcc.gnu.org/ml/gcc-patches/2009-04/msg01444.html>) for current
sources and retested it.  Although the original version was approved
conditional on the glibc patch, some fairly substantial changes were
needed for changes to hook handling in the past three years, so I'm
resubmitting (the non-C parts of) this patch rather than just
committing it.  (The C parts also have fairly substantial changes
relating to PCH, which seems to have got rather more fragile and
difficult to keep working in the past three years; the PCH-related
bits of this patch may well not be particularly ideal, but they were
what I found that actually works for the PCH tests for both old and
new glibc headers.)

Bootstrapped with no regressions on x86_64-unknown-linux-gnu (older
glibc).  Also tested with cross to arm-none-linux-gnueabi (current
glibc).  OK to commit?

gcc:
2012-09-28  Joseph Myers  <joseph@codesourcery.com>

	* config.gcc (*-*-linux* | frv-*-*linux* | *-*-kfreebsd*-gnu |
	*-*-knetbsd*-gnu | *-*-gnu* | *-*-kopensolaris*-gnu): Use
	glibc-c.o in c_target_objs and cxx_target_objs.  Use t-glibc in
	tmake_file.  Set target_has_targetcm.
	(tilegx-*-linux*, tilepro-*-linux*): Append to c_target_objs and
	cxx_target_objs rather than overriding previous value.
	* config/glibc-c.c, config/t-glibc: New.
	* doc/tm.texi.in (TARGET_C_PREINCLUDE): New @hook.
	* doc/tm.texi: Regenerate.
	* hooks.c (hook_constcharptr_void_null): New.
	* hooks.h (hook_constcharptr_void_null): Declare.

gcc/c-family:
2012-09-28  Joseph Myers  <joseph@codesourcery.com>

	* c-common.h (pch_cpp_save_state): Declare.
	* c-target.def (c_preinclude): New hook.
	* c-opts.c (done_preinclude): New.
	(push_command_line_include): Handle default preincluded header.
	(cb_file_change): Call pch_cpp_save_state when calling
	push_command_line_include.
	* c-pch.c (pch_ready_to_save_cpp_state, pch_cpp_state_saved)
	(pch_cpp_save_state): New.
	(pch_init): Call pch_cpp_save_state conditionally, instead of
	calling cpp_save_state.

gcc/testsuite:
2012-09-28  Joseph Myers  <joseph@codesourcery.com>

	* gcc.dg/c99-predef-1.c: New test.
	* gcc.dg/cpp/cmdlne-dU-1.c, gcc.dg/cpp/cmdlne-dU-2.c,
	gcc.dg/cpp/cmdlne-dU-3.c, gcc.dg/cpp/cmdlne-dU-4.c,
	gcc.dg/cpp/cmdlne-dU-5.c, gcc.dg/cpp/cmdlne-dU-6.c,
	gcc.dg/cpp/cmdlne-dU-7.c, gcc.dg/cpp/cmdlne-dU-8.c,
	gcc.dg/cpp/cmdlne-dU-9.c, gcc.dg/cpp/cmdlne-dU-10.c,
	gcc.dg/cpp/cmdlne-dU-11.c, gcc.dg/cpp/cmdlne-dU-12.c,
	gcc.dg/cpp/cmdlne-dU-13.c, gcc.dg/cpp/cmdlne-dU-14.c,
	gcc.dg/cpp/cmdlne-dU-15.c, gcc.dg/cpp/cmdlne-dU-16.c,
	gcc.dg/cpp/cmdlne-dU-17.c, gcc.dg/cpp/cmdlne-dU-18.c,
	gcc.dg/cpp/cmdlne-dU-19.c, gcc.dg/cpp/cmdlne-dU-20.c,
	gcc.dg/cpp/cmdlne-dU-21.c, gcc.dg/cpp/cmdlne-dU-22.c,
	gcc.dg/cpp/mi5.c, gcc.dg/cpp/multiline.c: Add -nostdinc to
	dg-options.

libcpp:
2012-09-28  Joseph Myers  <joseph@codesourcery.com>

	* files.c (struct _cpp_file): Add implicit_preinclude.
	(pch_open_file): Allow a previously opened implicitly included
	file.
	(_cpp_find_file): Add implicit_preinclude argument.  Free file and
	do not call open_file_failed if implicit_preinclude.  Store
	implicit_preinclude value.
	(_cpp_stack_include, _cpp_fake_include, _cpp_compare_file_date):
	Update calls to _cpp_find_file.
	(_cpp_stack_include): Handle IT_DEFAULT.
	(cpp_push_default_include): New.
	* include/cpplib.h (cpp_push_default_include): Declare.
	* init.c (cpp_read_main_file): Update call to _cpp_find_file.
	* internal.h (enum include_type): Add IT_DEFAULT.
	(_cpp_find_file): Update prototype.
Joseph S. Myers - Oct. 8, 2012, 2:49 p.m.
Ping.  This patch 
<http://gcc.gnu.org/ml/gcc-patches/2012-09/msg01907.html> (non-C parts) is 
pending review.
Joseph S. Myers - Oct. 15, 2012, 3:58 p.m.
Ping^2.  This patch 
<http://gcc.gnu.org/ml/gcc-patches/2012-09/msg01907.html> (non-C parts) is 
still pending review.
Joseph S. Myers - Oct. 23, 2012, 2:35 p.m.
Ping^3.  This patch 
<http://gcc.gnu.org/ml/gcc-patches/2012-09/msg01907.html> (non-C parts) is 
still pending review.
Jakub Jelinek - Oct. 23, 2012, 2:44 p.m.
On Tue, Oct 23, 2012 at 02:35:53PM +0000, Joseph S. Myers wrote:
> Ping^3.  This patch 
> <http://gcc.gnu.org/ml/gcc-patches/2012-09/msg01907.html> (non-C parts) is 
> still pending review.

Looks ok to me.

	Jakub

Patch

Index: gcc/doc/tm.texi
===================================================================
--- gcc/doc/tm.texi	(revision 191711)
+++ gcc/doc/tm.texi	(working copy)
@@ -10646,6 +10646,12 @@  convention when processing system header files, bu
 files @code{__STDC__} will always expand to 1.
 @end defmac
 
+@deftypefn {C Target Hook} {const char *} TARGET_C_PREINCLUDE (void)
+Define this hook to return the name of a header file to be included at the start of all compilations, as if it had been included with @code{#include <@var{file}>}.  If this hook returns @code{NULL}, or is not defined, or the header is not found, or if the user specifies @option{-ffreestanding} or @option{-nostdinc}, no header is included.
+
+ This hook can be used together with a header provided by the system C library to implement ISO C requirements for certain macros to be predefined that describe properties of the whole implementation rather than just the compiler.
+@end deftypefn
+
 @defmac NO_IMPLICIT_EXTERN_C
 Define this macro if the system header files support C++ as well as C@.
 This macro inhibits the usual method of using system header files in
Index: gcc/doc/tm.texi.in
===================================================================
--- gcc/doc/tm.texi.in	(revision 191711)
+++ gcc/doc/tm.texi.in	(working copy)
@@ -10504,6 +10504,8 @@  convention when processing system header files, bu
 files @code{__STDC__} will always expand to 1.
 @end defmac
 
+@hook TARGET_C_PREINCLUDE
+
 @defmac NO_IMPLICIT_EXTERN_C
 Define this macro if the system header files support C++ as well as C@.
 This macro inhibits the usual method of using system header files in
Index: gcc/hooks.c
===================================================================
--- gcc/hooks.c	(revision 191711)
+++ gcc/hooks.c	(working copy)
@@ -1,5 +1,5 @@ 
 /* General-purpose hooks.
-   Copyright (C) 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010, 2011
+   Copyright (C) 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010, 2011, 2012
    Free Software Foundation, Inc.
 
    This program is free software; you can redistribute it and/or modify it
@@ -333,6 +333,13 @@  hook_tree_tree_tree_tree_3rd_identity (tree a ATTR
   return c;
 }
 
+/* Generic hook that takes no arguments and returns a NULL string.  */
+const char *
+hook_constcharptr_void_null (void)
+{
+  return NULL;
+}
+
 /* Generic hook that takes a tree and returns a NULL string.  */
 const char *
 hook_constcharptr_const_tree_null (const_tree t ATTRIBUTE_UNUSED)
Index: gcc/hooks.h
===================================================================
--- gcc/hooks.h	(revision 191711)
+++ gcc/hooks.h	(working copy)
@@ -1,5 +1,5 @@ 
 /* General-purpose hooks.
-   Copyright (C) 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010, 2011
+   Copyright (C) 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010, 2011, 2012
    Free Software Foundation, Inc.
 
    This program is free software; you can redistribute it and/or modify it
@@ -94,6 +94,7 @@  extern rtx hook_rtx_rtx_identity (rtx);
 extern rtx hook_rtx_rtx_null (rtx);
 extern rtx hook_rtx_tree_int_null (tree, int);
 
+extern const char *hook_constcharptr_void_null (void);
 extern const char *hook_constcharptr_const_tree_null (const_tree);
 extern const char *hook_constcharptr_const_rtx_null (const_rtx);
 extern const char *hook_constcharptr_const_tree_const_tree_null (const_tree, const_tree);
Index: gcc/c-family/c-opts.c
===================================================================
--- gcc/c-family/c-opts.c	(revision 191711)
+++ gcc/c-family/c-opts.c	(working copy)
@@ -108,6 +108,9 @@  static size_t deferred_count;
 /* Number of deferred options scanned for -include.  */
 static size_t include_cursor;
 
+/* Whether any standard preincluded header has been preincluded.  */
+static bool done_preinclude;
+
 static void handle_OPT_d (const char *);
 static void set_std_cxx98 (int);
 static void set_std_cxx11 (int);
@@ -1432,6 +1435,19 @@  c_finish_options (void)
 static void
 push_command_line_include (void)
 {
+  if (!done_preinclude)
+    {
+      done_preinclude = true;
+      if (flag_hosted && std_inc && !cpp_opts->preprocessed)
+	{
+	  const char *preinc = targetcm.c_preinclude ();
+	  if (preinc && cpp_push_default_include (parse_in, preinc))
+	    return;
+	}
+    }
+
+  pch_cpp_save_state ();
+
   while (include_cursor < deferred_count)
     {
       struct deferred_opt *opt = &deferred_opts[include_cursor++];
@@ -1467,7 +1483,10 @@  cb_file_change (cpp_reader * ARG_UNUSED (pfile),
     fe_file_change (new_map);
 
   if (new_map == 0 || (new_map->reason == LC_LEAVE && MAIN_FILE_P (new_map)))
-    push_command_line_include ();
+    {
+      pch_cpp_save_state ();
+      push_command_line_include ();
+    }
 }
 
 void
Index: gcc/c-family/c-common.h
===================================================================
--- gcc/c-family/c-common.h	(revision 191711)
+++ gcc/c-family/c-common.h	(working copy)
@@ -1018,6 +1018,7 @@  extern tree c_build_bind_expr (location_t, tree, t
 
 /* In c-pch.c  */
 extern void pch_init (void);
+extern void pch_cpp_save_state (void);
 extern int c_common_valid_pch (cpp_reader *pfile, const char *name, int fd);
 extern void c_common_read_pch (cpp_reader *pfile, const char *name, int fd,
 			       const char *orig);
Index: gcc/c-family/c-target.def
===================================================================
--- gcc/c-family/c-target.def	(revision 191711)
+++ gcc/c-family/c-target.def	(working copy)
@@ -1,6 +1,6 @@ 
 /* Target hook definitions for C-family front ends.
    Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
-   2011
+   2011, 2012
    Free Software Foundation, Inc.
 
    This program is free software; you can redistribute it and/or modify it
@@ -89,5 +89,20 @@  DEFHOOK
   @var{format_arg} is one recognized as a valid string reference type.",
  void, (tree format_arg, tree args_list),
  NULL)
+
+DEFHOOK
+(c_preinclude,
+ "Define this hook to return the name of a header file to be included at\
+ the start of all compilations, as if it had been included with\
+ @code{#include <@var{file}>}.  If this hook returns @code{NULL}, or is\
+ not defined, or the header is not found, or if the user specifies\
+ @option{-ffreestanding} or @option{-nostdinc}, no header is included.\n\
+\n\
+ This hook can be used together with a header provided by the system C\
+ library to implement ISO C requirements for certain macros to be\
+ predefined that describe properties of the whole implementation rather\
+ than just the compiler.",
+ const char *, (void),
+ hook_constcharptr_void_null)
  
 HOOK_VECTOR_END (C90_EMPTY_HACK)
Index: gcc/c-family/c-pch.c
===================================================================
--- gcc/c-family/c-pch.c	(revision 191711)
+++ gcc/c-family/c-pch.c	(working copy)
@@ -93,6 +93,10 @@  get_ident (void)
   return result;
 }
 
+/* Whether preprocessor state should be saved by pch_init.  */
+
+static bool pch_ready_to_save_cpp_state = false;
+
 /* Prepare to write a PCH file, if one is being written.  This is
    called at the start of compilation.  */
 
@@ -136,9 +140,33 @@  pch_init (void)
   /* Let the debugging format deal with the PCHness.  */
   (*debug_hooks->handle_pch) (0);
 
-  cpp_save_state (parse_in, f);
+  if (pch_ready_to_save_cpp_state)
+    pch_cpp_save_state ();
 }
 
+/* Whether preprocessor state has been saved in a PCH file.  */
+
+static bool pch_cpp_state_saved = false;
+
+/* Save preprocessor state in a PCH file, after implicitly included
+   headers have been read.  If the PCH file has not yet been opened,
+   record that state should be saved when it is opened.  */
+
+void
+pch_cpp_save_state (void)
+{
+  if (!pch_cpp_state_saved)
+    {
+      if (pch_outfile)
+	{
+	  cpp_save_state (parse_in, pch_outfile);
+	  pch_cpp_state_saved = true;
+	}
+      else
+	pch_ready_to_save_cpp_state = true;
+    }
+}
+
 /* Write the PCH file.  This is called at the end of a compilation which
    will produce a PCH file.  */
 
Index: gcc/testsuite/gcc.dg/cpp/cmdlne-dU-5.c
===================================================================
--- gcc/testsuite/gcc.dg/cpp/cmdlne-dU-5.c	(revision 191711)
+++ gcc/testsuite/gcc.dg/cpp/cmdlne-dU-5.c	(working copy)
@@ -1,5 +1,5 @@ 
 /* { dg-do preprocess } */
-/* { dg-options "-P -dU" } */
+/* { dg-options "-nostdinc -P -dU" } */
 /* { dg-final { scan-file cmdlne-dU-5.i "^\n*#undef A\n*$" } } */
 #ifdef A
 #ifdef B
Index: gcc/testsuite/gcc.dg/cpp/cmdlne-dU-10.c
===================================================================
--- gcc/testsuite/gcc.dg/cpp/cmdlne-dU-10.c	(revision 191711)
+++ gcc/testsuite/gcc.dg/cpp/cmdlne-dU-10.c	(working copy)
@@ -1,7 +1,7 @@ 
 /* { dg-do preprocess } */
-/* { dg-options "-P -dU" } */
+/* { dg-options "-nostdinc -P -dU" } */
 /* { dg-final { scan-file cmdlne-dU-10.i "^\n*C\n+#define B C\n+#define A B\n*$" } } */
 /* This file deliberately has no final newline.  */
 #define A B
 #define B C
-A
\ No newline at end of file
+A
Index: gcc/testsuite/gcc.dg/cpp/cmdlne-dU-18.c
===================================================================
--- gcc/testsuite/gcc.dg/cpp/cmdlne-dU-18.c	(revision 191711)
+++ gcc/testsuite/gcc.dg/cpp/cmdlne-dU-18.c	(working copy)
@@ -1,5 +1,5 @@ 
 /* { dg-do preprocess } */
-/* { dg-options "-P -dU" } */
+/* { dg-options "-nostdinc -P -dU" } */
 /* { dg-final { scan-file cmdlne-dU-18.i "^\n*x 1 y\n+#define A 1\n*$" } } */
 #define A 1
 x A y
Index: gcc/testsuite/gcc.dg/cpp/cmdlne-dU-6.c
===================================================================
--- gcc/testsuite/gcc.dg/cpp/cmdlne-dU-6.c	(revision 191711)
+++ gcc/testsuite/gcc.dg/cpp/cmdlne-dU-6.c	(working copy)
@@ -1,5 +1,5 @@ 
 /* { dg-do preprocess } */
-/* { dg-options "-P -dU" } */
+/* { dg-options "-nostdinc -P -dU" } */
 /* { dg-final { scan-file cmdlne-dU-6.i "^\n*#undef A\n+#define A *\n*$" } } */
 #ifdef A
 #endif
Index: gcc/testsuite/gcc.dg/cpp/cmdlne-dU-11.c
===================================================================
--- gcc/testsuite/gcc.dg/cpp/cmdlne-dU-11.c	(revision 191711)
+++ gcc/testsuite/gcc.dg/cpp/cmdlne-dU-11.c	(working copy)
@@ -1,5 +1,5 @@ 
 /* { dg-do preprocess } */
-/* { dg-options "-P -dU" } */
+/* { dg-options "-nostdinc -P -dU" } */
 /* { dg-final { scan-file cmdlne-dU-11.i "^\n*\n*$" } } */
 #define A B
 #if 0
Index: gcc/testsuite/gcc.dg/cpp/mi5.c
===================================================================
--- gcc/testsuite/gcc.dg/cpp/mi5.c	(revision 191711)
+++ gcc/testsuite/gcc.dg/cpp/mi5.c	(working copy)
@@ -6,7 +6,7 @@ 
    otherwise it will not be interpreted all in one unit.  */
 
 /* { dg-do preprocess }
-   { dg-options "-H -C" }
+   { dg-options "-nostdinc -H -C" }
    { dg-message "mi1c\.h" "redundant include check with -C" { target *-*-* } 0 } */
 
 #include "mi1c.h"
Index: gcc/testsuite/gcc.dg/cpp/cmdlne-dU-19.c
===================================================================
--- gcc/testsuite/gcc.dg/cpp/cmdlne-dU-19.c	(revision 191711)
+++ gcc/testsuite/gcc.dg/cpp/cmdlne-dU-19.c	(working copy)
@@ -1,5 +1,5 @@ 
 /* { dg-do preprocess } */
-/* { dg-options "-P -dU" } */
+/* { dg-options "-nostdinc -P -dU" } */
 /* { dg-final { scan-file cmdlne-dU-19.i "^\n*B\n+#define A B\n+#undef A\n*$" } } */
 #define A B
 A
Index: gcc/testsuite/gcc.dg/cpp/cmdlne-dU-20.c
===================================================================
--- gcc/testsuite/gcc.dg/cpp/cmdlne-dU-20.c	(revision 191711)
+++ gcc/testsuite/gcc.dg/cpp/cmdlne-dU-20.c	(working copy)
@@ -1,5 +1,5 @@ 
 /* { dg-do preprocess } */
-/* { dg-options "-P -dU" } */
+/* { dg-options "-nostdinc -P -dU" } */
 /* { dg-final { scan-file cmdlne-dU-20.i "^\n*A B\n*$" } } */
 #define A(x) x
 A B
Index: gcc/testsuite/gcc.dg/cpp/cmdlne-dU-7.c
===================================================================
--- gcc/testsuite/gcc.dg/cpp/cmdlne-dU-7.c	(revision 191711)
+++ gcc/testsuite/gcc.dg/cpp/cmdlne-dU-7.c	(working copy)
@@ -1,5 +1,5 @@ 
 /* { dg-do preprocess } */
-/* { dg-options "-P -dU" } */
+/* { dg-options "-nostdinc -P -dU" } */
 /* { dg-final { scan-file cmdlne-dU-7.i "^\n*B\n+#define A B\n+C\n+#define A C\n*$" } } */
 #define A B
 A
Index: gcc/testsuite/gcc.dg/cpp/cmdlne-dU-12.c
===================================================================
--- gcc/testsuite/gcc.dg/cpp/cmdlne-dU-12.c	(revision 191711)
+++ gcc/testsuite/gcc.dg/cpp/cmdlne-dU-12.c	(working copy)
@@ -1,5 +1,5 @@ 
 /* { dg-do preprocess } */
-/* { dg-options "-P -dU" } */
+/* { dg-options "-nostdinc -P -dU" } */
 /* { dg-final { scan-file cmdlne-dU-12.i "^\n*#define A 1\n*$" } } */
 #define A 1
 #if A
Index: gcc/testsuite/gcc.dg/cpp/multiline.c
===================================================================
--- gcc/testsuite/gcc.dg/cpp/multiline.c	(revision 191711)
+++ gcc/testsuite/gcc.dg/cpp/multiline.c	(working copy)
@@ -1,6 +1,6 @@ 
 /* Copyright (C) 2000, 2003 Free Software Foundation, Inc.  */
 /* { dg-do preprocess } */
-/* { dg-options "-C" } */
+/* { dg-options "-nostdinc -C" } */
 /* Test that multi-line tokens are recognized by cpp0 as being
    multiline .  Source: Neil Booth, 17 Dec 2000.  */
 /* Line 1
Index: gcc/testsuite/gcc.dg/cpp/cmdlne-dU-21.c
===================================================================
--- gcc/testsuite/gcc.dg/cpp/cmdlne-dU-21.c	(revision 191711)
+++ gcc/testsuite/gcc.dg/cpp/cmdlne-dU-21.c	(working copy)
@@ -1,5 +1,5 @@ 
 /* { dg-do preprocess } */
-/* { dg-options "-P -dU" } */
+/* { dg-options "-nostdinc -P -dU" } */
 /* { dg-final { scan-file cmdlne-dU-21.i "^\n*hello There\n+#define ASTRING There\n+#define MACROARGS\\(A\\) A\n+#undef BSTRING\n*$" } } */
 #define ASTRING There
 #define MACROARGS(A) A
Index: gcc/testsuite/gcc.dg/cpp/cmdlne-dU-8.c
===================================================================
--- gcc/testsuite/gcc.dg/cpp/cmdlne-dU-8.c	(revision 191711)
+++ gcc/testsuite/gcc.dg/cpp/cmdlne-dU-8.c	(working copy)
@@ -1,5 +1,5 @@ 
 /* { dg-do preprocess } */
-/* { dg-options "-P -dU" } */
+/* { dg-options "-nostdinc -P -dU" } */
 /* { dg-final { scan-file cmdlne-dU-8.i "^\n*B D\n+#define A\\(x\\) B x\n+#define C D\n*$" } } */
 #define A(x) B x
 #define C D
Index: gcc/testsuite/gcc.dg/cpp/cmdlne-dU-13.c
===================================================================
--- gcc/testsuite/gcc.dg/cpp/cmdlne-dU-13.c	(revision 191711)
+++ gcc/testsuite/gcc.dg/cpp/cmdlne-dU-13.c	(working copy)
@@ -1,5 +1,5 @@ 
 /* { dg-do preprocess } */
-/* { dg-options "-P -dU" } */
+/* { dg-options "-nostdinc -P -dU" } */
 /* { dg-final { scan-file cmdlne-dU-13.i "^\n*#undef A\n*$" } } */
 #ifdef A
 #endif
Index: gcc/testsuite/gcc.dg/cpp/cmdlne-dU-22.c
===================================================================
--- gcc/testsuite/gcc.dg/cpp/cmdlne-dU-22.c	(revision 191711)
+++ gcc/testsuite/gcc.dg/cpp/cmdlne-dU-22.c	(working copy)
@@ -1,5 +1,5 @@ 
 /* { dg-do preprocess } */
-/* { dg-options "-P -dU" } */
+/* { dg-options "-nostdinc -P -dU" } */
 /* { dg-final { scan-file cmdlne-dU-22.i "^\n*#undef AAA\n+AAA is undefined\n+#undef BBB\n+BBB is undefined\n+#undef CCC\n+CCC is undefined\n*$" } } */
 #ifndef AAA
 AAA is undefined
Index: gcc/testsuite/gcc.dg/cpp/cmdlne-dU-1.c
===================================================================
--- gcc/testsuite/gcc.dg/cpp/cmdlne-dU-1.c	(revision 191711)
+++ gcc/testsuite/gcc.dg/cpp/cmdlne-dU-1.c	(working copy)
@@ -1,5 +1,5 @@ 
 /* { dg-do preprocess } */
-/* { dg-options "-P -dU" } */
+/* { dg-options "-nostdinc -P -dU" } */
 /* { dg-final { scan-file cmdlne-dU-1.i "^\n*#undef A\n*$" } } */
 #ifdef A
 #endif
Index: gcc/testsuite/gcc.dg/cpp/cmdlne-dU-9.c
===================================================================
--- gcc/testsuite/gcc.dg/cpp/cmdlne-dU-9.c	(revision 191711)
+++ gcc/testsuite/gcc.dg/cpp/cmdlne-dU-9.c	(working copy)
@@ -1,5 +1,5 @@ 
 /* { dg-do preprocess } */
-/* { dg-options "-P -dU" } */
+/* { dg-options "-nostdinc -P -dU" } */
 /* { dg-final { scan-file cmdlne-dU-9.i "^\n*C\n+#define B C\n+#define A B\n*$" } } */
 #define A B
 #define B C
Index: gcc/testsuite/gcc.dg/cpp/cmdlne-dU-14.c
===================================================================
--- gcc/testsuite/gcc.dg/cpp/cmdlne-dU-14.c	(revision 191711)
+++ gcc/testsuite/gcc.dg/cpp/cmdlne-dU-14.c	(working copy)
@@ -1,5 +1,5 @@ 
 /* { dg-do preprocess } */
-/* { dg-options "-P -dU" } */
+/* { dg-options "-nostdinc -P -dU" } */
 /* { dg-final { scan-file cmdlne-dU-14.i "^\n*B\n+#define A B\n+B\n*$" } } */
 #define A B
 A
Index: gcc/testsuite/gcc.dg/cpp/cmdlne-dU-2.c
===================================================================
--- gcc/testsuite/gcc.dg/cpp/cmdlne-dU-2.c	(revision 191711)
+++ gcc/testsuite/gcc.dg/cpp/cmdlne-dU-2.c	(working copy)
@@ -1,5 +1,5 @@ 
 /* { dg-do preprocess } */
-/* { dg-options "-P -dU" } */
+/* { dg-options "-nostdinc -P -dU" } */
 /* { dg-final { scan-file cmdlne-dU-2.i "^\n*#define A *\n*$" } } */
 #define A
 #ifdef A
Index: gcc/testsuite/gcc.dg/cpp/cmdlne-dU-15.c
===================================================================
--- gcc/testsuite/gcc.dg/cpp/cmdlne-dU-15.c	(revision 191711)
+++ gcc/testsuite/gcc.dg/cpp/cmdlne-dU-15.c	(working copy)
@@ -1,5 +1,5 @@ 
 /* { dg-do preprocess } */
-/* { dg-options "-P -dU" } */
+/* { dg-options "-nostdinc -P -dU" } */
 /* { dg-final { scan-file cmdlne-dU-15.i "^\n*\n*$" } } */
 #if A
 #endif
Index: gcc/testsuite/gcc.dg/cpp/cmdlne-dU-3.c
===================================================================
--- gcc/testsuite/gcc.dg/cpp/cmdlne-dU-3.c	(revision 191711)
+++ gcc/testsuite/gcc.dg/cpp/cmdlne-dU-3.c	(working copy)
@@ -1,5 +1,5 @@ 
 /* { dg-do preprocess } */
-/* { dg-options "-P -dU" } */
+/* { dg-options "-nostdinc -P -dU" } */
 /* { dg-final { scan-file cmdlne-dU-3.i "^\n*#define A B\n*$" } } */
 #define A B
 #ifndef A
Index: gcc/testsuite/gcc.dg/cpp/cmdlne-dU-16.c
===================================================================
--- gcc/testsuite/gcc.dg/cpp/cmdlne-dU-16.c	(revision 191711)
+++ gcc/testsuite/gcc.dg/cpp/cmdlne-dU-16.c	(working copy)
@@ -1,6 +1,6 @@ 
 /* { dg-do preprocess } */
-/* { dg-options "-P -dU" } */
-/* { dg-options "-P -dU -std=c89" { target *-*-solaris2.* } } */
+/* { dg-options "-nostdinc -P -dU" } */
+/* { dg-options "-nostdinc -P -dU -std=c89" { target *-*-solaris2.* } } */
 /* { dg-final { scan-file cmdlne-dU-16.i "^\n*#define __STDC__ 1\n*$" } } */
 #ifdef __STDC__
 #endif
Index: gcc/testsuite/gcc.dg/cpp/cmdlne-dU-4.c
===================================================================
--- gcc/testsuite/gcc.dg/cpp/cmdlne-dU-4.c	(revision 191711)
+++ gcc/testsuite/gcc.dg/cpp/cmdlne-dU-4.c	(working copy)
@@ -1,5 +1,5 @@ 
 /* { dg-do preprocess } */
-/* { dg-options "-P -dU" } */
+/* { dg-options "-nostdinc -P -dU" } */
 /* { dg-final { scan-file cmdlne-dU-4.i "^\n*#undef A\n*$" } } */
 #if defined(A)
 #endif
Index: gcc/testsuite/gcc.dg/cpp/cmdlne-dU-17.c
===================================================================
--- gcc/testsuite/gcc.dg/cpp/cmdlne-dU-17.c	(revision 191711)
+++ gcc/testsuite/gcc.dg/cpp/cmdlne-dU-17.c	(working copy)
@@ -1,5 +1,5 @@ 
 /* { dg-do preprocess } */
-/* { dg-options "-P -dU" } */
-/* { dg-options "-P -dU -std=c89" { target *-*-solaris2.* } } */
+/* { dg-options "-nostdinc -P -dU" } */
+/* { dg-options "-nostdinc -P -dU -std=c89" { target *-*-solaris2.* } } */
 /* { dg-final { scan-file cmdlne-dU-17.i "^\n*1\n+#define __STDC__ 1\n*$" } } */
 __STDC__
Index: gcc/testsuite/gcc.dg/c99-predef-1.c
===================================================================
--- gcc/testsuite/gcc.dg/c99-predef-1.c	(revision 0)
+++ gcc/testsuite/gcc.dg/c99-predef-1.c	(revision 0)
@@ -0,0 +1,63 @@ 
+/* Verify that predefined macros for properties of the compiler and
+   library together are the same before and after system headers are
+   included.  This is broken with older glibc versions.  */
+/* { dg-do compile } */
+/* { dg-options "-std=iso9899:1999 -pedantic-errors" } */
+
+#ifdef __STDC_IEC_559__
+#define IEC_559_DEFINED_BEFORE 1
+#else
+#define IEC_559_DEFINED_BEFORE 0
+#endif
+
+#ifdef __STDC_IEC_559_COMPLEX__
+#define IEC_559_COMPLEX_DEFINED_BEFORE 1
+#else
+#define IEC_559_COMPLEX_DEFINED_BEFORE 0
+#endif
+
+#ifdef __STDC_ISO_10646__
+#define ISO_10646_DEFINED_BEFORE 1
+#else
+#define ISO_10646_DEFINED_BEFORE 0
+#endif
+
+#include <stdio.h>
+
+#ifdef __STDC_IEC_559__
+#define IEC_559_DEFINED_AFTER 1
+#else
+#define IEC_559_DEFINED_AFTER 0
+#endif
+
+#ifdef __STDC_IEC_559_COMPLEX__
+#define IEC_559_COMPLEX_DEFINED_AFTER 1
+#else
+#define IEC_559_COMPLEX_DEFINED_AFTER 0
+#endif
+
+#ifdef __STDC_ISO_10646__
+#define ISO_10646_DEFINED_AFTER 1
+#else
+#define ISO_10646_DEFINED_AFTER 0
+#endif
+
+#if defined(__GLIBC__) && (__GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 16))
+#define BROKEN
+#endif
+
+#ifndef BROKEN
+
+#if IEC_559_DEFINED_BEFORE != IEC_559_DEFINED_AFTER
+#error "__STDC_IEC_559__ definition inconsistency"
+#endif
+
+#if IEC_559_COMPLEX_DEFINED_BEFORE != IEC_559_COMPLEX_DEFINED_AFTER
+#error "__STDC_IEC_559_COMPLEX__ definition inconsistency"
+#endif
+
+#if ISO_10646_DEFINED_BEFORE != ISO_10646_DEFINED_AFTER
+#error "__STDC_ISO_10646__ definition inconsistency"
+#endif
+
+#endif
Index: gcc/config.gcc
===================================================================
--- gcc/config.gcc	(revision 191711)
+++ gcc/config.gcc	(working copy)
@@ -667,6 +667,10 @@  case ${target} in
       tm_defines="$tm_defines ANDROID_DEFAULT=0"
       ;;
   esac
+  c_target_objs="${c_target_objs} glibc-c.o"
+  cxx_target_objs="${cxx_target_objs} glibc-c.o"
+  tmake_file="${tmake_file} t-glibc"
+  target_has_targetcm=yes
   ;;
 *-*-netbsd*)
   tmake_file="t-slibgcc"
@@ -2468,16 +2472,16 @@  tilegx-*-linux*)
 	tm_file="elfos.h gnu-user.h linux.h glibc-stdint.h tilegx/linux.h ${tm_file}"
         tmake_file="${tmake_file} tilegx/t-tilegx"
 	extra_objs="mul-tables.o"
-	c_target_objs="tilegx-c.o"
-	cxx_target_objs="tilegx-c.o"
+	c_target_objs="${c_target_objs} tilegx-c.o"
+	cxx_target_objs="${cxx_target_objs} tilegx-c.o"
 	extra_headers="feedback.h"
 	;;
 tilepro-*-linux*)
 	tm_file="elfos.h gnu-user.h linux.h glibc-stdint.h tilepro/linux.h ${tm_file}"
         tmake_file="${tmake_file} tilepro/t-tilepro"
 	extra_objs="mul-tables.o"
-	c_target_objs="tilepro-c.o"
-	cxx_target_objs="tilepro-c.o"
+	c_target_objs="${c_target_objs} tilepro-c.o"
+	cxx_target_objs="${cxx_target_objs} tilepro-c.o"
 	extra_headers="feedback.h"
 	;;
 v850-*-rtems*)
Index: gcc/config/t-glibc
===================================================================
--- gcc/config/t-glibc	(revision 0)
+++ gcc/config/t-glibc	(revision 0)
@@ -0,0 +1,23 @@ 
+# Copyright (C) 2012
+# Free Software Foundation, Inc.
+#
+# This file is part of GCC.
+#
+# GCC 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 3, or (at your option)
+# any later version.
+#
+# GCC 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 GCC; see the file COPYING3.  If not see
+# <http://www.gnu.org/licenses/>.
+
+glibc-c.o: config/glibc-c.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
+  $(C_TARGET_H) $(C_TARGET_DEF_H)
+	$(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) \
+	  $< $(OUTPUT_OPTION)
Index: gcc/config/glibc-c.c
===================================================================
--- gcc/config/glibc-c.c	(revision 0)
+++ gcc/config/glibc-c.c	(revision 0)
@@ -0,0 +1,38 @@ 
+/* C-family target hooks initializer for targets possibly using glibc.
+   Copyright (C) 2012
+   Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC 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 3, or (at your option) any later
+version.
+
+GCC 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 GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "c-family/c-target.h"
+#include "c-family/c-target-def.h"
+
+/* Implement TARGET_C_PREINCLUDE for glibc targets.  */
+
+static const char *
+glibc_c_preinclude (void)
+{
+  return "stdc-predef.h";
+}
+
+#undef TARGET_C_PREINCLUDE
+#define TARGET_C_PREINCLUDE glibc_c_preinclude
+
+struct gcc_targetcm targetcm = TARGETCM_INITIALIZER;
Index: libcpp/files.c
===================================================================
--- libcpp/files.c	(revision 191711)
+++ libcpp/files.c	(working copy)
@@ -110,6 +110,9 @@  struct _cpp_file
 
   /* If BUFFER above contains the true contents of the file.  */
   bool buffer_valid;
+
+  /* If this file is implicitly preincluded.  */
+  bool implicit_preinclude;
 };
 
 /* A singly-linked list for all searches for a given file name, with
@@ -291,7 +294,8 @@  pch_open_file (cpp_reader *pfile, _cpp_file *file,
   /* If the file is not included as first include from either the toplevel
      file or the command-line it is not a valid use of PCH.  */
   if (pfile->all_files
-      && pfile->all_files->next_file)
+      && pfile->all_files->next_file
+      && !pfile->all_files->next_file->implicit_preinclude)
     return false;
 
   flen = strlen (path);
@@ -480,9 +484,14 @@  _cpp_find_failed (_cpp_file *file)
    descriptor.  FD can be -1 if the file was found in the cache and
    had previously been closed.  To open it again pass the return value
    to open_file().
+
+   If IMPLICIT_PREINCLUDE then it is OK for the file to be missing.
+   If present, it is OK for a precompiled header to be included after
+   it.
 */
 _cpp_file *
-_cpp_find_file (cpp_reader *pfile, const char *fname, cpp_dir *start_dir, bool fake, int angle_brackets)
+_cpp_find_file (cpp_reader *pfile, const char *fname, cpp_dir *start_dir,
+		bool fake, int angle_brackets, bool implicit_preinclude)
 {
   struct file_hash_entry *entry, **hash_slot;
   _cpp_file *file;
@@ -506,6 +515,7 @@  _cpp_file *
     return entry->u.file;
 
   file = make_cpp_file (pfile, start_dir, fname);
+  file->implicit_preinclude = implicit_preinclude;
 
   /* Try each path in the include chain.  */
   for (; !fake ;)
@@ -535,7 +545,14 @@  _cpp_file *
 		cpp_error (pfile, CPP_DL_ERROR,
 			   "use -Winvalid-pch for more information");
 	    }
-	  open_file_failed (pfile, file, angle_brackets);
+	  if (implicit_preinclude)
+	    {
+	      free ((char *) file->name);
+	      free (file);
+	      return NULL;
+	    }
+	  else
+	    open_file_failed (pfile, file, angle_brackets);
 	  break;
 	}
 
@@ -949,7 +966,10 @@  _cpp_stack_include (cpp_reader *pfile, const char
   if (!dir)
     return false;
 
-  file = _cpp_find_file (pfile, fname, dir, false, angle_brackets);
+  file = _cpp_find_file (pfile, fname, dir, false, angle_brackets,
+			 type == IT_DEFAULT);
+  if (type == IT_DEFAULT && file == NULL)
+    return false;
 
   /* Compensate for the increment in linemap_add that occurs in
      _cpp_stack_file.  In the case of a normal #include, we're
@@ -959,7 +979,8 @@  _cpp_stack_include (cpp_reader *pfile, const char
      This does not apply if we found a PCH file (in which case
      linemap_add is not called) or we were included from the
      command-line.  */
-  if (file->pchname == NULL && file->err_no == 0 && type != IT_CMDLINE)
+  if (file->pchname == NULL && file->err_no == 0
+      && type != IT_CMDLINE && type != IT_DEFAULT)
     pfile->line_table->highest_location--;
 
   return _cpp_stack_file (pfile, file, type == IT_IMPORT);
@@ -1242,7 +1263,7 @@  cpp_clear_file_cache (cpp_reader *pfile)
 void
 _cpp_fake_include (cpp_reader *pfile, const char *fname)
 {
-  _cpp_find_file (pfile, fname, pfile->buffer->file->dir, true, 0);
+  _cpp_find_file (pfile, fname, pfile->buffer->file->dir, true, 0, false);
 }
 
 /* Not everyone who wants to set system-header-ness on a buffer can
@@ -1360,7 +1381,7 @@  _cpp_compare_file_date (cpp_reader *pfile, const c
   if (!dir)
     return -1;
 
-  file = _cpp_find_file (pfile, fname, dir, false, angle_brackets);
+  file = _cpp_find_file (pfile, fname, dir, false, angle_brackets, false);
   if (file->err_no)
     return -1;
 
@@ -1381,6 +1402,15 @@  cpp_push_include (cpp_reader *pfile, const char *f
   return _cpp_stack_include (pfile, fname, false, IT_CMDLINE);
 }
 
+/* Pushes the given file, implicitly included at the start of a
+   compilation, onto the buffer stack but without any errors if the
+   file is not found.  Returns nonzero if successful.  */
+bool
+cpp_push_default_include (cpp_reader *pfile, const char *fname)
+{
+  return _cpp_stack_include (pfile, fname, true, IT_DEFAULT);
+}
+
 /* Do appropriate cleanup when a file INC's buffer is popped off the
    input stack.  */
 void
Index: libcpp/include/cpplib.h
===================================================================
--- libcpp/include/cpplib.h	(revision 191711)
+++ libcpp/include/cpplib.h	(working copy)
@@ -1,6 +1,6 @@ 
 /* Definitions for CPP library.
    Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
-   2004, 2005, 2007, 2008, 2009, 2010, 2011
+   2004, 2005, 2007, 2008, 2009, 2010, 2011, 2012
    Free Software Foundation, Inc.
    Written by Per Bothner, 1994-95.
 
@@ -1010,6 +1010,7 @@  extern bool cpp_included (cpp_reader *, const char
 extern bool cpp_included_before (cpp_reader *, const char *, source_location);
 extern void cpp_make_system_header (cpp_reader *, int, int);
 extern bool cpp_push_include (cpp_reader *, const char *);
+extern bool cpp_push_default_include (cpp_reader *, const char *);
 extern void cpp_change_file (cpp_reader *, enum lc_reason, const char *);
 extern const char *cpp_get_path (struct _cpp_file *);
 extern cpp_dir *cpp_get_dir (struct _cpp_file *);
Index: libcpp/init.c
===================================================================
--- libcpp/init.c	(revision 191711)
+++ libcpp/init.c	(working copy)
@@ -1,7 +1,7 @@ 
 /* CPP Library.
    Copyright (C) 1986, 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
    1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008,
-   2009, 2010, 2011 Free Software Foundation, Inc.
+   2009, 2010, 2011, 2012 Free Software Foundation, Inc.
    Contributed by Per Bothner, 1994-95.
    Based on CCCP program by Paul Rubin, June 1986
    Adapted to ANSI C, Richard Stallman, Jan 1987
@@ -593,7 +593,7 @@  cpp_read_main_file (cpp_reader *pfile, const char
     }
 
   pfile->main_file
-    = _cpp_find_file (pfile, fname, &pfile->no_search_path, false, 0);
+    = _cpp_find_file (pfile, fname, &pfile->no_search_path, false, 0, false);
   if (_cpp_find_failed (pfile->main_file))
     return NULL;
 
Index: libcpp/internal.h
===================================================================
--- libcpp/internal.h	(revision 191711)
+++ libcpp/internal.h	(working copy)
@@ -117,7 +117,7 @@  extern unsigned char *_cpp_unaligned_alloc (cpp_re
 #define BUFF_LIMIT(BUFF) ((BUFF)->limit)
 
 /* #include types.  */
-enum include_type {IT_INCLUDE, IT_INCLUDE_NEXT, IT_IMPORT, IT_CMDLINE};
+enum include_type {IT_INCLUDE, IT_INCLUDE_NEXT, IT_IMPORT, IT_CMDLINE, IT_DEFAULT};
 
 union utoken
 {
@@ -625,7 +625,7 @@  extern void _cpp_destroy_hashtable (cpp_reader *);
 /* In files.c */
 typedef struct _cpp_file _cpp_file;
 extern _cpp_file *_cpp_find_file (cpp_reader *, const char *, cpp_dir *,
-				  bool, int);
+				  bool, int, bool);
 extern bool _cpp_find_failed (_cpp_file *);
 extern void _cpp_mark_file_once_only (cpp_reader *, struct _cpp_file *);
 extern void _cpp_fake_include (cpp_reader *, const char *);