gcc: 2009-04-18 Joseph Myers * target.h (struct gcc_target): Add c.preinclude. * target-def.h (TARGET_C_PREINCLUDE): Define. (TARGET_C): Update. * doc/tm.texi (TARGET_C_PREINCLUDE): Document. * hooks.c (hook_constcharptr_void_null): New. * hooks.h (hook_constcharptr_void_null): Declare. * targhooks.c (glibc_c_preinclude): New. * targhooks.h (glibc_c_preinclude): Declare. * c-opts.c (done_preinclude): New. (push_command_line_include): Handle default preincluded header. * config/linux.h (TARGET_C_PREINCLUDE): Define. * config/alpha/linux.h (TARGET_C_PREINCLUDE): Define. * config/rs6000/linux.h (TARGET_C_PREINCLUDE): Define. * config/rs6000/linux64.h (TARGET_C_PREINCLUDE): Define. gcc/testsuite: 2009-04-18 Joseph Myers * gcc.dg/c99-predef-1.c: New test. libcpp: 2009-04-18 Joseph Myers * files.c (_cpp_find_file): Add missing_ok argument. Do not call open_file_failed if missing_ok. (_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. Index: gcc/doc/tm.texi =================================================================== --- gcc/doc/tm.texi (revision 146291) +++ gcc/doc/tm.texi (working copy) @@ -10068,6 +10068,19 @@ files @code{__STDC__} will always expand to 1. @end defmac +@deftypefn {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/targhooks.c =================================================================== --- gcc/targhooks.c (revision 146291) +++ gcc/targhooks.c (working copy) @@ -1,5 +1,6 @@ /* Default target hook functions. - Copyright (C) 2003, 2004, 2005, 2007, 2008 Free Software Foundation, Inc. + Copyright (C) 2003, 2004, 2005, 2007, 2008, 2009 + Free Software Foundation, Inc. This file is part of GCC. @@ -765,4 +766,10 @@ return ret; } +const char * +glibc_c_preinclude (void) +{ + return "stdc-predef.h"; +} + #include "gt-targhooks.h" Index: gcc/targhooks.h =================================================================== --- gcc/targhooks.h (revision 146291) +++ gcc/targhooks.h (working copy) @@ -1,5 +1,6 @@ /* Default target hook functions. - Copyright (C) 2003, 2004, 2005, 2007, 2008 Free Software Foundation, Inc. + Copyright (C) 2003, 2004, 2005, 2007, 2008, 2009 + Free Software Foundation, Inc. This file is part of GCC. @@ -104,3 +105,5 @@ extern bool default_target_option_valid_attribute_p (tree, tree, tree, int); extern bool default_target_option_pragma_parse (tree, tree); extern bool default_target_option_can_inline_p (tree, tree); + +extern const char *glibc_c_preinclude (void); Index: gcc/hooks.c =================================================================== --- gcc/hooks.c (revision 146291) +++ gcc/hooks.c (working copy) @@ -1,5 +1,5 @@ /* General-purpose hooks. - Copyright (C) 2002, 2003, 2004, 2005, 2007, 2008 + Copyright (C) 2002, 2003, 2004, 2005, 2007, 2008, 2009 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it @@ -278,6 +278,13 @@ 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 146291) +++ gcc/hooks.h (working copy) @@ -1,5 +1,5 @@ /* General-purpose hooks. - Copyright (C) 2002, 2003, 2004, 2005, 2007, 2008 + Copyright (C) 2002, 2003, 2004, 2005, 2007, 2008, 2009 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it @@ -78,6 +78,7 @@ 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/target.h =================================================================== --- gcc/target.h (revision 146291) +++ gcc/target.h (working copy) @@ -924,6 +924,9 @@ /* Return machine mode for non-standard suffix or VOIDmode if non-standard suffixes are unsupported. */ enum machine_mode (*mode_for_suffix) (char); + /* Return the name of a header to preinclude in hosted + compilations. */ + const char * (*preinclude) (void); } c; /* Functions specific to the C++ frontend. */ 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 + +#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__ < 10)) +#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/c-opts.c =================================================================== --- gcc/c-opts.c (revision 146291) +++ gcc/c-opts.c (working copy) @@ -106,6 +106,9 @@ /* 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 set_Wimplicit (int); static void handle_OPT_d (const char *); static void set_std_cxx98 (int); @@ -1553,6 +1556,17 @@ static void push_command_line_include (void) { + if (!done_preinclude) + { + done_preinclude = true; + if (flag_hosted && std_inc) + { + const char *preinc = targetm.c.preinclude (); + if (preinc && cpp_push_default_include (parse_in, preinc)) + return; + } + } + while (include_cursor < deferred_count) { struct deferred_opt *opt = &deferred_opts[include_cursor++]; Index: gcc/target-def.h =================================================================== --- gcc/target-def.h (revision 146291) +++ gcc/target-def.h (working copy) @@ -1,5 +1,5 @@ /* Default initializers for a generic GCC target. - Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 + Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it @@ -659,9 +659,14 @@ #define TARGET_C_MODE_FOR_SUFFIX default_mode_for_suffix #endif +#ifndef TARGET_C_PREINCLUDE +#define TARGET_C_PREINCLUDE hook_constcharptr_void_null +#endif + #define TARGET_C \ { \ - TARGET_C_MODE_FOR_SUFFIX \ + TARGET_C_MODE_FOR_SUFFIX, \ + TARGET_C_PREINCLUDE \ } /* C++ specific. */ Index: gcc/config/linux.h =================================================================== --- gcc/config/linux.h (revision 146291) +++ gcc/config/linux.h (working copy) @@ -135,3 +135,5 @@ #define TARGET_HAS_SINCOS (OPTION_GLIBC) #define TARGET_POSIX_IO + +#define TARGET_C_PREINCLUDE glibc_c_preinclude Index: gcc/config/alpha/linux.h =================================================================== --- gcc/config/alpha/linux.h (revision 146291) +++ gcc/config/alpha/linux.h (working copy) @@ -1,6 +1,6 @@ /* Definitions of target machine for GNU compiler, for Alpha Linux-based GNU systems. - Copyright (C) 1996, 1997, 1998, 2002, 2003, 2004, 2005, 2006, 2007 + Copyright (C) 1996, 1997, 1998, 2002, 2003, 2004, 2005, 2006, 2007, 2009 Free Software Foundation, Inc. Contributed by Richard Henderson. @@ -73,6 +73,8 @@ #define TARGET_POSIX_IO +#define TARGET_C_PREINCLUDE glibc_c_preinclude + #define LINK_GCC_C_SEQUENCE_SPEC \ "%{static:--start-group} %G %L %{static:--end-group}%{!static:%G}" Index: gcc/config/rs6000/linux.h =================================================================== --- gcc/config/rs6000/linux.h (revision 146291) +++ gcc/config/rs6000/linux.h (working copy) @@ -1,7 +1,7 @@ /* Definitions of target machine for GNU compiler, for PowerPC machines running Linux. Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, - 2004, 2005, 2006, 2007 Free Software Foundation, Inc. + 2004, 2005, 2006, 2007, 2009 Free Software Foundation, Inc. Contributed by Michael Meissner (meissner@cygnus.com). This file is part of GCC. @@ -38,6 +38,8 @@ #undef TARGET_HAS_SINCOS #define TARGET_HAS_SINCOS (OPTION_GLIBC) +#define TARGET_C_PREINCLUDE glibc_c_preinclude + #undef TARGET_OS_CPP_BUILTINS #define TARGET_OS_CPP_BUILTINS() \ do \ Index: gcc/config/rs6000/linux64.h =================================================================== --- gcc/config/rs6000/linux64.h (revision 146291) +++ gcc/config/rs6000/linux64.h (working copy) @@ -295,6 +295,8 @@ #undef TARGET_HAS_SINCOS #define TARGET_HAS_SINCOS (OPTION_GLIBC) +#define TARGET_C_PREINCLUDE glibc_c_preinclude + #undef TARGET_OS_CPP_BUILTINS #define TARGET_OS_CPP_BUILTINS() \ do \ Index: libcpp/files.c =================================================================== --- libcpp/files.c (revision 146291) +++ libcpp/files.c (working copy) @@ -443,7 +443,8 @@ to open_file(). */ _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 missing_ok) { struct file_hash_entry *entry, **hash_slot; _cpp_file *file; @@ -496,7 +497,8 @@ cpp_error (pfile, CPP_DL_ERROR, "use -Winvalid-pch for more information"); } - open_file_failed (pfile, file, angle_brackets); + if (!missing_ok) + open_file_failed (pfile, file, angle_brackets); break; } @@ -910,7 +912,8 @@ 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); /* Compensate for the increment in linemap_add. In the case of a normal #include, we're currently at the start of the line @@ -919,7 +922,8 @@ complicates LAST_SOURCE_LINE_LOCATION. 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); @@ -1190,7 +1194,7 @@ 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 @@ -1308,7 +1312,7 @@ 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; @@ -1329,6 +1333,15 @@ 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 146291) +++ libcpp/include/cpplib.h (working copy) @@ -897,6 +897,7 @@ 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 146291) +++ libcpp/init.c (working copy) @@ -519,7 +519,7 @@ } 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 146291) +++ libcpp/internal.h (working copy) @@ -112,7 +112,7 @@ #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 { @@ -537,7 +537,7 @@ /* 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 *);