From 3930d12e4dcb2d79d70c3aa8a199aec0340d0b39 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Tue, 2 Dec 2025 16:32:04 -0800 Subject: [PATCH 1/2] Pacify gcc -Wdangling-else in dbusbind.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * src/dbusbind.c (XD_DBUS_VALIDATE_BUS_NAME) (XD_DBUS_VALIDATE_PATH, XD_DBUS_VALIDATE_INTERFACE) (XD_DBUS_VALIDATE_MEMBER): Make these expand to single statements when they are followed by ‘;’. All uses changed. --- src/dbusbind.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/dbusbind.c b/src/dbusbind.c index 5f89122eaf7..979b313bc33 100644 --- a/src/dbusbind.c +++ b/src/dbusbind.c @@ -328,34 +328,34 @@ XD_OBJECT_TO_STRING (Lisp_Object object) #if HAVE_DBUS_VALIDATE_BUS_NAME #define XD_DBUS_VALIDATE_BUS_NAME(bus_name) \ - XD_DBUS_VALIDATE_OBJECT(bus_name, dbus_validate_bus_name); + XD_DBUS_VALIDATE_OBJECT (bus_name, dbus_validate_bus_name) #else #define XD_DBUS_VALIDATE_BUS_NAME(bus_name) \ - if (!NILP (bus_name)) CHECK_STRING (bus_name); + do { if (!NILP (bus_name)) CHECK_STRING (bus_name); } while (false) #endif #if HAVE_DBUS_VALIDATE_PATH #define XD_DBUS_VALIDATE_PATH(path) \ - XD_DBUS_VALIDATE_OBJECT(path, dbus_validate_path); + XD_DBUS_VALIDATE_OBJECT (path, dbus_validate_path) #else #define XD_DBUS_VALIDATE_PATH(path) \ - if (!NILP (path)) CHECK_STRING (path); + do { if (!NILP (path)) CHECK_STRING (path); } while (false) #endif #if HAVE_DBUS_VALIDATE_INTERFACE #define XD_DBUS_VALIDATE_INTERFACE(interface) \ - XD_DBUS_VALIDATE_OBJECT(interface, dbus_validate_interface); + XD_DBUS_VALIDATE_OBJECT (interface, dbus_validate_interface) #else #define XD_DBUS_VALIDATE_INTERFACE(interface) \ - if (!NILP (interface)) CHECK_STRING (interface); + do { if (!NILP (interface)) CHECK_STRING (interface); } while (false) #endif #if HAVE_DBUS_VALIDATE_MEMBER #define XD_DBUS_VALIDATE_MEMBER(member) \ - XD_DBUS_VALIDATE_OBJECT(member, dbus_validate_member); + XD_DBUS_VALIDATE_OBJECT (member, dbus_validate_member) #else #define XD_DBUS_VALIDATE_MEMBER(member) \ - if (!NILP (member)) CHECK_STRING (member); + do { if (!NILP (member)) CHECK_STRING (member); } while (false) #endif /* Append to SIGNATURE a copy of X, making sure SIGNATURE does @@ -425,7 +425,7 @@ xd_signature (char *signature, int dtype, int parent_type, Lisp_Object object) /* We don't check the syntax of signature. This will be done by libdbus. */ if (dtype == DBUS_TYPE_OBJECT_PATH) - XD_DBUS_VALIDATE_PATH (object) + XD_DBUS_VALIDATE_PATH (object); else CHECK_STRING (object); sprintf (signature, "%c", dtype); @@ -749,7 +749,7 @@ xd_append_arg (int dtype, Lisp_Object object, DBusMessageIter *iter) /* We don't check the syntax of signature. This will be done by libdbus. */ if (dtype == DBUS_TYPE_OBJECT_PATH) - XD_DBUS_VALIDATE_PATH (object) + XD_DBUS_VALIDATE_PATH (object); else CHECK_STRING (object); { From 1b2b433fc0a62db933399eb37c8cae73e0446e86 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Tue, 2 Dec 2025 17:24:43 -0800 Subject: [PATCH 2/2] Port to GNU/Linux HPPA malloc On this platform, you cannot reliably malloc objects containing values of type pthread_mutex_t or pthread_cond_t, since malloc guarantees only 8-byte alignment but these two types require 16-byte alignment. See GCC bug 115750 reported by Sam James and Emacs bug 79936 reported by John Paul Adrian Glaubitz. * configure.ac (ALIGNOF_MAX_ALIGN_T, ALIGNOF_PTHREAD_COND_T) (ALIGNOF_PTHREAD_MUTEX_T) [HAVE_PTHREAD]: New C macros. * src/systhread.c (sys_mutex_init, sys_mutex_lock) (sys_mutex_unlock, sys_cond_init, sys_cond_wait) (sys_cond_signal, sys_cond_broadcast, sys_cond_destroy): Use SYTHREAD_ALIGN_PTR to convert sys_mutex_t and sys_cond_t to pthread_mutex_t and pthread_cond_t, since runtime conversion is needed on GNU/Linux HPPA. * src/systhread.h (SYSTHREAD_ALIGN_ROOM, SYSTHREAD_ALIGN_PTR): New macros, which affect the generated code only on unusual platforms like GNU/Linux HPPA. (sys_mutex_t, sys_cond_t) [HAVE_PTHREAD]: Use them. --- configure.ac | 6 ++++++ src/systhread.c | 25 +++++++++++++++++-------- src/systhread.h | 40 +++++++++++++++++++++++++++++++++++++--- 3 files changed, 60 insertions(+), 11 deletions(-) diff --git a/configure.ac b/configure.ac index 39f1fb10091..d17dbfa4358 100644 --- a/configure.ac +++ b/configure.ac @@ -3425,6 +3425,12 @@ if test "$ac_cv_header_pthread_h" && test "$opsys" != "mingw32"; then done]) if test "$emacs_cv_pthread_lib" != no; then AC_DEFINE([HAVE_PTHREAD], [1], [Define to 1 if you have POSIX threads.]) + m4_foreach([emacs_type], + [[max_align_t], [pthread_cond_t], [pthread_mutex_t]], + [AC_CHECK_ALIGNOF(emacs_type, + [[#include + #include + ]])]) case $emacs_cv_pthread_lib in -*) LIB_PTHREAD=$emacs_cv_pthread_lib;; esac diff --git a/src/systhread.c b/src/systhread.c index a14a4929d57..5cde785630d 100644 --- a/src/systhread.c +++ b/src/systhread.c @@ -106,8 +106,9 @@ sys_thread_yield (void) #include void -sys_mutex_init (sys_mutex_t *mutex) +sys_mutex_init (sys_mutex_t *sys_mutex) { + pthread_mutex_t *mutex = SYSTHREAD_ALIGN_PTR (pthread_mutex_t, sys_mutex); pthread_mutexattr_t *attr_ptr; #ifdef ENABLE_CHECKING pthread_mutexattr_t attr; @@ -135,22 +136,25 @@ sys_mutex_init (sys_mutex_t *mutex) } void -sys_mutex_lock (sys_mutex_t *mutex) +sys_mutex_lock (sys_mutex_t *sys_mutex) { + pthread_mutex_t *mutex = SYSTHREAD_ALIGN_PTR (pthread_mutex_t, sys_mutex); int error = pthread_mutex_lock (mutex); eassert (error == 0); } void -sys_mutex_unlock (sys_mutex_t *mutex) +sys_mutex_unlock (sys_mutex_t *sys_mutex) { + pthread_mutex_t *mutex = SYSTHREAD_ALIGN_PTR (pthread_mutex_t, sys_mutex); int error = pthread_mutex_unlock (mutex); eassert (error == 0); } void -sys_cond_init (sys_cond_t *cond) +sys_cond_init (sys_cond_t *sys_cond) { + pthread_cond_t *cond = SYSTHREAD_ALIGN_PTR (pthread_cond_t, sys_cond); int error = pthread_cond_init (cond, NULL); /* We could get ENOMEM. Can't do anything except aborting. */ if (error != 0) @@ -161,22 +165,26 @@ sys_cond_init (sys_cond_t *cond) } void -sys_cond_wait (sys_cond_t *cond, sys_mutex_t *mutex) +sys_cond_wait (sys_cond_t *sys_cond, sys_mutex_t *sys_mutex) { + pthread_cond_t *cond = SYSTHREAD_ALIGN_PTR (pthread_cond_t, sys_cond); + pthread_mutex_t *mutex = SYSTHREAD_ALIGN_PTR (pthread_mutex_t, sys_mutex); int error = pthread_cond_wait (cond, mutex); eassert (error == 0); } void -sys_cond_signal (sys_cond_t *cond) +sys_cond_signal (sys_cond_t *sys_cond) { + pthread_cond_t *cond = SYSTHREAD_ALIGN_PTR (pthread_cond_t, sys_cond); int error = pthread_cond_signal (cond); eassert (error == 0); } void -sys_cond_broadcast (sys_cond_t *cond) +sys_cond_broadcast (sys_cond_t *sys_cond) { + pthread_cond_t *cond = SYSTHREAD_ALIGN_PTR (pthread_cond_t, sys_cond); int error = pthread_cond_broadcast (cond); eassert (error == 0); #ifdef HAVE_NS @@ -189,8 +197,9 @@ sys_cond_broadcast (sys_cond_t *cond) } void -sys_cond_destroy (sys_cond_t *cond) +sys_cond_destroy (sys_cond_t *sys_cond) { + pthread_cond_t *cond = SYSTHREAD_ALIGN_PTR (pthread_cond_t, sys_cond); int error = pthread_cond_destroy (cond); eassert (error == 0); } diff --git a/src/systhread.h b/src/systhread.h index a321514d2bc..30fa5a94b45 100644 --- a/src/systhread.h +++ b/src/systhread.h @@ -27,11 +27,45 @@ along with GNU Emacs. If not, see . */ #include -/* A system mutex is just a pthread mutex. This is only used for the - GIL. */ -typedef pthread_mutex_t sys_mutex_t; +/* Deal with platforms like GNU/Linux on 32-bit HPPA, where pthread_mutex_t + and pthread_cond_t have alignments stricter than what malloc guarantees. + Unfortunately POSIX allows this curious situation. + Do this by allocating possibly-poorly-aligned objects a bit larger + than pthread_mutex_t and pthread_cond_t, and then aligning pointers + to these objects at runtime. */ +#if (ALIGNOF_PTHREAD_COND_T <= ALIGNOF_MAX_ALIGN_T \ + && ALIGNOF_PTHREAD_MUTEX_T <= ALIGNOF_MAX_ALIGN_T) +/* The typical case. Align PTR for TYPE *, where PTR is of type TYPE * + and is already aligned properly. */ +# define SYSTHREAD_ALIGN_PTR(type, ptr) (ptr) +#else +/* An unusual case, e.g., GNU/Linux 32-bit HPPA. + Aligning SYSTHREAD_ALIGN_ROOM (TYPE) * up for TYPE * results in a + valid pointer. TYPE's alignment must be at least that of int; + in practice it is always greater than that of max_align_t. */ +# define SYSTHREAD_ALIGN_ROOM(type) \ + union { int i; char room[sizeof (type) + alignof (type) - alignof (int)]; } +/* Align PTR up for TYPE *. + PTR should be of type SYSTHREAD_ALIGN_ROOM (TYPE) *. */ +# define SYSTHREAD_ALIGN_PTR(type, ptr) \ + ((type *) ((uintptr_t) ((ptr)->room + (alignof (type) - alignof (int))) \ + & ~(alignof (type) - alignof (int)))) +#endif + +/* A system mutex is just a pthread mutex, possibly with alignment slop. + It is used only for the GIL. */ +#if ALIGNOF_PTHREAD_MUTEX_T <= ALIGNOF_MAX_ALIGN_T +typedef pthread_mutex_t sys_mutex_t; +#else +typedef SYSTHREAD_ALIGN_ROOM (pthread_mutex_t) sys_mutex_t; +#endif + +#if ALIGNOF_PTHREAD_COND_T <= ALIGNOF_MAX_ALIGN_T typedef pthread_cond_t sys_cond_t; +#else +typedef SYSTHREAD_ALIGN_ROOM (pthread_cond_t) sys_cond_t; +#endif /* A system thread. */ typedef pthread_t sys_thread_t;