summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorAdrian Moreno <amorenoz@redhat.com>2022-03-23 12:56:16 +0100
committerIlya Maximets <i.maximets@ovn.org>2022-03-30 16:59:02 +0200
commit860e69a8c3d6994dc000b37d682bd16cd2925bef (patch)
treeb290b1962d59606fbd90dfdd8e8128b091c97bff /include
parent9e8d960a6b5258626130be611ae090dacbb4dc7c (diff)
downloadopenvswitch-860e69a8c3d6994dc000b37d682bd16cd2925bef.tar.gz
hmap: implement UB-safe hmap pop iterator.
HMAP_FOR_EACH_POP iterator has an additional difficulty, which is the use of two iterator variables of different types. In order to re-write this loop in a UB-safe manner, create a iterator struct to be used as loop variable. Acked-by: Dumitru Ceara <dceara@redhat.com> Acked-by: Eelco Chaudron <echaudro@redhat.com> Signed-off-by: Adrian Moreno <amorenoz@redhat.com> Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
Diffstat (limited to 'include')
-rw-r--r--include/openvswitch/hmap.h31
1 files changed, 19 insertions, 12 deletions
diff --git a/include/openvswitch/hmap.h b/include/openvswitch/hmap.h
index 610ad9987..68c284cf1 100644
--- a/include/openvswitch/hmap.h
+++ b/include/openvswitch/hmap.h
@@ -199,26 +199,33 @@ bool hmap_contains(const struct hmap *, const struct hmap_node *);
CONDITION_MULTIVAR(NODE, MEMBER, ITER_VAR(NODE) != NULL); \
UPDATE_MULTIVAR(NODE, hmap_next(HMAP, ITER_VAR(NODE))))
-static inline struct hmap_node *
-hmap_pop_helper__(struct hmap *hmap, size_t *bucket) {
+struct hmap_pop_helper_iter__ {
+ size_t bucket;
+ struct hmap_node *node;
+};
+
+static inline void
+hmap_pop_helper__(struct hmap *hmap, struct hmap_pop_helper_iter__ *iter) {
- for (; *bucket <= hmap->mask; (*bucket)++) {
- struct hmap_node *node = hmap->buckets[*bucket];
+ for (; iter->bucket <= hmap->mask; (iter->bucket)++) {
+ struct hmap_node *node = hmap->buckets[iter->bucket];
if (node) {
hmap_remove(hmap, node);
- return node;
+ iter->node = node;
+ return;
}
}
-
- return NULL;
+ iter->node = NULL;
}
-#define HMAP_FOR_EACH_POP(NODE, MEMBER, HMAP) \
- for (size_t bucket__ = 0; \
- INIT_CONTAINER(NODE, hmap_pop_helper__(HMAP, &bucket__), MEMBER), \
- (NODE != OBJECT_CONTAINING(NULL, NODE, MEMBER)) \
- || ((NODE = NULL), false);)
+#define HMAP_FOR_EACH_POP(NODE, MEMBER, HMAP) \
+ for (struct hmap_pop_helper_iter__ ITER_VAR(NODE) = { 0, NULL }; \
+ hmap_pop_helper__(HMAP, &ITER_VAR(NODE)), \
+ (ITER_VAR(NODE).node != NULL) ? \
+ (((NODE) = OBJECT_CONTAINING(ITER_VAR(NODE).node, \
+ NODE, MEMBER)),1): \
+ (((NODE) = NULL), 0);)
static inline struct hmap_node *hmap_first(const struct hmap *);
static inline struct hmap_node *hmap_next(const struct hmap *,