Patchwork Xfail builtin-object-size-8.c test (PR tree-optimization/54570)

login
register
mail settings
Submitter Jakub Jelinek
Date Dec. 11, 2012, 2:21 p.m.
Message ID <20121211142107.GP2315@tucnak.redhat.com>
Download mbox | patch
Permalink /patch/205239/
State New
Headers show

Comments

Jakub Jelinek - Dec. 11, 2012, 2:21 p.m.
Hi!

As discussed on IRC, fixing this issue is probably 4.9 material, we have
some plans, but not for 4.8.  What GCC generates is actually not incorrect,
given __builtin_object_size (x, 1) being a high bound, it is just larger than
strictly required, but I hope it won't trigger very much on real-world code,
where it could mean less strict -D_FORTIFY_SOURCE=2 protection.
The following patch xfails the problematic testcase and instead adds a new
testcase which tests the same things, but doesn't test interaction of
different __builtin_object_size calls (for different fields) from the same
pointer.  Tested on x86_64-linux, ok for trunk?

2012-12-11  Jakub Jelinek  <jakub@redhat.com>

	PR tree-optimization/54570
	* gcc.dg/builtin-object-size-8.c: Xfail.
	* gcc.dg/builtin-object-size-13.c: New test.


	Jakub
Richard Guenther - Dec. 11, 2012, 2:21 p.m.
On Tue, 11 Dec 2012, Jakub Jelinek wrote:

> Hi!
> 
> As discussed on IRC, fixing this issue is probably 4.9 material, we have
> some plans, but not for 4.8.  What GCC generates is actually not incorrect,
> given __builtin_object_size (x, 1) being a high bound, it is just larger than
> strictly required, but I hope it won't trigger very much on real-world code,
> where it could mean less strict -D_FORTIFY_SOURCE=2 protection.
> The following patch xfails the problematic testcase and instead adds a new
> testcase which tests the same things, but doesn't test interaction of
> different __builtin_object_size calls (for different fields) from the same
> pointer.  Tested on x86_64-linux, ok for trunk?

Ok.

Thanks,
Richard.

> 2012-12-11  Jakub Jelinek  <jakub@redhat.com>
> 
> 	PR tree-optimization/54570
> 	* gcc.dg/builtin-object-size-8.c: Xfail.
> 	* gcc.dg/builtin-object-size-13.c: New test.
> 
> --- gcc/testsuite/gcc.dg/builtin-object-size-8.c.jj	2009-07-20 20:41:51.000000000 +0200
> +++ gcc/testsuite/gcc.dg/builtin-object-size-8.c	2012-12-11 15:13:59.646748335 +0100
> @@ -1,4 +1,4 @@
> -/* { dg-do run } */
> +/* { dg-do run { xfail *-*-* } } */
>  /* { dg-options "-O2" } */
>  
>  typedef __SIZE_TYPE__ size_t;
> --- gcc/testsuite/gcc.dg/builtin-object-size-13.c.jj	2012-12-11 15:10:48.046891600 +0100
> +++ gcc/testsuite/gcc.dg/builtin-object-size-13.c	2012-12-11 15:10:24.000000000 +0100
> @@ -0,0 +1,351 @@
> +/* { dg-do run } */
> +/* { dg-options "-O2" } */
> +
> +typedef __SIZE_TYPE__ size_t;
> +extern void *malloc (size_t);
> +extern void free (void *);
> +extern void abort (void);
> +
> +union A
> +{
> +  int a1;
> +  char a2[3];
> +};
> +
> +union B
> +{
> +  long long b1;
> +  union A b2;
> +};
> +
> +struct C
> +{
> +  int c1;
> +  union A c2;
> +};
> +
> +struct D
> +{
> +  int d1;
> +  union B d2;
> +};
> +
> +union E
> +{
> +  struct C e1;
> +  char e2[3];
> +};
> +
> +union F
> +{
> +  int f1;
> +  struct D f2;
> +};
> +
> +struct G
> +{
> +  union A g1;
> +  char g2;
> +};
> +
> +struct H
> +{
> +  int h1;
> +  union E h2;
> +};
> +
> +#define T(X, S0, S1) \
> +  if (__builtin_object_size (X, 0) != (S0))	\
> +    abort ();					\
> +  if (__builtin_object_size (X, 1) != (S1))	\
> +    abort ();					\
> +  if (__builtin_object_size (X, 2) != (S0))	\
> +    abort ();					\
> +  if (__builtin_object_size (X, 3) != (S1))	\
> +    abort ()
> +#define TS(X, S0) T(&X, S0, sizeof (X))
> +#define TA(X, S0, S1) \
> +  T(X, S0, S1); T(&X[0], S0, S1); T(&X[1], (S0) - 1, (S1) - 1)
> +#define TF(X, S0) TA(X, S0, S0)
> +
> +int
> +main (void)
> +{
> +  size_t s, o, o2;
> +
> +  s = sizeof (union A);
> +  o = 0;
> +  union A *a1 = malloc (s);
> +  union A *a2 = malloc (o + 212);
> +  TS (a1->a1, s);
> +  s = o + 212;
> +  TS (a2->a1, s);
> +  free (a2);
> +  free (a1);
> +  s = sizeof (union A);
> +  o = 0;
> +  a1 = malloc (s);
> +  a2 = malloc (o + 212);
> +  TF (a1->a2, s);
> +  s = o + 212;
> +  TF (a2->a2, s);
> +  free (a2);
> +  free (a1);
> +
> +  s = sizeof (union B);
> +  o = 0;
> +  union B *b1 = malloc (s);
> +  union B *b2 = malloc (o + 212);
> +  TS (b1->b1, s);
> +  s = o + 212;
> +  TS (b2->b1, s);
> +  free (b2);
> +  free (b1);
> +  s = sizeof (union B);
> +  o = 0;
> +  b1 = malloc (s);
> +  b2 = malloc (o + 212);
> +  TS (b1->b2.a1, s);
> +  s = o + 212;
> +  TS (b2->b2.a1, s);
> +  free (b2);
> +  free (b1);
> +  s = sizeof (union B);
> +  o = 0;
> +  b1 = malloc (s);
> +  b2 = malloc (o + 212);
> +  TF (b1->b2.a2, s);
> +  s = o + 212;
> +  TF (b2->b2.a2, s);
> +  free (b2);
> +  free (b1);
> +
> +  s = sizeof (struct C);
> +  o = __builtin_offsetof (struct C, c2);
> +  struct C *c1 = malloc (s);
> +  struct C *c2 = malloc (o + 212);
> +  TS (c1->c1, s);
> +  s = o + 212;
> +  TS (c2->c1, s);
> +  free (c2);
> +  free (c1);
> +  s = sizeof (struct C);
> +  o = __builtin_offsetof (struct C, c2);
> +  c1 = malloc (s);
> +  c2 = malloc (o + 212);
> +  TS (c1->c2.a1, s - o);
> +  s = o + 212;
> +  TS (c2->c2.a1, s - o);
> +  free (c2);
> +  free (c1);
> +  s = sizeof (struct C);
> +  o = __builtin_offsetof (struct C, c2);
> +  c1 = malloc (s);
> +  c2 = malloc (o + 212);
> +  TF (c1->c2.a2, s - o);
> +  s = o + 212;
> +  TF (c2->c2.a2, s - o);
> +  free (c2);
> +  free (c1);
> +
> +  s = sizeof (struct D);
> +  o = __builtin_offsetof (struct D, d2);
> +  struct D *d1 = malloc (s);
> +  struct D *d2 = malloc (o + 212);
> +  TS (d1->d1, s);
> +  s = o + 212;
> +  TS (d2->d1, s);
> +  free (d2);
> +  free (d1);
> +  s = sizeof (struct D);
> +  o = __builtin_offsetof (struct D, d2);
> +  d1 = malloc (s);
> +  d2 = malloc (o + 212);
> +  TS (d1->d2.b1, s - o);
> +  s = o + 212;
> +  TS (d2->d2.b1, s - o);
> +  free (d2);
> +  free (d1);
> +  s = sizeof (struct D);
> +  o = __builtin_offsetof (struct D, d2);
> +  d1 = malloc (s);
> +  d2 = malloc (o + 212);
> +  TS (d1->d2.b2.a1, s - o);
> +  s = o + 212;
> +  TS (d2->d2.b2.a1, s - o);
> +  free (d2);
> +  free (d1);
> +  s = sizeof (struct D);
> +  o = __builtin_offsetof (struct D, d2);
> +  d1 = malloc (s);
> +  d2 = malloc (o + 212);
> +  TF (d1->d2.b2.a2, s - o);
> +  s = o + 212;
> +  TF (d2->d2.b2.a2, s - o);
> +  free (d2);
> +  free (d1);
> +
> +  s = sizeof (union E);
> +  o = __builtin_offsetof (union E, e1.c2);
> +  union E *e1 = malloc (s);
> +  union E *e2 = malloc (o + 212);
> +  TS (e1->e1.c1, s);
> +  s = o + 212;
> +  TS (e2->e1.c1, s);
> +  free (e2);
> +  free (e1);
> +  s = sizeof (union E);
> +  o = __builtin_offsetof (union E, e1.c2);
> +  e1 = malloc (s);
> +  e2 = malloc (o + 212);
> +  TS (e1->e1.c2.a1, s - o);
> +  s = o + 212;
> +  TS (e2->e1.c2.a1, s - o);
> +  free (e2);
> +  free (e1);
> +  s = sizeof (union E);
> +  o = __builtin_offsetof (union E, e1.c2);
> +  e1 = malloc (s);
> +  e2 = malloc (o + 212);
> +  TF (e1->e1.c2.a2, s - o);
> +  s = o + 212;
> +  TF (e2->e1.c2.a2, s - o);
> +  free (e2);
> +  free (e1);
> +  s = sizeof (union E);
> +  o = __builtin_offsetof (union E, e1.c2);
> +  e1 = malloc (s);
> +  e2 = malloc (o + 212);
> +  TF (e1->e2, s);
> +  s = o + 212;
> +  TF (e2->e2, s);
> +  free (e2);
> +  free (e1);
> +
> +  s = sizeof (union F);
> +  o = __builtin_offsetof (union F, f2.d2);
> +  union F *f1 = malloc (s);
> +  union F *f2 = malloc (o + 212);
> +  TS (f1->f1, s);
> +  s = o + 212;
> +  TS (f2->f1, s);
> +  free (f2);
> +  free (f1);
> +  s = sizeof (union F);
> +  o = __builtin_offsetof (union F, f2.d2);
> +  f1 = malloc (s);
> +  f2 = malloc (o + 212);
> +  TS (f1->f2.d1, s);
> +  s = o + 212;
> +  TS (f2->f2.d1, s);
> +  free (f2);
> +  free (f1);
> +  s = sizeof (union F);
> +  o = __builtin_offsetof (union F, f2.d2);
> +  f1 = malloc (s);
> +  f2 = malloc (o + 212);
> +  TS (f1->f2.d2.b1, s - o);
> +  s = o + 212;
> +  TS (f2->f2.d2.b1, s - o);
> +  free (f2);
> +  free (f1);
> +  s = sizeof (union F);
> +  o = __builtin_offsetof (union F, f2.d2);
> +  f1 = malloc (s);
> +  f2 = malloc (o + 212);
> +  TS (f1->f2.d2.b2.a1, s - o);
> +  s = o + 212;
> +  TS (f2->f2.d2.b2.a1, s - o);
> +  free (f2);
> +  free (f1);
> +  s = sizeof (union F);
> +  o = __builtin_offsetof (union F, f2.d2);
> +  f1 = malloc (s);
> +  f2 = malloc (o + 212);
> +  TF (f1->f2.d2.b2.a2, s - o);
> +  s = o + 212;
> +  TF (f2->f2.d2.b2.a2, s - o);
> +  free (f2);
> +  free (f1);
> +
> +  s = sizeof (struct G);
> +  o = __builtin_offsetof (struct G, g2);
> +  struct G *g1 = malloc (s);
> +  struct G *g2 = malloc (o + 212);
> +  TS (g1->g1.a1, s);
> +  s = o + 212;
> +  TS (g2->g1.a1, s);
> +  free (g2);
> +  free (g1);
> +  s = sizeof (struct G);
> +  o = __builtin_offsetof (struct G, g2);
> +  g1 = malloc (s);
> +  g2 = malloc (o + 212);
> +  TA (g1->g1.a2, s, sizeof (g1->g1.a2));
> +  s = o + 212;
> +  TA (g2->g1.a2, s, sizeof (g1->g1.a2));
> +  free (g2);
> +  free (g1);
> +  s = sizeof (struct G);
> +  o = __builtin_offsetof (struct G, g2);
> +  g1 = malloc (s);
> +  g2 = malloc (o + 212);
> +  TS (g1->g2, s - o);
> +  s = o + 212;
> +  TS (g2->g2, s - o);
> +  free (g2);
> +  free (g1);
> +
> +  s = sizeof (struct H);
> +  o = __builtin_offsetof (struct H, h2);
> +  o2 = __builtin_offsetof (struct H, h2.e1.c2);
> +  struct H *h1 = malloc (s);
> +  struct H *h2 = malloc (o2 + 212);
> +  TS (h1->h1, s);
> +  s = o2 + 212;
> +  TS (h2->h1, s);
> +  free (h2);
> +  free (h1);
> +  s = sizeof (struct H);
> +  o = __builtin_offsetof (struct H, h2);
> +  o2 = __builtin_offsetof (struct H, h2.e1.c2);
> +  h1 = malloc (s);
> +  h2 = malloc (o2 + 212);
> +  TS (h1->h2.e1.c1, s - o);
> +  s = o2 + 212;
> +  TS (h2->h2.e1.c1, s - o);
> +  free (h2);
> +  free (h1);
> +  s = sizeof (struct H);
> +  o = __builtin_offsetof (struct H, h2);
> +  o2 = __builtin_offsetof (struct H, h2.e1.c2);
> +  h1 = malloc (s);
> +  h2 = malloc (o2 + 212);
> +  TS (h1->h2.e1.c2.a1, s - o2);
> +  s = o2 + 212;
> +  TS (h2->h2.e1.c2.a1, s - o2);
> +  free (h2);
> +  free (h1);
> +  s = sizeof (struct H);
> +  o = __builtin_offsetof (struct H, h2);
> +  o2 = __builtin_offsetof (struct H, h2.e1.c2);
> +  h1 = malloc (s);
> +  h2 = malloc (o2 + 212);
> +  TA (h1->h2.e1.c2.a2, s - o2, sizeof (h1->h2.e1.c2.a2));
> +  s = o2 + 212;
> +  TA (h2->h2.e1.c2.a2, s - o2, sizeof (h2->h2.e1.c2.a2));
> +  free (h2);
> +  free (h1);
> +  s = sizeof (struct H);
> +  o = __builtin_offsetof (struct H, h2);
> +  o2 = __builtin_offsetof (struct H, h2.e1.c2);
> +  h1 = malloc (s);
> +  h2 = malloc (o2 + 212);
> +  TF (h1->h2.e2, s - o);
> +  s = o2 + 212;
> +  TF (h2->h2.e2, s - o);
> +  free (h2);
> +  free (h1);
> +
> +  return 0;
> +}
> 
> 	Jakub
> 
>

Patch

--- gcc/testsuite/gcc.dg/builtin-object-size-8.c.jj	2009-07-20 20:41:51.000000000 +0200
+++ gcc/testsuite/gcc.dg/builtin-object-size-8.c	2012-12-11 15:13:59.646748335 +0100
@@ -1,4 +1,4 @@ 
-/* { dg-do run } */
+/* { dg-do run { xfail *-*-* } } */
 /* { dg-options "-O2" } */
 
 typedef __SIZE_TYPE__ size_t;
--- gcc/testsuite/gcc.dg/builtin-object-size-13.c.jj	2012-12-11 15:10:48.046891600 +0100
+++ gcc/testsuite/gcc.dg/builtin-object-size-13.c	2012-12-11 15:10:24.000000000 +0100
@@ -0,0 +1,351 @@ 
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+
+typedef __SIZE_TYPE__ size_t;
+extern void *malloc (size_t);
+extern void free (void *);
+extern void abort (void);
+
+union A
+{
+  int a1;
+  char a2[3];
+};
+
+union B
+{
+  long long b1;
+  union A b2;
+};
+
+struct C
+{
+  int c1;
+  union A c2;
+};
+
+struct D
+{
+  int d1;
+  union B d2;
+};
+
+union E
+{
+  struct C e1;
+  char e2[3];
+};
+
+union F
+{
+  int f1;
+  struct D f2;
+};
+
+struct G
+{
+  union A g1;
+  char g2;
+};
+
+struct H
+{
+  int h1;
+  union E h2;
+};
+
+#define T(X, S0, S1) \
+  if (__builtin_object_size (X, 0) != (S0))	\
+    abort ();					\
+  if (__builtin_object_size (X, 1) != (S1))	\
+    abort ();					\
+  if (__builtin_object_size (X, 2) != (S0))	\
+    abort ();					\
+  if (__builtin_object_size (X, 3) != (S1))	\
+    abort ()
+#define TS(X, S0) T(&X, S0, sizeof (X))
+#define TA(X, S0, S1) \
+  T(X, S0, S1); T(&X[0], S0, S1); T(&X[1], (S0) - 1, (S1) - 1)
+#define TF(X, S0) TA(X, S0, S0)
+
+int
+main (void)
+{
+  size_t s, o, o2;
+
+  s = sizeof (union A);
+  o = 0;
+  union A *a1 = malloc (s);
+  union A *a2 = malloc (o + 212);
+  TS (a1->a1, s);
+  s = o + 212;
+  TS (a2->a1, s);
+  free (a2);
+  free (a1);
+  s = sizeof (union A);
+  o = 0;
+  a1 = malloc (s);
+  a2 = malloc (o + 212);
+  TF (a1->a2, s);
+  s = o + 212;
+  TF (a2->a2, s);
+  free (a2);
+  free (a1);
+
+  s = sizeof (union B);
+  o = 0;
+  union B *b1 = malloc (s);
+  union B *b2 = malloc (o + 212);
+  TS (b1->b1, s);
+  s = o + 212;
+  TS (b2->b1, s);
+  free (b2);
+  free (b1);
+  s = sizeof (union B);
+  o = 0;
+  b1 = malloc (s);
+  b2 = malloc (o + 212);
+  TS (b1->b2.a1, s);
+  s = o + 212;
+  TS (b2->b2.a1, s);
+  free (b2);
+  free (b1);
+  s = sizeof (union B);
+  o = 0;
+  b1 = malloc (s);
+  b2 = malloc (o + 212);
+  TF (b1->b2.a2, s);
+  s = o + 212;
+  TF (b2->b2.a2, s);
+  free (b2);
+  free (b1);
+
+  s = sizeof (struct C);
+  o = __builtin_offsetof (struct C, c2);
+  struct C *c1 = malloc (s);
+  struct C *c2 = malloc (o + 212);
+  TS (c1->c1, s);
+  s = o + 212;
+  TS (c2->c1, s);
+  free (c2);
+  free (c1);
+  s = sizeof (struct C);
+  o = __builtin_offsetof (struct C, c2);
+  c1 = malloc (s);
+  c2 = malloc (o + 212);
+  TS (c1->c2.a1, s - o);
+  s = o + 212;
+  TS (c2->c2.a1, s - o);
+  free (c2);
+  free (c1);
+  s = sizeof (struct C);
+  o = __builtin_offsetof (struct C, c2);
+  c1 = malloc (s);
+  c2 = malloc (o + 212);
+  TF (c1->c2.a2, s - o);
+  s = o + 212;
+  TF (c2->c2.a2, s - o);
+  free (c2);
+  free (c1);
+
+  s = sizeof (struct D);
+  o = __builtin_offsetof (struct D, d2);
+  struct D *d1 = malloc (s);
+  struct D *d2 = malloc (o + 212);
+  TS (d1->d1, s);
+  s = o + 212;
+  TS (d2->d1, s);
+  free (d2);
+  free (d1);
+  s = sizeof (struct D);
+  o = __builtin_offsetof (struct D, d2);
+  d1 = malloc (s);
+  d2 = malloc (o + 212);
+  TS (d1->d2.b1, s - o);
+  s = o + 212;
+  TS (d2->d2.b1, s - o);
+  free (d2);
+  free (d1);
+  s = sizeof (struct D);
+  o = __builtin_offsetof (struct D, d2);
+  d1 = malloc (s);
+  d2 = malloc (o + 212);
+  TS (d1->d2.b2.a1, s - o);
+  s = o + 212;
+  TS (d2->d2.b2.a1, s - o);
+  free (d2);
+  free (d1);
+  s = sizeof (struct D);
+  o = __builtin_offsetof (struct D, d2);
+  d1 = malloc (s);
+  d2 = malloc (o + 212);
+  TF (d1->d2.b2.a2, s - o);
+  s = o + 212;
+  TF (d2->d2.b2.a2, s - o);
+  free (d2);
+  free (d1);
+
+  s = sizeof (union E);
+  o = __builtin_offsetof (union E, e1.c2);
+  union E *e1 = malloc (s);
+  union E *e2 = malloc (o + 212);
+  TS (e1->e1.c1, s);
+  s = o + 212;
+  TS (e2->e1.c1, s);
+  free (e2);
+  free (e1);
+  s = sizeof (union E);
+  o = __builtin_offsetof (union E, e1.c2);
+  e1 = malloc (s);
+  e2 = malloc (o + 212);
+  TS (e1->e1.c2.a1, s - o);
+  s = o + 212;
+  TS (e2->e1.c2.a1, s - o);
+  free (e2);
+  free (e1);
+  s = sizeof (union E);
+  o = __builtin_offsetof (union E, e1.c2);
+  e1 = malloc (s);
+  e2 = malloc (o + 212);
+  TF (e1->e1.c2.a2, s - o);
+  s = o + 212;
+  TF (e2->e1.c2.a2, s - o);
+  free (e2);
+  free (e1);
+  s = sizeof (union E);
+  o = __builtin_offsetof (union E, e1.c2);
+  e1 = malloc (s);
+  e2 = malloc (o + 212);
+  TF (e1->e2, s);
+  s = o + 212;
+  TF (e2->e2, s);
+  free (e2);
+  free (e1);
+
+  s = sizeof (union F);
+  o = __builtin_offsetof (union F, f2.d2);
+  union F *f1 = malloc (s);
+  union F *f2 = malloc (o + 212);
+  TS (f1->f1, s);
+  s = o + 212;
+  TS (f2->f1, s);
+  free (f2);
+  free (f1);
+  s = sizeof (union F);
+  o = __builtin_offsetof (union F, f2.d2);
+  f1 = malloc (s);
+  f2 = malloc (o + 212);
+  TS (f1->f2.d1, s);
+  s = o + 212;
+  TS (f2->f2.d1, s);
+  free (f2);
+  free (f1);
+  s = sizeof (union F);
+  o = __builtin_offsetof (union F, f2.d2);
+  f1 = malloc (s);
+  f2 = malloc (o + 212);
+  TS (f1->f2.d2.b1, s - o);
+  s = o + 212;
+  TS (f2->f2.d2.b1, s - o);
+  free (f2);
+  free (f1);
+  s = sizeof (union F);
+  o = __builtin_offsetof (union F, f2.d2);
+  f1 = malloc (s);
+  f2 = malloc (o + 212);
+  TS (f1->f2.d2.b2.a1, s - o);
+  s = o + 212;
+  TS (f2->f2.d2.b2.a1, s - o);
+  free (f2);
+  free (f1);
+  s = sizeof (union F);
+  o = __builtin_offsetof (union F, f2.d2);
+  f1 = malloc (s);
+  f2 = malloc (o + 212);
+  TF (f1->f2.d2.b2.a2, s - o);
+  s = o + 212;
+  TF (f2->f2.d2.b2.a2, s - o);
+  free (f2);
+  free (f1);
+
+  s = sizeof (struct G);
+  o = __builtin_offsetof (struct G, g2);
+  struct G *g1 = malloc (s);
+  struct G *g2 = malloc (o + 212);
+  TS (g1->g1.a1, s);
+  s = o + 212;
+  TS (g2->g1.a1, s);
+  free (g2);
+  free (g1);
+  s = sizeof (struct G);
+  o = __builtin_offsetof (struct G, g2);
+  g1 = malloc (s);
+  g2 = malloc (o + 212);
+  TA (g1->g1.a2, s, sizeof (g1->g1.a2));
+  s = o + 212;
+  TA (g2->g1.a2, s, sizeof (g1->g1.a2));
+  free (g2);
+  free (g1);
+  s = sizeof (struct G);
+  o = __builtin_offsetof (struct G, g2);
+  g1 = malloc (s);
+  g2 = malloc (o + 212);
+  TS (g1->g2, s - o);
+  s = o + 212;
+  TS (g2->g2, s - o);
+  free (g2);
+  free (g1);
+
+  s = sizeof (struct H);
+  o = __builtin_offsetof (struct H, h2);
+  o2 = __builtin_offsetof (struct H, h2.e1.c2);
+  struct H *h1 = malloc (s);
+  struct H *h2 = malloc (o2 + 212);
+  TS (h1->h1, s);
+  s = o2 + 212;
+  TS (h2->h1, s);
+  free (h2);
+  free (h1);
+  s = sizeof (struct H);
+  o = __builtin_offsetof (struct H, h2);
+  o2 = __builtin_offsetof (struct H, h2.e1.c2);
+  h1 = malloc (s);
+  h2 = malloc (o2 + 212);
+  TS (h1->h2.e1.c1, s - o);
+  s = o2 + 212;
+  TS (h2->h2.e1.c1, s - o);
+  free (h2);
+  free (h1);
+  s = sizeof (struct H);
+  o = __builtin_offsetof (struct H, h2);
+  o2 = __builtin_offsetof (struct H, h2.e1.c2);
+  h1 = malloc (s);
+  h2 = malloc (o2 + 212);
+  TS (h1->h2.e1.c2.a1, s - o2);
+  s = o2 + 212;
+  TS (h2->h2.e1.c2.a1, s - o2);
+  free (h2);
+  free (h1);
+  s = sizeof (struct H);
+  o = __builtin_offsetof (struct H, h2);
+  o2 = __builtin_offsetof (struct H, h2.e1.c2);
+  h1 = malloc (s);
+  h2 = malloc (o2 + 212);
+  TA (h1->h2.e1.c2.a2, s - o2, sizeof (h1->h2.e1.c2.a2));
+  s = o2 + 212;
+  TA (h2->h2.e1.c2.a2, s - o2, sizeof (h2->h2.e1.c2.a2));
+  free (h2);
+  free (h1);
+  s = sizeof (struct H);
+  o = __builtin_offsetof (struct H, h2);
+  o2 = __builtin_offsetof (struct H, h2.e1.c2);
+  h1 = malloc (s);
+  h2 = malloc (o2 + 212);
+  TF (h1->h2.e2, s - o);
+  s = o2 + 212;
+  TF (h2->h2.e2, s - o);
+  free (h2);
+  free (h1);
+
+  return 0;
+}