From 2ba043d04468261cc767a3b91cec6df4b2238950 Mon Sep 17 00:00:00 2001 From: Justus Winter <4winter@informatik.uni-hamburg.de> Date: Sat, 11 Jul 2015 13:27:58 +0200 Subject: kern: make sure the queue macros are only used on queues This turns mistakes as the one corrected in e59f05e9 into compile-time errors. * kern/queue.h: Add a new macro, queue_assert, and use it to assert that all arguments given to the queue macros have the correct type. * device/net_io.c (ENQUEUE_DEAD): Adapt to the fact that `queue_next(q)' is no longer an lvalue. --- device/net_io.c | 2 +- kern/queue.h | 31 ++++++++++++++++++++++++++----- 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/device/net_io.c b/device/net_io.c index d2928cc..47ef2ea 100644 --- a/device/net_io.c +++ b/device/net_io.c @@ -353,7 +353,7 @@ decl_simple_lock_data(,net_hash_header_lock) /* entry_p must be net_rcv_port_t or net_hash_entry_t */ #define ENQUEUE_DEAD(dead, entry_p, chain) { \ - queue_next(&(entry_p)->chain) = (queue_entry_t) (dead); \ + (entry_p)->chain.next = (queue_entry_t) (dead); \ (dead) = (queue_entry_t)(entry_p); \ } diff --git a/kern/queue.h b/kern/queue.h index 518084d..f0b4002 100644 --- a/kern/queue.h +++ b/kern/queue.h @@ -86,6 +86,14 @@ queue_entry_t dequeue_tail(queue_t); void remqueue(queue_t, queue_entry_t); void insque(queue_entry_t, queue_entry_t); +/* + * Macro: queue_assert + * Function: + * Used by macros to assert that the given argument is a + * queue. + */ +#define queue_assert(q) (void) ((void) (q)->next, (q)->prev) + /* * Macro: queue_init * Function: @@ -104,7 +112,7 @@ void insque(queue_entry_t, queue_entry_t); * queue_entry_t queue_first(q) * queue_t q; *IN* */ -#define queue_first(q) ((q)->next) +#define queue_first(q) (queue_assert(q), (q)->next) /* * Macro: queue_next @@ -114,7 +122,7 @@ void insque(queue_entry_t, queue_entry_t); * queue_entry_t queue_next(qc) * queue_t qc; */ -#define queue_next(qc) ((qc)->next) +#define queue_next(qc) (queue_assert(qc), (qc)->next) /* * Macro: queue_last @@ -124,7 +132,7 @@ void insque(queue_entry_t, queue_entry_t); * queue_entry_t queue_last(q) * queue_t q; *IN* */ -#define queue_last(q) ((q)->prev) +#define queue_last(q) (queue_assert(q), (q)->prev) /* * Macro: queue_prev @@ -134,7 +142,7 @@ void insque(queue_entry_t, queue_entry_t); * queue_entry_t queue_prev(qc) * queue_t qc; */ -#define queue_prev(qc) ((qc)->prev) +#define queue_prev(qc) (queue_assert(qc), (qc)->prev) /* * Macro: queue_end @@ -146,7 +154,8 @@ void insque(queue_entry_t, queue_entry_t); * queue_t q; * queue_entry_t qe; */ -#define queue_end(q, qe) ((q) == (qe)) +#define queue_end(q, qe) (queue_assert(q), queue_assert(qe), \ + (q) == (qe)) /* * Macro: queue_empty @@ -179,6 +188,8 @@ void insque(queue_entry_t, queue_entry_t); */ #define queue_enter(head, elt, type, field) \ { \ + queue_assert(head); \ + queue_assert(&(elt)->field); \ queue_entry_t prev; \ \ prev = (head)->prev; \ @@ -206,6 +217,8 @@ void insque(queue_entry_t, queue_entry_t); */ #define queue_enter_first(head, elt, type, field) \ { \ + queue_assert(head); \ + queue_assert(&(elt)->field); \ queue_entry_t next; \ \ next = (head)->next; \ @@ -239,6 +252,8 @@ void insque(queue_entry_t, queue_entry_t); */ #define queue_remove(head, elt, type, field) \ { \ + queue_assert(head); \ + queue_assert(&(elt)->field); \ queue_entry_t next, prev; \ \ next = (elt)->field.next; \ @@ -266,6 +281,8 @@ void insque(queue_entry_t, queue_entry_t); */ #define queue_remove_first(head, entry, type, field) \ { \ + queue_assert(head); \ + queue_assert(&(entry)->field); \ queue_entry_t next; \ \ (entry) = (type) ((head)->next); \ @@ -289,6 +306,8 @@ void insque(queue_entry_t, queue_entry_t); */ #define queue_remove_last(head, entry, type, field) \ { \ + queue_assert(head); \ + queue_assert(&(entry)->field); \ queue_entry_t prev; \ \ (entry) = (type) ((head)->prev); \ @@ -306,6 +325,8 @@ void insque(queue_entry_t, queue_entry_t); */ #define queue_assign(to, from, type, field) \ { \ + queue_assert(&(to)->field); \ + queue_assert(&(from)->field); \ ((type)((from)->prev))->field.next = (to); \ ((type)((from)->next))->field.prev = (to); \ *to = *from; \ -- cgit v1.2.3