From c70d0414afa803f535420815116971725933234c Mon Sep 17 00:00:00 2001 From: Hans-Peter Nilsson Date: Mon, 22 Sep 2008 01:54:03 +0000 Subject: [PATCH] re PR target/37170 (gcc.dg/weak/weak-1.c) 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 | 13 +++++++++++++ gcc/config/darwin.c | 24 ++++++++++++++++++++++++ gcc/final.c | 38 ++++++++++++++++++++++++++++++-------- gcc/varasm.c | 22 +++++++++++++++------- 4 files changed, 82 insertions(+), 15 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8a1603e2f13..195457c5ba0 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,16 @@ +2008-09-22 Hans-Peter Nilsson + + 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 * config/sparc/sparc-protos.h (gen_compare_operator): Declare. diff --git a/gcc/config/darwin.c b/gcc/config/darwin.c index 20cce264101..fe332738c54 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 a9b51caeeca..e2d9e5a9766 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 b3f99907990..4fe3c967032 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