Birdlib: Modify lists to avoid problems with pointer aliasing rules

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)
This commit is contained in:
Jan Moskyto Matejka 2016-03-23 01:45:37 +01:00 committed by Ondrej Zajicek (work)
parent 665b8e5283
commit 54bb032d21
2 changed files with 20 additions and 7 deletions

View file

@ -41,7 +41,7 @@ add_tail(list *l, node *n)
{ {
node *z = l->tail; node *z = l->tail;
n->next = (node *) &l->null; n->next = &l->tail_node;
n->prev = z; n->prev = z;
z->next = n; z->next = n;
l->tail = n; l->tail = n;
@ -60,7 +60,7 @@ add_head(list *l, node *n)
node *z = l->head; node *z = l->head;
n->next = z; n->next = z;
n->prev = (node *) &l->head; n->prev = &l->head_node;
z->prev = n; z->prev = n;
l->head = n; l->head = n;
} }
@ -133,9 +133,9 @@ replace_node(node *old, node *new)
LIST_INLINE void LIST_INLINE void
init_list(list *l) init_list(list *l)
{ {
l->head = (node *) &l->null; l->head = &l->tail_node;
l->null = NULL; 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; p->next = q;
q->prev = p; q->prev = p;
q = l->tail; q = l->tail;
q->next = (node *) &to->null; q->next = &to->tail_node;
to->tail = q; to->tail = q;
} }

View file

@ -26,10 +26,23 @@ typedef struct node {
struct node *next, *prev; struct node *next, *prev;
} node; } node;
typedef struct list { /* In fact two overlayed nodes */ typedef union list { /* In fact two overlayed nodes */
struct node *head, *null, *tail; 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; } list;
#define NODE (node *) #define NODE (node *)
#define HEAD(list) ((void *)((list).head)) #define HEAD(list) ((void *)((list).head))
#define TAIL(list) ((void *)((list).tail)) #define TAIL(list) ((void *)((list).tail))