aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog13
-rw-r--r--gcc/config/darwin.c24
-rw-r--r--gcc/final.c38
-rw-r--r--gcc/varasm.c22
4 files changed, 82 insertions, 15 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 8a1603e..195457c 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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.
diff --git a/gcc/config/darwin.c b/gcc/config/darwin.c
index 20cce26..fe33273 100644
--- a/gcc/config/darwin.c
+++ b/gcc/config/darwin.c
@@ -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");
diff --git a/gcc/final.c b/gcc/final.c
index a9b51ca..e2d9e5a 100644
--- a/gcc/final.c
+++ b/gcc/final.c
@@ -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
diff --git a/gcc/varasm.c b/gcc/varasm.c
index b3f9990..4fe3c96 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -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