From 1081d7e8411d924c4e4a7bf6f7d848fbabca60dd Mon Sep 17 00:00:00 2001
From: David Edelsohn <dje.gcc@gmail.com>
Date: Thu, 9 Jul 2020 12:24:38 -0400
Subject: [PATCH] middle-end: Call get_constant_section with DECL not EXP.

output_constant_def_contents() can call get_constant_section() with an
EXP that is a CONSTRUCTOR, which is not a declaration.  This can hit
asserts in GCC machinery to choose a named section for the initialization
data that expects the parameters to be DECLs.

This patch changes get_constant_section() and its callers to pass the
DECL within the EXP instead of the EXP, and to explicitly pass the reloc
information that must be determined from the EXP.

gcc/ChangeLog

2020-07-09  David Edelsohn  <dje.gcc@gmail.com>

	* varasm.c (get_constant_section): Change first parameter from
	EXP to DECL and add reloc second parameter.
	(build_constant_desc): Adjust call.
	(output_constant_def_contents): Adjust call.
---
 gcc/varasm.c | 16 +++++++++-------
 1 file changed, 9 insertions(+), 7 deletions(-)

diff --git a/gcc/varasm.c b/gcc/varasm.c
index 84df52013d7..717b9f6967a 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -3306,14 +3306,12 @@ compare_constant (const tree t1, const tree t2)
   gcc_unreachable ();
 }
 
-/* Return the section into which constant EXP should be placed.  */
+/* Return the section into which constant DECL should be placed.  */
 
 static section *
-get_constant_section (tree exp, unsigned int align)
+get_constant_section (tree decl, int reloc, unsigned int align)
 {
-  return targetm.asm_out.select_section (exp,
-					 compute_reloc_for_constant (exp),
-					 align);
+  return targetm.asm_out.select_section (decl, reloc, align);
 }
 
 /* Return the size of constant EXP in bytes.  */
@@ -3388,7 +3386,9 @@ build_constant_desc (tree exp)
 		   || (VAR_P (decl) && DECL_IN_CONSTANT_POOL (decl))
 		   ? DECL_ALIGN (decl)
 		   : symtab_node::get (decl)->definition_alignment ());
-      section *sect = get_constant_section (exp, align);
+      section *sect = get_constant_section (decl,
+					    compute_reloc_for_constant (exp),
+					    align);
       symbol = create_block_symbol (ggc_strdup (label),
 				    get_block_for_section (sect), -1);
     }
@@ -3569,7 +3569,9 @@ output_constant_def_contents (rtx symbol)
 		   || (VAR_P (decl) && DECL_IN_CONSTANT_POOL (decl))
 		   ? DECL_ALIGN (decl)
 		   : symtab_node::get (decl)->definition_alignment ());
-      section *sect = get_constant_section (exp, align);
+      section *sect = get_constant_section (decl,
+					    compute_reloc_for_constant (exp),
+					    align);
       switch_to_section (sect);
       if (align > BITS_PER_UNIT)
 	ASM_OUTPUT_ALIGN (asm_out_file, floor_log2 (align / BITS_PER_UNIT));
-- 
2.20.1

