"Joseph S. Myers" <[EMAIL PROTECTED]> writes: > On Mon, 4 Mar 2007, Ian Lance Taylor wrote: > > > FX Coudert <[EMAIL PROTECTED]> writes: > > > > > I'd like to ping these two problems :) > > > > > > i386-unknown-netbsdelf2.0.2 (and possibly newer versions) and i386-pc- > > > mingw32 (latest released version) are still completely broken on > > > mainline, as they have been for more that three months. > > > > This patch (not yet approved) is my contribution to fixing the > > problem. > > > > http://gcc.gnu.org/ml/gcc-patches/2007-03/msg00021.html > > I was supposing there would be a patch repost following > <http://gcc.gnu.org/ml/gcc-patches/2007-03/msg00097.html> with the current > versions of the patch for consideration.
I only made one of the changes Jakub suggested: I fixed a typo in the documentation. So I didn't bother sending another copy. For clarity, here is the current version of the patch. Ian gcc/ChangeLog: 2007-03-05 Ian Lance Taylor <[EMAIL PROTECTED]> * c.opt (fgnu89-inline): New option. * c-opts.c (c_common_post_options): Set default value for flag_gnu89_inline. * c-decl.c (WANT_C99_INLINE_SEMANTICS): Remove. (pop_scope): Check flag_gnu89_inline rather than flag_isoc99 for inline functions. (diagnose_mismatched_decls, merge_decls, start_decl): Likewise. (grokdeclarator, start_function): Likewise. * c-cppbuiltin.c (c_cpp_builtins): Define either __GNUC_GNU_INLINE__ or __GNUC_STDC_INLINE__. * doc/invoke.texi (Option Summary): Mention -fgnu89-inline. (C Dialect Options): Document -fgnu89-inline. * doc/extend.texi (Function Attributes): Explain what the gnu_inline attribute does. * doc/cpp.texi (Common Predefined Macros): Document __GNUC_GNU_INLINE__ and __GNUC_STDC_INLINE__. gcc/testsuite/ChangeLog: 2007-03-05 Ian Lance Taylor <[EMAIL PROTECTED]> * gcc.dg/inline-18.c: New test. * gcc.dg/inline-19.c: New test. * gcc.dg/inline-20.c: New test. * gcc.dg/inline-21.c: New test. Index: gcc/doc/cpp.texi =================================================================== --- gcc/doc/cpp.texi (revision 122560) +++ gcc/doc/cpp.texi (working copy) @@ -2014,6 +2014,28 @@ functions. You should not use these mac sure that programs will execute with the same effect whether or not they are defined. If they are defined, their value is 1. [EMAIL PROTECTED] __GNUC_GNU_INLINE__ +GCC defines this macro if functions declared @code{inline} will be +handled in GCC's traditional gnu89 mode. In this mode an @code{extern +inline} function will never be compiled as a standalone function, and +an @code{inline} function which is neither @code{extern} nor [EMAIL PROTECTED] will always be compiled as a standalone function. + [EMAIL PROTECTED] __GNUC_STDC_INLINE__ +GCC defines this macro if functions declared @code{inline} will be +handled according to the ISO C99 standard. In this mode an [EMAIL PROTECTED] inline} function will always be compiled as a standalone +externally visible function, and an @code{inline} function which is +neither @code{extern} nor @code{static} will never be compiled as a +standalone function. + +If this macro is defined, GCC supports the @code{gnu_inline} function +attribute as a way to always get the gnu89 behaviour. Support for +this and @code{__GNUC_GNU_INLINE__} was added in GCC 4.1.3. If +neither macro is defined, an older version of GCC is being used: [EMAIL PROTECTED] functions will be compiled in gnu89 mode, and the [EMAIL PROTECTED] function attribute will not be recognized. + @item __CHAR_UNSIGNED__ GCC defines this macro if and only if the data type @code{char} is unsigned on the target machine. It exists to cause the standard header Index: gcc/doc/extend.texi =================================================================== --- gcc/doc/extend.texi (revision 122560) +++ gcc/doc/extend.texi (working copy) @@ -1618,8 +1618,37 @@ if no optimization level was specified. @item gnu_inline @cindex @code{gnu_inline} function attribute -This attribute on an inline declaration results in the old GNU C89 -inline behavior even in the ISO C99 mode. +This attribute should be used with a function which is also declared +with the @code{inline} keyword. It directs GCC to treat the function +as if it were defined in gnu89 mode even when compiling in C99 or +gnu99 mode. + +If the function is declared @code{extern}, then this definition of the +function is used only for inlining. In no case is the function +compiled as a standalone function, not even if you take its address +explicitly. Such an address becomes an external reference, as if you +had only declared the function, and had not defined it. This has +almost the effect of a macro. The way to use this is to put a +function definition in a header file with this attribute, and put +another copy of the function, without @code{extern}, in a library +file. The definition in the header file will cause most calls to the +function to be inlined. If any uses of the function remain, they will +refer to the single copy in the library. Note that the two +definitions of the functions need not be precisely the same, although +if they do not have the same effect your program may behave oddly. + +If the function is neither @code{extern} nor @code{static}, then the +function is compiled as a standalone function, as well as being +inlined where possible. + +This is how GCC traditionally handled functions declared [EMAIL PROTECTED] Since ISO C99 specifies a different semantics for [EMAIL PROTECTED], this function attribute is provided as a transition +measure and as a useful feature in its own right. This attribute is +available in GCC 4.1.3 and later. It is available if either of the +preprocessor macros @code{__GNUC_GNU_INLINE__} or [EMAIL PROTECTED] are defined. @xref{Inline,,An Inline +Function is As Fast As a Macro}. @cindex @code{flatten} function attribute @item flatten @@ -3846,10 +3875,11 @@ also direct GCC to try to integrate all into their callers with the option @option{-finline-functions}. GCC implements three different semantics of declaring a function -inline. One is available with @option{-std=gnu89} or when @code{gnu_inline} -attribute is present on all inline declarations, another when [EMAIL PROTECTED] or @option{-std=gnu99}, and the third is used when -compiling C++. +inline. One is available with @option{-std=gnu89} or [EMAIL PROTECTED] or when @code{gnu_inline} attribute is present +on all inline declarations, another when @option{-std=c99} or [EMAIL PROTECTED] (without @option{-fgnu89-inline}), and the third +is used when compiling C++. To declare a function inline, use the @code{inline} keyword in its declaration, like this: Index: gcc/doc/invoke.texi =================================================================== --- gcc/doc/invoke.texi (revision 122560) +++ gcc/doc/invoke.texi (working copy) @@ -166,7 +166,8 @@ in the following sections. @item C Language Options @xref{C Dialect Options,,Options Controlling C Dialect}. [EMAIL PROTECTED] [EMAIL PROTECTED] -aux-info @var{filename} @gol [EMAIL PROTECTED] [EMAIL PROTECTED] -fgnu89-inline @gol +-aux-info @var{filename} @gol -fno-asm -fno-builtin [EMAIL PROTECTED] @gol -fhosted -ffreestanding -fopenmp -fms-extensions @gol -trigraphs -no-integrated-cpp -traditional -traditional-cpp @gol @@ -1351,6 +1352,27 @@ the @code{inline} keyword in ISO C99) ar @xref{Standards,,Language Standards Supported by GCC}, for details of these standard versions. [EMAIL PROTECTED] -fgnu89-inline [EMAIL PROTECTED] fgnu89-inline +The option @option{-fgnu89-inline} tells GCC to use the traditional +GNU semantics for @code{inline} functions when in C99 mode. [EMAIL PROTECTED],,An Inline Function is As Fast As a Macro}. This option +is accepted and ignored by GCC versions 4.1.3 up to but not including +4.3. In GCC versions 4.3 and later it changes the behavior of GCC in +C99 mode. Using this option is roughly equivalent to adding the [EMAIL PROTECTED] function attribute to all inline functions +(@pxref{Function Attributes}). + +The option @option{-fno-gnu89-inline} explicitly tells GCC to use the +C99 semantics for @code{inline} when in C99 or gnu99 mode (i.e., it +specifies the default behavior). This option was first supported in +GCC 4.3. This option is not supported in C89 or gnu89 mode. + +The preprocesor macros @code{__GNUC_GNU_INLINE__} and [EMAIL PROTECTED] may be used to check which semantics are +in effect for @code{inline} functions. @xref{Common Predefined +Macros,,,cpp.info,The C Preprocessor}. + @item -aux-info @var{filename} @opindex aux-info Output to the given filename prototyped declarations for all functions Index: gcc/c-cppbuiltin.c =================================================================== --- gcc/c-cppbuiltin.c (revision 122560) +++ gcc/c-cppbuiltin.c (working copy) @@ -1,5 +1,6 @@ /* Define builtin-in macros for the C family front ends. - Copyright (C) 2002, 2003, 2004, 2005, 2007 Free Software Foundation, Inc. + Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 + Free Software Foundation, Inc. This file is part of GCC. @@ -495,6 +496,11 @@ c_cpp_builtins (cpp_reader *pfile) /* Misc. */ builtin_define_with_value ("__VERSION__", version_string, 1); + if (flag_gnu89_inline) + cpp_define (pfile, "__GNUC_GNU_INLINE__"); + else + cpp_define (pfile, "__GNUC_STDC_INLINE__"); + /* Definitions for LP64 model. */ if (TYPE_PRECISION (long_integer_type_node) == 64 && POINTER_SIZE == 64 Index: gcc/testsuite/gcc.dg/inline-19.c =================================================================== --- gcc/testsuite/gcc.dg/inline-19.c (revision 0) +++ gcc/testsuite/gcc.dg/inline-19.c (revision 0) @@ -0,0 +1,28 @@ +/* Test -fgnu89-extern-inline. */ +/* { dg-do compile } */ +/* { dg-options "-fgnu89-inline" } */ +/* { dg-final { scan-assembler "func1" } } */ +/* { dg-final { scan-assembler-not "func2" } } */ +/* { dg-final { scan-assembler "func3" } } */ +/* { dg-final { scan-assembler "func4" } } */ + +#ifndef __GNUC_GNU_INLINE__ +#error __GNUC_GNU_INLINE__ is not defined +#endif + +#ifdef __GNUC_STDC_INLINE__ +#error __GNUC_STDC_INLINE__ is defined +#endif + +extern inline int func1 (void) { return 0; } +inline int func1 (void) { return 1; } + +extern int func2 (void); +extern inline int func2 (void) { return 2; } + +inline int func3 (void); +inline int func3 (void) { return 3; } + +extern int func4 (void); +extern inline int func4 (void) { return 4; } +int func4 (void) { return 5; } Index: gcc/testsuite/gcc.dg/inline-21.c =================================================================== --- gcc/testsuite/gcc.dg/inline-21.c (revision 0) +++ gcc/testsuite/gcc.dg/inline-21.c (revision 0) @@ -0,0 +1,4 @@ +/* Test -fno-gnu89-extern-inline. */ +/* { dg-do compile } */ +/* { dg-options "-std=gnu89 -fno-gnu89-inline" } */ +/* { dg-error "only supported in GNU99 or C99 mode" "" { target *-*-* } 0 } */ Index: gcc/testsuite/gcc.dg/inline-18.c =================================================================== --- gcc/testsuite/gcc.dg/inline-18.c (revision 0) +++ gcc/testsuite/gcc.dg/inline-18.c (revision 0) @@ -0,0 +1,28 @@ +/* Test -fgnu89-extern-inline. */ +/* { dg-do compile } */ +/* { dg-options "-std=c99 -fgnu89-inline" } */ +/* { dg-final { scan-assembler "func1" } } */ +/* { dg-final { scan-assembler-not "func2" } } */ +/* { dg-final { scan-assembler "func3" } } */ +/* { dg-final { scan-assembler "func4" } } */ + +#ifndef __GNUC_GNU_INLINE__ +#error __GNUC_GNU_INLINE__ is not defined +#endif + +#ifdef __GNUC_STDC_INLINE__ +#error __GNUC_STDC_INLINE__ is defined +#endif + +extern inline int func1 (void) { return 0; } +inline int func1 (void) { return 1; } + +extern int func2 (void); +extern inline int func2 (void) { return 2; } + +inline int func3 (void); +inline int func3 (void) { return 3; } + +extern int func4 (void); +extern inline int func4 (void) { return 4; } +int func4 (void) { return 5; } Index: gcc/testsuite/gcc.dg/inline-20.c =================================================================== --- gcc/testsuite/gcc.dg/inline-20.c (revision 0) +++ gcc/testsuite/gcc.dg/inline-20.c (revision 0) @@ -0,0 +1,64 @@ +/* Test -fno-gnu89-extern-inline. */ +/* { dg-do compile } */ +/* { dg-options "-std=c99 -fno-gnu89-inline" } */ +/* { dg-final { scan-assembler-not "dontgenerate" } } */ +/* { dg-final { scan-assembler "func1" } } */ +/* { dg-final { scan-assembler "func2" } } */ +/* { dg-final { scan-assembler "func3" } } */ +/* { dg-final { scan-assembler "func4" } } */ +/* { dg-final { scan-assembler "func5" } } */ +/* { dg-final { scan-assembler "func6" } } */ +/* { dg-final { scan-assembler "func7" } } */ +/* { dg-final { scan-assembler "func8" } } */ +/* { dg-final { scan-assembler "func9" } } */ + +#ifdef __GNUC_GNU_INLINE__ +#error __GNUC_GNU_INLINE__ is defined +#endif + +#ifndef __GNUC_STDC_INLINE__ +#error __GNUC_STDC_INLINE__ is not defined +#endif + +inline int dontgenerate1 (void) +{ + return 1; +} + +inline int dontgenerate2 (void); +inline int dontgenerate2 (void) +{ + return 2; +} + +inline int dontgenerate3 (void) +{ + return 3; +} +inline int dontgenerate3 (void); + +extern inline int func1 (void) { return 1; } + +extern inline int func2 (void); +inline int func2 (void) { return 2; } + +inline int func3 (void) { return 3; } +extern inline int func3 (void); + +inline int func4 (void); +extern inline int func4 (void) { return 4; } + +extern inline int func5 (void) { return 5; } +inline int func5 (void); + +extern int func6 (void); +inline int func6 (void) { return 6; } + +inline int func7 (void) { return 7; } +extern int func7 (void); + +inline int func8 (void); +extern int func8 (void) { return 8; } + +extern int func9 (void) { return 9; } +inline int func9 (void); Index: gcc/c-decl.c =================================================================== --- gcc/c-decl.c (revision 122560) +++ gcc/c-decl.c (working copy) @@ -1,6 +1,6 @@ /* Process declarations and variables for C compiler. Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, - 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. + 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. This file is part of GCC. @@ -62,12 +62,6 @@ Software Foundation, 51 Franklin Street, #include "langhooks-def.h" #include "pointer-set.h" -/* Set this to 1 if you want the standard ISO C99 semantics of 'inline' - when you specify -std=c99 or -std=gnu99, and to 0 if you want - behavior compatible with the nonstandard semantics implemented by - GCC 2.95 through 4.2. */ -#define WANT_C99_INLINE_SEMANTICS 1 - /* In grokdeclarator, distinguish syntactic contexts of declarators. */ enum decl_context { NORMAL, /* Ordinary declaration */ @@ -803,7 +797,7 @@ pop_scope (void) else if (DECL_DECLARED_INLINE_P (p) && TREE_PUBLIC (p) && !DECL_INITIAL (p) - && flag_isoc99) + && !flag_gnu89_inline) pedwarn ("inline function %q+D declared but never defined", p); goto common_symbol; @@ -1330,15 +1324,13 @@ diagnose_mismatched_decls (tree newdecl, unit. */ if ((!DECL_EXTERN_INLINE (olddecl) || DECL_EXTERN_INLINE (newdecl) -#if WANT_C99_INLINE_SEMANTICS - || (flag_isoc99 + || (!flag_gnu89_inline && (!DECL_DECLARED_INLINE_P (olddecl) || !lookup_attribute ("gnu_inline", DECL_ATTRIBUTES (olddecl))) && (!DECL_DECLARED_INLINE_P (newdecl) || !lookup_attribute ("gnu_inline", DECL_ATTRIBUTES (newdecl)))) -#endif /* WANT_C99_INLINE_SEMANTICS */ ) && same_translation_unit_p (newdecl, olddecl)) { @@ -1553,7 +1545,7 @@ diagnose_mismatched_decls (tree newdecl, we still shouldn't warn.) */ if (DECL_DECLARED_INLINE_P (newdecl) && !DECL_DECLARED_INLINE_P (olddecl) && same_translation_unit_p (olddecl, newdecl) - && ! flag_isoc99) + && flag_gnu89_inline) { if (TREE_USED (olddecl)) { @@ -1783,12 +1775,11 @@ merge_decls (tree newdecl, tree olddecl, } } -#if WANT_C99_INLINE_SEMANTICS /* In c99, 'extern' declaration before (or after) 'inline' means this function is not DECL_EXTERNAL, unless 'gnu_inline' attribute is present. */ if (TREE_CODE (newdecl) == FUNCTION_DECL - && flag_isoc99 + && !flag_gnu89_inline && (DECL_DECLARED_INLINE_P (newdecl) || DECL_DECLARED_INLINE_P (olddecl)) && (!DECL_DECLARED_INLINE_P (newdecl) @@ -1797,7 +1788,6 @@ merge_decls (tree newdecl, tree olddecl, && DECL_EXTERNAL (newdecl) && !lookup_attribute ("gnu_inline", DECL_ATTRIBUTES (newdecl))) DECL_EXTERNAL (newdecl) = 0; -#endif /* WANT_C99_INLINE_SEMANTICS */ if (DECL_EXTERNAL (newdecl)) { @@ -3309,10 +3299,9 @@ start_decl (struct c_declarator *declara /* Set attributes here so if duplicate decl, will have proper attributes. */ decl_attributes (&decl, attributes, 0); -#if WANT_C99_INLINE_SEMANTICS /* Handle gnu_inline attribute. */ if (declspecs->inline_p - && flag_isoc99 + && !flag_gnu89_inline && TREE_CODE (decl) == FUNCTION_DECL && lookup_attribute ("gnu_inline", DECL_ATTRIBUTES (decl))) { @@ -3321,7 +3310,6 @@ start_decl (struct c_declarator *declara else if (declspecs->storage_class != csc_static) DECL_EXTERNAL (decl) = !DECL_EXTERNAL (decl); } -#endif /* WANT_C99_INLINE_SEMANTICS */ if (TREE_CODE (decl) == FUNCTION_DECL && targetm.calls.promote_prototypes (TREE_TYPE (decl))) @@ -4819,11 +4807,8 @@ grokdeclarator (const struct c_declarato in this file, C99 6.7.4p6. In GNU C89, a function declared 'extern inline' is an external reference. */ else if (declspecs->inline_p && storage_class != csc_static) -#if WANT_C99_INLINE_SEMANTICS - DECL_EXTERNAL (decl) = (storage_class == csc_extern) == !flag_isoc99; -#else - DECL_EXTERNAL (decl) = (storage_class == csc_extern); -#endif + DECL_EXTERNAL (decl) = ((storage_class == csc_extern) + == flag_gnu89_inline); else DECL_EXTERNAL (decl) = !initialized; @@ -6085,17 +6070,15 @@ start_function (struct c_declspecs *decl warning (OPT_Wattributes, "inline function %q+D given attribute noinline", decl1); -#if WANT_C99_INLINE_SEMANTICS /* Handle gnu_inline attribute. */ if (declspecs->inline_p - && flag_isoc99 + && !flag_gnu89_inline && TREE_CODE (decl1) == FUNCTION_DECL && lookup_attribute ("gnu_inline", DECL_ATTRIBUTES (decl1))) { if (declspecs->storage_class != csc_static) DECL_EXTERNAL (decl1) = !DECL_EXTERNAL (decl1); } -#endif /* WANT_C99_INLINE_SEMANTICS */ announce_function (decl1); Index: gcc/c.opt =================================================================== --- gcc/c.opt (revision 122560) +++ gcc/c.opt (working copy) @@ -1,5 +1,5 @@ ; Options for the C, ObjC, C++ and ObjC++ front ends. -; Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +; Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. ; ; This file is part of GCC. ; @@ -554,6 +554,10 @@ fgnu-runtime ObjC ObjC++ Generate code for GNU runtime environment +fgnu89-inline +C Var(flag_gnu89_inline) Init(-1) +Use traditional GNU semantics for inline functions + fguiding-decls C++ ObjC++ Index: gcc/c-opts.c =================================================================== --- gcc/c-opts.c (revision 122560) +++ gcc/c-opts.c (working copy) @@ -1023,6 +1023,13 @@ c_common_post_options (const char **pfil if (flag_inline_functions) flag_inline_trees = 2; + /* By default we use C99 inline semantics in GNU99 or C99 mode. C99 + inline semantics are not supported in GNU89 or C89 mode. */ + if (flag_gnu89_inline == -1) + flag_gnu89_inline = !flag_isoc99; + else if (!flag_gnu89_inline && !flag_isoc99) + error ("-fno-gnu89-inline is only supported in GNU99 or C99 mode"); + /* If we are given more than one input file, we must use unit-at-a-time mode. */ if (num_in_fnames > 1)