OSDN Git Service

* gcc.dg/compat/fnptr-by-value-1_main.c: New file.
authorjanis <janis@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 3 Jul 2003 20:15:48 +0000 (20:15 +0000)
committerjanis <janis@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 3 Jul 2003 20:15:48 +0000 (20:15 +0000)
* gcc.dg/compat/fnptr-by-value-1_x.c: New file.
* gcc.dg/compat/fnptr-by-value-1_y.c: New file.
* gcc.dg/compat/struct-align-1.h: New file.
* gcc.dg/compat/struct-align-1_main.c: New file.
* gcc.dg/compat/struct-align-1_x.c: New file.
* gcc.dg/compat/struct-align-1_y.c: New file.
* gcc.dg/compat/struct-align-2.h: New file.
* gcc.dg/compat/struct-align-2_main.c: New file.
* gcc.dg/compat/struct-align-2_x.c: New file.
* gcc.dg/compat/struct-align-2_y.c: New file.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@68901 138bc75d-0d04-0410-961f-82ee72b054a4

12 files changed:
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/compat/fnptr-by-value-1_main.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/compat/fnptr-by-value-1_x.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/compat/fnptr-by-value-1_y.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/compat/struct-align-1.h [new file with mode: 0644]
gcc/testsuite/gcc.dg/compat/struct-align-1_main.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/compat/struct-align-1_x.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/compat/struct-align-1_y.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/compat/struct-align-2.h [new file with mode: 0644]
gcc/testsuite/gcc.dg/compat/struct-align-2_main.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/compat/struct-align-2_x.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/compat/struct-align-2_y.c [new file with mode: 0644]

index bc17034..65fd171 100644 (file)
@@ -1,5 +1,17 @@
 2003-07-03  Janis Johnson  <janis187@us.ibm.com>
 
+       * gcc.dg/compat/fnptr-by-value-1_main.c: New file.
+       * gcc.dg/compat/fnptr-by-value-1_x.c: New file.
+       * gcc.dg/compat/fnptr-by-value-1_y.c: New file.
+       * gcc.dg/compat/struct-align-1.h: New file.
+       * gcc.dg/compat/struct-align-1_main.c: New file.
+       * gcc.dg/compat/struct-align-1_x.c: New file.
+       * gcc.dg/compat/struct-align-1_y.c: New file.
+       * gcc.dg/compat/struct-align-2.h: New file.
+       * gcc.dg/compat/struct-align-2_main.c: New file.
+       * gcc.dg/compat/struct-align-2_x.c: New file.
+       * gcc.dg/compat/struct-align-2_y.c: New file.
+
        * gcc.dg/compat/compat-common.h (DEBUG_FINI): New.
        * gcc.dg/compat/scalar-by-value-1_x.c: Use it.
        * gcc.dg/compat/scalar-by-value-2_x.c: Ditto.
diff --git a/gcc/testsuite/gcc.dg/compat/fnptr-by-value-1_main.c b/gcc/testsuite/gcc.dg/compat/fnptr-by-value-1_main.c
new file mode 100644 (file)
index 0000000..35c94aa
--- /dev/null
@@ -0,0 +1,12 @@
+/* Test passing function pointers.  */
+
+extern void fnptr_by_value_1_x (void);
+extern void exit (int);
+int fails;
+
+int
+main ()
+{
+  fnptr_by_value_1_x ();
+  exit (0);
+}
diff --git a/gcc/testsuite/gcc.dg/compat/fnptr-by-value-1_x.c b/gcc/testsuite/gcc.dg/compat/fnptr-by-value-1_x.c
new file mode 100644 (file)
index 0000000..d6984fc
--- /dev/null
@@ -0,0 +1,162 @@
+#include "compat-common.h"
+
+/* Turn off checking for variable arguments with -DSKIPVA.  */
+#ifdef SKIPVA
+const int test_va = 0;
+#else
+const int test_va = 1;
+#endif
+
+typedef void (*fpi)(int);
+typedef void (*fpd)(double);
+
+extern void test1a (fpi);
+extern void test1b (fpi, int);
+extern void test1c (double, fpd);
+extern void test2a (fpi, fpd);
+extern void test2b (fpi, fpd, int);
+extern void test2c (fpi, int, fpd);
+extern void test2d (int, fpi, fpd);
+extern void test2e (fpi, fpd, int, double);
+extern void test2f (fpi, int, fpd, double);
+extern void test2g (fpi, int, double, fpd);
+extern void test2h (double, fpd, fpi, int);
+extern void test2i (double, fpd, int, fpi);
+extern void test2j (int, double, fpi, fpd);
+
+int f1_val;
+double f2_val;
+
+void f1 (int i) { f1_val = i; }
+void f2 (double x) { f2_val = x; }
+
+void
+checki (int x, int v)
+{
+  if (x != v)
+    DEBUG_CHECK
+}
+
+void
+checkd (double x, double v)
+{
+  if (x != v)
+    DEBUG_CHECK
+}
+
+void
+testit (void)
+{
+  DEBUG_FPUTS ("test1a: ");
+  test1a (f1);
+  checki (f1_val, 1);
+  DEBUG_NL;
+  DEBUG_FPUTS ("test1b: ");
+  test1b (f1, 2);
+  checki (f1_val, 2);
+  DEBUG_NL;
+  DEBUG_FPUTS ("test1c: ");
+  test1c (3.0, f2);
+  checkd (f2_val, 3.0);
+  DEBUG_NL;
+  DEBUG_FPUTS ("test2a: ");
+  test2a (f1, f2);
+  checki (f1_val, 10);
+  checkd (f2_val, 10.0);
+  DEBUG_NL;
+  DEBUG_FPUTS ("test2b: ");
+  test2b (f1, f2, 11);
+  checki (f1_val, 11);
+  checkd (f2_val, 11.0);
+  DEBUG_NL;
+  DEBUG_FPUTS ("test2c: ");
+  test2c (f1, 12, f2);
+  checki (f1_val, 12);
+  checkd (f2_val, 12.0);
+  DEBUG_NL;
+  DEBUG_FPUTS ("test2d: ");
+  test2d (13, f1, f2);
+  checki (f1_val, 13);
+  checkd (f2_val, 13.0);
+  DEBUG_NL;
+  DEBUG_FPUTS ("test2e: ");
+  test2e (f1, f2, 14, 15.0);
+  checki (f1_val, 14);
+  checkd (f2_val, 15.0);
+  DEBUG_NL;
+  DEBUG_FPUTS ("test2f: ");
+  test2f (f1, 16, f2, 17.0);
+  checki (f1_val, 16);
+  checkd (f2_val, 17.0);
+  DEBUG_NL;
+  DEBUG_FPUTS ("test2g: ");
+  test2g (f1, 18, 19.0, f2);
+  checki (f1_val, 18);
+  checkd (f2_val, 19.0);
+  DEBUG_NL;
+  DEBUG_FPUTS ("test2h: ");
+  test2h (20.0, f2, f1, 21);
+  checkd (f2_val, 20.0);
+  checki (f1_val, 21);
+  DEBUG_NL;
+  DEBUG_FPUTS ("test2i: ");
+  test2i (22.0, f2, 23, f1);
+  checkd (f2_val, 22.0);
+  checki (f1_val, 23);
+  DEBUG_NL;
+  DEBUG_FPUTS ("test2j: ");
+  test2j (24, 25.0, f1, f2);
+  checki (f1_val, 24);
+  checkd (f2_val, 25.0);
+  if (test_va)
+    {
+      DEBUG_NL;
+      DEBUG_FPUTS ("testva: ");
+      testva (1, f1);
+      DEBUG_NL;
+      DEBUG_FPUTS ("        ");
+      testva (2, f1, f1);
+      DEBUG_NL;
+      DEBUG_FPUTS ("        ");
+      testva (3, f1, f1, f1);
+      DEBUG_NL;
+      DEBUG_FPUTS ("        ");
+      testva (4, f1, f1, f1, f1);
+      DEBUG_NL;
+      DEBUG_FPUTS ("        ");
+      testva (5, f1, f1, f1, f1, f1);
+      DEBUG_NL;
+      DEBUG_FPUTS ("        ");
+      testva (6, f1, f1, f1, f1, f1, f1);
+      DEBUG_NL;
+      DEBUG_FPUTS ("        ");
+      testva (7, f1, f1, f1, f1, f1, f1, f1);
+      DEBUG_NL;
+      DEBUG_FPUTS ("        ");
+      testva (8, f1, f1, f1, f1, f1, f1, f1, f1);
+      DEBUG_NL;
+      DEBUG_FPUTS ("        ");
+      testva (9, f1, f1, f1, f1, f1, f1, f1, f1, f1);
+      DEBUG_NL;
+      DEBUG_FPUTS ("        ");
+      testva (10, f1, f1, f1, f1, f1, f1, f1, f1, f1, f1);
+      DEBUG_NL;
+      DEBUG_FPUTS ("        ");
+      testva (11, f1, f1, f1, f1, f1, f1, f1, f1, f1, f1, f1);
+      DEBUG_NL;
+      DEBUG_FPUTS ("        ");
+      testva (12, f1, f1, f1, f1, f1, f1, f1, f1, f1, f1, f1, f1);
+    }
+  DEBUG_NL;
+}
+
+void
+fnptr_by_value_1_x ()
+{
+  DEBUG_INIT
+  testit ();
+  DEBUG_FINI
+
+  if (fails != 0)
+    abort ();
+}
diff --git a/gcc/testsuite/gcc.dg/compat/fnptr-by-value-1_y.c b/gcc/testsuite/gcc.dg/compat/fnptr-by-value-1_y.c
new file mode 100644 (file)
index 0000000..1f6917c
--- /dev/null
@@ -0,0 +1,111 @@
+#include <stdarg.h>
+
+#include "compat-common.h"
+
+typedef void (*fpi)(int);
+typedef void (*fpd)(double);
+
+extern int f1_val;
+extern void checki (int, int);
+
+void
+test1a (fpi f)
+{
+  (*f)(1);
+}
+
+void
+test1b (fpi f, int i)
+{
+  (*f)(i);
+}
+
+void
+test1c (double x, fpd f)
+{
+  (*f)(x);
+}
+
+void
+test2a (fpi f1, fpd f2)
+{
+  (*f1)(10);
+  (*f2)(10.0);
+}
+
+void
+test2b (fpi f1, fpd f2, int i)
+{
+  (*f1)(i);
+  (*f2)((double)i);
+}
+
+void
+test2c (fpi f1, int i, fpd f2)
+{
+  (*f1)(i);
+  (*f2)((double)i);
+}
+
+void
+test2d (int i, fpi f1, fpd f2)
+{
+  (*f1)(i);
+  (*f2)((double)i);
+}
+
+void
+test2e (fpi f1, fpd f2, int i, double x)
+{
+  (*f1)(i);
+  (*f2)(x);
+}
+
+void
+test2f (fpi f1, int i, fpd f2, double x)
+{
+  (*f1)(i);
+  (*f2)(x);
+}
+
+void
+test2g (fpi f1, int i, double x, fpd f2)
+{
+  (*f1)(i);
+  (*f2)(x);
+}
+
+void
+test2h (double x, fpd f1, fpi f2, int i)
+{
+  (*f1)(x);
+  (*f2)(i);
+}
+
+void
+test2i (double x, fpd f1, int i, fpi f2)
+{
+  (*f1)(x);
+  (*f2)(i);
+}
+
+void
+test2j (int i, double x, fpi f1, fpd f2)
+{
+  (*f1)(i);
+  (*f2)(x);
+}
+
+void
+testva (int n, ...)
+{
+  int i;
+  va_list ap;
+  va_start (ap, n);
+  for (i = 0; i < n; i++)
+    {
+      fpi fp = va_arg (ap, fpi);
+      (*fp)(i);
+      checki (f1_val, i);
+    }
+}
diff --git a/gcc/testsuite/gcc.dg/compat/struct-align-1.h b/gcc/testsuite/gcc.dg/compat/struct-align-1.h
new file mode 100644 (file)
index 0000000..5283e78
--- /dev/null
@@ -0,0 +1,178 @@
+/* Define several variants of a struct for which the alignment differs
+   between powerpc64-linux and powerpc64-aix.  This might be interesting
+   for other targets as well.  */
+
+#define DESC_orig "original"
+struct B1_orig {
+  char c;
+  double d;
+};
+
+struct A2_orig {
+  double d;
+};
+
+struct B2_orig {
+  char c;
+  struct A2_orig a2;
+};
+
+struct A3_orig {
+  double d;
+  int i;
+};
+
+struct B3_orig {
+  char c;
+  struct A3_orig a3;
+};
+
+#define DESC_p_all "packed attribute for all"
+struct B1_p_all {
+  char c;
+  double d;
+} __attribute__ ((packed));
+
+struct A2_p_all {
+  double d;
+} __attribute__ ((packed));
+
+struct B2_p_all {
+  char c;
+  struct A2_p_all a2;
+} __attribute__ ((packed));
+
+struct A3_p_all {
+  double d;
+  int i;
+} __attribute__ ((packed));
+
+struct B3_p_all {
+  char c;
+  struct A3_p_all a3;
+} __attribute__ ((packed));
+
+#define DESC_p_inner "packed attribute for inner"
+struct B1_p_inner {
+  char c;
+  double d;
+};
+
+struct A2_p_inner {
+  double d;
+} __attribute__ ((packed));
+
+struct B2_p_inner {
+  char c;
+  struct A2_p_inner a2;
+};
+
+struct A3_p_inner {
+  double d;
+  int i;
+} __attribute__ ((packed));
+
+struct B3_p_inner {
+  char c;
+  struct A3_p_inner a3;
+};
+
+#define DESC_p_outer "packed attribute for outer"
+struct B1_p_outer {
+  char c;
+  double d;
+} __attribute__ ((packed));
+
+struct A2_p_outer {
+  double d;
+};
+
+struct B2_p_outer {
+  char c;
+  struct A2_p_outer a2;
+} __attribute__ ((packed));
+
+struct A3_p_outer {
+  double d;
+  int i;
+};
+
+struct B3_p_outer {
+  char c;
+  struct A3_p_outer a3;
+} __attribute__ ((packed));
+
+#define DESC_a_max "maximum useful struct alignment for all"
+struct B1_a_max {
+  char c;
+  double d;
+} __attribute__ ((aligned));
+
+struct A2_a_max {
+  double d;
+} __attribute__ ((aligned));
+
+struct B2_a_max {
+  char c;
+  struct A2_a_max a2;
+} __attribute__ ((aligned));
+
+struct A3_a_max {
+  double d;
+  int i;
+} __attribute__ ((aligned));
+
+struct B3_a_max {
+  char c;
+  struct A3_a_max a3;
+} __attribute__ ((aligned));
+
+#define DESC_m_outer_p_inner "maximum alignment for outer, packed inner"
+struct B1_m_outer_p_inner {
+  char c;
+  double d;
+} __attribute__ ((aligned)) __attribute__ ((packed));
+
+struct A2_m_outer_p_inner {
+  double d;
+} __attribute__ ((packed));
+
+struct B2_m_outer_p_inner {
+  char c;
+  struct A2_m_outer_p_inner a2;
+} __attribute__ ((aligned));
+
+struct A3_m_outer_p_inner {
+  double d;
+  int i;
+} __attribute__ ((packed));
+
+struct B3_m_outer_p_inner {
+  char c;
+  struct A3_m_outer_p_inner a3;
+} __attribute__ ((aligned));
+
+#define DESC_m_inner_p_outer "maximum alignment for inner, packed outer"
+struct B1_m_inner_p_outer {
+  char c;
+  double d;
+} __attribute__ ((aligned)) __attribute__ ((packed));
+
+struct A2_m_inner_p_outer {
+  double d;
+} __attribute__ ((aligned));
+
+struct B2_m_inner_p_outer {
+  char c;
+  struct A2_m_inner_p_outer a2;
+} __attribute__ ((packed));
+
+struct A3_m_inner_p_outer {
+  double d;
+  int i;
+} __attribute__ ((aligned));
+
+struct B3_m_inner_p_outer {
+  char c;
+  struct A3_m_inner_p_outer a3;
+} __attribute__ ((packed));
diff --git a/gcc/testsuite/gcc.dg/compat/struct-align-1_main.c b/gcc/testsuite/gcc.dg/compat/struct-align-1_main.c
new file mode 100644 (file)
index 0000000..0b7f27b
--- /dev/null
@@ -0,0 +1,13 @@
+/* Test compatibility of structure layout and alignment for structs
+   which contain doubles.  The original structs here are from PR 10645.  */
+
+extern void struct_align_1_x (void);
+extern void exit (int);
+int fails;
+
+int
+main ()
+{
+  struct_align_1_x ();
+  exit (0);
+}
diff --git a/gcc/testsuite/gcc.dg/compat/struct-align-1_x.c b/gcc/testsuite/gcc.dg/compat/struct-align-1_x.c
new file mode 100644 (file)
index 0000000..1500fa7
--- /dev/null
@@ -0,0 +1,91 @@
+#include "compat-common.h"
+#include "struct-align-1.h"
+
+#define SETUP(NAME,V1,V2,V3)                           \
+char v1_##NAME = V1;                                   \
+double v2_##NAME = V2;                                 \
+int v3_##NAME = V3;                                    \
+                                                       \
+struct B1_##NAME b1_##NAME = { V1, V2 };               \
+struct B2_##NAME b2_##NAME = { V1, { V2 } };           \
+struct B3_##NAME b3_##NAME = { V1, { V2, V3 } };       \
+                                                       \
+struct B1_##NAME ab1_##NAME[2] =                       \
+  { { V1, V2 }, { V1, V2 } };                          \
+struct B2_##NAME ab2_##NAME[2] =                       \
+  { { V1, { V2 } }, { V1, { V2 } } };                  \
+struct B3_##NAME ab3_##NAME[2] =                       \
+  { { V1, { V2, V3 } }, { V1, { V2, V3 } } };          \
+                                                       \
+extern void test_##NAME (void);                                \
+extern void checkp1_##NAME (struct B1_##NAME *);       \
+extern void checkp2_##NAME (struct B2_##NAME *);       \
+extern void checkp3_##NAME (struct B3_##NAME *);       \
+extern void checkg1_##NAME (void);                     \
+extern void checkg2_##NAME (void);                     \
+extern void checkg3_##NAME (void);                     \
+                                                       \
+void                                                   \
+pass1_##NAME (struct B1_##NAME s)                      \
+{                                                      \
+  checkp1_##NAME (&s);                                 \
+}                                                      \
+                                                       \
+void                                                   \
+pass2_##NAME (struct B2_##NAME s)                      \
+{                                                      \
+  checkp2_##NAME (&s);                                 \
+}                                                      \
+                                                       \
+void                                                   \
+pass3_##NAME (struct B3_##NAME s)                      \
+{                                                      \
+  checkp3_##NAME (&s);                                 \
+}                                                      \
+                                                       \
+struct B1_##NAME                                       \
+return1_##NAME (void)                                  \
+{                                                      \
+  return ab1_##NAME[0];                                        \
+}                                                      \
+                                                       \
+struct B2_##NAME                                       \
+return2_##NAME (void)                                  \
+{                                                      \
+  return ab2_##NAME[0];                                        \
+}                                                      \
+                                                       \
+struct B3_##NAME                                       \
+return3_##NAME (void)                                  \
+{                                                      \
+  return ab3_##NAME[0];                                        \
+}
+
+#define CHECK(NAME) test_##NAME()
+
+SETUP (orig, 49, 1.0, 111111)
+SETUP (p_all, 50, 2.0, 222222)
+SETUP (p_inner, 51, 3.0, 333333)
+SETUP (p_outer, 52, 4.0, 444444)
+SETUP (a_max, 53, 5.0, 555555)
+SETUP (m_outer_p_inner, 54, 6.0, 666666)
+SETUP (m_inner_p_outer, 55, 7.0, 777777) 
+
+void
+struct_align_1_x (void)
+{
+  DEBUG_INIT
+
+  CHECK (orig);
+  CHECK (p_all);
+  CHECK (p_inner);
+  CHECK (p_outer);
+  CHECK (a_max);
+  CHECK (m_outer_p_inner);
+  CHECK (m_inner_p_outer);
+
+  DEBUG_FINI
+
+  if (fails != 0)
+    abort ();
+}
diff --git a/gcc/testsuite/gcc.dg/compat/struct-align-1_y.c b/gcc/testsuite/gcc.dg/compat/struct-align-1_y.c
new file mode 100644 (file)
index 0000000..744f4de
--- /dev/null
@@ -0,0 +1,88 @@
+#include "compat-common.h"
+#include "struct-align-1.h"
+
+#define TEST(NAME)                                             \
+extern char v1_##NAME;                                         \
+extern double v2_##NAME;                                       \
+extern int v3_##NAME;                                          \
+                                                               \
+extern struct B1_##NAME b1_##NAME, ab1_##NAME[2];              \
+extern struct B2_##NAME b2_##NAME, ab2_##NAME[2];              \
+extern struct B3_##NAME b3_##NAME, ab3_##NAME[2];              \
+                                                               \
+extern void pass1_##NAME (struct B1_##NAME);                   \
+extern void pass2_##NAME (struct B2_##NAME);                   \
+extern void pass3_##NAME (struct B3_##NAME);                   \
+extern struct B1_##NAME return1_##NAME (void);                 \
+extern struct B2_##NAME return2_##NAME (void);                 \
+extern struct B3_##NAME return3_##NAME (void);                 \
+                                                               \
+void                                                           \
+checkp1_##NAME (struct B1_##NAME *p)                           \
+{                                                              \
+  if (p->c != v1_##NAME)                                       \
+    DEBUG_CHECK;                                               \
+  if (p->d != v2_##NAME)                                       \
+    DEBUG_CHECK;                                               \
+}                                                              \
+                                                               \
+void                                                           \
+checkp2_##NAME (struct B2_##NAME *p)                           \
+{                                                              \
+  if (p->c != v1_##NAME)                                       \
+    DEBUG_CHECK;                                               \
+  if (p->a2.d != v2_##NAME)                                    \
+    DEBUG_CHECK;                                               \
+}                                                              \
+                                                               \
+void                                                           \
+checkp3_##NAME (struct B3_##NAME *p)                           \
+{                                                              \
+  if (p->c != v1_##NAME)                                       \
+    DEBUG_CHECK;                                               \
+  if (p->a3.d != v2_##NAME)                                    \
+    DEBUG_CHECK;                                               \
+  if (p->a3.i != v3_##NAME)                                    \
+    DEBUG_CHECK;                                               \
+}                                                              \
+                                                               \
+void                                                           \
+test_##NAME (void)                                             \
+{                                                              \
+  struct B1_##NAME s1;                                         \
+  struct B2_##NAME s2;                                         \
+  struct B3_##NAME s3;                                         \
+  DEBUG_FPUTS (DESC_##NAME);                                   \
+  DEBUG_NL;                                                    \
+  DEBUG_FPUTS ("  global variable");                           \
+  checkp1_##NAME (&b1_##NAME);                                 \
+  checkp2_##NAME (&b2_##NAME);                                 \
+  checkp3_##NAME (&b3_##NAME);                                 \
+  DEBUG_NL;                                                    \
+  DEBUG_FPUTS ("  global array");                              \
+  checkp1_##NAME (&ab1_##NAME[1]);                             \
+  checkp2_##NAME (&ab2_##NAME[1]);                             \
+  checkp3_##NAME (&ab3_##NAME[1]);                             \
+  DEBUG_NL;                                                    \
+  DEBUG_FPUTS ("  argument");                                  \
+  pass1_##NAME (b1_##NAME);                                    \
+  pass2_##NAME (b2_##NAME);                                    \
+  pass3_##NAME (b3_##NAME);                                    \
+  DEBUG_NL;                                                    \
+  DEBUG_FPUTS ("  function result");                           \
+  s1 = return1_##NAME ();                                      \
+  checkp1_##NAME (&s1);                                                \
+  s2 = return2_##NAME ();                                      \
+  checkp2_##NAME (&s2);                                                \
+  s3 = return3_##NAME ();                                      \
+  checkp3_##NAME (&s3);                                                \
+  DEBUG_NL;                                                    \
+}
+
+TEST (orig)
+TEST (p_all)
+TEST (p_inner)
+TEST (p_outer)
+TEST (a_max)
+TEST (m_outer_p_inner)
+TEST (m_inner_p_outer)
diff --git a/gcc/testsuite/gcc.dg/compat/struct-align-2.h b/gcc/testsuite/gcc.dg/compat/struct-align-2.h
new file mode 100644 (file)
index 0000000..c97a476
--- /dev/null
@@ -0,0 +1,73 @@
+/* Define several variants of struct epoll_event from the Linux kernel,
+   specifying various attributes that affect alignment and size.
+   This test was developed for systems for which int is 32 bits and
+   long long is 64 bits; it might need to be disabled for systems where
+   either of those is not true.  */
+
+#define DESC_orig "original"
+struct epoll_event_orig {
+  unsigned int events;
+  unsigned long long data;
+};
+
+#define DESC_structmax "maximum useful struct alignment"
+struct epoll_event_structmax {
+  unsigned int events;
+  unsigned long long data;
+} __attribute__ ((aligned));
+
+
+#define DESC_struct4 "4-byte struct alignment"
+struct epoll_event_struct4 {
+  unsigned int events;
+  unsigned long long data;
+} __attribute__ ((aligned(4)));
+
+#define DESC_struct8 "8-byte struct alignment"
+struct epoll_event_struct8 {
+  unsigned int events;
+  unsigned long long data;
+} __attribute__ ((aligned(8)));
+
+#define DESC_data4 "4-byte alignment for data"
+struct epoll_event_data4 {
+  unsigned int events;
+  unsigned long long data __attribute__ ((aligned(4)));
+};
+
+#define DESC_data8 "8-byte alignment for data"
+struct epoll_event_data8 {
+  unsigned int events;
+  unsigned long long data __attribute__ ((aligned(8)));
+};
+
+#define DESC_p "packed attribute"
+struct epoll_event_p {
+  unsigned int events;
+  unsigned long long data;
+} __attribute__ ((packed));
+
+#define DESC_pstruct4 "packed attribute, 4-byte struct alignment"
+struct epoll_event_pstruct4 {
+  unsigned int events;
+  unsigned long long data;
+} __attribute__ ((packed)) __attribute__ ((aligned(4)));
+
+#define DESC_pstruct8 "packed attribute, 8-byte struct alignment"
+struct epoll_event_pstruct8 {
+  unsigned int events;
+  unsigned long long data;
+} __attribute__ ((packed)) __attribute__ ((aligned(8)));
+
+#define DESC_pdata4 "packed attribute, 4-byte alignment for data"
+struct epoll_event_pdata4 {
+  unsigned int events;
+  unsigned long long data __attribute__ ((aligned(4)));
+} __attribute__ ((packed));
+
+#define DESC_pdata8 "packed attribute, 8-byte alignment for data"
+struct epoll_event_pdata8 {
+  unsigned int events;
+  unsigned long long data __attribute__ ((aligned(8)));
+} __attribute__ ((packed));
diff --git a/gcc/testsuite/gcc.dg/compat/struct-align-2_main.c b/gcc/testsuite/gcc.dg/compat/struct-align-2_main.c
new file mode 100644 (file)
index 0000000..b1dece1
--- /dev/null
@@ -0,0 +1,14 @@
+/* Test compatibility of structure layout and alignment for a struct
+   containing an int and a long long, with various combinations of
+   packed and aligned attributes.  The struct is from the Linux kernel.  */
+
+extern void struct_align_2_x (void);
+extern void exit (int);
+int fails;
+
+int
+main ()
+{
+  struct_align_2_x ();
+  exit (0);
+}
diff --git a/gcc/testsuite/gcc.dg/compat/struct-align-2_x.c b/gcc/testsuite/gcc.dg/compat/struct-align-2_x.c
new file mode 100644 (file)
index 0000000..e59cec3
--- /dev/null
@@ -0,0 +1,79 @@
+/* Disable this test for 16-bit targets.  */
+
+#if __INT_MAX__ > 32767
+
+#include "compat-common.h"
+#include "struct-align-2.h"
+
+#define SETUP(NAME,V1,V2,V3)                                   \
+struct outer_##NAME {                                          \
+  int i;                                                       \
+  struct epoll_event_##NAME ee;                                        \
+};                                                             \
+                                                               \
+unsigned int v1_##NAME = V1;                                   \
+unsigned int v2_##NAME = V2;                                   \
+unsigned long long v3_##NAME = V3;                             \
+                                                               \
+struct outer_##NAME s_##NAME[2] =                              \
+ { {V1, { V2, V3 } }, { V1, { V2, V3 } } };                    \
+                                                               \
+extern void test_##NAME (void);                                        \
+extern void checkp_##NAME (struct outer_##NAME *);             \
+extern void checkg_##NAME (void);                              \
+                                                               \
+void                                                           \
+pass_##NAME (struct outer_##NAME s)                            \
+{                                                              \
+  checkp_##NAME (&s);                                          \
+}                                                              \
+                                                               \
+struct outer_##NAME                                            \
+return_##NAME (void)                                           \
+{                                                              \
+  return s_##NAME[0];                                          \
+}
+
+#define CHECK(NAME)                                            \
+  test_##NAME()
+
+SETUP (orig,101, 102, 0x0101010101010101ULL)
+SETUP (structmax, 103, 104, 0x1212121212121212ULL)
+SETUP (struct4, 105, 106, 0x2323232323232323ULL)
+SETUP (struct8, 107, 108, 0x3434343434343434ULL)
+SETUP (data4, 109, 110, 0x4545454545454545ULL)
+SETUP (data8, 111, 112, 0x5656565656565656ULL)
+SETUP (p, 113, 114, 0x6767676767676767ULL)
+SETUP (pstruct4, 115, 116, 0x7878787878787878ULL)
+SETUP (pstruct8, 117, 118, 0x8989898989898989ULL)
+SETUP (pdata4, 119, 120, 0x9A9A9A9A9A9A9A9AULL)
+SETUP (pdata8, 121, 122, 0xABABABABABABABABULL)
+
+void
+struct_align_2_x (void)
+{
+  DEBUG_INIT
+
+  CHECK (orig);
+  CHECK (structmax);
+  CHECK (struct4);
+  CHECK (struct8);
+  CHECK (data4);
+  CHECK (data8);
+  CHECK (p);
+  CHECK (pstruct4);
+  CHECK (pstruct8);
+  CHECK (pdata4);
+  CHECK (pdata8);
+
+  DEBUG_FINI
+
+  if (fails != 0)
+    abort ();
+}
+
+#else
+
+void struct_align_2_x (void) {}
+
+#endif  /* __INT_MAX__ */
diff --git a/gcc/testsuite/gcc.dg/compat/struct-align-2_y.c b/gcc/testsuite/gcc.dg/compat/struct-align-2_y.c
new file mode 100644 (file)
index 0000000..0a5ec6e
--- /dev/null
@@ -0,0 +1,69 @@
+/* Disable this test for 16-bit targets.  */
+
+#if __INT_MAX__ > 32767
+
+#include "compat-common.h"
+#include "struct-align-2.h"
+
+#define TEST(NAME)                                             \
+struct outer_##NAME {                                          \
+  int i;                                                       \
+  struct epoll_event_##NAME ee;                                        \
+};                                                             \
+                                                               \
+extern unsigned int v1_##NAME;                                 \
+extern unsigned int v2_##NAME;                                 \
+extern unsigned long long v3_##NAME;                           \
+                                                               \
+extern struct outer_##NAME s_##NAME[2];                                \
+                                                               \
+extern void pass_##NAME (struct outer_##NAME);                 \
+extern struct outer_##NAME return_##NAME (void);               \
+                                                               \
+void                                                           \
+checkp_##NAME (struct outer_##NAME *p)                         \
+{                                                              \
+  if (p->i != v1_##NAME)                                       \
+    DEBUG_CHECK;                                               \
+  if (p->ee.events != v2_##NAME)                               \
+    DEBUG_CHECK;                                               \
+  if (p->ee.data != v3_##NAME)                                 \
+    DEBUG_CHECK;                                               \
+}                                                              \
+                                                               \
+void                                                           \
+test_##NAME (void)                                             \
+{                                                              \
+  struct outer_##NAME s;                                       \
+  DEBUG_FPUTS (DESC_##NAME);                                   \
+  DEBUG_NL;                                                    \
+  DEBUG_FPUTS ("  global array");                              \
+  checkp_##NAME (&s_##NAME[0]);                                        \
+  checkp_##NAME (&s_##NAME[1]);                                        \
+  DEBUG_NL;                                                    \
+  DEBUG_FPUTS ("  argument");                                  \
+  pass_##NAME (s_##NAME[0]);                                   \
+  DEBUG_NL;                                                    \
+  DEBUG_FPUTS ("  function result");                           \
+  s = return_##NAME ();                                                \
+  checkp_##NAME (&s);                                          \
+  DEBUG_NL;                                                    \
+}
+
+TEST (orig)
+TEST (structmax)
+TEST (struct4)
+TEST (struct8)
+TEST (data4)
+TEST (data8)
+TEST (p)
+TEST (pstruct4)
+TEST (pstruct8)
+TEST (pdata4)
+TEST (pdata8)
+
+#else
+
+int i;  /* prevent compiling an empty file */
+
+#endif  /* __INT_MAX__ */