From 55d2690646769467b6d26ad55516ff6eeb12869d Mon Sep 17 00:00:00 2001 From: Alex Wang Date: Mon, 22 Jul 2013 09:19:56 -0700 Subject: [PATCH] clang: Fix segfault in unit tests. It seems that 'clang' compiler applies strict protection on pointer dereference. And it causes unexpected execution in macro functions like "HMAP_FOR_EACH()" and unit test failures. This commit fixes this issue and pass all unit tests. Co-authored-by: Ethan Jackson Signed-off-by: Alex Wang Signed-off-by: Ben Pfaff --- lib/classifier.h | 4 ++-- lib/hindex.h | 6 +++--- lib/hmap.h | 10 +++++----- lib/sset.h | 8 +++++--- 4 files changed, 15 insertions(+), 13 deletions(-) diff --git a/lib/classifier.h b/lib/classifier.h index fdc3af7af..09b3a131a 100644 --- a/lib/classifier.h +++ b/lib/classifier.h @@ -124,13 +124,13 @@ struct cls_rule *cls_cursor_next(struct cls_cursor *, struct cls_rule *); #define CLS_CURSOR_FOR_EACH(RULE, MEMBER, CURSOR) \ for (ASSIGN_CONTAINER(RULE, cls_cursor_first(CURSOR), MEMBER); \ - &(RULE)->MEMBER != NULL; \ + RULE != OBJECT_CONTAINING(NULL, RULE, MEMBER); \ ASSIGN_CONTAINER(RULE, cls_cursor_next(CURSOR, &(RULE)->MEMBER), \ MEMBER)) #define CLS_CURSOR_FOR_EACH_SAFE(RULE, NEXT, MEMBER, CURSOR) \ for (ASSIGN_CONTAINER(RULE, cls_cursor_first(CURSOR), MEMBER); \ - (&(RULE)->MEMBER != NULL \ + (RULE != OBJECT_CONTAINING(NULL, RULE, MEMBER) \ ? ASSIGN_CONTAINER(NEXT, cls_cursor_next(CURSOR, &(RULE)->MEMBER), \ MEMBER) \ : 0); \ diff --git a/lib/hindex.h b/lib/hindex.h index 10bf0244d..ce46596ad 100644 --- a/lib/hindex.h +++ b/lib/hindex.h @@ -129,7 +129,7 @@ void hindex_remove(struct hindex *, struct hindex_node *); */ #define HINDEX_FOR_EACH_WITH_HASH(NODE, MEMBER, HASH, HINDEX) \ for (ASSIGN_CONTAINER(NODE, hindex_node_with_hash(HINDEX, HASH), MEMBER); \ - &(NODE)->MEMBER != NULL; \ + NODE != OBJECT_CONTAINING(NULL, NODE, MEMBER); \ ASSIGN_CONTAINER(NODE, (NODE)->MEMBER.s, MEMBER)) struct hindex_node *hindex_node_with_hash(const struct hindex *, size_t hash); @@ -139,14 +139,14 @@ struct hindex_node *hindex_node_with_hash(const struct hindex *, size_t hash); /* Iterates through every node in HINDEX. */ #define HINDEX_FOR_EACH(NODE, MEMBER, HINDEX) \ for (ASSIGN_CONTAINER(NODE, hindex_first(HINDEX), MEMBER); \ - &(NODE)->MEMBER != NULL; \ + NODE != OBJECT_CONTAINING(NULL, NODE, MEMBER); \ ASSIGN_CONTAINER(NODE, hindex_next(HINDEX, &(NODE)->MEMBER), MEMBER)) /* Safe when NODE may be freed (not needed when NODE may be removed from the * hash index but its members remain accessible and intact). */ #define HINDEX_FOR_EACH_SAFE(NODE, NEXT, MEMBER, HINDEX) \ for (ASSIGN_CONTAINER(NODE, hindex_first(HINDEX), MEMBER); \ - (&(NODE)->MEMBER != NULL \ + (NODE != OBJECT_CONTAINING(NULL, NODE, MEMBER) \ ? ASSIGN_CONTAINER(NEXT, hindex_next(HINDEX, &(NODE)->MEMBER), MEMBER) \ : 0); \ (NODE) = (NEXT)) diff --git a/lib/hmap.h b/lib/hmap.h index 9b6d8c7b3..c7df62a7f 100644 --- a/lib/hmap.h +++ b/lib/hmap.h @@ -116,12 +116,12 @@ struct hmap_node *hmap_random_node(const struct hmap *); */ #define HMAP_FOR_EACH_WITH_HASH(NODE, MEMBER, HASH, HMAP) \ for (ASSIGN_CONTAINER(NODE, hmap_first_with_hash(HMAP, HASH), MEMBER); \ - &(NODE)->MEMBER != NULL; \ + NODE != OBJECT_CONTAINING(NULL, NODE, MEMBER); \ ASSIGN_CONTAINER(NODE, hmap_next_with_hash(&(NODE)->MEMBER), \ MEMBER)) #define HMAP_FOR_EACH_IN_BUCKET(NODE, MEMBER, HASH, HMAP) \ for (ASSIGN_CONTAINER(NODE, hmap_first_in_bucket(HMAP, HASH), MEMBER); \ - &(NODE)->MEMBER != NULL; \ + NODE != OBJECT_CONTAINING(NULL, NODE, MEMBER); \ ASSIGN_CONTAINER(NODE, hmap_next_in_bucket(&(NODE)->MEMBER), MEMBER)) static inline struct hmap_node *hmap_first_with_hash(const struct hmap *, @@ -138,14 +138,14 @@ bool hmap_contains(const struct hmap *, const struct hmap_node *); /* Iterates through every node in HMAP. */ #define HMAP_FOR_EACH(NODE, MEMBER, HMAP) \ for (ASSIGN_CONTAINER(NODE, hmap_first(HMAP), MEMBER); \ - &(NODE)->MEMBER != NULL; \ + NODE != OBJECT_CONTAINING(NULL, NODE, MEMBER); \ ASSIGN_CONTAINER(NODE, hmap_next(HMAP, &(NODE)->MEMBER), MEMBER)) /* Safe when NODE may be freed (not needed when NODE may be removed from the * hash map but its members remain accessible and intact). */ #define HMAP_FOR_EACH_SAFE(NODE, NEXT, MEMBER, HMAP) \ for (ASSIGN_CONTAINER(NODE, hmap_first(HMAP), MEMBER); \ - (&(NODE)->MEMBER != NULL \ + (NODE != OBJECT_CONTAINING(NULL, NODE, MEMBER) \ ? ASSIGN_CONTAINER(NEXT, hmap_next(HMAP, &(NODE)->MEMBER), MEMBER) \ : 0); \ (NODE) = (NEXT)) @@ -153,7 +153,7 @@ bool hmap_contains(const struct hmap *, const struct hmap_node *); /* Continues an iteration from just after NODE. */ #define HMAP_FOR_EACH_CONTINUE(NODE, MEMBER, HMAP) \ for (ASSIGN_CONTAINER(NODE, hmap_next(HMAP, &(NODE)->MEMBER), MEMBER); \ - &(NODE)->MEMBER != NULL; \ + NODE != OBJECT_CONTAINING(NULL, NODE, MEMBER); \ ASSIGN_CONTAINER(NODE, hmap_next(HMAP, &(NODE)->MEMBER), MEMBER)) static inline struct hmap_node *hmap_first(const struct hmap *); diff --git a/lib/sset.h b/lib/sset.h index 625cea987..1e864efce 100644 --- a/lib/sset.h +++ b/lib/sset.h @@ -70,12 +70,12 @@ struct sset_node *sset_at_position(const struct sset *, /* Iteration macros. */ #define SSET_FOR_EACH(NAME, SSET) \ for ((NAME) = SSET_FIRST(SSET); \ - SSET_NODE_FROM_NAME(NAME) != NULL; \ + NAME != NULL; \ (NAME) = SSET_NEXT(SSET, NAME)) #define SSET_FOR_EACH_SAFE(NAME, NEXT, SSET) \ for ((NAME) = SSET_FIRST(SSET); \ - (SSET_NODE_FROM_NAME(NAME) != NULL \ + (NAME != NULL \ ? (NEXT) = SSET_NEXT(SSET, NAME), true \ : false); \ (NAME) = (NEXT)) @@ -87,7 +87,9 @@ const char **sset_sort(const struct sset *); #define SSET_NODE_FROM_HMAP_NODE(HMAP_NODE) \ CONTAINER_OF(HMAP_NODE, struct sset_node, hmap_node) #define SSET_NAME_FROM_HMAP_NODE(HMAP_NODE) \ - (CONST_CAST(const char *, (SSET_NODE_FROM_HMAP_NODE(HMAP_NODE)->name))) + HMAP_NODE == NULL \ + ? NULL \ + : (CONST_CAST(const char *, (SSET_NODE_FROM_HMAP_NODE(HMAP_NODE)->name))) #define SSET_NODE_FROM_NAME(NAME) CONTAINER_OF(NAME, struct sset_node, name) #define SSET_FIRST(SSET) SSET_NAME_FROM_HMAP_NODE(hmap_first(&(SSET)->map)) #define SSET_NEXT(SSET, NAME) \ -- 2.43.0