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:
parent
665b8e5283
commit
54bb032d21
2 changed files with 20 additions and 7 deletions
10
lib/lists.c
10
lib/lists.c
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
17
lib/lists.h
17
lib/lists.h
|
@ -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))
|
||||||
|
|
Loading…
Reference in a new issue