attribs.c (handle_noinline_attribute): New function.
authorAlexandre Oliva <aoliva@redhat.com>
Thu, 18 Oct 2001 18:29:02 +0000 (18:29 +0000)
committerAlexandre Oliva <aoliva@gcc.gnu.org>
Thu, 18 Oct 2001 18:29:02 +0000 (18:29 +0000)
* 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

gcc/ChangeLog
gcc/attribs.c
gcc/c-decl.c
gcc/doc/extend.texi

index 75937f9695904daf8cca2e96f9c4005b8fbc05ba..a85d7ddd449f310cededeb0d1542938515e8f007 100644 (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
index 29982dec52972c7ab76ff2598203b7b4cb2272d1..3f8edcebd51f17a2dd3f97e642c09957189b353d 100644 (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.  */
 
index ee45b8ff72a837981d6de100fe11cafb612aca53..de553b185440a1f2a49a77fdb412500235aff840 100644 (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))))
index 132ccbad14fe1a02b480d5221fe69b5a107db6ed..f94950b21023a879e27652c1cc539eaedd8603db 100644 (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