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 *);
