diff mbox

Fix ICE for sparc targets in function_arg_record_value (PR target/77759)

Message ID 20161005121226.17590-1-jrtc27@jrtc27.com
State New
Headers show

Commit Message

Jessica Clarke Oct. 5, 2016, 12:12 p.m. UTC
gcc/
	PR target/77759
	* config/sparc/sparc.c (classify_data_t): Remove unused int_regs field.
	(classify_registers): Don't set int_regs.
	(function_arg_slotno): Don't initialise int_regs. Check slotno is
	within range for empty structs, just like int register-only structs.

gcc/testsuite/
	PR target/77759
	* g++.dg/other/pr77759.C: New test.
---
 gcc/config/sparc/sparc.c             | 10 +++-------
 gcc/testsuite/g++.dg/other/pr77759.C | 27 +++++++++++++++++++++++++++
 2 files changed, 30 insertions(+), 7 deletions(-)

Comments

Eric Botcazou Oct. 6, 2016, 10:32 a.m. UTC | #1
> gcc/
> 	PR target/77759
> 	* config/sparc/sparc.c (classify_data_t): Remove unused int_regs 
field.
> 	(classify_registers): Don't set int_regs.
> 	(function_arg_slotno): Don't initialise int_regs. Check slotno is
> 	within range for empty structs, just like int register-only structs.
> 
> gcc/testsuite/
> 	PR target/77759
> 	* g++.dg/other/pr77759.C: New test.

Thanks, applied on the mainline and 6 branch in a slightly modified form, 
after testing and compat-testing on SPARC/Solaris.
diff mbox

Patch

diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
index c622b66..7af8ba1 100644
--- a/gcc/config/sparc/sparc.c
+++ b/gcc/config/sparc/sparc.c
@@ -6294,7 +6294,6 @@  traverse_record_type (const_tree type, bool named, T *data,
 
 typedef struct
 {
-  bool int_regs;	/* true if field eligible to int registers.  */
   bool fp_regs;		/* true if field eligible to FP registers.  */
   bool fp_regs_in_first_word;	/* true if such field in first word.  */
 } classify_data_t;
@@ -6311,8 +6310,6 @@  classify_registers (const_tree, HOST_WIDE_INT bitpos, bool fp,
       if (bitpos < BITS_PER_WORD)
 	data->fp_regs_in_first_word = true;
     }
-  else
-    data->int_regs = true;
 }
 
 /* Compute the slot number to pass an argument in.
@@ -6439,7 +6436,7 @@  function_arg_slotno (const struct sparc_args *cum, machine_mode mode,
 
 	  if (TREE_CODE (type) == RECORD_TYPE)
 	    {
-	      classify_data_t data = { false, false, false };
+	      classify_data_t data = { false, false };
 	      traverse_record_type<classify_data_t, classify_registers>
 		(type, named, &data);
 
@@ -6450,10 +6447,9 @@  function_arg_slotno (const struct sparc_args *cum, machine_mode mode,
 		  && slotno >= SPARC_FP_ARG_MAX - 1)
 		return -1;
 
-	      /* If there are only int args and all int slots are filled,
-		 then must pass on stack.  */
+	      /* If there are only int args or this is an empty record type,
+		 and all int slots are filled, then must pass on stack.  */
 	      if (!data.fp_regs
-		  && data.int_regs
 		  && slotno >= SPARC_INT_ARG_MAX)
 		return -1;
 	    }
diff --git a/gcc/testsuite/g++.dg/other/pr77759.C b/gcc/testsuite/g++.dg/other/pr77759.C
new file mode 100644
index 0000000..4494bb5
--- /dev/null
+++ b/gcc/testsuite/g++.dg/other/pr77759.C
@@ -0,0 +1,27 @@ 
+/* PR target/77759
+   This testcase ICEd on sparc because function_arg_slotno did not treat empty
+   structs as being passed in integer registers and tried to assign the
+   struct pair_empty to register slot 6, causing function_arg_record_value to
+   fail the assertion that at least one register was available. */
+/* { dg-do compile { target sparc*-*-* } } */
+
+struct empty {};
+
+struct pair_empty
+{
+  struct empty a;
+  struct empty b;
+};
+
+void f1(int slot0 __attribute__((unused)), int slot1 __attribute__((unused)),
+	int slot2 __attribute__((unused)), int slot3 __attribute__((unused)),
+	int slot4 __attribute__((unused)), int slot5 __attribute__((unused)),
+	struct pair_empty pair __attribute__((unused)))
+{
+}
+
+void f2(void)
+{
+  struct pair_empty pair;
+  f1(0, 0, 0, 0, 0, 0, pair);
+}