Skip to content

Commit 1d4e43a

Browse files
committed
Fix issue where alignment macro could cause ASAN false positives
1 parent 754e5ce commit 1d4e43a

File tree

2 files changed

+28
-10
lines changed

2 files changed

+28
-10
lines changed

distr/flecs.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -929,6 +929,8 @@ typedef struct ecs_allocator_t ecs_allocator_t;
929929
#define ECS_ALIGNOF(T) static_cast<int64_t>(alignof(T))
930930
#elif defined(ECS_TARGET_MSVC)
931931
#define ECS_ALIGNOF(T) (int64_t)__alignof(T)
932+
#elif __STDC_VERSION__ >= 201112L
933+
#define ECS_ALIGNOF(T) ((int64_t)_Alignof(T))
932934
#else
933935
/* Use the struct trick since on 32-bit platforms __alignof__ can return different
934936
* results than C++'s alignof. This is illustrated when doing:

include/flecs/private/api_defines.h

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -246,26 +246,42 @@ typedef struct ecs_allocator_t ecs_allocator_t;
246246

247247
#define ECS_SIZEOF(T) ECS_CAST(ecs_size_t, sizeof(T))
248248

249-
/* Use alignof in C++, or a trick in C. */
250-
#ifdef __cplusplus
251-
#define ECS_ALIGNOF(T) static_cast<int64_t>(alignof(T))
252-
#elif defined(ECS_TARGET_MSVC)
253-
#define ECS_ALIGNOF(T) (int64_t)__alignof(T)
254-
#else
255-
/* Use the struct trick since on 32-bit platforms __alignof__ can return different
256-
* results than C++'s alignof. This is illustrated when doing:
257-
*
249+
/* Alignment macros:
250+
* - Use alignof in C++
251+
* - Use _Alignof in C11 and above
252+
* - Use __alignof__ on 64 bit platforms on clang/gcc
253+
* - Use struct trick on other compilers/32 bit
254+
*
255+
* The reason the code doesn't use the struct trick everywhere is because this
256+
* can cause ASAN errors (runtime error: member access within null pointer).
257+
*
258+
* The reason why the clang/gcc __alignof__ feature is not used on 32 bit, is
259+
* because its behavior is different than C++:
260+
*
258261
* __alignof__(uint64_t) == 8 on 32-bit platforms
259262
* alignof(uint64_t) == 4 on 32-bit platforms
260-
*
263+
*
261264
* typedef struct {
262265
* uint64_t value;
263266
* } Foo;
264267
*
265268
* __alignof__(Foo) == 4 on 32-bit platforms
266269
* alignof(Foo) == 4 on 32-bit platforms
267270
*/
271+
#ifdef __cplusplus
272+
#define ECS_ALIGNOF(T) static_cast<int64_t>(alignof(T))
273+
#elif defined(ECS_TARGET_MSVC)
274+
#define ECS_ALIGNOF(T) (int64_t)__alignof(T)
275+
#elif __STDC_VERSION__ >= 201112L
276+
#define ECS_ALIGNOF(T) ((int64_t)_Alignof(T))
277+
#else
268278
#define ECS_ALIGNOF(T) ((int64_t)(size_t)&((struct { char c; T d; } *)0)->d)
279+
#if defined(ECS_TARGET_GNU) || defined(ECS_TARGET_CLANG)
280+
#if __SIZEOF_POINTER__ == 8
281+
#undef ECS_ALIGNOF
282+
#define ECS_ALIGNOF(T) (int64_t)__alignof__(T)
283+
#endif
284+
#endif
269285
#endif
270286

271287
#ifndef FLECS_NO_ALWAYS_INLINE

0 commit comments

Comments
 (0)