This patch updates the container_of() implementation taken from the Linux kernel.
We need to turn off -Wpointer-arith as the new container_of() implementation does void pointer artihmetic as shown by this example warning: linux_helpers.h:43:26: warning: pointer of type ‘void *’ used in arithmetic [-Wpointer-arith] --- dlm_controld/Makefile | 2 +- dlm_controld/linux_helpers.h | 36 ++++++++++++++++++++++++++++++++++++ dlm_controld/list.h | 12 +----------- dlm_controld/rbtree.h | 2 +- 4 files changed, 39 insertions(+), 13 deletions(-) diff --git a/dlm_controld/Makefile b/dlm_controld/Makefile index 28b6bb0a..328a64ba 100644 --- a/dlm_controld/Makefile +++ b/dlm_controld/Makefile @@ -38,7 +38,7 @@ LIB_SOURCE = lib.c CFLAGS += -D_GNU_SOURCE -O2 -ggdb \ -Wall -Wformat -Wformat-security -Wmissing-prototypes -Wnested-externs \ - -Wpointer-arith -Wextra -Wshadow -Wcast-align -Wwrite-strings \ + -Wextra -Wshadow -Wcast-align -Wwrite-strings \ -Waggregate-return -Wstrict-prototypes -Winline -Wredundant-decls \ -Wno-sign-compare -Wno-unused-parameter -Wp,-D_FORTIFY_SOURCE=2 \ -fexceptions -fasynchronous-unwind-tables -fdiagnostics-show-option \ diff --git a/dlm_controld/linux_helpers.h b/dlm_controld/linux_helpers.h index 5ef13466..09705cff 100644 --- a/dlm_controld/linux_helpers.h +++ b/dlm_controld/linux_helpers.h @@ -3,6 +3,42 @@ #ifndef __DLM_LINUX_HELPERS__ #define __DLM_LINUX_HELPERS__ +/* + * static_assert - check integer constant expression at build time + * + * static_assert() is a wrapper for the C11 _Static_assert, with a + * little macro magic to make the message optional (defaulting to the + * stringification of the tested expression). + * + * Contrary to BUILD_BUG_ON(), static_assert() can be used at global + * scope, but requires the expression to be an integer constant + * expression (i.e., it is not enough that __builtin_constant_p() is + * true for expr). + * + * Also note that BUILD_BUG_ON() fails the build if the condition is + * true, while static_assert() fails the build if the expression is + * false. + */ +#define static_assert(expr, ...) __static_assert(expr, ##__VA_ARGS__, #expr) +#define __static_assert(expr, msg, ...) _Static_assert(expr, msg) + +#define __same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b)) + +/** + * container_of - cast a member of a structure out to the containing structure + * @ptr: the pointer to the member. + * @type: the type of the container struct this is embedded in. + * @member: the name of the member within the struct. + * + * WARNING: any const qualifier of @ptr is lost. + */ +#define container_of(ptr, type, member) ({ \ + void *__mptr = (void *)(ptr); \ + static_assert(__same_type(*(ptr), ((type *)0)->member) || \ + __same_type(*(ptr), void), \ + "pointer type mismatch in container_of()"); \ + ((type *)(__mptr - offsetof(type, member))); }) + #define WRITE_ONCE(x, val) \ do { \ *(volatile typeof(x) *)&(x) = (val); \ diff --git a/dlm_controld/list.h b/dlm_controld/list.h index a2a5e5f3..e9df2ef2 100644 --- a/dlm_controld/list.h +++ b/dlm_controld/list.h @@ -3,17 +3,7 @@ #ifndef _LINUX_LIST_H #define _LINUX_LIST_H -/** - * container_of - cast a member of a structure out to the containing structure - * - * @ptr: the pointer to the member. - * @type: the type of the container struct this is embedded in. - * @member: the name of the member within the struct. - * - */ -#define container_of(ptr, type, member) ({ \ - const typeof( ((type *)0)->member ) *__mptr = (ptr); \ - (type *)( (char *)__mptr - offsetof(type,member) );}) +#include "linux_helpers.h" /* * These are non-NULL pointers that will result in page faults diff --git a/dlm_controld/rbtree.h b/dlm_controld/rbtree.h index ddb86ff6..48b6e32f 100644 --- a/dlm_controld/rbtree.h +++ b/dlm_controld/rbtree.h @@ -20,7 +20,7 @@ #include <stdbool.h> #include <string.h> -#include "list.h" +#include "linux_helpers.h" #include "rbtree_types.h" #define rb_parent(r) ((struct rb_node *)((r)->__rb_parent_color & ~3)) -- 2.31.1