diff options
author | Alexandre Oliva <aoliva@redhat.com> | 2001-10-18 18:29:02 +0000 |
---|---|---|
committer | Alexandre Oliva <aoliva@gcc.gnu.org> | 2001-10-18 18:29:02 +0000 |
commit | 9162542e3d0cd270ab972615f66d7da16662466d (patch) | |
tree | ba59c40e9652d1cafe3687880cd7a3e173e06791 /gcc | |
parent | 97055d5c4e5ce6792523800bbd326313f81a48ef (diff) | |
download | gcc-9162542e3d0cd270ab972615f66d7da16662466d.zip gcc-9162542e3d0cd270ab972615f66d7da16662466d.tar.gz gcc-9162542e3d0cd270ab972615f66d7da16662466d.tar.bz2 |
attribs.c (handle_noinline_attribute): New function.
* attribs.c (handle_noinline_attribute): New function.
(handle_used_attribute): Likewise.
(c_common_attribute_table): Added noinline and used.
* doc/extend.texi (Function Attributes): Document them.
* c-decl.c (duplicate_decls): Propagate DECL_UNINLINABLE.
Warn when merging inline with attribute noinline.
(start_decl, start_function): Warn if inline and attribute
noinline appear in the same declaration.
From-SVN: r46334
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 11 | ||||
-rw-r--r-- | gcc/attribs.c | 53 | ||||
-rw-r--r-- | gcc/c-decl.c | 55 | ||||
-rw-r--r-- | gcc/doc/extend.texi | 28 |
4 files changed, 138 insertions, 9 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 75937f9..a85d7dd 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2001-10-18 Alexandre Oliva <aoliva@redhat.com> + + * attribs.c (handle_noinline_attribute): New function. + (handle_used_attribute): Likewise. + (c_common_attribute_table): Added noinline and used. + * doc/extend.texi (Function Attributes): Document them. + * c-decl.c (duplicate_decls): Propagate DECL_UNINLINABLE. + Warn when merging inline with attribute noinline. + (start_decl, start_function): Warn if inline and attribute + noinline appear in the same declaration. + 2001-10-17 Neil Booth <neil@daikokuya.demon.co.uk> * config.gcc: Update c4x and i370 for C front end-specific diff --git a/gcc/attribs.c b/gcc/attribs.c index 29982de..3f8edce 100644 --- a/gcc/attribs.c +++ b/gcc/attribs.c @@ -49,6 +49,10 @@ static tree handle_common_attribute PARAMS ((tree *, tree, tree, int, bool *)); static tree handle_noreturn_attribute PARAMS ((tree *, tree, tree, int, bool *)); +static tree handle_noinline_attribute PARAMS ((tree *, tree, tree, int, + bool *)); +static tree handle_used_attribute PARAMS ((tree *, tree, tree, int, + bool *)); static tree handle_unused_attribute PARAMS ((tree *, tree, tree, int, bool *)); static tree handle_const_attribute PARAMS ((tree *, tree, tree, int, @@ -100,6 +104,10 @@ static const struct attribute_spec c_common_attribute_table[] = handle_noreturn_attribute }, { "volatile", 0, 0, true, false, false, handle_noreturn_attribute }, + { "noinline", 0, 0, true, false, false, + handle_noinline_attribute }, + { "used", 0, 0, true, false, false, + handle_used_attribute }, { "unused", 0, 0, false, false, false, handle_unused_attribute }, /* The same comments as for noreturn attributes apply to const ones. */ @@ -509,6 +517,51 @@ handle_noreturn_attribute (node, name, args, flags, no_add_attrs) return NULL_TREE; } +/* Handle a "noinline" attribute; arguments as in + struct attribute_spec.handler. */ + +static tree +handle_noinline_attribute (node, name, args, flags, no_add_attrs) + tree *node; + tree name; + tree args ATTRIBUTE_UNUSED; + int flags ATTRIBUTE_UNUSED; + bool *no_add_attrs; +{ + if (TREE_CODE (*node) == FUNCTION_DECL) + DECL_UNINLINABLE (*node) = 1; + else + { + warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name)); + *no_add_attrs = true; + } + + return NULL_TREE; +} + +/* Handle a "used" attribute; arguments as in + struct attribute_spec.handler. */ + +static tree +handle_used_attribute (node, name, args, flags, no_add_attrs) + tree *node; + tree name; + tree args ATTRIBUTE_UNUSED; + int flags ATTRIBUTE_UNUSED; + bool *no_add_attrs; +{ + if (TREE_CODE (*node) == FUNCTION_DECL) + TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (*node)) + = TREE_USED (*node) = 1; + else + { + warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name)); + *no_add_attrs = true; + } + + return NULL_TREE; +} + /* Handle a "unused" attribute; arguments as in struct attribute_spec.handler. */ diff --git a/gcc/c-decl.c b/gcc/c-decl.c index ee45b8f..de553b1 100644 --- a/gcc/c-decl.c +++ b/gcc/c-decl.c @@ -1405,8 +1405,43 @@ duplicate_decls (newdecl, olddecl, different_binding_level) int errmsg = 0; if (DECL_P (olddecl)) - DECL_ATTRIBUTES (newdecl) - = (*targetm.merge_decl_attributes) (olddecl, newdecl); + { + if (TREE_CODE (newdecl) == FUNCTION_DECL + && TREE_CODE (olddecl) == FUNCTION_DECL + && (DECL_UNINLINABLE (newdecl) || DECL_UNINLINABLE (olddecl))) + { + if (DECL_DECLARED_INLINE_P (newdecl) + && DECL_UNINLINABLE (newdecl) + && lookup_attribute ("noinline", DECL_ATTRIBUTES (newdecl))) + /* Already warned elsewhere. */; + else if (DECL_DECLARED_INLINE_P (olddecl) + && DECL_UNINLINABLE (olddecl) + && lookup_attribute ("noinline", DECL_ATTRIBUTES (olddecl))) + /* Already warned. */; + else if (DECL_DECLARED_INLINE_P (newdecl) + && ! DECL_DECLARED_INLINE_P (olddecl) + && DECL_UNINLINABLE (olddecl) + && lookup_attribute ("noinline", DECL_ATTRIBUTES (olddecl))) + { + warning_with_decl (newdecl, + "function `%s' redeclared as inline"); + warning_with_decl (olddecl, + "previous declaration of function `%s' with attribute noinline"); + } + else if (DECL_DECLARED_INLINE_P (olddecl) + && DECL_UNINLINABLE (newdecl) + && lookup_attribute ("noinline", DECL_ATTRIBUTES (newdecl))) + { + warning_with_decl (newdecl, + "function `%s' redeclared with attribute noinline"); + warning_with_decl (olddecl, + "previous declaration of function `%s' was inline"); + } + } + + DECL_ATTRIBUTES (newdecl) + = (*targetm.merge_decl_attributes) (olddecl, newdecl); + } if (TREE_CODE (newtype) == ERROR_MARK || TREE_CODE (oldtype) == ERROR_MARK) @@ -1983,6 +2018,9 @@ duplicate_decls (newdecl, olddecl, different_binding_level) DECL_DECLARED_INLINE_P (olddecl) = 1; DECL_DECLARED_INLINE_P (newdecl) = DECL_DECLARED_INLINE_P (olddecl); + + DECL_UNINLINABLE (newdecl) = DECL_UNINLINABLE (olddecl) + = (DECL_UNINLINABLE (newdecl) || DECL_UNINLINABLE (olddecl)); } if (DECL_BUILT_IN (olddecl)) @@ -3483,6 +3521,13 @@ start_decl (declarator, declspecs, initialized, attributes) /* Set attributes here so if duplicate decl, will have proper attributes. */ decl_attributes (&decl, attributes, 0); + if (TREE_CODE (decl) == FUNCTION_DECL + && DECL_DECLARED_INLINE_P (decl) + && DECL_UNINLINABLE (decl) + && lookup_attribute ("noinline", DECL_ATTRIBUTES (decl))) + warning_with_decl (decl, + "inline function `%s' given attribute noinline"); + /* Add this decl to the current binding level. TEM may equal DECL or it may be a previous decl of the same name. */ tem = pushdecl (decl); @@ -6022,6 +6067,12 @@ start_function (declspecs, declarator, attributes) decl_attributes (&decl1, attributes, 0); + if (DECL_DECLARED_INLINE_P (decl1) + && DECL_UNINLINABLE (decl1) + && lookup_attribute ("noinline", DECL_ATTRIBUTES (decl1))) + warning_with_decl (decl1, + "inline function `%s' given attribute noinline"); + announce_function (decl1); if (!COMPLETE_OR_VOID_TYPE_P (TREE_TYPE (TREE_TYPE (decl1)))) diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index 132ccba..f94950b 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -1925,13 +1925,14 @@ carefully. The keyword @code{__attribute__} allows you to specify special attributes when making a declaration. This keyword is followed by an -attribute specification inside double parentheses. Fourteen attributes, -@code{noreturn}, @code{pure}, @code{const}, @code{format}, -@code{format_arg}, @code{no_instrument_function}, @code{section}, -@code{constructor}, @code{destructor}, @code{unused}, @code{weak}, -@code{malloc}, @code{alias} and @code{no_check_memory_usage} are -currently defined for functions. Several other attributes are defined -for functions on particular target systems. Other attributes, including +attribute specification inside double parentheses. The following +attributs are currently defined for functions on all targets: +@code{noreturn}, @code{noinline}, @code{pure}, @code{const}, +@code{format}, @code{format_arg}, @code{no_instrument_function}, +@code{section}, @code{constructor}, @code{destructor}, @code{used}, +@code{unused}, @code{weak}, @code{malloc}, @code{alias} and +@code{no_check_memory_usage}. Several other attributes are defined for +functions on particular target systems. Other attributes, including @code{section} are supported for variables declarations (@pxref{Variable Attributes}) and for types (@pxref{Type Attributes}). @@ -1987,6 +1988,11 @@ typedef void voidfn (); volatile voidfn fatal; @end smallexample +@cindex @code{noinline} function attribute +@item noinline +This function attribute prevents a function from being considered for +inlining. + @cindex @code{pure} function attribute @item pure Many functions have no effects except the return value and their @@ -2174,12 +2180,20 @@ the program. These attributes are not currently implemented for Objective-C@. +@cindex @code{unused} attribute. @item unused This attribute, attached to a function, means that the function is meant to be possibly unused. GCC will not produce a warning for this function. GNU C++ does not currently support this attribute as definitions without parameters are valid in C++. +@cindex @code{used} attribute. +@item used +This attribute, attached to a function, means that code must be emitted +for the function even if it appears that the function is not referenced. +This is useful, for example, when the function is referenced only in +inline assembly. + @item weak @cindex @code{weak} attribute The @code{weak} attribute causes the declaration to be emitted as a weak |