c-decl.c: Include c-pragma.h.
authorRichard Henderson <rth@redhat.com>
Fri, 15 Mar 2002 07:11:14 +0000 (23:11 -0800)
committerRichard Henderson <rth@gcc.gnu.org>
Fri, 15 Mar 2002 07:11:14 +0000 (23:11 -0800)
        * c-decl.c: Include c-pragma.h.
        (start_decl, start_function): Invoke maybe_apply_pragma_weak.
        (finish_function): Tidy.
        * c-pragma.c: Include c-common.h.
        (pending_weaks, apply_pragma_weak, maybe_apply_pragma_weak): New.
        (handle_pragma_weak): Use them.
        (init_pragma): Register pending_weaks.
        * c-pragma.h (maybe_apply_pragma_weak): Declare.
        * print-tree.c (print_node): Print DECL_WEAK.
        * varasm.c (mark_weak_decls): Remove.
        (remove_from_pending_weak_list): Remove.
        (add_weak): Remove.
        (asm_emit_uninitialised): Call globalize_decl for weak commons.
        (weak_decls): Make a tree_list.
        (declare_weak): Cons weak_decls directly.
        (globalize_decl): Remove weak_decls elements directly.
        (weak_finish): Simplify weak_decls walk.  Don't weaken unused
        symbols.  Don't pretend to handle aliases.
        (init_varasm_once): Update weak_decls registry.
* Makefile.in: Update dependencies.

        * cp/decl.c: Include c-pragma.h.
        (start_decl, start_function): Invoke maybe_apply_pragma_weak.
* cp/Make-lang.in: Update dependencies.

* gcc.dg/weak-1.c: New.

From-SVN: r50797

gcc/ChangeLog
gcc/Makefile.in
gcc/c-decl.c
gcc/c-pragma.c
gcc/c-pragma.h
gcc/cp/ChangeLog
gcc/cp/Make-lang.in
gcc/cp/decl.c
gcc/print-tree.c
gcc/testsuite/gcc.dg/weak-1.c [new file with mode: 0644]
gcc/varasm.c

index 558a1897bfabce89ea52f7ec12aa26715493bac2..a1f9c16f4203827c0ba03a6d4c81b5fbe5e7d0bf 100644 (file)
@@ -1,3 +1,26 @@
+2002-03-14  Richard Henderson  <rth@redhat.com>
+
+       * c-decl.c: Include c-pragma.h.
+       (start_decl, start_function): Invoke maybe_apply_pragma_weak.
+       (finish_function): Tidy.
+       * c-pragma.c: Include c-common.h.
+       (pending_weaks, apply_pragma_weak, maybe_apply_pragma_weak): New.
+       (handle_pragma_weak): Use them.
+       (init_pragma): Register pending_weaks.
+       * c-pragma.h (maybe_apply_pragma_weak): Declare.
+       * print-tree.c (print_node): Print DECL_WEAK.
+       * varasm.c (mark_weak_decls): Remove.
+       (remove_from_pending_weak_list): Remove.
+       (add_weak): Remove.
+       (asm_emit_uninitialised): Call globalize_decl for weak commons.
+       (weak_decls): Make a tree_list.
+       (declare_weak): Cons weak_decls directly.
+       (globalize_decl): Remove weak_decls elements directly.
+       (weak_finish): Simplify weak_decls walk.  Don't weaken unused
+       symbols.  Don't pretend to handle aliases.
+       (init_varasm_once): Update weak_decls registry.
+       * Makefile.in: Update dependencies.
+
 2002-03-14  Richard Henderson  <rth@redhat.com>
 
        PR target/5312
index 2cb9f84a2eb7ce01ec1ee42f0c15a11a94274476..df8281f945e52796f210fbce499a6ca12118d4a1 100644 (file)
@@ -1148,7 +1148,7 @@ $(srcdir)/c-parse.y: c-parse.in
 
 c-decl.o : c-decl.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(RTL_H) $(C_TREE_H) \
     $(GGC_H) $(TARGET_H) c-lex.h flags.h function.h output.h $(EXPR_H) \
-    debug.h toplev.h intl.h $(TM_P_H) tree-inline.h $(TIMEVAR_H)
+    debug.h toplev.h intl.h $(TM_P_H) tree-inline.h $(TIMEVAR_H) c-pragma.h
 c-typeck.o : c-typeck.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(C_TREE_H) \
     $(TARGET_H) flags.h intl.h output.h $(EXPR_H) $(RTL_H) toplev.h $(TM_P_H)
 c-lang.o : c-lang.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(C_TREE_H) \
@@ -1165,7 +1165,7 @@ c-aux-info.o : c-aux-info.c  $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(C_TREE_H) \
     flags.h toplev.h
 c-convert.o : c-convert.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) flags.h toplev.h
 c-pragma.o: c-pragma.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) function.h \
-    c-pragma.h toplev.h output.h $(GGC_H) $(TM_P_H)
+    c-pragma.h toplev.h output.h $(GGC_H) $(TM_P_H) $(C_COMMON_H)
 mbchar.o: mbchar.c $(CONFIG_H) $(SYSTEM_H) mbchar.h
 graph.o: graph.c $(CONFIG_H) $(SYSTEM_H) toplev.h flags.h output.h $(RTL_H) \
     function.h hard-reg-set.h $(BASIC_BLOCK_H) graph.h
index d15f47e4baac48248c977ba6a3edff81ff5a2e83..9242b03b3f996a74304c1f5ccba1e645eed377ef 100644 (file)
@@ -46,6 +46,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "debug.h"
 #include "timevar.h"
 #include "c-common.h"
+#include "c-pragma.h"
 
 /* In grokdeclarator, distinguish syntactic contexts of declarators.  */
 enum decl_context
@@ -3403,6 +3404,10 @@ start_decl (declarator, declspecs, initialized, attributes)
   /* Set attributes here so if duplicate decl, will have proper attributes.  */
   decl_attributes (&decl, attributes, 0);
 
+  /* If #pragma weak was used, mark the decl weak now.  */
+  if (current_binding_level == global_binding_level)
+    maybe_apply_pragma_weak (decl);
+
   if (TREE_CODE (decl) == FUNCTION_DECL
       && DECL_DECLARED_INLINE_P (decl)
       && DECL_UNINLINABLE (decl)
@@ -6042,6 +6047,10 @@ start_function (declspecs, declarator, attributes)
 
   decl_attributes (&decl1, attributes, 0);
 
+  /* If #pragma weak was used, mark the decl weak now.  */
+  if (current_binding_level == global_binding_level)
+    maybe_apply_pragma_weak (decl1);
+
   if (DECL_DECLARED_INLINE_P (decl1)
       && DECL_UNINLINABLE (decl1)
       && lookup_attribute ("noinline", DECL_ATTRIBUTES (decl1)))
@@ -6691,9 +6700,11 @@ finish_function (nested)
 {
   tree fndecl = current_function_decl;
 
-/*  TREE_READONLY (fndecl) = 1;
-    This caused &foo to be of type ptr-to-const-function
-    which then got a warning when stored in a ptr-to-function variable.  */
+#if 0
+  /* This caused &foo to be of type ptr-to-const-function which then
+     got a warning when stored in a ptr-to-function variable.  */
+  TREE_READONLY (fndecl) = 1;
+#endif
 
   poplevel (1, 0, 1);
   BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl;
@@ -6755,6 +6766,7 @@ finish_function (nested)
     {
       /* Generate RTL for the body of this function.  */
       c_expand_body (fndecl, nested, 1);
+
       /* Let the error reporting routines know that we're outside a
         function.  For a nested function, this value is used in
         pop_c_function_context and then reset via pop_function_context.  */
index 26bf27735f14d0bf848ed5a6966fb566a8b8ccdc..1a17e67f1c51cd81ee865e5b864b4db7dd84bbb6 100644 (file)
@@ -30,6 +30,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "toplev.h"
 #include "ggc.h"
 #include "c-lex.h"
+#include "c-common.h"
 #include "output.h"
 #include "tm_p.h"
 
@@ -55,9 +56,9 @@ static struct align_stack * alignment_stack = NULL;
    maximum_field_alignment in effect.  When the final pop_alignment() 
    happens, we restore the value to this, not to a value of 0 for
    maximum_field_alignment.  Value is in bits.  */
-static int  default_alignment;
+static int default_alignment;
 #define SET_GLOBAL_ALIGNMENT(ALIGN) \
-(default_alignment = maximum_field_alignment = (ALIGN))
+  (default_alignment = maximum_field_alignment = (ALIGN))
 
 static void push_alignment PARAMS ((int, tree));
 static void pop_alignment  PARAMS ((tree));
@@ -69,7 +70,6 @@ push_alignment (alignment, id)
      int alignment;
      tree id;
 {
-  
   if (alignment_stack == NULL
       || alignment_stack->alignment != alignment
       || id != NULL_TREE)
@@ -274,14 +274,53 @@ handle_pragma_pack (dummy)
 #endif  /* HANDLE_PRAGMA_PACK */
 
 #ifdef HANDLE_PRAGMA_WEAK
+static void apply_pragma_weak PARAMS ((tree, tree));
 static void handle_pragma_weak PARAMS ((cpp_reader *));
 
+static tree pending_weaks;
+
+static void
+apply_pragma_weak (decl, value)
+     tree decl, value;
+{
+  if (value)
+    decl_attributes (&decl, build_tree_list (get_identifier ("alias"),
+                                            build_tree_list (NULL, value)),
+                    0);
+  declare_weak (decl);
+}
+
+void
+maybe_apply_pragma_weak (decl)
+     tree decl;
+{
+  tree *p, t, id;
+
+  /* Copied from the check in set_decl_assembler_name.  */
+  if (TREE_CODE (decl) == FUNCTION_DECL
+      || (TREE_CODE (decl) == VAR_DECL 
+          && (TREE_STATIC (decl) 
+              || DECL_EXTERNAL (decl) 
+              || TREE_PUBLIC (decl))))
+    id = DECL_ASSEMBLER_NAME (decl);
+  else
+    return;
+
+  for (p = &pending_weaks; (t = *p) ; p = &TREE_CHAIN (t))
+    if (id == TREE_PURPOSE (t))
+      {
+       apply_pragma_weak (decl, TREE_VALUE (t));
+       *p = TREE_CHAIN (t);
+       break;
+      }
+}
+
 /* #pragma weak name [= value] */
 static void
 handle_pragma_weak (dummy)
      cpp_reader *dummy ATTRIBUTE_UNUSED;
 {
-  tree name, value, x;
+  tree name, value, x, decl;
   enum cpp_ttype t;
 
   value = 0;
@@ -298,10 +337,19 @@ handle_pragma_weak (dummy)
   if (t != CPP_EOF)
     warning ("junk at end of #pragma weak");
 
-  add_weak (NULL_TREE, IDENTIFIER_POINTER (name),
-           value ? IDENTIFIER_POINTER (value) : NULL);
+  decl = identifier_global_value (name);
+  if (decl && TREE_CODE_CLASS (TREE_CODE (decl)) == 'd')
+    apply_pragma_weak (decl, value);
+  else
+    pending_weaks = tree_cons (name, value, pending_weaks);
 }
-#endif
+#else
+void
+maybe_apply_pragma_weak (decl)
+     tree decl ATTRIBUTE_UNUSED;
+{
+}
+#endif /* HANDLE_PRAGMA_WEAK */
 
 void
 init_pragma ()
@@ -311,6 +359,7 @@ init_pragma ()
 #endif
 #ifdef HANDLE_PRAGMA_WEAK
   cpp_register_pragma (parse_in, 0, "weak", handle_pragma_weak);
+  ggc_add_tree_root (&pending_weaks, 1);
 #endif
 #ifdef REGISTER_TARGET_PRAGMAS
   REGISTER_TARGET_PRAGMAS (parse_in);
index 8d0c4f585019ffd15047c68fc3a9c44bec33d9dd..ea5a9826d6149f0b6315be7c779bc2a63dfdd8ff 100644 (file)
@@ -53,4 +53,6 @@ extern void cpp_register_pragma PARAMS ((cpp_reader *,
                                         void (*) PARAMS ((cpp_reader *))));
 #endif
 
+extern void maybe_apply_pragma_weak PARAMS ((tree));
+
 #endif /* GCC_C_PRAGMA_H */
index 79fd46f8bee16fc5dc841432e0aee0e5421ede21..2c9b1e55df235156b72ba10189f7f0cf323c2d83 100644 (file)
@@ -1,3 +1,9 @@
+2002-03-14  Richard Henderson  <rth@redhat.com>
+
+       * decl.c: Include c-pragma.h.
+       (start_decl, start_function): Invoke maybe_apply_pragma_weak.
+       * Make-lang.in: Update dependencies.
+
 2002-03-14  Jakub Jelinek  <jakub@redhat.com>
 
        PR c++/5908
index 1e721b6ac5665859dc5e5e8e69a18f000d552928..a4e8299382e8bf2a77ce925adb55339a762d9b53 100644 (file)
@@ -255,7 +255,7 @@ cp/cp-lang.o: cp/cp-lang.c $(CXX_TREE_H) toplev.h langhooks.h langhooks-def.h \
   c-common.h
 cp/decl.o: cp/decl.c $(CXX_TREE_H) flags.h cp/lex.h cp/decl.h stack.h \
   output.h $(EXPR_H) except.h toplev.h hash.h $(GGC_H) $(RTL_H) \
-  cp/operators.def $(TM_P_H) tree-inline.h diagnostic.h
+  cp/operators.def $(TM_P_H) tree-inline.h diagnostic.h c-pragma.h
 cp/decl2.o: cp/decl2.c $(CXX_TREE_H) flags.h cp/lex.h cp/decl.h $(EXPR_H) \
   output.h except.h toplev.h $(GGC_H) $(RTL_H)
 cp/typeck2.o: cp/typeck2.c $(CXX_TREE_H) flags.h toplev.h output.h $(TM_P_H) \
index 12028df385d2b48b05a39b2bcc738f69f0b70854..a1f128ff95c87902d987cf144b1ba5250a43566a 100644 (file)
@@ -46,6 +46,7 @@ Boston, MA 02111-1307, USA.  */
 #include "tm_p.h"
 #include "target.h"
 #include "c-common.h"
+#include "c-pragma.h"
 #include "diagnostic.h"
 
 extern const struct attribute_spec *lang_attribute_table;
@@ -7256,6 +7257,10 @@ start_decl (declarator, declspecs, initialized, attributes, prefix_attributes)
   /* Set attributes here so if duplicate decl, will have proper attributes.  */
   cplus_decl_attributes (&decl, attributes, 0);
 
+  /* If #pragma weak was used, mark the decl weak now.  */
+  if (current_binding_level == global_binding_level)
+    maybe_apply_pragma_weak (decl);
+
   if (TREE_CODE (decl) == FUNCTION_DECL
       && DECL_DECLARED_INLINE_P (decl)
       && DECL_UNINLINABLE (decl)
@@ -13476,6 +13481,10 @@ start_function (declspecs, declarator, attrs, flags)
 
       cplus_decl_attributes (&decl1, attrs, 0);
 
+      /* If #pragma weak was used, mark the decl weak now.  */
+      if (current_binding_level == global_binding_level)
+       maybe_apply_pragma_weak (decl1);
+
       fntype = TREE_TYPE (decl1);
 
       restype = TREE_TYPE (fntype);
index e5627e2bfa5f5f0d100e552d8dde9b9ffa868253..f5c7d88c1f618b32b44be194e6bf2991559e2606 100644 (file)
@@ -317,6 +317,8 @@ print_node (file, prefix, node, indent)
        fputs (" common", file);
       if (DECL_EXTERNAL (node))
        fputs (" external", file);
+      if (DECL_WEAK (node))
+       fputs (" weak", file);
       if (DECL_REGISTER (node) && TREE_CODE (node) != FIELD_DECL
          && TREE_CODE (node) != FUNCTION_DECL
          && TREE_CODE (node) != LABEL_DECL)
diff --git a/gcc/testsuite/gcc.dg/weak-1.c b/gcc/testsuite/gcc.dg/weak-1.c
new file mode 100644 (file)
index 0000000..95e56f0
--- /dev/null
@@ -0,0 +1,51 @@
+/* { dg-do compile } */
+/* COFF does not support weak, and dg doesn't support UNSUPPORTED.  */
+/* { dg-do compile { xfail *-*-coff i?86-pc-cygwin } } */
+
+/* { dg-final { scan-assembler "weak[^         ]*[     ]_?a" } } */
+/* { dg-final { scan-assembler "weak[^         ]*[     ]_?b" } } */
+/* { dg-final { scan-assembler "weak[^         ]*[     ]_?c" } } */
+/* { dg-final { scan-assembler "weak[^         ]*[     ]_?d" } } */
+/* { dg-final { scan-assembler "weak[^         ]*[     ]_?e" } } */
+/* { dg-final { scan-assembler "weak[^         ]*[     ]_?g" } } */
+/* { dg-final { scan-assembler-not "weak[^     ]*[     ]_?i" } } */
+/* { dg-final { scan-assembler "weak[^         ]*[     ]_?j" } } */
+
+#pragma weak a
+int a;
+
+int b;
+#pragma weak b
+
+#pragma weak c
+extern int c;
+int c;
+
+extern int d;
+#pragma weak d
+int d;
+
+#pragma weak e
+void e(void) { }
+
+#if 0
+/* This permutation is illegal.  */
+void f(void) { }
+#pragma weak f
+#endif
+
+#pragma weak g
+int g = 1;
+
+#if 0
+/* This permutation is illegal.  */
+int h = 1;
+#pragma weak h
+#endif
+
+#pragma weak i
+extern int i;
+
+#pragma weak j
+extern int j;
+int use_j() { return j; }
index 5d41f638ab1f0250960cbc84ea054b0c580d24cf..06ee8b82db9b2f3be9a8366bebb4147095820a6c 100644 (file)
@@ -167,10 +167,6 @@ static unsigned HOST_WIDE_INT array_size_for_constructor PARAMS ((tree));
 static unsigned min_align              PARAMS ((unsigned, unsigned));
 static void output_constructor         PARAMS ((tree, HOST_WIDE_INT,
                                                 unsigned int));
-static void mark_weak_decls            PARAMS ((void *));
-#if defined (ASM_WEAKEN_LABEL) || defined (ASM_WEAKEN_DECL)
-static void remove_from_pending_weak_list      PARAMS ((const char *));
-#endif
 static void globalize_decl             PARAMS ((tree));
 static void maybe_assemble_visibility  PARAMS ((tree));
 static int in_named_entry_eq           PARAMS ((const PTR, const PTR));
@@ -1399,6 +1395,17 @@ asm_emit_uninitialised (decl, name, size, rounded)
        destination = asm_dest_common;
     }
 
+  switch (destination)
+    {
+    case asm_dest_common:
+      if (! DECL_WEAK (decl))
+       break;
+    case asm_dest_bss:
+      globalize_decl (decl);
+    default:
+      break;
+    }
+
   if (flag_shared_data)
     {
       switch (destination)
@@ -1429,7 +1436,6 @@ asm_emit_uninitialised (decl, name, size, rounded)
     {
 #ifdef ASM_EMIT_BSS
     case asm_dest_bss:
-      globalize_decl (decl);
       ASM_EMIT_BSS (decl, name, size, rounded);
       break;
 #endif
@@ -4994,55 +5000,9 @@ output_constructor (exp, size, align)
     assemble_zeros (size - total_bytes);
 }
 
-
-/* This structure contains any weak symbol declarations waiting
+/* This TREE_LIST contains any weak symbol declarations waiting
    to be emitted.  */
-struct weak_syms
-{
-  struct weak_syms * next;
-  tree decl;
-  const char * name;
-  const char * value;
-};
-
-static struct weak_syms * weak_decls;
-
-/* Mark weak_decls for garbage collection.  */
-
-static void
-mark_weak_decls (arg)
-     void *arg;
-{
-  struct weak_syms *t;
-
-  for (t = *(struct weak_syms **) arg; t != NULL; t = t->next)
-    ggc_mark_tree (t->decl);
-}
-
-/* Add function NAME to the weak symbols list.  VALUE is a weak alias
-   associated with NAME.  */
-
-int
-add_weak (decl, name, value)
-     tree decl;
-     const char *name;
-     const char *value;
-{
-  struct weak_syms *weak;
-
-  weak = (struct weak_syms *) xmalloc (sizeof (struct weak_syms));
-
-  if (weak == NULL)
-    return 0;
-
-  weak->next = weak_decls;
-  weak->decl = decl;
-  weak->name = name;
-  weak->value = value;
-  weak_decls = weak;
-
-  return 1;
-}
+static tree weak_decls;
 
 /* Declare DECL to be a weak symbol.  */
 
@@ -5055,7 +5015,10 @@ declare_weak (decl)
   else if (TREE_ASM_WRITTEN (decl))
     error_with_decl (decl, "weak declaration of `%s' must precede definition");
   else if (SUPPORTS_WEAK)
-    add_weak (decl, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)), NULL);
+    {
+      if (! DECL_WEAK (decl))
+       weak_decls = tree_cons (NULL, decl, weak_decls);
+    }
   else
     warning_with_decl (decl, "weak declaration of `%s' not supported");
 
@@ -5067,59 +5030,30 @@ declare_weak (decl)
 void
 weak_finish ()
 {
-  if (SUPPORTS_WEAK)
+  tree t;
+
+  for (t = weak_decls; t ; t = TREE_CHAIN (t))
     {
-      struct weak_syms *t;
-      for (t = weak_decls; t != NULL; t = t->next)
-       {
+      tree decl = TREE_VALUE (t);
+      const char *name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
+
+      if (! TREE_USED (decl))
+       continue;
+
 #ifdef ASM_WEAKEN_DECL
-         tree decl = t->decl;
-         if (decl == NULL_TREE)
-           {
-             tree name = get_identifier (t->name);
-             if (name)
-               decl = lookup_name (name);
-           }
-         ASM_WEAKEN_DECL (asm_out_file, decl, t->name, t->value);
-#else
-#ifdef ASM_OUTPUT_WEAK_ALIAS
-         ASM_OUTPUT_WEAK_ALIAS (asm_out_file, t->name, t->value);
+      ASM_WEAKEN_DECL (asm_out_file, decl, name, NULL);
 #else
 #ifdef ASM_WEAKEN_LABEL
-         if (t->value)
-           abort ();
-         ASM_WEAKEN_LABEL (asm_out_file, t->name);
+      ASM_WEAKEN_LABEL (asm_out_file, name);
+#else
+#ifdef ASM_OUTPUT_WEAK_ALIAS
+      warning ("only weak aliases are supported in this configuration");
+      return;
 #endif
 #endif
 #endif
-       }
-    }
-}
-
-/* Remove NAME from the pending list of weak symbols.  This prevents
-   the compiler from emitting multiple .weak directives which confuses
-   some assemblers.  */
-#if defined (ASM_WEAKEN_LABEL) || defined (ASM_WEAKEN_DECL)
-static void
-remove_from_pending_weak_list (name)
-     const char *name;
-{
-  struct weak_syms *t;
-  struct weak_syms **p;
-
-  for (p = &weak_decls; *p; )
-    {
-      t = *p;
-      if (strcmp (name, t->name) == 0)
-        {
-          *p = t->next;
-          free (t);
-        }
-      else
-        p = &(t->next);
     }
 }
-#endif /* defined (ASM_WEAKEN_LABEL) || defined (ASM_WEAKEN_DECL) */
 
 /* Emit the assembly bits to indicate that DECL is globally visible.  */
 
@@ -5132,18 +5066,26 @@ globalize_decl (decl)
 #if defined (ASM_WEAKEN_LABEL) || defined (ASM_WEAKEN_DECL)
   if (DECL_WEAK (decl))
     {
+      tree *p, t;
+
 #ifdef ASM_WEAKEN_DECL
       ASM_WEAKEN_DECL (asm_out_file, decl, name, 0);
 #else
       ASM_WEAKEN_LABEL (asm_out_file, name);
 #endif
+
       /* Remove this function from the pending weak list so that
         we do not emit multiple .weak directives for it.  */
-      remove_from_pending_weak_list (name);
+      for (p = &weak_decls; (t = *p) ; p = &TREE_CHAIN (t))
+       if (TREE_VALUE (t) == decl)
+         {
+           *p = TREE_CHAIN (t);
+           break;
+         }
       return;
     }
-  /* else */
 #endif
+
   ASM_GLOBALIZE_LABEL (asm_out_file, name);
 }
 
@@ -5168,7 +5110,6 @@ assemble_alias (decl, target)
   if (TREE_PUBLIC (decl))
     {
       globalize_decl (decl);
-
       maybe_assemble_visibility (decl);
     }
 
@@ -5282,7 +5223,7 @@ init_varasm_once ()
                mark_const_hash_entry);
   ggc_add_root (&const_str_htab, 1, sizeof const_str_htab,
                mark_const_str_htab);
-  ggc_add_root (&weak_decls, 1, sizeof weak_decls, mark_weak_decls);
+  ggc_add_tree_root (&weak_decls, 1);
 
   const_alias_set = new_alias_set ();
 }