From 84b347060cb51e70927cdc592277f0c275819742 Mon Sep 17 00:00:00 2001 From: LIU Hao Date: Sun, 14 Jan 2024 17:30:21 +0800 Subject: [PATCH] cxa: Remove `transparent_union` hack Actual calls to `__cdecl` functions are only emitted by the compiler, so it is not necessary to maintain compatibility at source level. I would like the headers to be usable with MSVC. --- mcfgthread/cxa.c | 6 +++--- mcfgthread/cxa.h | 20 -------------------- mcfgthread/fwd.h | 5 ++--- test/cxa_atexit_all.c | 22 ++++++++++++---------- test/cxa_atexit_dso.c | 22 ++++++++++++---------- 5 files changed, 29 insertions(+), 46 deletions(-) diff --git a/mcfgthread/cxa.c b/mcfgthread/cxa.c index ec9be1654..a15245f3f 100644 --- a/mcfgthread/cxa.c +++ b/mcfgthread/cxa.c @@ -42,7 +42,7 @@ __MCF_cxa_atexit(__MCF_cxa_dtor_union dtor, void* this, void* dso) { /* Push the element to the global queue. */ _MCF_mutex_lock(__MCF_g->__cxa_atexit_mtx, NULL); - __MCF_dtor_element elem = { dtor.__cdecl_ptr, this, dso }; + __MCF_dtor_element elem = { dtor, this, dso }; int err = __MCF_dtor_queue_push(__MCF_g->__cxa_atexit_queue, &elem); _MCF_mutex_unlock(__MCF_g->__cxa_atexit_mtx); return err; @@ -61,7 +61,7 @@ __MCF_cxa_at_quick_exit(__MCF_cxa_dtor_union dtor, void* this, void* dso) { /* Push the element to the global queue. */ _MCF_mutex_lock(__MCF_g->__cxa_at_quick_exit_mtx, NULL); - __MCF_dtor_element elem = { dtor.__cdecl_ptr, this, dso }; + __MCF_dtor_element elem = { dtor, this, dso }; int err = __MCF_dtor_queue_push(__MCF_g->__cxa_at_quick_exit_queue, &elem); _MCF_mutex_unlock(__MCF_g->__cxa_at_quick_exit_mtx); return err; @@ -83,7 +83,7 @@ __MCF_cxa_thread_atexit(__MCF_cxa_dtor_union dtor, void* this, void* dso) return -1; /* Push the element to the thread-specific queue. */ - __MCF_dtor_element elem = { dtor.__cdecl_ptr, this, dso }; + __MCF_dtor_element elem = { dtor, this, dso }; int err = __MCF_dtor_queue_push(self->__atexit_queue, &elem); return err; } diff --git a/mcfgthread/cxa.h b/mcfgthread/cxa.h index ef95c58ad..cfa654f7b 100644 --- a/mcfgthread/cxa.h +++ b/mcfgthread/cxa.h @@ -16,26 +16,6 @@ __MCF_C_DECLARATIONS_BEGIN /* See for details about * individual functions. */ -union __attribute__((__transparent_union__)) __MCF_cxa_dtor_union - { - __MCF_cxa_dtor_cdecl* __cdecl_ptr; - __MCF_cxa_dtor_thiscall* __thiscall_ptr; - -#ifdef __cplusplus - /* GCC ignores `__transparent_union__` attribute so mimic it. */ - __MCF_CXX11(constexpr) - __MCF_cxa_dtor_union(__MCF_cxa_dtor_cdecl* __arg) __MCF_NOEXCEPT - : __cdecl_ptr(__arg) { } - -# ifdef __i386__ - __MCF_CXX11(constexpr) - __MCF_cxa_dtor_union(__MCF_cxa_dtor_thiscall* __arg) __MCF_NOEXCEPT - : __thiscall_ptr(__arg) { } -# endif -#endif /* __cplusplus */ - }; - -/* Declare 'real' functions here. */ __MCF_CXA_IMPORT int __MCF_cxa_guard_acquire(int64_t* __guard) __MCF_NOEXCEPT; diff --git a/mcfgthread/fwd.h b/mcfgthread/fwd.h index c6d407c5e..af9c1d2a7 100644 --- a/mcfgthread/fwd.h +++ b/mcfgthread/fwd.h @@ -145,7 +145,6 @@ typedef struct __MCF_dtor_element __MCF_dtor_element; typedef struct __MCF_dtor_queue __MCF_dtor_queue; typedef struct __MCF_tls_table __MCF_tls_table; typedef struct __MCF_tls_element __MCF_tls_element; -typedef union __MCF_cxa_dtor_union __MCF_cxa_dtor_union; typedef struct __MCF_cond _MCF_cond; typedef struct __MCF_mutex _MCF_mutex; @@ -172,8 +171,8 @@ typedef void _MCF_tls_dtor(void* __ptr); /* Note: In the case of i386, the argument is passed both via the ECX register * and on the stack, to allow both `__cdecl` and `__thiscall` functions to work * properly. The function prototype is declared for compatibility with GCC. */ -typedef void __cdecl __MCF_cxa_dtor_cdecl(void* __arg); -typedef void __thiscall __MCF_cxa_dtor_thiscall(void* __arg); +typedef void __MCF_cxa_dtor_cdecl(void* __arg); +typedef __MCF_cxa_dtor_cdecl __MCF_cxa_dtor_union; /* Define the prototype for `atexit()` and `at_quick_exit()`. */ typedef void __MCF_atexit_callback(void); diff --git a/test/cxa_atexit_all.c b/test/cxa_atexit_all.c index 11d942d59..2a8701147 100644 --- a/test/cxa_atexit_all.c +++ b/test/cxa_atexit_all.c @@ -12,14 +12,16 @@ static char buffer[1000]; static int dso_1, dso_2; static -void __cdecl +void +__cdecl cleanup_1(void* ptr) { strcat(buffer, ptr); } static -void __thiscall +void +__thiscall cleanup_2(void* ptr) { strcat(buffer, ptr); @@ -38,13 +40,13 @@ main(void) assert(r == 0); r = __MCF_cxa_atexit(cleanup_1, (void*) "dN", NULL); assert(r == 0); - r = __MCF_cxa_atexit(cleanup_2, (void*) "e2", &dso_2); + r = __MCF_cxa_atexit((__MCF_cxa_dtor_cdecl*) cleanup_2, (void*) "e2", &dso_2); assert(r == 0); - r = __MCF_cxa_atexit(cleanup_2, (void*) "f1", &dso_1); + r = __MCF_cxa_atexit((__MCF_cxa_dtor_cdecl*) cleanup_2, (void*) "f1", &dso_1); assert(r == 0); - r = __MCF_cxa_atexit(cleanup_2, (void*) "g1", &dso_1); + r = __MCF_cxa_atexit((__MCF_cxa_dtor_cdecl*) cleanup_2, (void*) "g1", &dso_1); assert(r == 0); - r = __MCF_cxa_atexit(cleanup_2, (void*) "hN", NULL); + r = __MCF_cxa_atexit((__MCF_cxa_dtor_cdecl*) cleanup_2, (void*) "hN", NULL); assert(r == 0); r = __MCF_cxa_atexit(cleanup_1, (void*) "i1", &dso_1); assert(r == 0); @@ -54,13 +56,13 @@ main(void) assert(r == 0); r = __MCF_cxa_atexit(cleanup_1, (void*) "lN", NULL); assert(r == 0); - r = __MCF_cxa_atexit(cleanup_2, (void*) "m1", &dso_1); + r = __MCF_cxa_atexit((__MCF_cxa_dtor_cdecl*) cleanup_2, (void*) "m1", &dso_1); assert(r == 0); - r = __MCF_cxa_atexit(cleanup_2, (void*) "n2", &dso_2); + r = __MCF_cxa_atexit((__MCF_cxa_dtor_cdecl*) cleanup_2, (void*) "n2", &dso_2); assert(r == 0); - r = __MCF_cxa_atexit(cleanup_2, (void*) "o2", &dso_2); + r = __MCF_cxa_atexit((__MCF_cxa_dtor_cdecl*) cleanup_2, (void*) "o2", &dso_2); assert(r == 0); - r = __MCF_cxa_atexit(cleanup_2, (void*) "pN", NULL); + r = __MCF_cxa_atexit((__MCF_cxa_dtor_cdecl*) cleanup_2, (void*) "pN", NULL); assert(r == 0); assert(strcmp(buffer, "") == 0); diff --git a/test/cxa_atexit_dso.c b/test/cxa_atexit_dso.c index c304d0543..6fa07c78d 100644 --- a/test/cxa_atexit_dso.c +++ b/test/cxa_atexit_dso.c @@ -12,14 +12,16 @@ static char buffer[1000]; static int dso_1, dso_2; static -void __cdecl +void +__cdecl cleanup_1(void* ptr) { strcat(buffer, ptr); } static -void __thiscall +void +__thiscall cleanup_2(void* ptr) { strcat(buffer, ptr); @@ -38,13 +40,13 @@ main(void) assert(r == 0); r = __MCF_cxa_atexit(cleanup_1, (void*) "dN", NULL); assert(r == 0); - r = __MCF_cxa_atexit(cleanup_2, (void*) "e2", &dso_2); + r = __MCF_cxa_atexit((__MCF_cxa_dtor_cdecl*) cleanup_2, (void*) "e2", &dso_2); assert(r == 0); - r = __MCF_cxa_atexit(cleanup_2, (void*) "f1", &dso_1); + r = __MCF_cxa_atexit((__MCF_cxa_dtor_cdecl*) cleanup_2, (void*) "f1", &dso_1); assert(r == 0); - r = __MCF_cxa_atexit(cleanup_2, (void*) "g1", &dso_1); + r = __MCF_cxa_atexit((__MCF_cxa_dtor_cdecl*) cleanup_2, (void*) "g1", &dso_1); assert(r == 0); - r = __MCF_cxa_atexit(cleanup_2, (void*) "hN", NULL); + r = __MCF_cxa_atexit((__MCF_cxa_dtor_cdecl*) cleanup_2, (void*) "hN", NULL); assert(r == 0); r = __MCF_cxa_atexit(cleanup_1, (void*) "i1", &dso_1); assert(r == 0); @@ -54,13 +56,13 @@ main(void) assert(r == 0); r = __MCF_cxa_atexit(cleanup_1, (void*) "lN", NULL); assert(r == 0); - r = __MCF_cxa_atexit(cleanup_2, (void*) "m1", &dso_1); + r = __MCF_cxa_atexit((__MCF_cxa_dtor_cdecl*) cleanup_2, (void*) "m1", &dso_1); assert(r == 0); - r = __MCF_cxa_atexit(cleanup_2, (void*) "n2", &dso_2); + r = __MCF_cxa_atexit((__MCF_cxa_dtor_cdecl*) cleanup_2, (void*) "n2", &dso_2); assert(r == 0); - r = __MCF_cxa_atexit(cleanup_2, (void*) "o2", &dso_2); + r = __MCF_cxa_atexit((__MCF_cxa_dtor_cdecl*) cleanup_2, (void*) "o2", &dso_2); assert(r == 0); - r = __MCF_cxa_atexit(cleanup_2, (void*) "pN", NULL); + r = __MCF_cxa_atexit((__MCF_cxa_dtor_cdecl*) cleanup_2, (void*) "pN", NULL); assert(r == 0); assert(strcmp(buffer, "") == 0);