aboutsummaryrefslogtreecommitdiffstats
path: root/gcc-4.4.0/gcc/testsuite/gcc.c-torture/execute/pr40022.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc-4.4.0/gcc/testsuite/gcc.c-torture/execute/pr40022.c')
-rw-r--r--gcc-4.4.0/gcc/testsuite/gcc.c-torture/execute/pr40022.c51
1 files changed, 51 insertions, 0 deletions
diff --git a/gcc-4.4.0/gcc/testsuite/gcc.c-torture/execute/pr40022.c b/gcc-4.4.0/gcc/testsuite/gcc.c-torture/execute/pr40022.c
new file mode 100644
index 000000000..1e8f728ab
--- /dev/null
+++ b/gcc-4.4.0/gcc/testsuite/gcc.c-torture/execute/pr40022.c
@@ -0,0 +1,51 @@
+extern void abort (void);
+
+struct A
+{
+ struct A *a;
+};
+
+struct B
+{
+ struct A *b;
+};
+
+__attribute__((noinline))
+struct A *
+foo (struct A *x)
+{
+ asm volatile ("" : : "g" (x) : "memory");
+ return x;
+}
+
+__attribute__((noinline))
+void
+bar (struct B *w, struct A *x, struct A *y, struct A *z)
+{
+ struct A **c;
+ c = &w->b;
+ *c = foo (x);
+ while (*c)
+ c = &(*c)->a;
+ *c = foo (y);
+ while (*c)
+ c = &(*c)->a;
+ *c = foo (z);
+}
+
+struct B d;
+struct A e, f, g;
+
+int
+main (void)
+{
+ f.a = &g;
+ bar (&d, &e, &f, 0);
+ if (d.b == 0
+ || d.b->a == 0
+ || d.b->a->a == 0
+ || d.b->a->a->a != 0)
+ abort ();
+ return 0;
+}
+