Skip to content

Commit e68a032

Browse files
[libc] fix -Wcast-function-type via union rather than reinterpret_cast (#76875)
The GCC build is producing the following diagnostic: llvm-project/libc/src/signal/linux/signal_utils.h: In member function ‘__llvm_libc_18_0_0_git::KernelSigaction& __llvm_libc_18_0_0_git::KernelSigaction::operator=(const sigaction&)’: llvm-project/libc/src/signal/linux/signal_utils.h:38:20: warning: cast between incompatible function types from ‘void (*)(int, siginfo_t*, void*)’ to ‘void (*)(int)’ [-Wcast-function-type] 38 | sa_handler = reinterpret_cast<HandlerType *>(sa.sa_sigaction); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ llvm-project/libc/src/signal/linux/signal_utils.h: In member function ‘__llvm_libc_18_0_0_git::KernelSigaction::operator sigaction() const’: llvm-project/libc/src/signal/linux/signal_utils.h:51:25: warning: cast between incompatible function types from ‘void (*)(int)’ to ‘void (*)(int, siginfo_t*, void*)’ [-Wcast-function-type] 51 | sa.sa_sigaction = reinterpret_cast<SiginfoHandlerType *>(sa_handler); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Two issues here: 1. Clang supports -Wcast-function-type, but not as part of the -Wextra group. 2. The existing implementation tried to work around the oddity that is the kernel's struct sigaction != POSIX via reinterpret_cast in a way that's not compatible with -Wcast-function-type. Just use a union which is well defined (and two function pointers are the same size.) Link: #76872 Fixes: #74617
1 parent 7a4c497 commit e68a032

File tree

1 file changed

+6
-6
lines changed

1 file changed

+6
-6
lines changed

libc/src/signal/linux/signal_utils.h

+6-6
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,12 @@ namespace LIBC_NAMESPACE {
2727
// handler taking siginfo_t * argument, one can set sa_handler to sa_sigaction
2828
// if SA_SIGINFO is set in sa_flags.
2929
struct KernelSigaction {
30-
using HandlerType = void(int);
31-
using SiginfoHandlerType = void(int, siginfo_t *, void *);
32-
3330
LIBC_INLINE KernelSigaction &operator=(const struct sigaction &sa) {
3431
sa_flags = sa.sa_flags;
3532
sa_restorer = sa.sa_restorer;
3633
sa_mask = sa.sa_mask;
3734
if (sa_flags & SA_SIGINFO) {
38-
sa_handler = reinterpret_cast<HandlerType *>(sa.sa_sigaction);
35+
sa_sigaction = sa.sa_sigaction;
3936
} else {
4037
sa_handler = sa.sa_handler;
4138
}
@@ -48,13 +45,16 @@ struct KernelSigaction {
4845
sa.sa_mask = sa_mask;
4946
sa.sa_restorer = sa_restorer;
5047
if (sa_flags & SA_SIGINFO)
51-
sa.sa_sigaction = reinterpret_cast<SiginfoHandlerType *>(sa_handler);
48+
sa.sa_sigaction = sa_sigaction;
5249
else
5350
sa.sa_handler = sa_handler;
5451
return sa;
5552
}
5653

57-
HandlerType *sa_handler;
54+
union {
55+
void (*sa_handler)(int);
56+
void (*sa_sigaction)(int, siginfo_t *, void *);
57+
};
5858
unsigned long sa_flags;
5959
void (*sa_restorer)(void);
6060
// Our public definition of sigset_t matches that of the kernel's definition.

0 commit comments

Comments
 (0)