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
This commit is contained in:
Alexandre Oliva 2001-10-18 18:29:02 +00:00 committed by Alexandre Oliva
parent 97055d5c4e
commit 9162542e3d
4 changed files with 138 additions and 9 deletions

View File

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

View File

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

View File

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

View File

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