1  /* { dg-do run } */
       2  /* { dg-options "-O2" } */
       3  
       4  #include "builtin-object-size-common.h"
       5  
       6  union A
       7  {
       8    int a1;
       9    char a2[3];
      10  };
      11  
      12  union B
      13  {
      14    long long b1;
      15    union A b2;
      16  };
      17  
      18  struct C
      19  {
      20    int c1;
      21    union A c2;
      22  };
      23  
      24  struct D
      25  {
      26    int d1;
      27    union B d2;
      28  };
      29  
      30  union E
      31  {
      32    struct C e1;
      33    char e2[3];
      34  };
      35  
      36  union F
      37  {
      38    int f1;
      39    struct D f2;
      40  };
      41  
      42  struct G
      43  {
      44    union A g1;
      45    char g2;
      46  };
      47  
      48  struct H
      49  {
      50    int h1;
      51    union E h2;
      52  };
      53  
      54  #define T(X, S0, S1) \
      55    if (__builtin_object_size (X, 0) != (S0))	\
      56      FAIL ();					\
      57    if (__builtin_object_size (X, 1) != (S1))	\
      58      FAIL ();					\
      59    if (__builtin_object_size (X, 2) != (S0))	\
      60      FAIL ();					\
      61    if (__builtin_object_size (X, 3) != (S1))	\
      62      FAIL ()
      63  #define TS(X, S0) T(&X, S0, sizeof (X))
      64  #define TA(X, S0, S1) \
      65    T(X, S0, S1); T(&X[0], S0, S1); T(&X[1], (S0) - 1, (S1) - 1)
      66  #define TF(X, S0) TA(X, S0, S0)
      67  
      68  int
      69  main (void)
      70  {
      71    size_t s, o, o2;
      72  
      73    s = sizeof (union A);
      74    o = 0;
      75    union A *a1 = malloc (s);
      76    union A *a2 = malloc (o + 212);
      77    TS (a1->a1, s);
      78    TF (a1->a2, s);
      79    s = o + 212;
      80    TS (a2->a1, s);
      81    TF (a2->a2, s);
      82    free (a2);
      83    free (a1);
      84  
      85    s = sizeof (union B);
      86    o = 0;
      87    union B *b1 = malloc (s);
      88    union B *b2 = malloc (o + 212);
      89    TS (b1->b1, s);
      90    TS (b1->b2.a1, s);
      91    TF (b1->b2.a2, s);
      92    s = o + 212;
      93    TS (b2->b1, s);
      94    TS (b2->b2.a1, s);
      95    TF (b2->b2.a2, s);
      96    free (b2);
      97    free (b1);
      98  
      99    s = sizeof (struct C);
     100    o = __builtin_offsetof (struct C, c2);
     101    struct C *c1 = malloc (s);
     102    struct C *c2 = malloc (o + 212);
     103    TS (c1->c1, s);
     104    TS (c1->c2.a1, s - o);
     105    TF (c1->c2.a2, s - o);
     106    s = o + 212;
     107    TS (c2->c1, s);
     108    TS (c2->c2.a1, s - o);
     109    TF (c2->c2.a2, s - o);
     110    free (c2);
     111    free (c1);
     112  
     113    s = sizeof (struct D);
     114    o = __builtin_offsetof (struct D, d2);
     115    struct D *d1 = malloc (s);
     116    struct D *d2 = malloc (o + 212);
     117    TS (d1->d1, s);
     118    TS (d1->d2.b1, s - o);
     119    TS (d1->d2.b2.a1, s - o);
     120    TF (d1->d2.b2.a2, s - o);
     121    s = o + 212;
     122    TS (d2->d1, s);
     123    TS (d2->d2.b1, s - o);
     124    TS (d2->d2.b2.a1, s - o);
     125    TF (d2->d2.b2.a2, s - o);
     126    free (d2);
     127    free (d1);
     128  
     129    s = sizeof (union E);
     130    o = __builtin_offsetof (union E, e1.c2);
     131    union E *e1 = malloc (s);
     132    union E *e2 = malloc (o + 212);
     133    TS (e1->e1.c1, s);
     134    TS (e1->e1.c2.a1, s - o);
     135    TF (e1->e1.c2.a2, s - o);
     136    TF (e1->e2, s);
     137    s = o + 212;
     138    TS (e2->e1.c1, s);
     139    TS (e2->e1.c2.a1, s - o);
     140    TF (e2->e1.c2.a2, s - o);
     141    TF (e2->e2, s);
     142    free (e2);
     143    free (e1);
     144  
     145    s = sizeof (union F);
     146    o = __builtin_offsetof (union F, f2.d2);
     147    union F *f1 = malloc (s);
     148    union F *f2 = malloc (o + 212);
     149    TS (f1->f1, s);
     150    TS (f1->f2.d1, s);
     151    TS (f1->f2.d2.b1, s - o);
     152    TS (f1->f2.d2.b2.a1, s - o);
     153    TF (f1->f2.d2.b2.a2, s - o);
     154    s = o + 212;
     155    TS (f2->f1, s);
     156    TS (f2->f2.d1, s);
     157    TS (f2->f2.d2.b1, s - o);
     158    TS (f2->f2.d2.b2.a1, s - o);
     159    TF (f2->f2.d2.b2.a2, s - o);
     160    free (f2);
     161    free (f1);
     162  
     163    s = sizeof (struct G);
     164    o = __builtin_offsetof (struct G, g2);
     165    struct G *g1 = malloc (s);
     166    struct G *g2 = malloc (o + 212);
     167    TS (g1->g1.a1, s);
     168    TA (g1->g1.a2, s, sizeof (g1->g1.a2));
     169    TS (g1->g2, s - o);
     170    s = o + 212;
     171    TS (g2->g1.a1, s);
     172    TA (g2->g1.a2, s, sizeof (g1->g1.a2));
     173    TS (g2->g2, s - o);
     174    free (g2);
     175    free (g1);
     176  
     177    s = sizeof (struct H);
     178    o = __builtin_offsetof (struct H, h2);
     179    o2 = __builtin_offsetof (struct H, h2.e1.c2);
     180    struct H *h1 = malloc (s);
     181    struct H *h2 = malloc (o2 + 212);
     182    TS (h1->h1, s);
     183    TS (h1->h2.e1.c1, s - o);
     184    TS (h1->h2.e1.c2.a1, s - o2);
     185    TA (h1->h2.e1.c2.a2, s - o2, sizeof (h1->h2.e1.c2.a2));
     186    TF (h1->h2.e2, s - o);
     187    s = o2 + 212;
     188    TS (h2->h1, s);
     189    TS (h2->h2.e1.c1, s - o);
     190    TS (h2->h2.e1.c2.a1, s - o2);
     191    TA (h2->h2.e1.c2.a2, s - o2, sizeof (h2->h2.e1.c2.a2));
     192    TF (h2->h2.e2, s - o);
     193    free (h2);
     194    free (h1);
     195  
     196    DONE ();
     197  }