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];
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.
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: aliasing -fno-tree- tail-merge && ./a.out ; echo $? tail-merge && ./a.out ; echo $? aliasing -fno-tree- tail-merge && ./a.out ; echo $? tail-merge && ./a.out ; echo $?
...
$ gcc -DFORCE="1 ||" bug-mod.c -O2 -fno-strict-
0
$ gcc -DFORCE="1 ||" bug-mod.c -O2 -fstrict-aliasing -fno-tree-
0
$ gcc -DFORCE="0 &&" bug-mod.c -O2 -fno-strict-
0
$ gcc -DFORCE="0 &&" bug-mod.c -O2 -fstrict-aliasing -fno-tree-
1
...
The last result seems to suggest that the example is not type-safe.
My understanding is that the problem is in the line: heads[2] )->next = node.next */
n->prev->next = n->next;
where we effectively do:
/* ((struct node*)&
which is type-unsafe.