re PR target/37170 (gcc.dg/weak/weak-1.c)
authorHans-Peter Nilsson <hp@axis.com>
Mon, 22 Sep 2008 01:54:03 +0000 (01:54 +0000)
committerHans-Peter Nilsson <hp@gcc.gnu.org>
Mon, 22 Sep 2008 01:54:03 +0000 (01:54 +0000)
PR middle-end/37170
PR middle-end/37280
* final.c (mark_symbol_ref_as_used): New helper function.
(output_operand): Instead of just looking inside MEMs for
SYMBOL_REFs, use new helper function and for_each_rtx.
* varasm.c (assemble_external): Move #ifndef ASM_OUTPUT_EXTERNAL
to after weak-handling.  Don't mark decls with TREE_STATIC as weak.
Make head comment more general.
* config/darwin.c (machopic_output_indirection): Handle weak
references here, like in assemble_external.

From-SVN: r140539

gcc/ChangeLog
gcc/config/darwin.c
gcc/final.c
gcc/varasm.c

index 8a1603e..195457c 100644 (file)
@@ -1,3 +1,16 @@
+2008-09-22  Hans-Peter Nilsson  <hp@axis.com>
+
+       PR middle-end/37170
+       PR middle-end/37280
+       * final.c (mark_symbol_ref_as_used): New helper function.
+       (output_operand): Instead of just looking inside MEMs for
+       SYMBOL_REFs, use new helper function and for_each_rtx.
+       * varasm.c (assemble_external): Move #ifndef ASM_OUTPUT_EXTERNAL
+       to after weak-handling.  Don't mark decls with TREE_STATIC as weak.
+       Make head comment more general.
+       * config/darwin.c (machopic_output_indirection): Handle weak
+       references here, like in assemble_external.
+
 2008-09-21  Eric Botcazou  <ebotcazou@adacore.com>
 
        * config/sparc/sparc-protos.h (gen_compare_operator): Declare.
index 20cce26..fe33273 100644 (file)
@@ -1002,6 +1002,30 @@ machopic_output_indirection (void **slot, void *data)
       rtx init = const0_rtx;
 
       switch_to_section (darwin_sections[machopic_nl_symbol_ptr_section]);
+
+      /* Mach-O symbols are passed around in code through indirect
+        references and the original symbol_ref hasn't passed through
+        the generic handling and reference-catching in
+        output_operand, so we need to manually mark weak references
+        as such.  */
+      if (SYMBOL_REF_WEAK (symbol))
+       {
+         tree decl = SYMBOL_REF_DECL (symbol);
+         gcc_assert (DECL_P (decl));
+
+         if (decl != NULL_TREE
+             && DECL_EXTERNAL (decl) && TREE_PUBLIC (decl)
+             /* Handle only actual external-only definitions, not
+                e.g. extern inline code or variables for which
+                storage has been allocated.  */
+             && !TREE_STATIC (decl))
+           {
+             fputs ("\t.weak_reference ", asm_out_file);
+             assemble_name (asm_out_file, sym_name);
+             fputc ('\n', asm_out_file);
+           }
+       }
+
       assemble_name (asm_out_file, ptr_name);
       fprintf (asm_out_file, ":\n");
 
index a9b51ca..e2d9e5a 100644 (file)
@@ -3349,6 +3349,31 @@ output_asm_label (rtx x)
   assemble_name (asm_out_file, buf);
 }
 
+/* Helper rtx-iteration-function for output_operand.  Marks
+   SYMBOL_REFs as referenced through use of assemble_external.  */
+
+static int
+mark_symbol_ref_as_used (rtx *xp, void *dummy ATTRIBUTE_UNUSED)
+{
+  rtx x = *xp;
+
+  /* If we have a used symbol, we may have to emit assembly
+     annotations corresponding to whether the symbol is external, weak
+     or has non-default visibility.  */
+  if (GET_CODE (x) == SYMBOL_REF)
+    {
+      tree t;
+
+      t = SYMBOL_REF_DECL (x);
+      if (t)
+       assemble_external (t);
+
+      return -1;
+    }
+
+  return 0;
+}
+
 /* Print operand X using machine-dependent assembler syntax.
    The macro PRINT_OPERAND is defined just to control this function.
    CODE is a non-digit that preceded the operand-number in the % spec,
@@ -3369,14 +3394,11 @@ output_operand (rtx x, int code ATTRIBUTE_UNUSED)
   gcc_assert (!x || !REG_P (x) || REGNO (x) < FIRST_PSEUDO_REGISTER);
 
   PRINT_OPERAND (asm_out_file, x, code);
-  if (x && MEM_P (x) && GET_CODE (XEXP (x, 0)) == SYMBOL_REF)
-    {
-      tree t;
-      x = XEXP (x, 0);
-      t = SYMBOL_REF_DECL (x);
-      if (t)
-       assemble_external (t);
-    }
+
+  if (x == NULL_RTX)
+    return;
+
+  for_each_rtx (&x, mark_symbol_ref_as_used, NULL);
 }
 
 /* Print a memory reference operand for address X
index b3f9990..4fe3c96 100644 (file)
@@ -2290,9 +2290,10 @@ process_pending_assemble_externals (void)
    to be emitted.  */
 static GTY(()) tree weak_decls;
 
-/* Output something to declare an external symbol to the assembler.
-   (Most assemblers don't need this, so we normally output nothing.)
-   Do nothing if DECL is not external.  */
+/* Output something to declare an external symbol to the assembler,
+   and qualifiers such as weakness.  (Most assemblers don't need
+   extern declaration, so we normally output nothing.)  Do nothing if
+   DECL is not external.  */
 
 void
 assemble_external (tree decl ATTRIBUTE_UNUSED)
@@ -2303,15 +2304,22 @@ assemble_external (tree decl ATTRIBUTE_UNUSED)
      open.  If it's not, we should not be calling this function.  */
   gcc_assert (asm_out_file);
 
-#ifdef ASM_OUTPUT_EXTERNAL
   if (!DECL_P (decl) || !DECL_EXTERNAL (decl) || !TREE_PUBLIC (decl))
     return;
 
-  if (SUPPORTS_WEAK && DECL_WEAK (decl))
+  /* We want to output annotation for weak and external symbols at
+     very last to check if they are references or not.  */
+
+  if (SUPPORTS_WEAK && DECL_WEAK (decl)
+      /* TREE_STATIC is a weird and abused creature which is not
+        generally the right test for whether an entity has been
+        locally emitted, inlined or otherwise not-really-extern, but
+        for declarations that can be weak, it happens to be
+        match.  */
+      && !TREE_STATIC (decl))
     weak_decls = tree_cons (NULL, decl, weak_decls);
 
-  /* We want to output external symbols at very last to check if they
-     are references or not.  */
+#ifdef ASM_OUTPUT_EXTERNAL
   pending_assemble_externals = tree_cons (0, decl,
                                          pending_assemble_externals);
 #endif