diff options
author | hp <hp@138bc75d-0d04-0410-961f-82ee72b054a4> | 2008-09-22 01:54:03 +0000 |
---|---|---|
committer | hp <hp@138bc75d-0d04-0410-961f-82ee72b054a4> | 2008-09-22 01:54:03 +0000 |
commit | cd1862289cb7b38e6c7f0552ebf870525710d4d8 (patch) | |
tree | dacbdaca2921aa2efeafb9bf75733643142af3ea | |
parent | 2aa870e4b9e542ace7ace77a22704c9a91b92be4 (diff) | |
download | ppe42-gcc-cd1862289cb7b38e6c7f0552ebf870525710d4d8.tar.gz ppe42-gcc-cd1862289cb7b38e6c7f0552ebf870525710d4d8.zip |
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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@140539 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/ChangeLog | 13 | ||||
-rw-r--r-- | gcc/config/darwin.c | 24 | ||||
-rw-r--r-- | gcc/final.c | 38 | ||||
-rw-r--r-- | 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 <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 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 |