From 48dbb5b6caf563ec1e34a6ae9ebbe44523c7a7ab Mon Sep 17 00:00:00 2001 From: Demi Marie Obenour Date: Wed, 26 Oct 2022 21:00:57 -0400 Subject: [PATCH] Avoid undefined behavior due to strict aliasing This does not make XCB conform to the C99+ strict aliasing rules, but it does use attributes to prevent GCC and Clang from assuming the rules are followed in the cases where XCB does violate them. Signed-off-by: Demi Marie Obenour --- configure.ac | 21 ++++++++++++++++++++- src/Makefile.am | 4 ++-- src/c_client.py | 14 +++++++------- src/xcb.h | 6 ++++++ xcb-composite.pc.in | 2 +- xcb-damage.pc.in | 2 +- xcb-dbe.pc.in | 2 +- xcb-dpms.pc.in | 2 +- xcb-dri2.pc.in | 2 +- xcb-dri3.pc.in | 2 +- xcb-ge.pc.in | 2 +- xcb-glx.pc.in | 2 +- xcb-present.pc.in | 2 +- xcb-randr.pc.in | 2 +- xcb-record.pc.in | 2 +- xcb-render.pc.in | 2 +- xcb-res.pc.in | 2 +- xcb-screensaver.pc.in | 2 +- xcb-shape.pc.in | 2 +- xcb-shm.pc.in | 2 +- xcb-sync.pc.in | 2 +- xcb-xevie.pc.in | 2 +- xcb-xf86dri.pc.in | 2 +- xcb-xfixes.pc.in | 2 +- xcb-xinerama.pc.in | 2 +- xcb-xinput.pc.in | 2 +- xcb-xkb.pc.in | 2 +- xcb-xprint.pc.in | 2 +- xcb-xselinux.pc.in | 2 +- xcb-xtest.pc.in | 2 +- xcb-xv.pc.in | 2 +- xcb-xvmc.pc.in | 2 +- xcb.pc.in | 2 +- 33 files changed, 64 insertions(+), 39 deletions(-) diff --git a/configure.ac b/configure.ac index 4e6f028..67ed2de 100644 --- a/configure.ac +++ b/configure.ac @@ -15,7 +15,7 @@ AM_INIT_AUTOMAKE([foreign dist-xz]) AM_PATH_PYTHON([3.0]) # Set common system defines for POSIX extensions, such as _GNU_SOURCE -# Must be called before any macros that run the compiler (like AC_PROG_LIBTOOL) +# Must be called before any macros that run the compiler (like LT_INIT) # to avoid autoconf errors. AC_USE_SYSTEM_EXTENSIONS AC_SYS_LARGEFILE @@ -27,6 +27,8 @@ LT_INIT([win32-dll]) # Require xorg-macros minimum of 1.18 - Initial version m4_ifndef([XORG_MACROS_VERSION], [m4_fatal([must install xorg-macros 1.18 or later before running autoconf/autogen])]) +XORG_TESTSET_CFLAG([XCB_CFLAGS], [-fno-strict-aliasing]) +AC_SUBST([XCB_CFLAGS]) XORG_MACROS_VERSION(1.18) XORG_DEFAULT_OPTIONS XORG_ENABLE_DEVEL_DOCS @@ -248,6 +250,23 @@ XCB_EXTENSION(XTest, yes) XCB_EXTENSION(Xv, yes) XCB_EXTENSION(XvMC, yes) +AC_MSG_CHECKING([[if __attribute__((may_alias)) is supported]]) +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +typedef struct x { int a; } __attribute__((may_alias)) x; +]])],[ +AC_DEFINE([[XCB_MAY_ALIAS]], [[__attribute__((may_alias))]], [Define if __attribute__((may_alias)) works]) +AC_MSG_RESULT([[yes]]) +],[ +AC_MSG_RESULT([[no]]) +AC_MSG_CHECKING([[if -fno-strict-aliasing works]])[ +case $XCB_CFLAGS in +*-fno-strict-aliasing*)] + AC_MSG_RESULT([[yes]]) + AC_MSG_WARN([[may_alias not supported, programs must use -fno-strict-aliasing]]);; +*) + AC_MSG_RESULT([[no (flags are $XCB_CFLAGS)]]) + AC_MSG_FAILURE([[No method of suppressing strict-aliasing found]]);; +[esac]]) AC_ARG_WITH(serverside-support, AS_HELP_STRING([--with-serverside-support], [Build with support for server-side usage of xcb. This is still EXPERIMENTAL! ABI/API may change! (default: no)]), [XCB_SERVERSIDE_SUPPORT=$withval], [XCB_SERVERSIDE_SUPPORT=no]) AM_CONDITIONAL(XCB_SERVERSIDE_SUPPORT, test "x$XCB_SERVERSIDE_SUPPORT" = "xyes") diff --git a/src/Makefile.am b/src/Makefile.am index 9861a2d..9cc41c0 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -4,7 +4,7 @@ EXTSOURCES = xproto.c \ bigreq.c \ xc_misc.c -AM_CFLAGS = $(BASE_CFLAGS) $(NEEDED_CFLAGS) $(XDMCP_CFLAGS) +AM_CFLAGS = $(BASE_CFLAGS) $(NEEDED_CFLAGS) $(XDMCP_CFLAGS) $(XCB_CFLAGS) libxcb_la_LIBADD = $(NEEDED_LIBS) $(XDMCP_LIBS) libxcb_la_SOURCES = \ xcb_conn.c xcb_out.c xcb_in.c xcb_ext.c xcb_xid.c \ @@ -249,7 +249,7 @@ nodist_libxcb_ge_la_SOURCES = ge.c ge.h endif EXTHEADERS=$(EXTSOURCES:.c=.h) -xcbinclude_HEADERS = xcb.h xcbext.h +xcbinclude_HEADERS = xcb.h xcbext.h config.h if XCB_HAVE_WIN32 xcbinclude_HEADERS += xcb_windefs.h endif diff --git a/src/c_client.py b/src/c_client.py index 7726ecc..0e6f953 100644 --- a/src/c_client.py +++ b/src/c_client.py @@ -279,7 +279,7 @@ def c_open(self): _h('#include "xcb.h"') _c('#ifdef HAVE_CONFIG_H') - _c('#include "config.h"') + _hc('#include "config.h"') _c('#endif') _c('#include ') _c('#include ') @@ -1642,7 +1642,7 @@ def _c_iterator(self, name): param[0], ' ' * (len(self.c_type) + 1 - len(param[0])), param[2]) - _h('} %s;', self.c_iterator_type) + _h('} XCB_MAY_ALIAS %s;', self.c_iterator_type) _h_setlevel(1) _c_setlevel(1) @@ -2254,7 +2254,7 @@ def _c_complex(self, force_packed = False): if b.type.has_name: _h(' } %s;', b.c_field_name) - _h('} %s%s;', 'XCB_PACKED ' if force_packed else '', self.c_type) + _h('} %sXCB_MAY_ALIAS %s;', 'XCB_PACKED ' if force_packed else '', self.c_type) def c_struct(self, name): ''' @@ -2756,7 +2756,7 @@ def _c_cookie(self, name): _h(' **/') _h('typedef struct %s {', self.c_cookie_type) _h(' unsigned int sequence;') - _h('} %s;', self.c_cookie_type) + _h('} XCB_MAY_ALIAS %s;', self.c_cookie_type) def _man_request(self, name, void, aux): param_fields = [f for f in self.fields if f.visible] @@ -2812,7 +2812,7 @@ def _man_request(self, name, void, aux): f.write('.SS Reply datastructure\n') f.write('.nf\n') f.write('.sp\n') - f.write('typedef %s %s {\n' % (self.reply.c_container, self.reply.c_type)) + f.write('typedef XCB_MAY_ALIAS %s %s {\n' % (self.reply.c_container, self.reply.c_type)) struct_fields = [] maxtypelen = 0 @@ -3389,7 +3389,7 @@ def c_event(self, name): else: # Typedef _h('') - _h('typedef %s %s;', _t(self.name + ('event',)), _t(name + ('event',))) + _h('typedef XCB_MAY_ALIAS %s %s;', _t(self.name + ('event',)), _t(name + ('event',))) # Create sizeof-function for eventcopies for compatibility reasons if self.c_need_sizeof: @@ -3424,7 +3424,7 @@ def c_error(self, name): else: # Typedef _h('') - _h('typedef %s %s;', _t(self.name + ('error',)), _t(name + ('error',))) + _h('typedef XCB_MAY_ALIAS %s %s;', _t(self.name + ('error',)), _t(name + ('error',))) # Main routine starts here diff --git a/src/xcb.h b/src/xcb.h index 3f39bb4..2dfb51c 100644 --- a/src/xcb.h +++ b/src/xcb.h @@ -53,8 +53,14 @@ extern "C" { #ifdef __GNUC__ #define XCB_PACKED __attribute__((__packed__)) +#ifndef XCB_MAY_ALIAS +#define XCB_MAY_ALIAS __attribute__((may_alias)) +#endif #else #define XCB_PACKED +#ifndef XCB_MAY_ALIAS +#define XCB_MAY_ALIAS +#endif #endif /** diff --git a/xcb-composite.pc.in b/xcb-composite.pc.in index b9b74c2..ebe577e 100644 --- a/xcb-composite.pc.in +++ b/xcb-composite.pc.in @@ -8,4 +8,4 @@ Description: XCB Composite Extension Version: @PACKAGE_VERSION@ Requires.private: xcb xcb-xfixes Libs: -L${libdir} -lxcb-composite -Cflags: -I${includedir} +Cflags: -I${includedir} @XCB_CFLAGS@ diff --git a/xcb-damage.pc.in b/xcb-damage.pc.in index 3fb46b7..d89e683 100644 --- a/xcb-damage.pc.in +++ b/xcb-damage.pc.in @@ -8,4 +8,4 @@ Description: XCB Damage Extension Version: @PACKAGE_VERSION@ Requires.private: xcb xcb-xfixes Libs: -L${libdir} -lxcb-damage -Cflags: -I${includedir} +Cflags: -I${includedir} @XCB_CFLAGS@ diff --git a/xcb-dbe.pc.in b/xcb-dbe.pc.in index 05df0d5..e06dcc6 100644 --- a/xcb-dbe.pc.in +++ b/xcb-dbe.pc.in @@ -8,4 +8,4 @@ Description: XCB Double Buffer Extension Version: @PACKAGE_VERSION@ Requires.private: xcb Libs: -L${libdir} -lxcb-dbe -Cflags: -I${includedir} +Cflags: -I${includedir} @XCB_CFLAGS@ diff --git a/xcb-dpms.pc.in b/xcb-dpms.pc.in index 281861c..9c2a4ee 100644 --- a/xcb-dpms.pc.in +++ b/xcb-dpms.pc.in @@ -8,4 +8,4 @@ Description: XCB DPMS Extension Version: @PACKAGE_VERSION@ Requires.private: xcb Libs: -L${libdir} -lxcb-dpms -Cflags: -I${includedir} +Cflags: -I${includedir} @XCB_CFLAGS@ diff --git a/xcb-dri2.pc.in b/xcb-dri2.pc.in index fdb188b..31256e9 100644 --- a/xcb-dri2.pc.in +++ b/xcb-dri2.pc.in @@ -8,4 +8,4 @@ Description: XCB DRI2 Extension Version: @PACKAGE_VERSION@ Requires.private: xcb Libs: -L${libdir} -lxcb-dri2 -Cflags: -I${includedir} +Cflags: -I${includedir} @XCB_CFLAGS@ diff --git a/xcb-dri3.pc.in b/xcb-dri3.pc.in index befe11e..85c680f 100644 --- a/xcb-dri3.pc.in +++ b/xcb-dri3.pc.in @@ -8,4 +8,4 @@ Description: XCB DRI3 Extension Version: @PACKAGE_VERSION@ Requires.private: xcb Libs: -L${libdir} -lxcb-dri3 -Cflags: -I${includedir} +Cflags: -I${includedir} @XCB_CFLAGS@ diff --git a/xcb-ge.pc.in b/xcb-ge.pc.in index b5f380d..6f80545 100644 --- a/xcb-ge.pc.in +++ b/xcb-ge.pc.in @@ -8,4 +8,4 @@ Description: XCB GenericEvent Extension Version: @PACKAGE_VERSION@ Requires.private: xcb Libs: -L${libdir} -lxcb-ge -Cflags: -I${includedir} +Cflags: -I${includedir} @XCB_CFLAGS@ diff --git a/xcb-glx.pc.in b/xcb-glx.pc.in index 79805ef..09c851a 100644 --- a/xcb-glx.pc.in +++ b/xcb-glx.pc.in @@ -8,4 +8,4 @@ Description: XCB GLX Extension Version: @PACKAGE_VERSION@ Requires.private: xcb Libs: -L${libdir} -lxcb-glx -Cflags: -I${includedir} +Cflags: -I${includedir} @XCB_CFLAGS@ diff --git a/xcb-present.pc.in b/xcb-present.pc.in index 2459d1d..75340fc 100644 --- a/xcb-present.pc.in +++ b/xcb-present.pc.in @@ -8,4 +8,4 @@ Description: XCB Present Extension Version: @PACKAGE_VERSION@ Requires.private: xcb xcb-randr xcb-xfixes xcb-sync xcb-dri3 Libs: -L${libdir} -lxcb-present -Cflags: -I${includedir} +Cflags: -I${includedir} @XCB_CFLAGS@ diff --git a/xcb-randr.pc.in b/xcb-randr.pc.in index 4c0de13..e58d12b 100644 --- a/xcb-randr.pc.in +++ b/xcb-randr.pc.in @@ -8,4 +8,4 @@ Description: XCB RandR Extension Version: @PACKAGE_VERSION@ Requires.private: xcb xcb-render Libs: -L${libdir} -lxcb-randr -Cflags: -I${includedir} +Cflags: -I${includedir} @XCB_CFLAGS@ diff --git a/xcb-record.pc.in b/xcb-record.pc.in index b441c9a..6f1b848 100644 --- a/xcb-record.pc.in +++ b/xcb-record.pc.in @@ -8,4 +8,4 @@ Description: XCB Record Extension Version: @PACKAGE_VERSION@ Requires.private: xcb Libs: -L${libdir} -lxcb-record -Cflags: -I${includedir} +Cflags: -I${includedir} @XCB_CFLAGS@ diff --git a/xcb-render.pc.in b/xcb-render.pc.in index 9ad543e..0d6831f 100644 --- a/xcb-render.pc.in +++ b/xcb-render.pc.in @@ -8,4 +8,4 @@ Description: XCB Render Extension Version: @PACKAGE_VERSION@ Requires.private: xcb Libs: -L${libdir} -lxcb-render -Cflags: -I${includedir} +Cflags: -I${includedir} @XCB_CFLAGS@ diff --git a/xcb-res.pc.in b/xcb-res.pc.in index 1f2889d..64963bd 100644 --- a/xcb-res.pc.in +++ b/xcb-res.pc.in @@ -8,4 +8,4 @@ Description: XCB X-Resource Extension Version: @PACKAGE_VERSION@ Requires.private: xcb Libs: -L${libdir} -lxcb-res -Cflags: -I${includedir} +Cflags: -I${includedir} @XCB_CFLAGS@ diff --git a/xcb-screensaver.pc.in b/xcb-screensaver.pc.in index 1209b20..86a2e17 100644 --- a/xcb-screensaver.pc.in +++ b/xcb-screensaver.pc.in @@ -8,4 +8,4 @@ Description: XCB Screensaver Extension Version: @PACKAGE_VERSION@ Requires.private: xcb Libs: -L${libdir} -lxcb-screensaver -Cflags: -I${includedir} +Cflags: -I${includedir} @XCB_CFLAGS@ diff --git a/xcb-shape.pc.in b/xcb-shape.pc.in index 09637b4..180e81b 100644 --- a/xcb-shape.pc.in +++ b/xcb-shape.pc.in @@ -8,4 +8,4 @@ Description: XCB Shape Extension Version: @PACKAGE_VERSION@ Requires.private: xcb Libs: -L${libdir} -lxcb-shape -Cflags: -I${includedir} +Cflags: -I${includedir} @XCB_CFLAGS@ diff --git a/xcb-shm.pc.in b/xcb-shm.pc.in index 47c193b..cbe30b7 100644 --- a/xcb-shm.pc.in +++ b/xcb-shm.pc.in @@ -8,4 +8,4 @@ Description: XCB Shm Extension Version: @PACKAGE_VERSION@ Requires.private: xcb Libs: -L${libdir} -lxcb-shm -Cflags: -I${includedir} +Cflags: -I${includedir} @XCB_CFLAGS@ diff --git a/xcb-sync.pc.in b/xcb-sync.pc.in index 7a4c315..5eb5c02 100644 --- a/xcb-sync.pc.in +++ b/xcb-sync.pc.in @@ -8,4 +8,4 @@ Description: XCB Sync Extension Version: @PACKAGE_VERSION@ Requires.private: xcb Libs: -L${libdir} -lxcb-sync -Cflags: -I${includedir} +Cflags: -I${includedir} @XCB_CFLAGS@ diff --git a/xcb-xevie.pc.in b/xcb-xevie.pc.in index dc4fee4..14a2575 100644 --- a/xcb-xevie.pc.in +++ b/xcb-xevie.pc.in @@ -8,4 +8,4 @@ Description: XCB Xevie Extension Version: @PACKAGE_VERSION@ Requires.private: xcb Libs: -L${libdir} -lxcb-xevie -Cflags: -I${includedir} +Cflags: -I${includedir} @XCB_CFLAGS@ diff --git a/xcb-xf86dri.pc.in b/xcb-xf86dri.pc.in index 87c93d5..07c447d 100644 --- a/xcb-xf86dri.pc.in +++ b/xcb-xf86dri.pc.in @@ -8,4 +8,4 @@ Description: XCB XFree86-DRI Extension Version: @PACKAGE_VERSION@ Requires.private: xcb Libs: -L${libdir} -lxcb-xf86dri -Cflags: -I${includedir} +Cflags: -I${includedir} @XCB_CFLAGS@ diff --git a/xcb-xfixes.pc.in b/xcb-xfixes.pc.in index 2ebb9cf..bad5206 100644 --- a/xcb-xfixes.pc.in +++ b/xcb-xfixes.pc.in @@ -8,4 +8,4 @@ Description: XCB XFixes Extension Version: @PACKAGE_VERSION@ Requires.private: xcb xcb-render xcb-shape Libs: -L${libdir} -lxcb-xfixes -Cflags: -I${includedir} +Cflags: -I${includedir} @XCB_CFLAGS@ diff --git a/xcb-xinerama.pc.in b/xcb-xinerama.pc.in index abc3012..0337b2c 100644 --- a/xcb-xinerama.pc.in +++ b/xcb-xinerama.pc.in @@ -8,4 +8,4 @@ Description: XCB Xinerama Extension Version: @PACKAGE_VERSION@ Requires.private: xcb Libs: -L${libdir} -lxcb-xinerama -Cflags: -I${includedir} +Cflags: -I${includedir} @XCB_CFLAGS@ diff --git a/xcb-xinput.pc.in b/xcb-xinput.pc.in index 1f1bb27..e6c1ec9 100644 --- a/xcb-xinput.pc.in +++ b/xcb-xinput.pc.in @@ -8,4 +8,4 @@ Description: XCB XInput Extension (EXPERIMENTAL) Version: @PACKAGE_VERSION@ Requires.private: xcb xcb-xfixes Libs: -L${libdir} -lxcb-xinput -Cflags: -I${includedir} +Cflags: -I${includedir} @XCB_CFLAGS@ diff --git a/xcb-xkb.pc.in b/xcb-xkb.pc.in index d5b1bad..7218748 100644 --- a/xcb-xkb.pc.in +++ b/xcb-xkb.pc.in @@ -8,4 +8,4 @@ Description: XCB Keyboard Extension (EXPERIMENTAL) Version: @PACKAGE_VERSION@ Requires.private: xcb Libs: -L${libdir} -lxcb-xkb -Cflags: -I${includedir} +Cflags: -I${includedir} @XCB_CFLAGS@ diff --git a/xcb-xprint.pc.in b/xcb-xprint.pc.in index 7ac65f6..d6f81fb 100644 --- a/xcb-xprint.pc.in +++ b/xcb-xprint.pc.in @@ -8,4 +8,4 @@ Description: XCB Xprint Extension Version: @PACKAGE_VERSION@ Requires.private: xcb Libs: -L${libdir} -lxcb-xprint -Cflags: -I${includedir} +Cflags: -I${includedir} @XCB_CFLAGS@ diff --git a/xcb-xselinux.pc.in b/xcb-xselinux.pc.in index 0f86a93..1319c02 100644 --- a/xcb-xselinux.pc.in +++ b/xcb-xselinux.pc.in @@ -8,4 +8,4 @@ Description: XCB SELinux Extension Version: @PACKAGE_VERSION@ Requires.private: xcb Libs: -L${libdir} -lxcb-xselinux -Cflags: -I${includedir} +Cflags: -I${includedir} @XCB_CFLAGS@ diff --git a/xcb-xtest.pc.in b/xcb-xtest.pc.in index 9961152..a452f23 100644 --- a/xcb-xtest.pc.in +++ b/xcb-xtest.pc.in @@ -8,4 +8,4 @@ Description: XCB XTEST Extension Version: @PACKAGE_VERSION@ Requires.private: xcb Libs: -L${libdir} -lxcb-xtest -Cflags: -I${includedir} +Cflags: -I${includedir} @XCB_CFLAGS@ diff --git a/xcb-xv.pc.in b/xcb-xv.pc.in index f31de1a..6adc91d 100644 --- a/xcb-xv.pc.in +++ b/xcb-xv.pc.in @@ -8,4 +8,4 @@ Description: XCB Xv Extension Version: @PACKAGE_VERSION@ Requires.private: xcb xcb-shm Libs: -L${libdir} -lxcb-xv -Cflags: -I${includedir} +Cflags: -I${includedir} @XCB_CFLAGS@ diff --git a/xcb-xvmc.pc.in b/xcb-xvmc.pc.in index 93c51a9..226a2d8 100644 --- a/xcb-xvmc.pc.in +++ b/xcb-xvmc.pc.in @@ -8,4 +8,4 @@ Description: XCB XvMC Extension Version: @PACKAGE_VERSION@ Requires.private: xcb xcb-xv Libs: -L${libdir} -lxcb-xvmc -Cflags: -I${includedir} +Cflags: -I${includedir} @XCB_CFLAGS@ diff --git a/xcb.pc.in b/xcb.pc.in index 2dc8c13..4cdee23 100644 --- a/xcb.pc.in +++ b/xcb.pc.in @@ -10,4 +10,4 @@ Version: @PACKAGE_VERSION@ Requires.private: @NEEDED@ Libs: -L${libdir} -lxcb Libs.private: @LIBS@ -Cflags: -I${includedir} +Cflags: -I${includedir} @XCB_CFLAGS@