aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorAlexandre Oliva <aoliva@redhat.com>2001-10-18 18:29:02 +0000
committerAlexandre Oliva <aoliva@gcc.gnu.org>2001-10-18 18:29:02 +0000
commit9162542e3d0cd270ab972615f66d7da16662466d (patch)
treeba59c40e9652d1cafe3687880cd7a3e173e06791 /gcc
parent97055d5c4e5ce6792523800bbd326313f81a48ef (diff)
downloadgcc-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/ChangeLog11
-rw-r--r--gcc/attribs.c53
-rw-r--r--gcc/c-decl.c55
-rw-r--r--gcc/doc/extend.texi28
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