| /* { 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; |
| } |