OSDN Git Service

PR c/5163:
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 24 Dec 2001 08:45:59 +0000 (08:45 +0000)
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 24 Dec 2001 08:45:59 +0000 (08:45 +0000)
        * c-decl.c (duplicate_decls): As needed, set DECL_INLINE when
        we have a function body associated.  Minor cleanups.
        (grokdeclarator): Do not set DECL_INLINE without a function body.

        * gcc.dg/20011223-1.c: New.
        * gcc.dg/inline-1.c: New.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@48302 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/c-decl.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/20011223-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/inline-1.c [new file with mode: 0644]

index 7df5b18..c526245 100644 (file)
@@ -1,5 +1,12 @@
 2001-12-23  Richard Henderson  <rth@redhat.com>
 
+       PR c/5163:
+       * c-decl.c (duplicate_decls): As needed, set DECL_INLINE when
+       we have a function body associated.  Minor cleanups.
+       (grokdeclarator): Do not set DECL_INLINE without a function body.
+
+2001-12-23  Richard Henderson  <rth@redhat.com>
+
        * stmt.c (resolve_operand_names): Handle operand modifiers.
 
 2001-12-23  Richard Henderson  <rth@redhat.com>
index c7e1e0a..495425b 100644 (file)
@@ -1974,10 +1974,8 @@ duplicate_decls (newdecl, olddecl, different_binding_level)
          /* If either decl says `inline', this fn is inline,
             unless its definition was passed already.  */
          if (DECL_DECLARED_INLINE_P (newdecl)
-             && DECL_DECLARED_INLINE_P (olddecl) == 0)
-           DECL_DECLARED_INLINE_P (olddecl) = 1;
-
-         DECL_DECLARED_INLINE_P (newdecl) = DECL_DECLARED_INLINE_P (olddecl);
+             || DECL_DECLARED_INLINE_P (olddecl))
+           DECL_DECLARED_INLINE_P (newdecl) = 1;
 
          DECL_UNINLINABLE (newdecl) = DECL_UNINLINABLE (olddecl)
            = (DECL_UNINLINABLE (newdecl) || DECL_UNINLINABLE (olddecl));
@@ -2003,9 +2001,8 @@ duplicate_decls (newdecl, olddecl, different_binding_level)
              DECL_FUNCTION_CODE (newdecl) = DECL_FUNCTION_CODE (olddecl);
            }
        }
+
       /* Also preserve various other info from the definition.  */
-      else if (! new_is_definition)
-       DECL_NUM_STMTS (newdecl) = DECL_NUM_STMTS (olddecl);
       if (! new_is_definition)
        {
          DECL_RESULT (newdecl) = DECL_RESULT (olddecl);
@@ -2016,12 +2013,27 @@ duplicate_decls (newdecl, olddecl, different_binding_level)
            DECL_INITIAL (newdecl) = DECL_INITIAL (olddecl);
          DECL_SAVED_INSNS (newdecl) = DECL_SAVED_INSNS (olddecl);
          DECL_SAVED_TREE (newdecl) = DECL_SAVED_TREE (olddecl);
+         DECL_NUM_STMTS (newdecl) = DECL_NUM_STMTS (olddecl);
          DECL_ARGUMENTS (newdecl) = DECL_ARGUMENTS (olddecl);
-         if (DECL_INLINE (newdecl))
-           DECL_ABSTRACT_ORIGIN (newdecl)
-             = (different_binding_level
-                ? DECL_ORIGIN (olddecl)
-                : DECL_ABSTRACT_ORIGIN (olddecl));
+
+         /* Set DECL_INLINE on the declaration if we've got a body
+            from which to instantiate.  */
+         if (DECL_INLINE (olddecl) && ! DECL_UNINLINABLE (newdecl))
+           {
+             DECL_INLINE (newdecl) = 1;
+             DECL_ABSTRACT_ORIGIN (newdecl)
+               = (different_binding_level
+                  ? DECL_ORIGIN (olddecl)
+                  : DECL_ABSTRACT_ORIGIN (olddecl));
+           }
+       }
+      else
+       {
+         /* If a previous declaration said inline, mark the
+            definition as inlinable.  */
+         if (DECL_DECLARED_INLINE_P (newdecl)
+             && ! DECL_UNINLINABLE (newdecl))
+           DECL_INLINE (newdecl) = 1;
        }
     }
   if (different_binding_level)
@@ -5049,16 +5061,23 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
        else if (inlinep)
          {
            /* Assume that otherwise the function can be inlined.  */
-           DECL_INLINE (decl) = 1;
            DECL_DECLARED_INLINE_P (decl) = 1;
 
-           if (specbits & (1 << (int) RID_EXTERN))
-             current_extern_inline = 1;
+           /* Do not mark bare declarations as DECL_INLINE.  Doing so
+              in the presence of multiple declarations can result in
+              the abstract origin pointing between the declarations,
+              which will confuse dwarf2out.  */
+           if (initialized)
+             {
+               DECL_INLINE (decl) = 1;
+               if (specbits & (1 << (int) RID_EXTERN))
+                 current_extern_inline = 1;
+             }
          }
        /* If -finline-functions, assume it can be inlined.  This does
           two things: let the function be deferred until it is actually
           needed, and let dwarf2 know that the function is inlinable.  */
-       else if (flag_inline_trees == 2)
+       else if (flag_inline_trees == 2 && initialized)
          {
            DECL_INLINE (decl) = 1;
            DECL_DECLARED_INLINE_P (decl) = 0;
index cddb9ab..c2bb361 100644 (file)
@@ -1,3 +1,8 @@
+2001-12-24  Richard Henderson  <rth@redhat.com>
+
+       * gcc.dg/20011223-1.c: New.
+       * gcc.dg/inline-1.c: New.
+
 2001-12-23  Richard Henderson  <rth@redhat.com>
 
        * gcc.dg/asm-4.c: Test operand modifiers.
diff --git a/gcc/testsuite/gcc.dg/20011223-1.c b/gcc/testsuite/gcc.dg/20011223-1.c
new file mode 100644 (file)
index 0000000..53f7f20
--- /dev/null
@@ -0,0 +1,12 @@
+/* Origin: PR c/5163 from aj@suse.de.  */
+/* { dg-do compile } */
+/* { dg-options "-O3 -g" } */
+
+extern int bar (int);
+
+int
+foo (void)
+{
+  extern int bar (int);
+  return bar (5);
+}
diff --git a/gcc/testsuite/gcc.dg/inline-1.c b/gcc/testsuite/gcc.dg/inline-1.c
new file mode 100644 (file)
index 0000000..17a9a2f
--- /dev/null
@@ -0,0 +1,28 @@
+/* Verify that DECL_INLINE gets copied between DECLs properly.  */
+/* { dg-do compile } */
+/* { dg-options "-O1" } */
+/* { dg-final { scan-assembler-not "xyzzy" } } */
+
+/* Test that declaration followed by definition inlines.  */
+static inline int xyzzy0 (int);
+static int xyzzy0 (int x) { return x; }
+int test0 (void)
+{
+  return xyzzy0 (5);
+}
+
+/* Test that definition following declaration inlines.  */
+static int xyzzy1 (int);
+static inline int xyzzy1 (int x) { return x; }
+int test1 (void)
+{
+  return xyzzy1 (5);
+}
+
+/* Test that redeclaration inside a function body inlines.  */
+extern inline int xyzzy2 (int x) { return x; }
+int test2 (void)
+{
+  extern int xyzzy2 (int);
+  return xyzzy2 (5);
+}