summaryrefslogtreecommitdiffstats
path: root/lib/generic
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--lib/generic/array.h14
-rw-r--r--lib/generic/lru.h5
-rw-r--r--lib/generic/queue.c10
-rw-r--r--lib/generic/queue.h6
-rw-r--r--lib/generic/trie.c4
5 files changed, 28 insertions, 11 deletions
diff --git a/lib/generic/array.h b/lib/generic/array.h
index 9f35118..9bea546 100644
--- a/lib/generic/array.h
+++ b/lib/generic/array.h
@@ -113,7 +113,7 @@ static inline void array_std_free(void *baton, void *p)
* Mempool usage: pass kr_memreserve and a knot_mm_t* .
* @return 0 if success, <0 on failure */
#define array_reserve_mm(array, n, reserve, baton) \
- (reserve)((baton), (void **) &(array).at, sizeof((array).at[0]), (n), &(array).cap)
+ (reserve)((baton), (void **) &(array).at, array_member_size((array)), (n), &(array).cap)
/**
* Push value at the end of the array, resize it if necessary.
@@ -122,9 +122,9 @@ static inline void array_std_free(void *baton, void *p)
* @return element index on success, <0 on failure
*/
#define array_push_mm(array, val, reserve, baton) \
- (int)((array).len < (array).cap ? ((array).at[(array).len] = val, (array).len++) \
+ (int)((array).len < (array).cap ? ((array).at[(array).len] = (val), (array).len++) \
: (array_reserve_mm(array, ((array).cap + 1), reserve, baton) < 0 ? -1 \
- : ((array).at[(array).len] = val, (array).len++)))
+ : ((array).at[(array).len] = (val), (array).len++)))
/**
* Push value at the end of the array, resize it if necessary (plain malloc/free).
@@ -152,6 +152,12 @@ static inline void array_std_free(void *baton, void *p)
* @warning Undefined if the array is empty.
*/
#define array_tail(array) \
- (array).at[(array).len - 1]
+ (array).at[(array).len - 1]
+
+/**
+ * Return the size of a singular member in the array.
+ */
+#define array_member_size(array) \
+ (sizeof((array).at[0])) // NOLINT(bugprone-sizeof-expression): usually a false-positive
/** @} */
diff --git a/lib/generic/lru.h b/lib/generic/lru.h
index 448c1b9..1c1dd81 100644
--- a/lib/generic/lru.h
+++ b/lib/generic/lru.h
@@ -130,7 +130,10 @@
#define lru_get_new(table, key_, len_, is_new) \
(__typeof__((table)->pdata_t)) \
lru_get_impl(&(table)->lru, (key_), (len_), \
- sizeof(*(table)->pdata_t), true, is_new)
+ lru_member_size((table)), true, is_new)
+
+#define lru_member_size(table) \
+ (sizeof(*(table)->pdata_t)) // NOLINT(bugprone-sizeof-expression): usually a false-positive
/**
* @brief Apply a function to every item in LRU.
diff --git a/lib/generic/queue.c b/lib/generic/queue.c
index 5bed153..29609dd 100644
--- a/lib/generic/queue.c
+++ b/lib/generic/queue.c
@@ -62,7 +62,7 @@ void * queue_push_impl(struct queue *q)
if (t->begin * 2 >= t->cap) {
/* Utilization is below 50%, so let's shift (no overlap).
* (size_t cast is to avoid unintended sign-extension) */
- memcpy(t->data, t->data + t->begin * q->item_size,
+ memcpy(t->data, t->data + t->begin * (size_t)q->item_size,
(size_t) (t->end - t->begin) * (size_t) q->item_size);
t->end -= t->begin;
t->begin = 0;
@@ -76,7 +76,7 @@ void * queue_push_impl(struct queue *q)
kr_require(t->end < t->cap);
++(q->len);
++(t->end);
- return t->data + q->item_size * (t->end - 1);
+ return t->data + (size_t)q->item_size * (t->end - 1);
}
/* Return pointer to the space for the new element. */
@@ -98,8 +98,8 @@ void * queue_push_head_impl(struct queue *q)
* Computations here are simplified due to h->begin == 0.
* (size_t cast is to avoid unintended sign-extension) */
const int cnt = h->end;
- memcpy(h->data + (h->cap - cnt) * q->item_size, h->data,
- (size_t) cnt * (size_t) q->item_size);
+ memcpy(h->data + ((size_t)h->cap - cnt) * q->item_size, h->data,
+ (size_t)cnt * (size_t)q->item_size);
h->begin = h->cap - cnt;
h->end = h->cap;
} else {
@@ -113,7 +113,7 @@ void * queue_push_head_impl(struct queue *q)
kr_require(h->begin > 0);
--(h->begin);
++(q->len);
- return h->data + q->item_size * h->begin;
+ return h->data + (size_t)q->item_size * h->begin;
}
void queue_pop_impl(struct queue *q)
diff --git a/lib/generic/queue.h b/lib/generic/queue.h
index 3fa52ce..fc2a86f 100644
--- a/lib/generic/queue.h
+++ b/lib/generic/queue.h
@@ -71,7 +71,7 @@
/** @brief Initialize a queue. You can malloc() it the usual way. */
#define queue_init(q) do { \
(void)(((__typeof__(((q).pdata_t)))0) == (void *)0); /* typecheck queue_t */ \
- queue_init_impl(&(q).queue, sizeof(*(q).pdata_t)); \
+ queue_init_impl(&(q).queue, queue_member_size((q))); \
} while (false)
/** @brief De-initialize a queue: make it invalid and free any inner allocations. */
@@ -105,6 +105,10 @@
#define queue_len(q) \
((const size_t)(q).queue.len)
+/** @brief Return the size of a single element in the queue. */
+#define queue_member_size(q) \
+ (sizeof(*(q).pdata_t)) // NOLINT(bugprone-sizeof-expression): usually a false-positive
+
/** @brief Type for queue iterator, parametrized by value type.
* It's a simple structure that owns no other resources.
diff --git a/lib/generic/trie.c b/lib/generic/trie.c
index f9aceda..21254eb 100644
--- a/lib/generic/trie.c
+++ b/lib/generic/trie.c
@@ -470,6 +470,10 @@ static int ns_longer_alloc(nstack_t *ns)
memcpy(st, ns->stack, ns->len * sizeof(node_t *));
} else {
st = realloc(ns->stack, new_size);
+ if (st == NULL) {
+ free(ns->stack); // left behind by realloc, callers bail out
+ ns->stack = NULL;
+ }
}
if (st == NULL)
return KNOT_ENOMEM;