This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[SPARC] Fix PR target/69072


This fixes an ICE on SPARC 64-bit in a corner case where a struct containing a 
nested packed struct is passed beyond the 6th position to a function.  The 
various routines of the back-end implementing the complex calling convention 
disagree on the passing mechanism, leading to an assertion failure.

Tested (incl. binary compatibility) on SPARC/Solaris, applied on the mainline.


2016-01-04  Eric Botcazou  <ebotcazou@adacore.com>

	PR target/69072
	* config/sparc/sparc.c (scan_record_type): Take into account subfields
	to compute the PACKED_P predicate.
	(function_arg_record_value): Minor tweaks.


2016-01-04  Eric Botcazou  <ebotcazou@adacore.com>

	* gcc.target/sparc/20160104-1.c: New test.

-- 
Eric Botcazou
Index: config/sparc/sparc.c
===================================================================
--- config/sparc/sparc.c	(revision 231971)
+++ config/sparc/sparc.c	(working copy)
@@ -6140,30 +6140,28 @@ sparc_strict_argument_naming (cumulative_args_t ca
       that is eligible for promotion in integer registers.
     - FP_REGS_P: the record contains at least one field or sub-field
       that is eligible for promotion in floating-point registers.
-    - PACKED_P: the record contains at least one field that is packed.
+    - PACKED_P: the record contains at least one field that is packed.  */
 
-   Sub-fields are not taken into account for the PACKED_P predicate.  */
-
 static void
 scan_record_type (const_tree type, int *intregs_p, int *fpregs_p,
 		  int *packed_p)
 {
-  tree field;
-
-  for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
+  for (tree field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
     {
       if (TREE_CODE (field) == FIELD_DECL)
 	{
-	  if (TREE_CODE (TREE_TYPE (field)) == RECORD_TYPE)
-	    scan_record_type (TREE_TYPE (field), intregs_p, fpregs_p, 0);
-	  else if ((FLOAT_TYPE_P (TREE_TYPE (field))
-		   || TREE_CODE (TREE_TYPE (field)) == VECTOR_TYPE)
+	  tree field_type = TREE_TYPE (field);
+
+	  if (TREE_CODE (field_type) == RECORD_TYPE)
+	    scan_record_type (field_type, intregs_p, fpregs_p, packed_p);
+	  else if ((FLOAT_TYPE_P (field_type)
+		   || TREE_CODE (field_type) == VECTOR_TYPE)
 		  && TARGET_FPU)
 	    *fpregs_p = 1;
 	  else
 	    *intregs_p = 1;
 
-	  if (packed_p && DECL_PACKED (field))
+	  if (DECL_PACKED (field))
 	    *packed_p = 1;
 	}
     }
@@ -6647,9 +6645,10 @@ function_arg_record_value (const_tree type, machin
 
       parms.nregs += intslots;
     }
+
+  /* Allocate the vector and handle some annoying special cases.  */
   nregs = parms.nregs;
 
-  /* Allocate the vector and handle some annoying special cases.  */
   if (nregs == 0)
     {
       /* ??? Empty structure has no value?  Duh?  */
@@ -6661,17 +6660,16 @@ function_arg_record_value (const_tree type, machin
 	     load.  */
 	  return gen_rtx_REG (mode, regbase);
 	}
-      else
-	{
-	  /* ??? C++ has structures with no fields, and yet a size.  Give up
-	     for now and pass everything back in integer registers.  */
-	  nregs = (typesize + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
-	}
+
+      /* ??? C++ has structures with no fields, and yet a size.  Give up
+	 for now and pass everything back in integer registers.  */
+      nregs = (typesize + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
       if (nregs + slotno > SPARC_INT_ARG_MAX)
 	nregs = SPARC_INT_ARG_MAX - slotno;
     }
-  gcc_assert (nregs != 0);
 
+  gcc_assert (nregs > 0);
+
   parms.ret = gen_rtx_PARALLEL (mode, rtvec_alloc (parms.stack + nregs));
 
   /* If at least one field must be passed on the stack, generate
/* PR target/69072 */
/* Reported by Zdenek Sojka <zsojka@seznam.cz> */

/* { dg-do compile } */

typedef struct
{
  struct
  {
    double d;
  } __attribute__((packed)) a;
} S;

void
foo (S s1, S s2, S s3, S s4, S s5, S s6, S s7)
{}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]