Skip to content

Commit

Permalink
Avoid uninitialized variable warnings with OBJECT_OFFSETOF() in MSVC.
Browse files Browse the repository at this point in the history
Implementation of OBJECT_OFFSETOF() for non-GNUC compilers like MSVC
causes "uninitialized variable" warnings. Since OBJECT_OFFSETOF() is
indirectly used through all the *_FOR_EACH() (through ASSIGN_CONTAINER()
and  OBJECT_CONTAINING()) macros, the OVS build
on Windows gets littered with "uninitialized variable" warnings.
This patch attempts to workaround the problem.

Signed-off-by: Gurucharan Shetty <[email protected]>
Acked-by: Alin Gabriel Serdean <[email protected]>
Acked-by: Saurabh Shah <[email protected]>
Acked-by: Ben Pfaff <[email protected]>
  • Loading branch information
shettyg committed Sep 12, 2014
1 parent 74467d5 commit f17e8ad
Show file tree
Hide file tree
Showing 8 changed files with 31 additions and 23 deletions.
5 changes: 3 additions & 2 deletions lib/classifier.c
Original file line number Diff line number Diff line change
Expand Up @@ -1561,7 +1561,7 @@ find_match_wc(const struct cls_subtable *subtable, const struct flow *flow,
struct flow_wildcards *wc)
{
uint32_t basis = 0, hash;
struct cls_match *rule;
struct cls_match *rule = NULL;
int i;
struct range ofs;

Expand Down Expand Up @@ -1767,7 +1767,8 @@ static struct cls_match *
next_rule_in_list__(struct cls_match *rule)
OVS_NO_THREAD_SAFETY_ANALYSIS
{
struct cls_match *next = OBJECT_CONTAINING(rule->list.next, next, list);
struct cls_match *next = NULL;
next = OBJECT_CONTAINING(rule->list.next, next, list);
return next;
}

Expand Down
4 changes: 2 additions & 2 deletions lib/classifier.h
Original file line number Diff line number Diff line change
Expand Up @@ -334,7 +334,7 @@ void cls_cursor_advance(struct cls_cursor *);
#define CLS_FOR_EACH_TARGET(RULE, MEMBER, CLS, TARGET) \
for (struct cls_cursor cursor__ = cls_cursor_start(CLS, TARGET, false); \
(cursor__.rule \
? (ASSIGN_CONTAINER(RULE, cursor__.rule, MEMBER), \
? (INIT_CONTAINER(RULE, cursor__.rule, MEMBER), \
true) \
: false); \
cls_cursor_advance(&cursor__))
Expand All @@ -345,7 +345,7 @@ void cls_cursor_advance(struct cls_cursor *);
#define CLS_FOR_EACH_TARGET_SAFE(RULE, MEMBER, CLS, TARGET) \
for (struct cls_cursor cursor__ = cls_cursor_start(CLS, TARGET, true); \
(cursor__.rule \
? (ASSIGN_CONTAINER(RULE, cursor__.rule, MEMBER), \
? (INIT_CONTAINER(RULE, cursor__.rule, MEMBER), \
cls_cursor_advance(&cursor__), \
true) \
: false); \
Expand Down
6 changes: 3 additions & 3 deletions lib/cmap.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,11 +114,11 @@ void cmap_replace(struct cmap *, struct cmap_node *old_node,
* to change during iteration. It may be very slightly faster.
*/
#define CMAP_FOR_EACH_WITH_HASH(NODE, MEMBER, HASH, CMAP) \
for (ASSIGN_CONTAINER(NODE, cmap_find(CMAP, HASH), MEMBER); \
for (INIT_CONTAINER(NODE, cmap_find(CMAP, HASH), MEMBER); \
(NODE) != OBJECT_CONTAINING(NULL, NODE, MEMBER); \
ASSIGN_CONTAINER(NODE, cmap_node_next(&(NODE)->MEMBER), MEMBER))
#define CMAP_FOR_EACH_WITH_HASH_PROTECTED(NODE, MEMBER, HASH, CMAP) \
for (ASSIGN_CONTAINER(NODE, cmap_find_locked(CMAP, HASH), MEMBER); \
for (INIT_CONTAINER(NODE, cmap_find_locked(CMAP, HASH), MEMBER); \
(NODE) != OBJECT_CONTAINING(NULL, NODE, MEMBER); \
ASSIGN_CONTAINER(NODE, cmap_node_next_protected(&(NODE)->MEMBER), \
MEMBER))
Expand Down Expand Up @@ -174,7 +174,7 @@ struct cmap_node *cmap_find_protected(const struct cmap *, uint32_t hash);

#define CMAP_CURSOR_FOR_EACH__(NODE, CURSOR, MEMBER) \
((CURSOR)->node \
? (ASSIGN_CONTAINER(NODE, (CURSOR)->node, MEMBER), \
? (INIT_CONTAINER(NODE, (CURSOR)->node, MEMBER), \
cmap_cursor_advance(CURSOR), \
true) \
: false)
Expand Down
2 changes: 1 addition & 1 deletion lib/heap.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ void heap_rebuild(struct heap *);
* element. */
#define HEAP_FOR_EACH(NODE, MEMBER, HEAP) \
for (((HEAP)->n > 0 \
? ASSIGN_CONTAINER(NODE, (HEAP)->array[1], MEMBER) \
? INIT_CONTAINER(NODE, (HEAP)->array[1], MEMBER) \
: ((NODE) = NULL, (void) 0)); \
(NODE) != NULL; \
((NODE)->MEMBER.idx < (HEAP)->n \
Expand Down
10 changes: 5 additions & 5 deletions lib/hindex.h
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ void hindex_remove(struct hindex *, struct hindex_node *);
* Evaluates HASH only once.
*/
#define HINDEX_FOR_EACH_WITH_HASH(NODE, MEMBER, HASH, HINDEX) \
for (ASSIGN_CONTAINER(NODE, hindex_node_with_hash(HINDEX, HASH), MEMBER); \
for (INIT_CONTAINER(NODE, hindex_node_with_hash(HINDEX, HASH), MEMBER); \
NODE != OBJECT_CONTAINING(NULL, NODE, MEMBER); \
ASSIGN_CONTAINER(NODE, (NODE)->MEMBER.s, MEMBER))

Expand All @@ -149,16 +149,16 @@ hindex_node_with_hash(const struct hindex *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); \
for (INIT_CONTAINER(NODE, hindex_first(HINDEX), MEMBER); \
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); \
#define HINDEX_FOR_EACH_SAFE(NODE, NEXT, MEMBER, HINDEX) \
for (INIT_CONTAINER(NODE, hindex_first(HINDEX), MEMBER); \
(NODE != OBJECT_CONTAINING(NULL, NODE, MEMBER) \
? ASSIGN_CONTAINER(NEXT, hindex_next(HINDEX, &(NODE)->MEMBER), MEMBER), 1 \
? INIT_CONTAINER(NEXT, hindex_next(HINDEX, &(NODE)->MEMBER), MEMBER), 1 \
: 0); \
(NODE) = (NEXT))

Expand Down
10 changes: 5 additions & 5 deletions lib/hmap.h
Original file line number Diff line number Diff line change
Expand Up @@ -126,12 +126,12 @@ struct hmap_node *hmap_random_node(const struct hmap *);
* HASH is only evaluated once.
*/
#define HMAP_FOR_EACH_WITH_HASH(NODE, MEMBER, HASH, HMAP) \
for (ASSIGN_CONTAINER(NODE, hmap_first_with_hash(HMAP, HASH), MEMBER); \
for (INIT_CONTAINER(NODE, hmap_first_with_hash(HMAP, HASH), MEMBER); \
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); \
for (INIT_CONTAINER(NODE, hmap_first_in_bucket(HMAP, HASH), MEMBER); \
NODE != OBJECT_CONTAINING(NULL, NODE, MEMBER); \
ASSIGN_CONTAINER(NODE, hmap_next_in_bucket(&(NODE)->MEMBER), MEMBER))

Expand All @@ -148,16 +148,16 @@ 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); \
for (INIT_CONTAINER(NODE, hmap_first(HMAP), MEMBER); \
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); \
for (INIT_CONTAINER(NODE, hmap_first(HMAP), MEMBER); \
(NODE != OBJECT_CONTAINING(NULL, NODE, MEMBER) \
? ASSIGN_CONTAINER(NEXT, hmap_next(HMAP, &(NODE)->MEMBER), MEMBER), 1 \
? INIT_CONTAINER(NEXT, hmap_next(HMAP, &(NODE)->MEMBER), MEMBER), 1 \
: 0); \
(NODE) = (NEXT))

Expand Down
10 changes: 5 additions & 5 deletions lib/list.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,25 +58,25 @@ bool list_is_singleton(const struct list *);
bool list_is_short(const struct list *);

#define LIST_FOR_EACH(ITER, MEMBER, LIST) \
for (ASSIGN_CONTAINER(ITER, (LIST)->next, MEMBER); \
for (INIT_CONTAINER(ITER, (LIST)->next, MEMBER); \
&(ITER)->MEMBER != (LIST); \
ASSIGN_CONTAINER(ITER, (ITER)->MEMBER.next, MEMBER))
#define LIST_FOR_EACH_CONTINUE(ITER, MEMBER, LIST) \
for (ASSIGN_CONTAINER(ITER, (ITER)->MEMBER.next, MEMBER); \
for (INIT_CONTAINER(ITER, (ITER)->MEMBER.next, MEMBER); \
&(ITER)->MEMBER != (LIST); \
ASSIGN_CONTAINER(ITER, (ITER)->MEMBER.next, MEMBER))
#define LIST_FOR_EACH_REVERSE(ITER, MEMBER, LIST) \
for (ASSIGN_CONTAINER(ITER, (LIST)->prev, MEMBER); \
for (INIT_CONTAINER(ITER, (LIST)->prev, MEMBER); \
&(ITER)->MEMBER != (LIST); \
ASSIGN_CONTAINER(ITER, (ITER)->MEMBER.prev, MEMBER))
#define LIST_FOR_EACH_REVERSE_CONTINUE(ITER, MEMBER, LIST) \
for (ASSIGN_CONTAINER(ITER, (ITER)->MEMBER.prev, MEMBER); \
&(ITER)->MEMBER != (LIST); \
ASSIGN_CONTAINER(ITER, (ITER)->MEMBER.prev, MEMBER))
#define LIST_FOR_EACH_SAFE(ITER, NEXT, MEMBER, LIST) \
for (ASSIGN_CONTAINER(ITER, (LIST)->next, MEMBER); \
for (INIT_CONTAINER(ITER, (LIST)->next, MEMBER); \
(&(ITER)->MEMBER != (LIST) \
? ASSIGN_CONTAINER(NEXT, (ITER)->MEMBER.next, MEMBER), 1 \
? INIT_CONTAINER(NEXT, (ITER)->MEMBER.next, MEMBER), 1 \
: 0); \
(ITER) = (NEXT))

Expand Down
7 changes: 7 additions & 0 deletions lib/util.h
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,13 @@ ovs_prefetch_range(const void *start, size_t size)
#define ASSIGN_CONTAINER(OBJECT, POINTER, MEMBER) \
((OBJECT) = OBJECT_CONTAINING(POINTER, OBJECT, MEMBER), (void) 0)

/* As explained in the comment above OBJECT_OFFSETOF(), non-GNUC compilers
* like MSVC will complain about un-initialized variables if OBJECT
* hasn't already been initialized. To prevent such warnings, INIT_CONTAINER()
* can be used as a wrapper around ASSIGN_CONTAINER. */
#define INIT_CONTAINER(OBJECT, POINTER, MEMBER) \
((OBJECT) = NULL, ASSIGN_CONTAINER(OBJECT, POINTER, MEMBER))

/* Given ATTR, and TYPE, cast the ATTR to TYPE by first casting ATTR to
* (void *). This is to suppress the alignment warning issued by clang. */
#define ALIGNED_CAST(TYPE, ATTR) ((TYPE) (void *) (ATTR))
Expand Down

0 comments on commit f17e8ad

Please sign in to comment.