> After upgrading the CI to use a newer clang for the check with sanitizers, > I see a couple of runtime errors:
And similarly in libtextstyle. Here it is because some function prototypes take a 'struct term_style_user_data *' parameter, whereas in some compilation unit there is a #define term_style_user_data foobar such that the function prototypes here take a 'struct foobar *' parameter. This is intentional use of a generic / user-definable type. This patch silences the errors. 2026-08-13 Bruno Haible <[email protected]> term-style-control: Avoid clang UBSAN runtime errors. * lib/term-style-control.c (INVOKES_FN_PTR): New macro. (atexit_handler, fatal_or_stopping_signal_handler, continuing_signal_handler, activate_term_non_default_mode, deactivate_term_non_default_mode, activate_term_style_controller, deactivate_term_style_controller): Mark as INVOKES_FN_PTR. diff --git a/lib/term-style-control.c b/lib/term-style-control.c index c6f904f0c9..d7e08756c4 100644 --- a/lib/term-style-control.c +++ b/lib/term-style-control.c @@ -55,6 +55,16 @@ #include "same-inode.h" #include "xalloc.h" +/* Avoid that the macro definition + #define term_style_user_data ... + done in specific compilation units of some packages causes runtime errors + "call to function ... through pointer to incorrect function type". */ +#if defined __clang__ && __clang_major__ >= 4 +# define INVOKES_FN_PTR __attribute__ ((no_sanitize ("function"))) +#else +# define INVOKES_FN_PTR +#endif + /* ============================ EINTR handling ============================ */ @@ -450,6 +460,7 @@ static pthread_t volatile active_thread; /* The exit handler. */ static void atexit_handler (void) + INVOKES_FN_PTR { /* Only do something while some output was started but not completed. */ if (active_controller != NULL) @@ -691,6 +702,7 @@ show_signal_marker (int sig) It is reentrant. */ static _GL_ASYNC_SAFE void fatal_or_stopping_signal_handler (int sig) + INVOKES_FN_PTR { #if HAVE_TCGETATTR bool echo_was_off = false; @@ -815,6 +827,7 @@ stopping_signal_handler (int sig) It is reentrant. */ static _GL_ASYNC_SAFE void continuing_signal_handler (int sigcont) + INVOKES_FN_PTR { int saved_errno = errno; @@ -966,6 +979,7 @@ ensure_other_signal_handlers (void) void activate_term_non_default_mode (const struct term_style_controller *controller, struct term_style_user_data *user_data) + INVOKES_FN_PTR { struct term_style_control_data *control_data = controller->get_control_data (user_data); @@ -1018,6 +1032,7 @@ activate_term_non_default_mode (const struct term_style_controller *controller, void deactivate_term_non_default_mode (const struct term_style_controller *controller, struct term_style_user_data *user_data) + INVOKES_FN_PTR { struct term_style_control_data *control_data = controller->get_control_data (user_data); @@ -1059,6 +1074,7 @@ void activate_term_style_controller (const struct term_style_controller *controller, struct term_style_user_data *user_data, int fd, ttyctl_t tty_control) + INVOKES_FN_PTR { struct term_style_control_data *control_data = controller->get_control_data (user_data); @@ -1114,6 +1130,7 @@ activate_term_style_controller (const struct term_style_controller *controller, void deactivate_term_style_controller (const struct term_style_controller *controller, struct term_style_user_data *user_data) + INVOKES_FN_PTR { struct term_style_control_data *control_data = controller->get_control_data (user_data);
