From 9a76e490aee0e6a284cddfd44459ebe049672c87 Mon Sep 17 00:00:00 2001 From: Paul Khuong Date: Mon, 4 May 2020 16:17:45 -0400 Subject: [PATCH] ck_cc: use __builtin_offsetof for CK_CC_CONTAINER on gcc-ish compilers Less undefined behaviour is always good. In practice, compilers seem to handle either form correctly, but some static analysis tools have trouble with (size_t)&((T *)0)->M). --- include/ck_cc.h | 2 ++ include/gcc/ck_cc.h | 9 +++++++++ 2 files changed, 11 insertions(+) diff --git a/include/ck_cc.h b/include/ck_cc.h index 9a152a3..1b4ff46 100644 --- a/include/ck_cc.h +++ b/include/ck_cc.h @@ -50,6 +50,7 @@ * Container function. * This relies on (compiler) implementation-defined behavior. */ +#ifndef CK_CC_CONTAINER #define CK_CC_CONTAINER(F, T, M, N) \ CK_CC_INLINE static T * \ N(F *p) \ @@ -57,6 +58,7 @@ F *n = p; \ return (T *)(void *)(((char *)n) - ((size_t)&((T *)0)->M)); \ } +#endif #define CK_CC_PAD(x) union { char pad[x]; } diff --git a/include/gcc/ck_cc.h b/include/gcc/ck_cc.h index 6ebc59c..0a6d17b 100644 --- a/include/gcc/ck_cc.h +++ b/include/gcc/ck_cc.h @@ -39,6 +39,15 @@ #define CK_CC_UNUSED __attribute__((unused)) #define CK_CC_USED __attribute__((used)) #define CK_CC_IMM "i" + +#define CK_CC_CONTAINER(F, T, M, N) \ + CK_CC_INLINE static T * \ + N(F *p) \ + { \ + \ + return (T *)(void *)((char *)p - __builtin_offsetof(T, M)); \ + } + #if defined(__x86_64__) || defined(__x86__) #define CK_CC_IMM_U32 "Z" #define CK_CC_IMM_S32 "e"