Blame SOURCES/gcc34-weakref.patch

6fdc0f
2005-11-16  Alexandre Oliva  <aoliva@redhat.com>
6fdc0f
6fdc0f
	* c-common.c (handle_weakref_attribute): New.
6fdc0f
	(c_common_attribute_table): Add weakref.
6fdc0f
	* defaults.h (ASM_OUTPUT_WEAKREF): Define.
6fdc0f
	* doc/extend.texi: Document weakref attribute.
6fdc0f
	* varasm.c (do_assemble_alias): Handle weakrefs.
6fdc0f
	(finish_aliases_1): Do not reject weakrefs to external symbols.
6fdc0f
	* gthr-posix.h: Define __gthrw.  For all identifiers that
6fdc0f
	might be weak, introduce weakrefs or non-weak aliases with
6fdc0f
	__gthrw, and prefix all uses with __ghtrw.
6fdc0f
	* config/rs6000/rs6000.h (ASM_OUTPUT_WEAKREF): Define.
6fdc0f
6fdc0f
	* g++.old-deja/g++.ext/weakref1.C: New test.
6fdc0f
	* g++.old-deja/g++.ext/weakref1a.cc: New helper file.
6fdc0f
6fdc0f
	* thr-objc.c (_XOPEN_SOURCE): Define.
6fdc0f
6fdc0f
--- gcc/c-common.c.orig	2005-11-15 19:54:00.000000000 -0200
6fdc0f
+++ gcc/c-common.c	2005-11-15 19:54:02.000000000 -0200
6fdc0f
@@ -753,6 +753,7 @@
6fdc0f
 static tree handle_aligned_attribute (tree *, tree, tree, int, bool *);
6fdc0f
 static tree handle_weak_attribute (tree *, tree, tree, int, bool *) ;
6fdc0f
 static tree handle_alias_attribute (tree *, tree, tree, int, bool *);
6fdc0f
+static tree handle_weakref_attribute (tree *, tree, tree, int, bool *) ;
6fdc0f
 static tree handle_visibility_attribute (tree *, tree, tree, int,
6fdc0f
 					 bool *);
6fdc0f
 static tree handle_tls_model_attribute (tree *, tree, tree, int,
6fdc0f
@@ -825,6 +826,8 @@
6fdc0f
 			      handle_weak_attribute },
6fdc0f
   { "alias",                  1, 1, true,  false, false,
6fdc0f
 			      handle_alias_attribute },
6fdc0f
+  { "weakref",                0, 1, true,  false, false,
6fdc0f
+			      handle_weakref_attribute },
6fdc0f
   { "no_instrument_function", 0, 0, true,  false, false,
6fdc0f
 			      handle_no_instrument_function_attribute },
6fdc0f
   { "malloc",                 0, 0, true,  false, false,
6fdc0f
@@ -4988,7 +4991,12 @@
6fdc0f
       if (TREE_CODE (decl) == FUNCTION_DECL)
6fdc0f
 	DECL_INITIAL (decl) = error_mark_node;
6fdc0f
       else
6fdc0f
-	DECL_EXTERNAL (decl) = 0;
6fdc0f
+	{
6fdc0f
+	  if (lookup_attribute ("weakref", DECL_ATTRIBUTES (decl)))
6fdc0f
+	    DECL_EXTERNAL (decl) = 1;
6fdc0f
+	  else
6fdc0f
+	    DECL_EXTERNAL (decl) = 0;
6fdc0f
+	}
6fdc0f
     }
6fdc0f
   else
6fdc0f
     {
6fdc0f
@@ -4999,6 +5007,40 @@
6fdc0f
   return NULL_TREE;
6fdc0f
 }
6fdc0f
 
6fdc0f
+/* Handle a "weakref" attribute; arguments as in struct
6fdc0f
+   attribute_spec.handler.  */
6fdc0f
+
6fdc0f
+static tree
6fdc0f
+handle_weakref_attribute (tree *node, tree name ATTRIBUTE_UNUSED, tree args,
6fdc0f
+			  int flags, bool *no_add_attrs)
6fdc0f
+{
6fdc0f
+  tree attr = NULL_TREE;
6fdc0f
+
6fdc0f
+  /* The idea here is that `weakref("name")' mutates into `weakref,
6fdc0f
+     alias("name")', and weakref without arguments, in turn,
6fdc0f
+     implicitly adds weak. */
6fdc0f
+
6fdc0f
+  if (args)
6fdc0f
+    {
6fdc0f
+      attr = tree_cons (get_identifier ("alias"), args, attr);
6fdc0f
+      attr = tree_cons (get_identifier ("weakref"), NULL_TREE, attr);
6fdc0f
+
6fdc0f
+      *no_add_attrs = true;
6fdc0f
+    }
6fdc0f
+  else
6fdc0f
+    {
6fdc0f
+      if (lookup_attribute ("alias", DECL_ATTRIBUTES (*node)))
6fdc0f
+	error ("%Jweakref attribute must appear before alias attribute",
6fdc0f
+	       *node);
6fdc0f
+
6fdc0f
+      attr = tree_cons (get_identifier ("weak"), NULL_TREE, attr);
6fdc0f
+    }
6fdc0f
+
6fdc0f
+  decl_attributes (node, attr, flags);
6fdc0f
+
6fdc0f
+  return NULL_TREE;
6fdc0f
+}
6fdc0f
+
6fdc0f
 /* Handle an "visibility" attribute; arguments as in
6fdc0f
    struct attribute_spec.handler.  */
6fdc0f
 
6fdc0f
--- gcc/defaults.h.orig	2005-11-15 19:54:00.000000000 -0200
6fdc0f
+++ gcc/defaults.h	2005-11-16 13:35:20.000000000 -0200
6fdc0f
@@ -182,6 +182,25 @@
6fdc0f
 #endif
6fdc0f
 #endif
6fdc0f
 
6fdc0f
+/* This is how we tell the assembler that a symbol is a weak alias to
6fdc0f
+   another symbol that doesn't require the other symbol to be defined.
6fdc0f
+   Uses of the former will turn into weak uses of the latter, i.e.,
6fdc0f
+   uses that, in case the latter is undefined, will not cause errors,
6fdc0f
+   and will add it to the symbol table as weak undefined.  However, if
6fdc0f
+   the latter is referenced directly, a strong reference prevails.  */
6fdc0f
+#ifndef ASM_OUTPUT_WEAKREF
6fdc0f
+#define ASM_OUTPUT_WEAKREF(FILE, DECL, NAME, VALUE)			\
6fdc0f
+  do									\
6fdc0f
+    {									\
6fdc0f
+      fprintf ((FILE), "\t.weakref\t");					\
6fdc0f
+      assemble_name ((FILE), (NAME));					\
6fdc0f
+      fprintf ((FILE), ",");						\
6fdc0f
+      assemble_name ((FILE), (VALUE));					\
6fdc0f
+      fprintf ((FILE), "\n");						\
6fdc0f
+    }									\
6fdc0f
+  while (0)
6fdc0f
+#endif
6fdc0f
+
6fdc0f
 /* How to emit a .type directive.  */
6fdc0f
 #ifndef ASM_OUTPUT_TYPE_DIRECTIVE
6fdc0f
 #if defined TYPE_ASM_OP && defined TYPE_OPERAND_FMT
6fdc0f
--- gcc/doc/extend.texi.orig	2005-11-15 19:54:00.000000000 -0200
6fdc0f
+++ gcc/doc/extend.texi	2005-11-15 19:54:02.000000000 -0200
6fdc0f
@@ -2356,6 +2356,38 @@
6fdc0f
 for ELF targets, and also for a.out targets when using the GNU assembler
6fdc0f
 and linker.
6fdc0f
 
6fdc0f
+@item weakref
6fdc0f
+@itemx weakref ("@var{target}")
6fdc0f
+@cindex @code{weakref} attribute
6fdc0f
+The @code{weakref} attribute marks a declaration as a weak reference.
6fdc0f
+Without arguments, it should be accompanied by an @code{alias} attribute
6fdc0f
+naming the target symbol.  Optionally, the @var{target} may be given as
6fdc0f
+an argument to @code{weakref} itself.  In either case, @code{weakref}
6fdc0f
+implicitly marks the declaration as @code{weak}.  Without a
6fdc0f
+@var{target}, given as an argument to @code{weakref} or to @code{alias},
6fdc0f
+@code{weakref} is equivalent to @code{weak}.
6fdc0f
+
6fdc0f
+@smallexample
6fdc0f
+extern int x() __attribute__ ((weakref ("y")));
6fdc0f
+/* is equivalent to... */
6fdc0f
+extern int x() __attribute__ ((weak, weakref, alias ("y")));
6fdc0f
+/* and to... */
6fdc0f
+extern int x() __attribute__ ((weakref));
6fdc0f
+extern int x() __attribute__ ((alias ("y")));
6fdc0f
+@end smallexample
6fdc0f
+
6fdc0f
+A weak reference is an alias that does not by itself require a
6fdc0f
+definition to be given for the target symbol.  If the target symbol is
6fdc0f
+only referenced through weak references, then the becomes a @code{weak}
6fdc0f
+undefined symbol.  If it is directly referenced, however, then such
6fdc0f
+strong references prevail, and a definition will be required for the
6fdc0f
+symbol, not necessarily in the same translation unit.
6fdc0f
+
6fdc0f
+The effect is equivalent to moving all references to the alias to a
6fdc0f
+separate translation unit, renaming the alias to the aliased symbol,
6fdc0f
+declaring it as weak, compiling the two separate translation units and
6fdc0f
+performing a reloadable link on them.
6fdc0f
+
6fdc0f
 @item malloc
6fdc0f
 @cindex @code{malloc} attribute
6fdc0f
 The @code{malloc} attribute is used to tell the compiler that a function
6fdc0f
--- gcc/gthr-posix.h.orig	2005-11-15 19:54:00.000000000 -0200
6fdc0f
+++ gcc/gthr-posix.h	2005-11-15 19:54:34.000000000 -0200
6fdc0f
@@ -58,8 +58,56 @@
6fdc0f
 #define __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION __gthread_recursive_mutex_init_function
6fdc0f
 #endif
6fdc0f
 
6fdc0f
-#if SUPPORTS_WEAK && GTHREAD_USE_WEAK
6fdc0f
+#if SUPPORTS_WEAK && GTHREAD_USE_WEAK && defined __GNUC_RH_RELEASE__ \
6fdc0f
+    && ((__GNUC__ == 3 && __GNUC_MINOR__ == 4 && (__GNUC_PATCHLEVEL__ > 4 || (__GNUC_PATCHLEVEL__ == 4 && __GNUC_RH_RELEASE__ > 2))) \
6fdc0f
+	|| (__GNUC__ == 4 && __GNUC_MINOR__ == 0 && (__GNUC_PATCHLEVEL__ > 2 || (__GNUC_PATCHLEVEL__ == 2 && __GNUC_RH_RELEASE__ > 6)))) \
6fdc0f
+    && ! defined __attribute__
6fdc0f
+# define __gthrw(name) \
6fdc0f
+  extern __typeof(name) __gthrw_ ## name __attribute__ ((__weakref__(#name)))
6fdc0f
+
6fdc0f
+__gthrw(pthread_once);
6fdc0f
+__gthrw(pthread_key_create);
6fdc0f
+__gthrw(pthread_key_delete);
6fdc0f
+__gthrw(pthread_getspecific);
6fdc0f
+__gthrw(pthread_setspecific);
6fdc0f
+__gthrw(pthread_create);
6fdc0f
+
6fdc0f
+__gthrw(pthread_mutex_lock);
6fdc0f
+__gthrw(pthread_mutex_trylock);
6fdc0f
+__gthrw(pthread_mutex_unlock);
6fdc0f
+__gthrw(pthread_mutexattr_init);
6fdc0f
+__gthrw(pthread_mutexattr_settype);
6fdc0f
+__gthrw(pthread_mutexattr_destroy);
6fdc0f
+
6fdc0f
+__gthrw(pthread_mutex_init);
6fdc0f
 
6fdc0f
+# if defined(_LIBOBJC) || defined(_LIBOBJC_WEAK)
6fdc0f
+/* Objective-C.  */
6fdc0f
+__gthrw(pthread_cond_broadcast);
6fdc0f
+__gthrw(pthread_cond_destroy);
6fdc0f
+__gthrw(pthread_cond_init);
6fdc0f
+__gthrw(pthread_cond_signal);
6fdc0f
+__gthrw(pthread_cond_wait);
6fdc0f
+__gthrw(pthread_exit);
6fdc0f
+__gthrw(pthread_mutex_destroy);
6fdc0f
+__gthrw(pthread_self);
6fdc0f
+/* These really should be protected by _POSIX_PRIORITY_SCHEDULING, but
6fdc0f
+   we use them inside a _POSIX_THREAD_PRIORITY_SCHEDULING block.  */
6fdc0f
+#  ifdef _POSIX_THREAD_PRIORITY_SCHEDULING
6fdc0f
+__gthrw(sched_get_priority_max);
6fdc0f
+__gthrw(sched_get_priority_min);
6fdc0f
+#  endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */
6fdc0f
+__gthrw(sched_yield);
6fdc0f
+__gthrw(pthread_attr_destroy);
6fdc0f
+__gthrw(pthread_attr_init);
6fdc0f
+__gthrw(pthread_attr_setdetachstate);
6fdc0f
+#  ifdef _POSIX_THREAD_PRIORITY_SCHEDULING
6fdc0f
+__gthrw(pthread_getschedparam);
6fdc0f
+__gthrw(pthread_setschedparam);
6fdc0f
+#  endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */
6fdc0f
+# endif /* _LIBOBJC || _LIBOBJC_WEAK */
6fdc0f
+#else
6fdc0f
+# if SUPPORTS_WEAK && GTHREAD_USE_WEAK
6fdc0f
 #pragma weak pthread_once
6fdc0f
 #pragma weak pthread_key_create
6fdc0f
 #pragma weak pthread_key_delete
6fdc0f
@@ -101,11 +146,58 @@
6fdc0f
 #pragma weak pthread_setschedparam
6fdc0f
 #endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */
6fdc0f
 #endif /* _LIBOBJC || _LIBOBJC_WEAK */
6fdc0f
+#endif /* SUPPORTS_WEAK && GTHREAD_USE_WEAK */
6fdc0f
+
6fdc0f
+#define __gthrw_pthread_once pthread_once
6fdc0f
+#define __gthrw_pthread_key_create pthread_key_create
6fdc0f
+#define __gthrw_pthread_key_delete pthread_key_delete
6fdc0f
+#define __gthrw_pthread_getspecific pthread_getspecific
6fdc0f
+#define __gthrw_pthread_setspecific pthread_setspecific
6fdc0f
+#define __gthrw_pthread_create pthread_create
6fdc0f
+
6fdc0f
+#define __gthrw_pthread_mutex_lock pthread_mutex_lock
6fdc0f
+#define __gthrw_pthread_mutex_trylock pthread_mutex_trylock
6fdc0f
+#define __gthrw_pthread_mutex_unlock pthread_mutex_unlock
6fdc0f
+#define __gthrw_pthread_mutexattr_init pthread_mutexattr_init
6fdc0f
+#define __gthrw_pthread_mutexattr_settype pthread_mutexattr_settype
6fdc0f
+#define __gthrw_pthread_mutexattr_destroy pthread_mutexattr_destroy
6fdc0f
+
6fdc0f
+#define __gthrw_pthread_mutex_init pthread_mutex_init
6fdc0f
+
6fdc0f
+#if defined(_LIBOBJC) || defined(_LIBOBJC_WEAK)
6fdc0f
+/* Objective-C.  */
6fdc0f
+#define __gthrw_pthread_cond_broadcast pthread_cond_broadcast
6fdc0f
+#define __gthrw_pthread_cond_destroy pthread_cond_destroy
6fdc0f
+#define __gthrw_pthread_cond_init pthread_cond_init
6fdc0f
+#define __gthrw_pthread_cond_signal pthread_cond_signal
6fdc0f
+#define __gthrw_pthread_cond_wait pthread_cond_wait
6fdc0f
+#define __gthrw_pthread_exit pthread_exit
6fdc0f
+#define __gthrw_pthread_mutex_destroy pthread_mutex_destroy
6fdc0f
+#define __gthrw_pthread_self pthread_self
6fdc0f
+/* These really should be protected by _POSIX_PRIORITY_SCHEDULING, but
6fdc0f
+   we use them inside a _POSIX_THREAD_PRIORITY_SCHEDULING block.  */
6fdc0f
+#ifdef _POSIX_THREAD_PRIORITY_SCHEDULING
6fdc0f
+#define __gthrw_sched_get_priority_max sched_get_priority_max
6fdc0f
+#define __gthrw_sched_get_priority_min sched_get_priority_min
6fdc0f
+#endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */
6fdc0f
+#define __gthrw_sched_yield sched_yield
6fdc0f
+#define __gthrw_pthread_attr_destroy pthread_attr_destroy
6fdc0f
+#define __gthrw_pthread_attr_init pthread_attr_init
6fdc0f
+#define __gthrw_pthread_attr_setdetachstate pthread_attr_setdetachstate
6fdc0f
+#ifdef _POSIX_THREAD_PRIORITY_SCHEDULING
6fdc0f
+#define __gthrw_pthread_getschedparam pthread_getschedparam
6fdc0f
+#define __gthrw_pthread_setschedparam pthread_setschedparam
6fdc0f
+#endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */
6fdc0f
+#endif /* _LIBOBJC || _LIBOBJC_WEAK */
6fdc0f
+#endif
6fdc0f
+
6fdc0f
+
6fdc0f
+#if SUPPORTS_WEAK && GTHREAD_USE_WEAK
6fdc0f
 
6fdc0f
 static inline int
6fdc0f
 __gthread_active_p (void)
6fdc0f
 {
6fdc0f
-  static void *const __gthread_active_ptr = (void *) &pthread_create;
6fdc0f
+  static void *const __gthread_active_ptr = (void *) &__gthrw_pthread_create;
6fdc0f
   return __gthread_active_ptr != 0;
6fdc0f
 }
6fdc0f
 
6fdc0f
@@ -144,13 +236,13 @@
6fdc0f
   if (__gthread_active_p ())
6fdc0f
     {
6fdc0f
       /* Initialize the thread storage key */
6fdc0f
-      if (pthread_key_create (&_objc_thread_storage, NULL) == 0)
6fdc0f
+      if (__gthrw_pthread_key_create (&_objc_thread_storage, NULL) == 0)
6fdc0f
 	{
6fdc0f
 	  /* The normal default detach state for threads is
6fdc0f
 	   * PTHREAD_CREATE_JOINABLE which causes threads to not die
6fdc0f
 	   * when you think they should.  */
6fdc0f
-	  if (pthread_attr_init (&_objc_thread_attribs) == 0
6fdc0f
-	      && pthread_attr_setdetachstate (&_objc_thread_attribs,
6fdc0f
+	  if (__gthrw_pthread_attr_init (&_objc_thread_attribs) == 0
6fdc0f
+	      && __gthrw_pthread_attr_setdetachstate (&_objc_thread_attribs,
6fdc0f
 					      PTHREAD_CREATE_DETACHED) == 0)
6fdc0f
 	    return 0;
6fdc0f
 	}
6fdc0f
@@ -164,8 +256,8 @@
6fdc0f
 __gthread_objc_close_thread_system (void)
6fdc0f
 {
6fdc0f
   if (__gthread_active_p ()
6fdc0f
-      && pthread_key_delete (_objc_thread_storage) == 0
6fdc0f
-      && pthread_attr_destroy (&_objc_thread_attribs) == 0)
6fdc0f
+      && __gthrw_pthread_key_delete (_objc_thread_storage) == 0
6fdc0f
+      && __gthrw_pthread_attr_destroy (&_objc_thread_attribs) == 0)
6fdc0f
     return 0;
6fdc0f
 
6fdc0f
   return -1;
6fdc0f
@@ -183,7 +275,7 @@
6fdc0f
   if (!__gthread_active_p ())
6fdc0f
     return NULL;
6fdc0f
 
6fdc0f
-  if (!(pthread_create (&new_thread_handle, NULL, (void *) func, arg)))
6fdc0f
+  if (!(__gthrw_pthread_create (&new_thread_handle, NULL, (void *) func, arg)))
6fdc0f
     thread_id = (objc_thread_t) new_thread_handle;
6fdc0f
   else
6fdc0f
     thread_id = NULL;
6fdc0f
@@ -200,17 +292,17 @@
6fdc0f
   else
6fdc0f
     {
6fdc0f
 #ifdef _POSIX_THREAD_PRIORITY_SCHEDULING
6fdc0f
-      pthread_t thread_id = pthread_self ();
6fdc0f
+      pthread_t thread_id = __gthrw_pthread_self ();
6fdc0f
       int policy;
6fdc0f
       struct sched_param params;
6fdc0f
       int priority_min, priority_max;
6fdc0f
 
6fdc0f
-      if (pthread_getschedparam (thread_id, &policy, &params) == 0)
6fdc0f
+      if (__gthrw_pthread_getschedparam (thread_id, &policy, &params) == 0)
6fdc0f
 	{
6fdc0f
-	  if ((priority_max = sched_get_priority_max (policy)) == -1)
6fdc0f
+	  if ((priority_max = __gthrw_sched_get_priority_max (policy)) == -1)
6fdc0f
 	    return -1;
6fdc0f
 
6fdc0f
-	  if ((priority_min = sched_get_priority_min (policy)) == -1)
6fdc0f
+	  if ((priority_min = __gthrw_sched_get_priority_min (policy)) == -1)
6fdc0f
 	    return -1;
6fdc0f
 
6fdc0f
 	  if (priority > priority_max)
6fdc0f
@@ -224,7 +316,7 @@
6fdc0f
 	   * this should be a pointer to policy but pthread.h is universally
6fdc0f
 	   * at odds with this.
6fdc0f
 	   */
6fdc0f
-	  if (pthread_setschedparam (thread_id, policy, &params) == 0)
6fdc0f
+	  if (__gthrw_pthread_setschedparam (thread_id, policy, &params) == 0)
6fdc0f
 	    return 0;
6fdc0f
 	}
6fdc0f
 #endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */
6fdc0f
@@ -242,7 +334,7 @@
6fdc0f
       int policy;
6fdc0f
       struct sched_param params;
6fdc0f
 
6fdc0f
-      if (pthread_getschedparam (pthread_self (), &policy, &params) == 0)
6fdc0f
+      if (__gthrw_pthread_getschedparam (__gthrw_pthread_self (), &policy, &params) == 0)
6fdc0f
 	return params.sched_priority;
6fdc0f
       else
6fdc0f
 	return -1;
6fdc0f
@@ -257,7 +349,7 @@
6fdc0f
 __gthread_objc_thread_yield (void)
6fdc0f
 {
6fdc0f
   if (__gthread_active_p ())
6fdc0f
-    sched_yield ();
6fdc0f
+    __gthrw_sched_yield ();
6fdc0f
 }
6fdc0f
 
6fdc0f
 /* Terminate the current thread.  */
6fdc0f
@@ -266,7 +358,7 @@
6fdc0f
 {
6fdc0f
   if (__gthread_active_p ())
6fdc0f
     /* exit the thread */
6fdc0f
-    pthread_exit (&__objc_thread_exit_status);
6fdc0f
+    __gthrw_pthread_exit (&__objc_thread_exit_status);
6fdc0f
 
6fdc0f
   /* Failed if we reached here */
6fdc0f
   return -1;
6fdc0f
@@ -277,7 +369,7 @@
6fdc0f
 __gthread_objc_thread_id (void)
6fdc0f
 {
6fdc0f
   if (__gthread_active_p ())
6fdc0f
-    return (objc_thread_t) pthread_self ();
6fdc0f
+    return (objc_thread_t) __gthrw_pthread_self ();
6fdc0f
   else
6fdc0f
     return (objc_thread_t) 1;
6fdc0f
 }
6fdc0f
@@ -287,7 +379,7 @@
6fdc0f
 __gthread_objc_thread_set_data (void *value)
6fdc0f
 {
6fdc0f
   if (__gthread_active_p ())
6fdc0f
-    return pthread_setspecific (_objc_thread_storage, value);
6fdc0f
+    return __gthrw_pthread_setspecific (_objc_thread_storage, value);
6fdc0f
   else
6fdc0f
     {
6fdc0f
       thread_local_storage = value;
6fdc0f
@@ -300,7 +392,7 @@
6fdc0f
 __gthread_objc_thread_get_data (void)
6fdc0f
 {
6fdc0f
   if (__gthread_active_p ())
6fdc0f
-    return pthread_getspecific (_objc_thread_storage);
6fdc0f
+    return __gthrw_pthread_getspecific (_objc_thread_storage);
6fdc0f
   else
6fdc0f
     return thread_local_storage;
6fdc0f
 }
6fdc0f
@@ -315,7 +407,7 @@
6fdc0f
     {
6fdc0f
       mutex->backend = objc_malloc (sizeof (pthread_mutex_t));
6fdc0f
 
6fdc0f
-      if (pthread_mutex_init ((pthread_mutex_t *) mutex->backend, NULL))
6fdc0f
+      if (__gthrw_pthread_mutex_init ((pthread_mutex_t *) mutex->backend, NULL))
6fdc0f
 	{
6fdc0f
 	  objc_free (mutex->backend);
6fdc0f
 	  mutex->backend = NULL;
6fdc0f
@@ -336,18 +428,18 @@
6fdc0f
 
6fdc0f
       /*
6fdc0f
        * Posix Threads specifically require that the thread be unlocked
6fdc0f
-       * for pthread_mutex_destroy to work.
6fdc0f
+       * for __gthrw_pthread_mutex_destroy to work.
6fdc0f
        */
6fdc0f
 
6fdc0f
       do
6fdc0f
 	{
6fdc0f
-	  count = pthread_mutex_unlock ((pthread_mutex_t *) mutex->backend);
6fdc0f
+	  count = __gthrw_pthread_mutex_unlock ((pthread_mutex_t *) mutex->backend);
6fdc0f
 	  if (count < 0)
6fdc0f
 	    return -1;
6fdc0f
 	}
6fdc0f
       while (count);
6fdc0f
 
6fdc0f
-      if (pthread_mutex_destroy ((pthread_mutex_t *) mutex->backend))
6fdc0f
+      if (__gthrw_pthread_mutex_destroy ((pthread_mutex_t *) mutex->backend))
6fdc0f
 	return -1;
6fdc0f
 
6fdc0f
       objc_free (mutex->backend);
6fdc0f
@@ -361,7 +453,7 @@
6fdc0f
 __gthread_objc_mutex_lock (objc_mutex_t mutex)
6fdc0f
 {
6fdc0f
   if (__gthread_active_p ()
6fdc0f
-      && pthread_mutex_lock ((pthread_mutex_t *) mutex->backend) != 0)
6fdc0f
+      && __gthrw_pthread_mutex_lock ((pthread_mutex_t *) mutex->backend) != 0)
6fdc0f
     {
6fdc0f
       return -1;
6fdc0f
     }
6fdc0f
@@ -374,7 +466,7 @@
6fdc0f
 __gthread_objc_mutex_trylock (objc_mutex_t mutex)
6fdc0f
 {
6fdc0f
   if (__gthread_active_p ()
6fdc0f
-      && pthread_mutex_trylock ((pthread_mutex_t *) mutex->backend) != 0)
6fdc0f
+      && __gthrw_pthread_mutex_trylock ((pthread_mutex_t *) mutex->backend) != 0)
6fdc0f
     {
6fdc0f
       return -1;
6fdc0f
     }
6fdc0f
@@ -387,7 +479,7 @@
6fdc0f
 __gthread_objc_mutex_unlock (objc_mutex_t mutex)
6fdc0f
 {
6fdc0f
   if (__gthread_active_p ()
6fdc0f
-      && pthread_mutex_unlock ((pthread_mutex_t *) mutex->backend) != 0)
6fdc0f
+      && __gthrw_pthread_mutex_unlock ((pthread_mutex_t *) mutex->backend) != 0)
6fdc0f
     {
6fdc0f
       return -1;
6fdc0f
     }
6fdc0f
@@ -405,7 +497,7 @@
6fdc0f
     {
6fdc0f
       condition->backend = objc_malloc (sizeof (pthread_cond_t));
6fdc0f
 
6fdc0f
-      if (pthread_cond_init ((pthread_cond_t *) condition->backend, NULL))
6fdc0f
+      if (__gthrw_pthread_cond_init ((pthread_cond_t *) condition->backend, NULL))
6fdc0f
 	{
6fdc0f
 	  objc_free (condition->backend);
6fdc0f
 	  condition->backend = NULL;
6fdc0f
@@ -422,7 +514,7 @@
6fdc0f
 {
6fdc0f
   if (__gthread_active_p ())
6fdc0f
     {
6fdc0f
-      if (pthread_cond_destroy ((pthread_cond_t *) condition->backend))
6fdc0f
+      if (__gthrw_pthread_cond_destroy ((pthread_cond_t *) condition->backend))
6fdc0f
 	return -1;
6fdc0f
 
6fdc0f
       objc_free (condition->backend);
6fdc0f
@@ -436,7 +528,7 @@
6fdc0f
 __gthread_objc_condition_wait (objc_condition_t condition, objc_mutex_t mutex)
6fdc0f
 {
6fdc0f
   if (__gthread_active_p ())
6fdc0f
-    return pthread_cond_wait ((pthread_cond_t *) condition->backend,
6fdc0f
+    return __gthrw_pthread_cond_wait ((pthread_cond_t *) condition->backend,
6fdc0f
 			      (pthread_mutex_t *) mutex->backend);
6fdc0f
   else
6fdc0f
     return 0;
6fdc0f
@@ -447,7 +539,7 @@
6fdc0f
 __gthread_objc_condition_broadcast (objc_condition_t condition)
6fdc0f
 {
6fdc0f
   if (__gthread_active_p ())
6fdc0f
-    return pthread_cond_broadcast ((pthread_cond_t *) condition->backend);
6fdc0f
+    return __gthrw_pthread_cond_broadcast ((pthread_cond_t *) condition->backend);
6fdc0f
   else
6fdc0f
     return 0;
6fdc0f
 }
6fdc0f
@@ -457,7 +549,7 @@
6fdc0f
 __gthread_objc_condition_signal (objc_condition_t condition)
6fdc0f
 {
6fdc0f
   if (__gthread_active_p ())
6fdc0f
-    return pthread_cond_signal ((pthread_cond_t *) condition->backend);
6fdc0f
+    return __gthrw_pthread_cond_signal ((pthread_cond_t *) condition->backend);
6fdc0f
   else
6fdc0f
     return 0;
6fdc0f
 }
6fdc0f
@@ -468,7 +560,7 @@
6fdc0f
 __gthread_once (__gthread_once_t *once, void (*func) (void))
6fdc0f
 {
6fdc0f
   if (__gthread_active_p ())
6fdc0f
-    return pthread_once (once, func);
6fdc0f
+    return __gthrw_pthread_once (once, func);
6fdc0f
   else
6fdc0f
     return -1;
6fdc0f
 }
6fdc0f
@@ -476,32 +568,32 @@
6fdc0f
 static inline int
6fdc0f
 __gthread_key_create (__gthread_key_t *key, void (*dtor) (void *))
6fdc0f
 {
6fdc0f
-  return pthread_key_create (key, dtor);
6fdc0f
+  return __gthrw_pthread_key_create (key, dtor);
6fdc0f
 }
6fdc0f
 
6fdc0f
 static inline int
6fdc0f
 __gthread_key_delete (__gthread_key_t key)
6fdc0f
 {
6fdc0f
-  return pthread_key_delete (key);
6fdc0f
+  return __gthrw_pthread_key_delete (key);
6fdc0f
 }
6fdc0f
 
6fdc0f
 static inline void *
6fdc0f
 __gthread_getspecific (__gthread_key_t key)
6fdc0f
 {
6fdc0f
-  return pthread_getspecific (key);
6fdc0f
+  return __gthrw_pthread_getspecific (key);
6fdc0f
 }
6fdc0f
 
6fdc0f
 static inline int
6fdc0f
 __gthread_setspecific (__gthread_key_t key, const void *ptr)
6fdc0f
 {
6fdc0f
-  return pthread_setspecific (key, ptr);
6fdc0f
+  return __gthrw_pthread_setspecific (key, ptr);
6fdc0f
 }
6fdc0f
 
6fdc0f
 static inline int
6fdc0f
 __gthread_mutex_lock (__gthread_mutex_t *mutex)
6fdc0f
 {
6fdc0f
   if (__gthread_active_p ())
6fdc0f
-    return pthread_mutex_lock (mutex);
6fdc0f
+    return __gthrw_pthread_mutex_lock (mutex);
6fdc0f
   else
6fdc0f
     return 0;
6fdc0f
 }
6fdc0f
@@ -510,7 +602,7 @@
6fdc0f
 __gthread_mutex_trylock (__gthread_mutex_t *mutex)
6fdc0f
 {
6fdc0f
   if (__gthread_active_p ())
6fdc0f
-    return pthread_mutex_trylock (mutex);
6fdc0f
+    return __gthrw_pthread_mutex_trylock (mutex);
6fdc0f
   else
6fdc0f
     return 0;
6fdc0f
 }
6fdc0f
@@ -519,7 +611,7 @@
6fdc0f
 __gthread_mutex_unlock (__gthread_mutex_t *mutex)
6fdc0f
 {
6fdc0f
   if (__gthread_active_p ())
6fdc0f
-    return pthread_mutex_unlock (mutex);
6fdc0f
+    return __gthrw_pthread_mutex_unlock (mutex);
6fdc0f
   else
6fdc0f
     return 0;
6fdc0f
 }
6fdc0f
@@ -533,13 +625,13 @@
6fdc0f
       pthread_mutexattr_t attr;
6fdc0f
       int r;
6fdc0f
 
6fdc0f
-      r = pthread_mutexattr_init (&attr);
6fdc0f
+      r = __gthrw_pthread_mutexattr_init (&attr);
6fdc0f
       if (!r)
6fdc0f
-	r = pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE);
6fdc0f
+	r = __gthrw_pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE);
6fdc0f
       if (!r)
6fdc0f
-	r = pthread_mutex_init (mutex, &attr);
6fdc0f
+	r = __gthrw_pthread_mutex_init (mutex, &attr);
6fdc0f
       if (!r)
6fdc0f
-	r = pthread_mutexattr_destroy (&attr);
6fdc0f
+	r = __gthrw_pthread_mutexattr_destroy (&attr);
6fdc0f
       return r;
6fdc0f
     }
6fdc0f
 }
6fdc0f
--- gcc/varasm.c.orig	2005-11-15 19:54:00.000000000 -0200
6fdc0f
+++ gcc/varasm.c	2005-11-16 13:32:07.000000000 -0200
6fdc0f
@@ -4393,6 +4393,9 @@
6fdc0f
       if (! TREE_USED (decl))
6fdc0f
 	continue;
6fdc0f
 
6fdc0f
+      if (lookup_attribute ("weakref", DECL_ATTRIBUTES (decl)))
6fdc0f
+	continue;
6fdc0f
+
6fdc0f
 #ifdef ASM_WEAKEN_DECL
6fdc0f
       ASM_WEAKEN_DECL (asm_out_file, decl, name, NULL);
6fdc0f
 #else
6fdc0f
@@ -4506,6 +4509,18 @@
6fdc0f
      we don't use it here.  */
6fdc0f
   make_decl_rtl (decl, NULL);
6fdc0f
 
6fdc0f
+  if (lookup_attribute ("weakref", DECL_ATTRIBUTES (decl)))
6fdc0f
+    {
6fdc0f
+#ifdef ASM_OUTPUT_WEAKREF
6fdc0f
+      ASM_OUTPUT_WEAKREF (asm_out_file, decl,
6fdc0f
+			  IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)),
6fdc0f
+			  IDENTIFIER_POINTER (target));
6fdc0f
+#else
6fdc0f
+      error ("%Jweakref is not supported in this configuration", decl);
6fdc0f
+#endif
6fdc0f
+      return;
6fdc0f
+    }
6fdc0f
+
6fdc0f
 #ifdef ASM_OUTPUT_DEF
6fdc0f
   /* Make name accessible from other files, if appropriate.  */
6fdc0f
 
6fdc0f
--- libobjc/thr-objc.c.orig	2005-11-15 19:54:00.000000000 -0200
6fdc0f
+++ libobjc/thr-objc.c	2005-11-15 19:54:02.000000000 -0200
6fdc0f
@@ -24,6 +24,10 @@
6fdc0f
    covered by the GNU General Public License.  */
6fdc0f
 
6fdc0f
 #define _LIBOBJC
6fdc0f
+/* The line below is needed for declarations of functions such as
6fdc0f
+   pthread_mutexattr_settype, without which gthr-posix.h may fail to
6fdc0f
+   compile within libobjc.  */
6fdc0f
+#define _XOPEN_SOURCE 500
6fdc0f
 #include "tconfig.h"
6fdc0f
 #include "coretypes.h"
6fdc0f
 #include "tm.h"
6fdc0f
--- gcc/testsuite/g++.old-deja/g++.ext/weakref1.C	1970-01-01 00:00:00.000000000 +0000
6fdc0f
+++ gcc/testsuite/g++.old-deja/g++.ext/weakref1.C	2005-11-15 19:54:02.000000000 -0200
6fdc0f
@@ -0,0 +1,228 @@
6fdc0f
+// { dg-do run }
6fdc0f
+// { dg-additional-sources " weakref1a.cc" }
6fdc0f
+// { dg-require-weak "" }
6fdc0f
+// { dg-options "-O2" }
6fdc0f
+
6fdc0f
+// Copyright 2005 Free Software Foundation, Inc.
6fdc0f
+// Contributed by Alexandre Oliva <aoliva@redhat.com>
6fdc0f
+
6fdc0f
+// Torture test for weakrefs.  The first letter of an identifier
6fdc0f
+// indicates whether/how it is defined; the second letter indicates
6fdc0f
+// whether it is part of a variable or function test; the number that
6fdc0f
+// follows is a test counter, and a letter that may follow enables
6fdc0f
+// multiple identifiers within the same test (e.g., multiple weakrefs
6fdc0f
+// or pointers to the same identifier).
6fdc0f
+
6fdc0f
+// Identifiers starting with W are weakrefs; those with p are
6fdc0f
+// pointers; those with g are global definitions; those with l are
6fdc0f
+// local definitions; those with w are expected to be weak undefined
6fdc0f
+// in the symbol table; those with u are expected to be marked as
6fdc0f
+// non-weak undefined in the symbol table.
6fdc0f
+
6fdc0f
+#include <stdlib.h>
6fdc0f
+
6fdc0f
+#define USED __attribute__((used))
6fdc0f
+
6fdc0f
+extern "C" {
6fdc0f
+typedef int vtype;
6fdc0f
+
6fdc0f
+extern vtype wv1;
6fdc0f
+extern vtype Wv1a __attribute__((weakref ("wv1")));
6fdc0f
+static vtype *pv1a USED = &Wv1a;
6fdc0f
+extern vtype Wv1b __attribute__((weak, weakref, alias ("wv1")));
6fdc0f
+static vtype *pv1b USED = &Wv1b;
6fdc0f
+extern vtype Wv1c __attribute__((weakref));
6fdc0f
+extern vtype Wv1c __attribute__((alias ("wv1")));
6fdc0f
+static vtype *pv1c USED = &Wv1c;
6fdc0f
+
6fdc0f
+vtype gv2;
6fdc0f
+extern vtype Wv2a __attribute__((weakref ("gv2")));
6fdc0f
+static vtype *pv2a USED = &Wv2a;
6fdc0f
+
6fdc0f
+static vtype lv3;
6fdc0f
+extern vtype Wv3a __attribute__((weakref ("lv3")));
6fdc0f
+static vtype *pv3a USED = &Wv3a;
6fdc0f
+
6fdc0f
+extern vtype uv4;
6fdc0f
+extern vtype Wv4a __attribute__((weakref ("uv4")));
6fdc0f
+static vtype *pv4a USED = &Wv4a;
6fdc0f
+static vtype *pv4 USED = &uv;;
6fdc0f
+
6fdc0f
+extern vtype Wv5a __attribute__((weakref ("uv5")));
6fdc0f
+static vtype *pv5a USED = &Wv5a;
6fdc0f
+extern vtype uv5;
6fdc0f
+static vtype *pv5 USED = &uv;;
6fdc0f
+
6fdc0f
+extern vtype Wv6a __attribute__((weakref ("wv6")));
6fdc0f
+static vtype *pv6a USED = &Wv6a;
6fdc0f
+extern vtype wv6;
6fdc0f
+
6fdc0f
+extern vtype Wv7a __attribute__((weakref ("uv7")));
6fdc0f
+static vtype* USED fv7 (void) {
6fdc0f
+  return &Wv7a;
6fdc0f
+}
6fdc0f
+extern vtype uv7;
6fdc0f
+static vtype* USED fv7a (void) {
6fdc0f
+  return &uv;;
6fdc0f
+}
6fdc0f
+
6fdc0f
+extern vtype uv8;
6fdc0f
+static vtype* USED fv8a (void) {
6fdc0f
+  return &uv;;
6fdc0f
+}
6fdc0f
+extern vtype Wv8a __attribute__((weakref ("uv8")));
6fdc0f
+static vtype* USED fv8 (void) {
6fdc0f
+  return &Wv8a;
6fdc0f
+}
6fdc0f
+
6fdc0f
+extern vtype wv9 __attribute__((weak));
6fdc0f
+extern vtype Wv9a __attribute__((weakref ("wv9")));
6fdc0f
+static vtype *pv9a USED = &Wv9a;
6fdc0f
+
6fdc0f
+extern vtype Wv10a __attribute__((weakref ("Wv10b")));
6fdc0f
+extern vtype Wv10b __attribute__((weakref ("Wv10c")));
6fdc0f
+extern vtype Wv10c __attribute__((weakref ("Wv10d")));
6fdc0f
+extern vtype Wv10d __attribute__((weakref ("wv10")));
6fdc0f
+extern vtype wv10;
6fdc0f
+
6fdc0f
+extern vtype wv11;
6fdc0f
+extern vtype Wv11d __attribute__((weakref ("wv11")));
6fdc0f
+extern vtype Wv11c __attribute__((weakref ("Wv11d")));
6fdc0f
+extern vtype Wv11b __attribute__((weakref ("Wv11c")));
6fdc0f
+extern vtype Wv11a __attribute__((weakref ("Wv11b")));
6fdc0f
+
6fdc0f
+extern vtype Wv12 __attribute__((weakref ("wv12")));
6fdc0f
+extern vtype wv12 __attribute__((weak));
6fdc0f
+
6fdc0f
+extern vtype Wv13 __attribute__((weakref ("wv13")));
6fdc0f
+extern vtype wv13 __attribute__((weak));
6fdc0f
+
6fdc0f
+extern vtype Wv14a __attribute__((weakref ("wv14")));
6fdc0f
+extern vtype Wv14b __attribute__((weakref ("wv14")));
6fdc0f
+extern vtype wv14 __attribute__((weak));
6fdc0f
+
6fdc0f
+typedef void ftype(void);
6fdc0f
+
6fdc0f
+extern ftype wf1;
6fdc0f
+extern ftype Wf1a __attribute__((weakref ("wf1")));
6fdc0f
+static ftype *pf1a USED = &Wf1;;
6fdc0f
+extern ftype Wf1b __attribute__((weak, weakref, alias ("wf1")));
6fdc0f
+static ftype *pf1b USED = &Wf1;;
6fdc0f
+extern ftype Wf1c __attribute__((weakref));
6fdc0f
+extern ftype Wf1c __attribute__((alias ("wf1")));
6fdc0f
+static ftype *pf1c USED = &Wf1;;
6fdc0f
+
6fdc0f
+void gf2(void) {}
6fdc0f
+extern ftype Wf2a __attribute__((weakref ("gf2")));
6fdc0f
+static ftype *pf2a USED = &Wf2;;
6fdc0f
+
6fdc0f
+static void lf3(void) {}
6fdc0f
+extern ftype Wf3a __attribute__((weakref ("lf3")));
6fdc0f
+static ftype *pf3a USED = &Wf3;;
6fdc0f
+
6fdc0f
+extern ftype uf4;
6fdc0f
+extern ftype Wf4a __attribute__((weakref ("uf4")));
6fdc0f
+static ftype *pf4a USED = &Wf4;;
6fdc0f
+static ftype *pf4 USED = &uf4;
6fdc0f
+
6fdc0f
+extern ftype Wf5a __attribute__((weakref ("uf5")));
6fdc0f
+static ftype *pf5a USED = &Wf5;;
6fdc0f
+extern ftype uf5;
6fdc0f
+static ftype *pf5 USED = &uf5;
6fdc0f
+
6fdc0f
+extern ftype Wf6a __attribute__((weakref ("wf6")));
6fdc0f
+static ftype *pf6a USED = &Wf6;;
6fdc0f
+extern ftype wf6;
6fdc0f
+
6fdc0f
+extern ftype Wf7a __attribute__((weakref ("uf7")));
6fdc0f
+static ftype* USED ff7 (void) {
6fdc0f
+  return &Wf7;;
6fdc0f
+}
6fdc0f
+extern ftype uf7;
6fdc0f
+static ftype* USED ff7a (void) {
6fdc0f
+  return &uf7;
6fdc0f
+}
6fdc0f
+
6fdc0f
+extern ftype uf8;
6fdc0f
+static ftype* USED ff8a (void) {
6fdc0f
+  return &uf8;
6fdc0f
+}
6fdc0f
+extern ftype Wf8a __attribute__((weakref ("uf8")));
6fdc0f
+static ftype* USED ff8 (void) {
6fdc0f
+  return &Wf8;;
6fdc0f
+}
6fdc0f
+
6fdc0f
+extern ftype wf9 __attribute__((weak));
6fdc0f
+extern ftype Wf9a __attribute__((weakref ("wf9")));
6fdc0f
+static ftype *pf9a USED = &Wf9;;
6fdc0f
+
6fdc0f
+extern ftype Wf10a __attribute__((weakref ("Wf10b")));
6fdc0f
+extern ftype Wf10b __attribute__((weakref ("Wf10c")));
6fdc0f
+extern ftype Wf10c __attribute__((weakref ("Wf10d")));
6fdc0f
+extern ftype Wf10d __attribute__((weakref ("wf10")));
6fdc0f
+extern ftype wf10;
6fdc0f
+
6fdc0f
+extern ftype wf11;
6fdc0f
+extern ftype Wf11d __attribute__((weakref ("wf11")));
6fdc0f
+extern ftype Wf11c __attribute__((weakref ("Wf11d")));
6fdc0f
+extern ftype Wf11b __attribute__((weakref ("Wf11c")));
6fdc0f
+extern ftype Wf11a __attribute__((weakref ("Wf11b")));
6fdc0f
+
6fdc0f
+extern ftype Wf12 __attribute__((weakref ("wf12")));
6fdc0f
+extern ftype wf12 __attribute__((weak));
6fdc0f
+
6fdc0f
+extern ftype Wf13 __attribute__((weakref ("wf13")));
6fdc0f
+extern ftype wf13 __attribute__((weak));
6fdc0f
+
6fdc0f
+extern ftype Wf14a __attribute__((weakref ("wf14")));
6fdc0f
+extern ftype Wf14b __attribute__((weakref ("wf14")));
6fdc0f
+extern ftype wf14 __attribute__((weak));
6fdc0f
+}
6fdc0f
+
6fdc0f
+#define chk(p) do { if (!p) abort (); } while (0)
6fdc0f
+
6fdc0f
+int main () {
6fdc0f
+  chk (!pv1a);
6fdc0f
+  chk (!pv1b);
6fdc0f
+  chk (!pv1c);
6fdc0f
+  chk (pv2a);
6fdc0f
+  chk (pv3a);
6fdc0f
+  chk (pv4a);
6fdc0f
+  chk (pv4);
6fdc0f
+  chk (pv5a);
6fdc0f
+  chk (pv5);
6fdc0f
+  chk (!pv6a);
6fdc0f
+  chk (fv7 ());
6fdc0f
+  chk (fv7a ());
6fdc0f
+  chk (fv8 ());
6fdc0f
+  chk (fv8a ());
6fdc0f
+  chk (!pv9a);
6fdc0f
+  chk (!&Wv10a);
6fdc0f
+  chk (!&Wv11a);
6fdc0f
+  chk (!&Wv12);
6fdc0f
+  chk (!&wv12);
6fdc0f
+  chk (!&wv13);
6fdc0f
+  chk (!&Wv14a);
6fdc0f
+
6fdc0f
+  chk (!pf1a);
6fdc0f
+  chk (!pf1b);
6fdc0f
+  chk (!pf1c);
6fdc0f
+  chk (pf2a);
6fdc0f
+  chk (pf3a);
6fdc0f
+  chk (pf4a);
6fdc0f
+  chk (pf4);
6fdc0f
+  chk (pf5a);
6fdc0f
+  chk (pf5);
6fdc0f
+  chk (!pf6a);
6fdc0f
+  chk (ff7 ());
6fdc0f
+  chk (ff7a ());
6fdc0f
+  chk (ff8 ());
6fdc0f
+  chk (ff8a ());
6fdc0f
+  chk (!pf9a);
6fdc0f
+  chk (!&Wf10a);
6fdc0f
+  chk (!&Wf11a);
6fdc0f
+  chk (!&Wf12);
6fdc0f
+  chk (!&wf12);
6fdc0f
+  chk (!&wf13);
6fdc0f
+  chk (!&Wf14a);
6fdc0f
+}
6fdc0f
--- gcc/testsuite/g++.old-deja/g++.ext/weakref1a.cc	1970-01-01 00:00:00.000000000 +0000
6fdc0f
+++ gcc/testsuite/g++.old-deja/g++.ext/weakref1a.cc	2005-11-15 19:54:02.000000000 -0200
6fdc0f
@@ -0,0 +1,10 @@
6fdc0f
+extern "C" {
6fdc0f
+int uv4;
6fdc0f
+int uv5;
6fdc0f
+int uv7;
6fdc0f
+int uv8;
6fdc0f
+void uf4 (void) {}
6fdc0f
+void uf5 (void) {}
6fdc0f
+void uf7 (void) {}
6fdc0f
+void uf8 (void) {}
6fdc0f
+}
6fdc0f
--- gcc/config/rs6000/rs6000.h.orig	2005-11-16 13:29:07.000000000 -0200
6fdc0f
+++ gcc/config/rs6000/rs6000.h	2005-11-16 14:10:04.000000000 -0200
6fdc0f
@@ -2383,6 +2383,24 @@
6fdc0f
   while (0)
6fdc0f
 #endif
6fdc0f
 
6fdc0f
+#define ASM_OUTPUT_WEAKREF(FILE, DECL, NAME, VALUE)			\
6fdc0f
+  do									\
6fdc0f
+    {									\
6fdc0f
+      fputs ("\t.weakref\t", (FILE));					\
6fdc0f
+      RS6000_OUTPUT_BASENAME ((FILE), (NAME)); 				\
6fdc0f
+      fputs (", ", (FILE));						\
6fdc0f
+      RS6000_OUTPUT_BASENAME ((FILE), (VALUE));				\
6fdc0f
+      if ((DECL) && TREE_CODE (DECL) == FUNCTION_DECL			\
6fdc0f
+	  && DEFAULT_ABI == ABI_AIX && DOT_SYMBOLS)			\
6fdc0f
+	{								\
6fdc0f
+	  fputs ("\n\t.weakref\t.", (FILE));				\
6fdc0f
+	  RS6000_OUTPUT_BASENAME ((FILE), (NAME)); 			\
6fdc0f
+	  fputs (", .", (FILE));					\
6fdc0f
+	  RS6000_OUTPUT_BASENAME ((FILE), (VALUE));			\
6fdc0f
+	}								\
6fdc0f
+      fputc ('\n', (FILE));						\
6fdc0f
+    } while (0)
6fdc0f
+
6fdc0f
 /* This implements the `alias' attribute.  */
6fdc0f
 #undef	ASM_OUTPUT_DEF_FROM_DECLS
6fdc0f
 #define	ASM_OUTPUT_DEF_FROM_DECLS(FILE, DECL, TARGET)			\