From 47214903b1c6d0590780c7e69a2e3e612f43e4a2 Mon Sep 17 00:00:00 2001 From: Xing Xue Date: Mon, 6 May 2024 06:39:31 -0400 Subject: [PATCH] [libc++abi][AIX] Use different function pointer types for destructors with 1 or 2 args (#89624) The destructors generated by the legacy IBM `xlclang++` compiler can take 1 or 2 arguments and the differences were handled by type `cast` where it is needed. Clang now treats the `cast` here as an error after https://github.com/llvm/llvm-project/commit/999d4f840777bf8de26d45947192aa0728edc0fb landed with `-Xextra -Werror`. The issue had been worked around by using `#pragma GCC diagnostic push/pop`. This patch defines 2 separate destructor types for 1 argument and 2 arguments respectively so `cast` is not needed. --- libcxxabi/src/aix_state_tab_eh.inc | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/libcxxabi/src/aix_state_tab_eh.inc b/libcxxabi/src/aix_state_tab_eh.inc index 9f46001b020906..285c9ac71d60d5 100644 --- a/libcxxabi/src/aix_state_tab_eh.inc +++ b/libcxxabi/src/aix_state_tab_eh.inc @@ -102,8 +102,6 @@ static bool state_tab_dbg() { namespace __state_table_eh { -using destruct_f = void (*)(void*); - // Definition of flags for the state table entry field 'action flag'. enum FSMEntryCount : intptr_t { beginCatch = -1, endCatch = -2, deleteObject = -3, cleanupLabel = -4, terminate = -5 }; @@ -145,8 +143,10 @@ struct FSMEntry { intptr_t nextStatePtr; }; union { - // Address of the destructor function. - void (*destructor)(void*, size_t); + // Address of the destructor function with 1 argument. + void (*destructor)(void*); + // Address of the destructor function with 2 arguments. + void (*xlCDestructor)(void*, size_t); // The address of the catch block or cleanup code. void* landingPad; }; @@ -191,17 +191,12 @@ static void invoke_destructor(FSMEntry* fsmEntry, void* addr) { try { if (fsmEntry->elementCount == 1) { _LIBCXXABI_TRACE_STATETAB0("calling scalar destructor\n"); - (*fsmEntry->destructor)(addr, dtorArgument); + (*fsmEntry->xlCDestructor)(addr, dtorArgument); _LIBCXXABI_TRACE_STATETAB0("returned from scalar destructor\n"); } else { _LIBCXXABI_TRACE_STATETAB0("calling vector destructor\n"); - // TODO: in the legacy ABI, destructors had a second argument. We don't expect to encounter - // destructors of this type in the itanium-based ABI, so this should be safe, but this could use some cleanup. -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wcast-function-type" __cxa_vec_cleanup(addr, reinterpret_cast(fsmEntry->elementCount), fsmEntry->elemSize, - reinterpret_cast(fsmEntry->destructor)); -#pragma GCC diagnostic pop + fsmEntry->destructor); _LIBCXXABI_TRACE_STATETAB0("returned from vector destructor\n"); } } catch (...) { @@ -218,7 +213,7 @@ static void invoke_delete(FSMEntry* fsmEntry, void* addr) { try { _LIBCXXABI_TRACE_STATETAB0("..calling delete()\n"); // 'destructor' holds a function pointer to delete(). - (*fsmEntry->destructor)(objectAddress, fsmEntry->elemSize); + (*fsmEntry->xlCDestructor)(objectAddress, fsmEntry->elemSize); _LIBCXXABI_TRACE_STATETAB0("..returned from delete()\n"); } catch (...) { _LIBCXXABI_TRACE_STATETAB0("Uncaught exception in delete(), terminating\n");