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 dave.ang...@bell.net
2017-05-10 John David Anglin <dang...@gcc.gnu.org> 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. */