2007-10-01 Alexandre Oliva <aoliva@redhat.com>
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 3 Oct 2007 19:38:01 +0000 (19:38 +0000)
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 3 Oct 2007 19:38:01 +0000 (19:38 +0000)
* decl.c (duplicate_decls): Preserve linkage flags for mere
redeclarations of gnu_inline definitions.

* g++.dg/ext/gnu-inline-global-redecl.C: New.

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

gcc/cp/ChangeLog
gcc/cp/decl.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/ext/gnu-inline-global-redecl.C [new file with mode: 0644]
gcc/tree-ssa-ter.c

index 02d549f..2efe051 100644 (file)
@@ -1,3 +1,8 @@
+2007-10-03  Alexandre Oliva  <aoliva@redhat.com>
+
+       * decl.c (duplicate_decls): Preserve linkage flags for mere
+       redeclarations of gnu_inline definitions.
+
 2007-10-03  Jason Merrill  <jason@redhat.com>
 
        PR c++/15764
index d653fc4..83195af 100644 (file)
@@ -1846,24 +1846,24 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
   new_template = NULL_TREE;
   if (DECL_LANG_SPECIFIC (newdecl) && DECL_LANG_SPECIFIC (olddecl))
     {
-      bool old_decl_gnu_inline;
+      bool new_redefines_gnu_inline = false;
 
-      if ((DECL_INTERFACE_KNOWN (olddecl)
-          && TREE_CODE (olddecl) == FUNCTION_DECL)
-         || (TREE_CODE (olddecl) == TEMPLATE_DECL
-             && TREE_CODE (DECL_TEMPLATE_RESULT (olddecl)) == FUNCTION_DECL))
+      if (new_defines_function
+         && ((DECL_INTERFACE_KNOWN (olddecl)
+              && TREE_CODE (olddecl) == FUNCTION_DECL)
+             || (TREE_CODE (olddecl) == TEMPLATE_DECL
+                 && (TREE_CODE (DECL_TEMPLATE_RESULT (olddecl))
+                     == FUNCTION_DECL))))
        {
          tree fn = olddecl;
 
          if (TREE_CODE (fn) == TEMPLATE_DECL)
            fn = DECL_TEMPLATE_RESULT (olddecl);
 
-         old_decl_gnu_inline = GNU_INLINE_P (fn) && DECL_INITIAL (fn);
+         new_redefines_gnu_inline = GNU_INLINE_P (fn) && DECL_INITIAL (fn);
        }
-      else
-       old_decl_gnu_inline = false;
 
-      if (!old_decl_gnu_inline)
+      if (!new_redefines_gnu_inline)
        {
          DECL_INTERFACE_KNOWN (newdecl) |= DECL_INTERFACE_KNOWN (olddecl);
          DECL_NOT_REALLY_EXTERN (newdecl) |= DECL_NOT_REALLY_EXTERN (olddecl);
index 277c25d..0173411 100644 (file)
@@ -1,3 +1,7 @@
+2007-10-03  Alexandre Oliva  <aoliva@redhat.com>
+
+       * g++.dg/ext/gnu-inline-global-redecl.C: New.
+
 2007-10-03  Richard Sandiford  <rsandifo@nildram.co.uk>
 
        PR target/33635
diff --git a/gcc/testsuite/g++.dg/ext/gnu-inline-global-redecl.C b/gcc/testsuite/g++.dg/ext/gnu-inline-global-redecl.C
new file mode 100644 (file)
index 0000000..fc72d26
--- /dev/null
@@ -0,0 +1,19 @@
+/* Test __attribute__((gnu_inline)).
+
+   Check that we don't get out-of-line definitions for extern inline
+   gnu_inline functions, regardless of redeclaration.
+
+ */
+
+/* { dg-do link } */
+/* { dg-options "-O" } */ // such that static functions are optimized out
+
+#include "gnu-inline-common.h"
+
+decl(extern, fn)
+gnuindef(fn, 0)
+decl(extern, fn)
+
+int main () {
+  fn ();
+}
index f0fef24..424ccbe 100644 (file)
@@ -443,7 +443,7 @@ finished_with_expr (temp_expr_table_p tab, int version, bool free_expr)
 }
 
 
-/* Create an expression entry fora replaceable expression.  */
+/* Create an expression entry for a replaceable expression.  */
 
 static void 
 process_replaceable (temp_expr_table_p tab, tree stmt)