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]

[PATCH] Fix x86-64 aligned empty aggregate passing (PR target/20795)


Hi!

The testcase below ICEs on x86-64.  The problem is that
in C++, struct S { union {} a; } __attribute__((aligned (16)))
has sizeof (S) == 16 and __alignof__ (S) == 16, so needs to occupy
2 slots, but contains no real data in it, therefore both
are classified as NO_CLASS.
construct_container from this creates a bogus
(parallel:BLK []) which is 1) unclear what it really means
(pass the argument nowhere?) and 2) it confuses the middle-end,
both in outgoing and incoming argument handling.

Unfortunately x86-64-ABI's low-level-sys-info.tex doesn't talk
about where NO_CLASS is passed in, but judging from where
is struct T { union {} a; }; passed I guess memory.

It seems G++ 3.{2,3,4} all ICE on this, so we certainly can't talk
about binary compatibility here.

Ok for HEAD/4.0?

2005-04-06  Jakub Jelinek  <jakub@redhat.com>

	PR target/20795
	* config/i386/i386.c (construct_container): Pass empty aligned
	struct, union or class in memory.

	* g++.dg/abi/param2.C: New test.

--- gcc/config/i386/i386.c.jj	2005-04-06 18:33:09.000000000 +0200
+++ gcc/config/i386/i386.c	2005-04-06 18:33:09.000000000 +0200
@@ -2682,6 +2682,11 @@ construct_container (enum machine_mode m
 	    abort ();
 	}
     }
+
+  /* Empty aligned struct, union or class.  */
+  if (nexps == 0)
+    return NULL;
+
   ret =  gen_rtx_PARALLEL (mode, rtvec_alloc (nexps));
   for (i = 0; i < nexps; i++)
     XVECEXP (ret, 0, i) = exp [i];
--- gcc/testsuite/g++.dg/abi/param2.C.jj	2005-04-06 18:49:13.000000000 +0200
+++ gcc/testsuite/g++.dg/abi/param2.C	2005-04-06 18:53:42.000000000 +0200
@@ -0,0 +1,18 @@
+// PR target/20795
+// Test passing aligned empty aggregate
+// { dg-do compile }
+
+struct S { union {} a; } __attribute__((aligned));
+
+S
+foo (S arg)
+{
+  return arg;
+}
+
+void
+bar (void)
+{
+  S arg;
+  foo (arg);
+}

	Jakub


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