From eeae74a1a98590abc9eda18b198ff92f473f2e36 Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hongjiu.lu@intel.com>
Date: Sun, 29 Mar 2009 15:45:10 +0000
Subject: [PATCH] re PR target/39545 (Structures with flexible array member
 passed/returned incorrectly)

gcc/

2009-03-29  H.J. Lu  <hongjiu.lu@intel.com>

	PR target/39545
	* config/i386/i386.c (classify_argument): Ignore flexible array
	member in struct and warn ABI change.

gcc/testsuite/

2009-03-29  H.J. Lu  <hongjiu.lu@intel.com>

	PR target/39545
	* gcc.c-torture/compile/pr16566-2.c: Add -Wno-psabi for x86-64.

	* gcc.target/i386/pr39545-1.c: New.
	* gcc.target/i386/pr39545-2.c: Likewise.

	* gcc.target/x86_64/abi/test_passing_structs.c (flex1_struct): New.
	(flex2_struct): Likewise.
	(check_struct_passing7): Likewise.
	(check_struct_passing8): Likewise.
	(f1s): Likewise.
	(f2s): Likewise.
	(main): Call check_struct_passing7 and check_struct_passing8.

From-SVN: r145237
---
 gcc/ChangeLog                                 |  6 +++
 gcc/config/i386/i386.c                        | 26 ++++++++++++-
 gcc/testsuite/ChangeLog                       | 16 ++++++++
 .../gcc.c-torture/compile/pr16566-2.c         |  1 +
 gcc/testsuite/gcc.target/i386/pr39545-1.c     | 24 ++++++++++++
 gcc/testsuite/gcc.target/i386/pr39545-2.c     | 18 +++++++++
 .../x86_64/abi/test_passing_structs.c         | 39 +++++++++++++++++++
 7 files changed, 128 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/i386/pr39545-1.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr39545-2.c

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 0f8d30cab8d4..dca869b74a12 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2009-03-29  H.J. Lu  <hongjiu.lu@intel.com>
+
+	PR target/39545
+	* config/i386/i386.c (classify_argument): Ignore flexible array
+	member in struct and warn ABI change.
+
 2009-03-29  H.J. Lu  <hongjiu.lu@intel.com>
 
 	* config/i386/i386-protos.h (ix86_agi_dependent): New.
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 4a6d601ce45e..3dec02f3acd7 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -4942,8 +4942,30 @@ classify_argument (enum machine_mode mode, const_tree type,
 		    }
 		  else
 		    {
-		      num = classify_argument (TYPE_MODE (TREE_TYPE (field)),
-					       TREE_TYPE (field), subclasses,
+		      type = TREE_TYPE (field);
+
+		      /* Flexible array member is ignored.  */
+		      if (TYPE_MODE (type) == BLKmode
+			  && TREE_CODE (type) == ARRAY_TYPE
+			  && TYPE_SIZE (type) == NULL_TREE
+			  && TYPE_DOMAIN (type) != NULL_TREE
+			  && (TYPE_MAX_VALUE (TYPE_DOMAIN (type))
+			      == NULL_TREE))
+			{
+			  static bool warned;
+			  
+			  if (!warned && warn_psabi)
+			    {
+			      warned = true;
+			      inform (input_location,
+				      "The ABI of passing struct with"
+				      " a flexible array member has"
+				      " changed in GCC 4.4");
+			    }
+			  continue;
+			}
+		      num = classify_argument (TYPE_MODE (type), type,
+					       subclasses,
 					       (int_bit_position (field)
 						+ bit_offset) % 256);
 		      if (!num)
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 2f6072615653..7546a2d33a0b 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,19 @@
+2009-03-29  H.J. Lu  <hongjiu.lu@intel.com>
+
+	PR target/39545
+	* gcc.c-torture/compile/pr16566-2.c: Add -Wno-psabi for x86-64.
+
+	* gcc.target/i386/pr39545-1.c: New.
+	* gcc.target/i386/pr39545-2.c: Likewise.
+
+	* gcc.target/x86_64/abi/test_passing_structs.c (flex1_struct): New.
+	(flex2_struct): Likewise.
+	(check_struct_passing7): Likewise.
+	(check_struct_passing8): Likewise.
+	(f1s): Likewise.
+	(f2s): Likewise.
+	(main): Call check_struct_passing7 and check_struct_passing8.
+
 2009-03-29  Richard Guenther  <rguenther@suse.de>
 
 	* gcc.c-torture/execute/20090113-1.c: New testcase.
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr16566-2.c b/gcc/testsuite/gcc.c-torture/compile/pr16566-2.c
index c0036f0fc645..2f7a10668a73 100644
--- a/gcc/testsuite/gcc.c-torture/compile/pr16566-2.c
+++ b/gcc/testsuite/gcc.c-torture/compile/pr16566-2.c
@@ -1,5 +1,6 @@
 /* ICE with flexible arrays in non-lvalue structures.  Bug 16566
    (comment #5).  */
+/* { dg-options "-Wno-psabi" { target { { i?86-*-* x86_64-*-* } && lp64 } } } */
 
 struct A
 {
diff --git a/gcc/testsuite/gcc.target/i386/pr39545-1.c b/gcc/testsuite/gcc.target/i386/pr39545-1.c
new file mode 100644
index 000000000000..62bc33fa21d5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr39545-1.c
@@ -0,0 +1,24 @@
+/* PR target/39545 */
+/* { dg-do compile } */
+/* { dg-require-effective-target lp64 } */
+/* { dg-options "-O2" } */
+
+struct flex
+{
+  int i;
+  int flex [];
+};
+
+int
+foo (struct flex s) /* { dg-message "note: The ABI of passing struct with a flexible array member has changed in GCC 4.4" } */
+{
+  return s.i;
+}
+
+struct flex
+bar (int x)
+{
+  struct flex s;
+  s.i = x;
+  return s;
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr39545-2.c b/gcc/testsuite/gcc.target/i386/pr39545-2.c
new file mode 100644
index 000000000000..143c3827fd6c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr39545-2.c
@@ -0,0 +1,18 @@
+/* PR target/39545 */
+/* { dg-do compile } */
+/* { dg-require-effective-target lp64 } */
+/* { dg-options "-O2" } */
+
+struct flex
+{
+  int i;
+  int flex [];
+};
+
+struct flex
+foo (int x)
+{ /* { dg-message "note: The ABI of passing struct with a flexible array member has changed in GCC 4.4" } */
+  struct flex s;
+  s.i = x;
+  return s;
+}
diff --git a/gcc/testsuite/gcc.target/x86_64/abi/test_passing_structs.c b/gcc/testsuite/gcc.target/x86_64/abi/test_passing_structs.c
index 3ce0db14652e..68eca53a2e43 100644
--- a/gcc/testsuite/gcc.target/x86_64/abi/test_passing_structs.c
+++ b/gcc/testsuite/gcc.target/x86_64/abi/test_passing_structs.c
@@ -92,6 +92,33 @@ check_struct_passing6 (struct m128_2_struct ms ATTRIBUTE_UNUSED)
 }
 #endif
 
+struct flex1_struct
+{
+  long i;
+  long flex[];
+};
+
+struct flex2_struct
+{
+  long i;
+  long flex[0];
+};
+
+void
+check_struct_passing7 (struct flex1_struct is ATTRIBUTE_UNUSED)
+{
+  check_int_arguments;
+}
+
+void
+check_struct_passing8 (struct flex2_struct is ATTRIBUTE_UNUSED)
+{
+  check_int_arguments;
+}
+
+static struct flex1_struct f1s = { 60, { } };
+static struct flex2_struct f2s = { 61, { } };
+
 int
 main (void)
 {
@@ -146,5 +173,17 @@ main (void)
   WRAP_CALL (check_struct_passing6)(m128_2s);
 #endif
 
+  clear_struct_registers;
+  iregs.I0 = f1s.i;
+  num_iregs = 1;
+  clear_int_hardware_registers;
+  WRAP_CALL (check_struct_passing7)(f1s);
+
+  clear_struct_registers;
+  iregs.I0 = f2s.i;
+  num_iregs = 1;
+  clear_int_hardware_registers;
+  WRAP_CALL (check_struct_passing8)(f2s);
+
   return 0;
 }
-- 
GitLab