There are situations on hppa when call assemble_external will result in actual
assembly code
being generated. An example is shown in PR target/80090 where compiling
autodock-vina fails.
The problem is that output_addr_const may output visibility information while
outputting an address constant:
case SYMBOL_REF:
if (SYMBOL_REF_DECL (x))
assemble_external (SYMBOL_REF_DECL (x));
#ifdef ASM_OUTPUT_SYMBOL_REF
ASM_OUTPUT_SYMBOL_REF (file, x);
#else
assemble_name (file, XSTR (x, 0));
#endif
break;
This can result in visibility information being output in the middle of an
assembly line. The attached change works
around this issue by calling assemble_external earlier, when we have a
SYMBOL_REF_DECL, and temporarily
setting the SYMBOL_REF_DECL to NULL.
Tested on hppa-unknown-linux-gnu, hppa2.0w-hp-hpux11.11 and
hppa64-hp-hpux11.11. Committed to trunk.
Dave
--
John David Anglin [email protected]
2017-05-10 John David Anglin <[email protected]>
PR target/80090
* config/pa/pa.c (pa_assemble_integer): When outputting a SYMBOL_REF,
handle calling assemble_external ourself.
Index: config/pa/pa.c
===================================================================
--- config/pa/pa.c (revision 247871)
+++ config/pa/pa.c (working copy)
@@ -3299,6 +3299,24 @@
static bool
pa_assemble_integer (rtx x, unsigned int size, int aligned_p)
{
+ bool result;
+ tree decl = NULL;
+
+ /* When we have a SYMBOL_REF with a SYMBOL_REF_DECL, we need to call
+ call assemble_external and set the SYMBOL_REF_DECL to NULL before
+ calling output_addr_const. Otherwise, it may call assemble_external
+ in the midst of outputing the assembler code for the SYMBOL_REF.
+ We restore the SYMBOL_REF_DECL after the output is done. */
+ if (GET_CODE (x) == SYMBOL_REF)
+ {
+ decl = SYMBOL_REF_DECL (x);
+ if (decl)
+ {
+ assemble_external (decl);
+ SET_SYMBOL_REF_DECL (x, NULL);
+ }
+ }
+
if (size == UNITS_PER_WORD
&& aligned_p
&& function_label_operand (x, VOIDmode))
@@ -3311,9 +3329,15 @@
output_addr_const (asm_out_file, x);
fputc ('\n', asm_out_file);
- return true;
+ result = true;
}
- return default_assemble_integer (x, size, aligned_p);
+ else
+ result = default_assemble_integer (x, size, aligned_p);
+
+ if (decl)
+ SET_SYMBOL_REF_DECL (x, decl);
+
+ return result;
}
/* Output an ascii string. */