]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
decl.c (record_key_method_defined): New, broken out of ...
authorNathan Sidwell <nathan@codesourcery.com>
Tue, 8 Jun 2010 09:59:10 +0000 (09:59 +0000)
committerNathan Sidwell <nathan@gcc.gnu.org>
Tue, 8 Jun 2010 09:59:10 +0000 (09:59 +0000)
cp/
* decl.c (record_key_method_defined): New, broken out of ...
(finish_function): ... here.  Call it.
(start_decl): Treat aliases as definitions.

testsuite/
* g++.dg/ext/attr-alias-1.C: New.
* g++.dg/ext/attr-alias-2.C: New.

From-SVN: r160431

gcc/cp/ChangeLog
gcc/cp/decl.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/ext/attr-alias-1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/ext/attr-alias-2.C [new file with mode: 0644]

index 931cbe141ebee3e7ec2c777b7203bad0d120af42..3bb19a09af086224e803bb4e875b21968fbbb26c 100644 (file)
@@ -1,3 +1,9 @@
+2010-06-08  Nathan Sidwell  <nathan@codesourcery.com>
+
+       * decl.c (record_key_method_defined): New, broken out of ...
+       (finish_function): ... here.  Call it.  
+       (start_decl): Treat aliases as definitions.
+
 2010-06-08  Laurynas Biveinis  <laurynas.biveinis@gmail.com>
 
        * typeck2.c (abstract_virtuals_error): Use typed GC allocation.
index 706eee9b6669085cd2aedf19b6ac1995915cd6bf..ca3152f9caf6b6abb8f759c0c8fb34bfdbedf769 100644 (file)
@@ -90,6 +90,7 @@ static void check_function_type (tree, tree);
 static void finish_constructor_body (void);
 static void begin_destructor_body (void);
 static void finish_destructor_body (void);
+static void record_key_method_defined (tree);
 static tree create_array_type_for_decl (tree, tree, tree);
 static tree get_atexit_node (void);
 static tree get_dso_handle_node (void);
@@ -4129,6 +4130,7 @@ start_decl (const cp_declarator *declarator,
   tree context;
   bool was_public;
   int flags;
+  bool alias;
 
   *pushed_scope_p = NULL_TREE;
 
@@ -4190,6 +4192,10 @@ start_decl (const cp_declarator *declarator,
       if (toplevel_bindings_p ())
        TREE_STATIC (decl) = 1;
     }
+  alias = lookup_attribute ("alias", DECL_ATTRIBUTES (decl)) != 0;
+  
+  if (alias && TREE_CODE (decl) == FUNCTION_DECL)
+    record_key_method_defined (decl);
 
   /* If this is a typedef that names the class for linkage purposes
      (7.1.3p8), apply any attributes directly to the type.  */
@@ -4292,7 +4298,9 @@ start_decl (const cp_declarator *declarator,
            DECL_EXTERNAL (decl) = 1;
        }
 
-      if (DECL_EXTERNAL (decl) && ! DECL_TEMPLATE_SPECIALIZATION (decl))
+      if (DECL_EXTERNAL (decl) && ! DECL_TEMPLATE_SPECIALIZATION (decl)
+         /* Aliases are definitions. */
+         && !alias)
        permerror (input_location, "declaration of %q#D outside of class is not definition",
                   decl);
 
@@ -12502,6 +12510,22 @@ outer_curly_brace_block (tree fndecl)
   return block;
 }
 
+/* If FNDECL is a class's key method, add the class to the list of
+   keyed classes that should be emitted.  */
+
+static void
+record_key_method_defined (tree fndecl)
+{
+  if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fndecl)
+      && DECL_VIRTUAL_P (fndecl)
+      && !processing_template_decl)
+    {
+      tree fnclass = DECL_CONTEXT (fndecl);
+      if (fndecl == CLASSTYPE_KEY_METHOD (fnclass))
+       keyed_classes = tree_cons (NULL_TREE, fnclass, keyed_classes);
+    }
+}
+
 /* Finish up a function declaration and compile that function
    all the way to assembler language output.  The free the storage
    for the function definition.
@@ -12528,14 +12552,7 @@ finish_function (int flags)
   gcc_assert (!defer_mark_used_calls);
   defer_mark_used_calls = true;
 
-  if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fndecl)
-      && DECL_VIRTUAL_P (fndecl)
-      && !processing_template_decl)
-    {
-      tree fnclass = DECL_CONTEXT (fndecl);
-      if (fndecl == CLASSTYPE_KEY_METHOD (fnclass))
-       keyed_classes = tree_cons (NULL_TREE, fnclass, keyed_classes);
-    }
+  record_key_method_defined (fndecl);
 
   nested = function_depth > 1;
   fntype = TREE_TYPE (fndecl);
index 239ef3eead6e18c97a7b8a42304803bbcacde902..284bbc951fbb0664a1d4f9cf6fd7a02c6c461a34 100644 (file)
@@ -1,3 +1,8 @@
+2010-06-08  Nathan Sidwell  <nathan@codesourcery.com>
+
+       * g++.dg/ext/attr-alias-1.C: New.
+       * g++.dg/ext/attr-alias-2.C: New.
+
 2010-06-07  Tobias Burnus  <burnus@net-b.de>
 
        PR fortran/44446
diff --git a/gcc/testsuite/g++.dg/ext/attr-alias-1.C b/gcc/testsuite/g++.dg/ext/attr-alias-1.C
new file mode 100644 (file)
index 0000000..1427267
--- /dev/null
@@ -0,0 +1,37 @@
+/* { dg-do run }  */
+/* { dg-require-alias "" } */
+
+#include <typeinfo>
+
+struct Klass
+{
+  int implementation () const;
+  int magic () const;
+};
+
+int Klass::implementation (void) const
+{
+  return 0;
+}
+
+int Klass::magic () const
+  __attribute__ ((alias ("_ZNK5Klass14implementationEv")));
+
+int __attribute__ ((noinline))
+  Foo (Klass const *ptr)
+{
+  if (ptr->magic () != 0)
+    return 1;
+
+  if (typeid (*ptr) != typeid (Klass))
+    return 2;
+
+  return 0;
+}
+
+int main ()
+{
+  Klass obj;
+  
+  return Foo (&obj);
+}
diff --git a/gcc/testsuite/g++.dg/ext/attr-alias-2.C b/gcc/testsuite/g++.dg/ext/attr-alias-2.C
new file mode 100644 (file)
index 0000000..61a132f
--- /dev/null
@@ -0,0 +1,37 @@
+/* { dg-do run }  */
+/* { dg-require-alias "" } */
+
+#include <typeinfo>
+
+struct Klass
+{
+  int implementation () const;
+  virtual int magic () const;
+};
+
+int Klass::implementation (void) const
+{
+  return 0;
+}
+
+int Klass::magic () const
+  __attribute__ ((alias ("_ZNK5Klass14implementationEv")));
+
+int __attribute__ ((noinline))
+  Foo (Klass const *ptr)
+{
+  if (ptr->magic () != 0)
+    return 1;
+
+  if (typeid (*ptr) != typeid (Klass))
+    return 2;
+
+  return 0;
+}
+
+int main ()
+{
+  Klass obj;
+  
+  return Foo (&obj);
+}