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
This commit is contained in:
Hans-Peter Nilsson 2008-09-22 01:54:03 +00:00 committed by Hans-Peter Nilsson
parent df969fc7a3
commit c70d0414af
4 changed files with 82 additions and 15 deletions

View 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> 2008-09-21 Eric Botcazou <ebotcazou@adacore.com>
* config/sparc/sparc-protos.h (gen_compare_operator): Declare. * config/sparc/sparc-protos.h (gen_compare_operator): Declare.

View file

@ -1002,6 +1002,30 @@ machopic_output_indirection (void **slot, void *data)
rtx init = const0_rtx; rtx init = const0_rtx;
switch_to_section (darwin_sections[machopic_nl_symbol_ptr_section]); 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); assemble_name (asm_out_file, ptr_name);
fprintf (asm_out_file, ":\n"); fprintf (asm_out_file, ":\n");

View file

@ -3349,6 +3349,31 @@ output_asm_label (rtx x)
assemble_name (asm_out_file, buf); 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. /* Print operand X using machine-dependent assembler syntax.
The macro PRINT_OPERAND is defined just to control this function. The macro PRINT_OPERAND is defined just to control this function.
CODE is a non-digit that preceded the operand-number in the % spec, 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); gcc_assert (!x || !REG_P (x) || REGNO (x) < FIRST_PSEUDO_REGISTER);
PRINT_OPERAND (asm_out_file, x, code); PRINT_OPERAND (asm_out_file, x, code);
if (x && MEM_P (x) && GET_CODE (XEXP (x, 0)) == SYMBOL_REF)
{ if (x == NULL_RTX)
tree t; return;
x = XEXP (x, 0);
t = SYMBOL_REF_DECL (x); for_each_rtx (&x, mark_symbol_ref_as_used, NULL);
if (t)
assemble_external (t);
}
} }
/* Print a memory reference operand for address X /* Print a memory reference operand for address X

View file

@ -2290,9 +2290,10 @@ process_pending_assemble_externals (void)
to be emitted. */ to be emitted. */
static GTY(()) tree weak_decls; static GTY(()) tree weak_decls;
/* Output something to declare an external symbol to the assembler. /* Output something to declare an external symbol to the assembler,
(Most assemblers don't need this, so we normally output nothing.) and qualifiers such as weakness. (Most assemblers don't need
Do nothing if DECL is not external. */ extern declaration, so we normally output nothing.) Do nothing if
DECL is not external. */
void void
assemble_external (tree decl ATTRIBUTE_UNUSED) 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. */ open. If it's not, we should not be calling this function. */
gcc_assert (asm_out_file); gcc_assert (asm_out_file);
#ifdef ASM_OUTPUT_EXTERNAL
if (!DECL_P (decl) || !DECL_EXTERNAL (decl) || !TREE_PUBLIC (decl)) if (!DECL_P (decl) || !DECL_EXTERNAL (decl) || !TREE_PUBLIC (decl))
return; 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); weak_decls = tree_cons (NULL, decl, weak_decls);
/* We want to output external symbols at very last to check if they #ifdef ASM_OUTPUT_EXTERNAL
are references or not. */
pending_assemble_externals = tree_cons (0, decl, pending_assemble_externals = tree_cons (0, decl,
pending_assemble_externals); pending_assemble_externals);
#endif #endif