This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[C++] fix alias and members


I've committed this patch to fix uses of the alias attribute with member functions. Broken out of the IFUNC patch as these are independent goodness.

built and tested on i686-pc-linux-gnu.

nathan
--
Nathan Sidwell    ::   http://www.codesourcery.com   ::         CodeSourcery

2010-06-08  Nathan Sidwell  <nathan@codesourcery.com>

	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.

Index: testsuite/g++.dg/ext/attr-alias-1.C
===================================================================
--- testsuite/g++.dg/ext/attr-alias-1.C	(revision 0)
+++ testsuite/g++.dg/ext/attr-alias-1.C	(revision 0)
@@ -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);
+}
Index: testsuite/g++.dg/ext/attr-alias-2.C
===================================================================
--- testsuite/g++.dg/ext/attr-alias-2.C	(revision 0)
+++ testsuite/g++.dg/ext/attr-alias-2.C	(revision 0)
@@ -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);
+}
Index: cp/decl.c
===================================================================
--- cp/decl.c	(revision 160427)
+++ cp/decl.c	(working copy)
@@ -90,6 +90,7 @@
 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 @@
   tree context;
   bool was_public;
   int flags;
+  bool alias;
 
   *pushed_scope_p = NULL_TREE;
 
@@ -4190,6 +4192,10 @@
       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 @@
 	    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 @@
   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 @@
   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 Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]