c.opt (fgnu89-inline): New option.

* 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__.

From-SVN: r122565
This commit is contained in:
Ian Lance Taylor 2007-03-05 19:45:20 +00:00 committed by Ian Lance Taylor
parent 3b6d448dbc
commit da1c7394b3
13 changed files with 259 additions and 35 deletions

View File

@ -1,3 +1,22 @@
2007-03-05 Ian Lance Taylor <iant@google.com>
* 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__.
2007-03-05 Ian Lance Taylor <iant@google.com>
PR tree-optimization/31034

View File

@ -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

View File

@ -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, Fifth Floor, Boston, MA
#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, tree olddecl,
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, tree olddecl,
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, tree newtype, tree oldtype)
}
}
#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, tree newtype, tree oldtype)
&& 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 *declarator, struct c_declspecs *declspecs,
/* 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 *declarator, struct c_declspecs *declspecs,
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_declarator *declarator,
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 *declspecs, struct c_declarator *declarator,
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);

View File

@ -1023,6 +1023,13 @@ c_common_post_options (const char **pfilename)
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)

View File

@ -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++

View File

@ -2014,6 +2014,28 @@ functions. You should not use these macros in any way unless you make
sure that programs will execute with the same effect whether or not they
are defined. If they are defined, their value is 1.
@item __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
@code{static} will always be compiled as a standalone function.
@item __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
@code{extern 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:
@code{inline} functions will be compiled in gnu89 mode, and the
@code{gnu_inline} 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

View File

@ -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
@code{inline}. Since ISO C99 specifies a different semantics for
@code{inline}, 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
@code{__GNUC_STDC_INLINE__} 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 ``simple enough'' functions
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
@option{-std=c99} or @option{-std=gnu99}, and the third is used when
compiling C++.
inline. One is available with @option{-std=gnu89} or
@option{-fgnu89-inline} or when @code{gnu_inline} attribute is present
on all inline declarations, another when @option{-std=c99} or
@option{-std=gnu99} (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:

View File

@ -166,7 +166,8 @@ in the following sections.
@item C Language Options
@xref{C Dialect Options,,Options Controlling C Dialect}.
@gccoptlist{-ansi -std=@var{standard} -aux-info @var{filename} @gol
@gccoptlist{-ansi -std=@var{standard} -fgnu89-inline @gol
-aux-info @var{filename} @gol
-fno-asm -fno-builtin -fno-builtin-@var{function} @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) are not disabled.
@xref{Standards,,Language Standards Supported by GCC}, for details of
these standard versions.
@item -fgnu89-inline
@opindex fgnu89-inline
The option @option{-fgnu89-inline} tells GCC to use the traditional
GNU semantics for @code{inline} functions when in C99 mode.
@xref{Inline,,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
@code{gnu_inline} 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
@code{__GNUC_STDC_INLINE__} 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

View File

@ -1,3 +1,10 @@
2007-03-05 Ian Lance Taylor <iant@google.com>
* 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.
2007-03-05 Richard Guenther <rguenther@suse.de>
PR tree-optimization/14052

View File

@ -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; }

View File

@ -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; }

View File

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

View File

@ -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 } */