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.  */

Reply via email to