This bug was essentially that darwin_rs6000_special_round_type_align()
was ignoring externally-imposed capping of field alignment.
Signed-off-by: Iain Sandoe <iain@sandoe.co.uk>
PR target/110044
gcc/ChangeLog:
* config/rs6000/rs6000.c (darwin_rs6000_special_round_type_align):
Make sure that we do not have a cap on field alignment before altering
the struct layout based on the type alignment of the first entry.
gcc/testsuite/ChangeLog:
* gcc.target/powerpc/darwin-abi-13-0.c: New test.
* gcc.target/powerpc/darwin-abi-13-1.c: New test.
* gcc.target/powerpc/darwin-abi-13-2.c: New test.
* gcc.target/powerpc/darwin-structs-0.h: New test.
(cherry picked from commit
84d080a29a780973bef47171ba708ae2f7b4ee47)
type = TREE_TYPE (type);
} while (AGGREGATE_TYPE_P (type));
- if (! AGGREGATE_TYPE_P (type) && type != error_mark_node)
+ if (type != error_mark_node && ! AGGREGATE_TYPE_P (type)
+ && ! TYPE_PACKED (type) && maximum_field_alignment == 0)
align = MAX (align, TYPE_ALIGN (type));
return align;
--- /dev/null
+/* { dg-do compile { target powerpc*-*-darwin* } } */
+/* { dg-require-effective-target ilp32 } */
+/* { dg-options "-Wno-long-long" } */
+
+#include "darwin-structs-0.h"
+
+int tcd[sizeof(cd) != 12 ? -1 : 1];
+int acd[__alignof__(cd) != 4 ? -1 : 1];
+
+int sdc[sizeof(dc) != 16 ? -1 : 1];
+int adc[__alignof__(dc) != 8 ? -1 : 1];
+
+int scL[sizeof(cL) != 12 ? -1 : 1];
+int acL[__alignof__(cL) != 4 ? -1 : 1];
+
+int sLc[sizeof(Lc) != 16 ? -1 : 1];
+int aLc[__alignof__(Lc) != 8 ? -1 : 1];
+
+int scD[sizeof(cD) != 32 ? -1 : 1];
+int acD[__alignof__(cD) != 16 ? -1 : 1];
+
+int sDc[sizeof(Dc) != 32 ? -1 : 1];
+int aDc[__alignof__(Dc) != 16 ? -1 : 1];
--- /dev/null
+/* { dg-do compile { target powerpc*-*-darwin* } } */
+/* { dg-require-effective-target ilp32 } */
+/* { dg-options "-Wno-long-long" } */
+
+#pragma pack(push, 1)
+
+#include "darwin-structs-0.h"
+
+int tcd[sizeof(cd) != 9 ? -1 : 1];
+int acd[__alignof__(cd) != 1 ? -1 : 1];
+
+int sdc[sizeof(dc) != 9 ? -1 : 1];
+int adc[__alignof__(dc) != 1 ? -1 : 1];
+
+int scL[sizeof(cL) != 9 ? -1 : 1];
+int acL[__alignof__(cL) != 1 ? -1 : 1];
+
+int sLc[sizeof(Lc) != 9 ? -1 : 1];
+int aLc[__alignof__(Lc) != 1 ? -1 : 1];
+
+int scD[sizeof(cD) != 17 ? -1 : 1];
+int acD[__alignof__(cD) != 1 ? -1 : 1];
+
+int sDc[sizeof(Dc) != 17 ? -1 : 1];
+int aDc[__alignof__(Dc) != 1 ? -1 : 1];
+
+#pragma pack(pop)
--- /dev/null
+/* { dg-do compile { target powerpc*-*-darwin* } } */
+/* { dg-require-effective-target ilp32 } */
+/* { dg-options "-Wno-long-long" } */
+
+#pragma pack(push, 2)
+
+#include "darwin-structs-0.h"
+
+int tcd[sizeof(cd) != 10 ? -1 : 1];
+int acd[__alignof__(cd) != 2 ? -1 : 1];
+
+int sdc[sizeof(dc) != 10 ? -1 : 1];
+int adc[__alignof__(dc) != 2 ? -1 : 1];
+
+int scL[sizeof(cL) != 10 ? -1 : 1];
+int acL[__alignof__(cL) != 2 ? -1 : 1];
+
+int sLc[sizeof(Lc) != 10 ? -1 : 1];
+int aLc[__alignof__(Lc) != 2 ? -1 : 1];
+
+int scD[sizeof(cD) != 18 ? -1 : 1];
+int acD[__alignof__(cD) != 2 ? -1 : 1];
+
+int sDc[sizeof(Dc) != 18 ? -1 : 1];
+int aDc[__alignof__(Dc) != 2 ? -1 : 1];
+
+#pragma pack(pop)
--- /dev/null
+typedef struct _cd {
+ char c;
+ double d;
+} cd;
+
+typedef struct _dc {
+ double d;
+ char c;
+} dc;
+
+typedef struct _cL {
+ char c;
+ long long L;
+} cL;
+
+typedef struct _Lc {
+ long long L;
+ char c;
+} Lc;
+
+typedef struct _cD {
+ char c;
+ long double D;
+} cD;
+
+typedef struct _Dc {
+ long double D;
+ char c;
+} Dc;