]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Birdlib: Modify lists to avoid problems with pointer aliasing rules
authorJan Moskyto Matejka <mq@ucw.cz>
Wed, 23 Mar 2016 00:45:37 +0000 (01:45 +0100)
committerOndrej Zajicek (work) <santiago@crfreenet.org>
Wed, 23 Mar 2016 01:21:42 +0000 (02:21 +0100)
The old linked list implementation used some wild typecasts and required
GCC option -fno-strict-aliasing to work properly. This patch fixes that.
However, we still keep the option due to other potential problems.

(Commited by Ondrej Santiago Zajicek)

lib/lists.c
lib/lists.h

index 20a9a0728e5ac158079c07afeb976ee07611a4ac..12ef3cc633010158f9bd2ea1abba0eeb643e640e 100644 (file)
@@ -41,7 +41,7 @@ add_tail(list *l, node *n)
 {
   node *z = l->tail;
 
-  n->next = (node *) &l->null;
+  n->next = &l->tail_node;
   n->prev = z;
   z->next = n;
   l->tail = n;
@@ -60,7 +60,7 @@ add_head(list *l, node *n)
   node *z = l->head;
 
   n->next = z;
-  n->prev = (node *) &l->head;
+  n->prev = &l->head_node;
   z->prev = n;
   l->head = n;
 }
@@ -133,9 +133,9 @@ replace_node(node *old, node *new)
 LIST_INLINE void
 init_list(list *l)
 {
-  l->head = (node *) &l->null;
+  l->head = &l->tail_node;
   l->null = NULL;
-  l->tail = (node *) &l->head;
+  l->tail = &l->head_node;
 }
 
 /**
@@ -155,6 +155,6 @@ add_tail_list(list *to, list *l)
   p->next = q;
   q->prev = p;
   q = l->tail;
-  q->next = (node *) &to->null;
+  q->next = &to->tail_node;
   to->tail = q;
 }
index 4204cbc5bec061f78ae066d807f7f2af02c5490a..51856b053cdbf6e0c2158cb544233c5026fa8a24 100644 (file)
@@ -26,10 +26,23 @@ typedef struct node {
   struct node *next, *prev;
 } node;
 
-typedef struct list {                  /* In fact two overlayed nodes */
-  struct node *head, *null, *tail;
+typedef union list {                   /* In fact two overlayed nodes */
+  struct {                             /* Head node */
+    struct node head_node;
+    void *head_padding;
+  };
+  struct {                             /* Tail node */
+    void *tail_padding;
+    struct node tail_node;
+  };
+  struct {                             /* Split to separate pointers */
+    struct node *head;
+    struct node *null;
+    struct node *tail;
+  };
 } list;
 
+
 #define NODE (node *)
 #define HEAD(list) ((void *)((list).head))
 #define TAIL(list) ((void *)((list).tail))