https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61964
vries at gcc dot gnu.org changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |vries at gcc dot gnu.org --- Comment #8 from vries at gcc dot gnu.org --- Using this patch on the example from the description field, I can modify the example on the command line: ... $ diff -u bug-orig.c bug-mod.c --- bug-orig.c 2014-07-31 14:00:50.663275717 +0200 +++ bug-mod.c 2014-07-31 14:01:49.403276412 +0200 @@ -11,7 +11,7 @@ struct node *n = head->first; struct head *h = &heads[k]; - if (n->prev == (void *)h) + if (FORCE n->prev == (void *)h) h->first = n->next; else n->prev->next = n->next; ... 1. -DFORCE="" gives the original 2. -DFORCE="1 ||" forces the condition to true 3. -DFORCE="0 &&" forces the confition to false In this experiment, we don't use tree-tail-merge: ... $ gcc -DFORCE="1 ||" bug-mod.c -O2 -fno-strict-aliasing -fno-tree-tail-merge && ./a.out ; echo $? 0 $ gcc -DFORCE="1 ||" bug-mod.c -O2 -fstrict-aliasing -fno-tree-tail-merge && ./a.out ; echo $? 0 $ gcc -DFORCE="0 &&" bug-mod.c -O2 -fno-strict-aliasing -fno-tree-tail-merge && ./a.out ; echo $? 0 $ gcc -DFORCE="0 &&" bug-mod.c -O2 -fstrict-aliasing -fno-tree-tail-merge && ./a.out ; echo $? 1 ... The last result seems to suggest that the example is not type-safe. My understanding is that the problem is in the line: n->prev->next = n->next; where we effectively do: /* ((struct node*)&heads[2])->next = node.next */ which is type-unsafe.