diff options
Diffstat (limited to 'gcc/testsuite/gcc.dg/tree-ssa/pr22591.c')
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/pr22591.c | 56 |
1 files changed, 56 insertions, 0 deletions
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr22591.c b/gcc/testsuite/gcc.dg/tree-ssa/pr22591.c new file mode 100644 index 000000000..f1f5ec849 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr22591.c @@ -0,0 +1,56 @@ +/* { dg-do run } */ +/* { dg-options "-O2" } */ + +void abort (); + +typedef struct _Node +{ + struct _Node *next, *prev; +} Node; + +void __attribute__ ((noinline)) append (Node * q, Node * p) +{ + p->next = q; + p->prev = q; + q->next = p; + q->prev = p; +} + +inline void +swap (Node ** a, Node ** b) +{ + Node *tmp = *a; + *a = *b; + *b = tmp; +} + +/* Miscompilation seems to happen here. If one removes the if condition + (which should be true) the program works fine. */ +void +ListSwap (Node * x, Node * y) +{ + Node *tmp; + if (x->next) + { + swap (&x->next, &y->next); + swap (&x->prev, &y->prev); + x->next->prev = x->prev->next = x; + y->next->prev = y->prev->next = y; + } +} + +int +main () +{ + Node A, A1, B, B1; + + append (&A, &A1); + append (&B, &B1); + + ListSwap (&A, &B); + + if (&A != A.next->prev) + abort (); + + return 0; +} |