From e69dcccbcb53b2c0f3fbe3f6c3e04aadae7e9265 Mon Sep 17 00:00:00 2001 From: Florian Weimer Date: Mon, 18 May 2015 13:58:54 +0200 Subject: Avoid some aliasing violations in libio --- libio/libioP.h | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) (limited to 'libio/libioP.h') diff --git a/libio/libioP.h b/libio/libioP.h index d8604ca21d..784a47b743 100644 --- a/libio/libioP.h +++ b/libio/libioP.h @@ -32,6 +32,8 @@ FIXME: All of the C++ cruft eventually needs to go away. */ +#include + #include #ifndef __set_errno # define __set_errno(Val) errno = (Val) @@ -104,17 +106,30 @@ extern "C" { # define _IO_JUMPS_OFFSET 0 #endif +/* Type of MEMBER in struct type TYPE. */ +#define _IO_MEMBER_TYPE(TYPE, MEMBER) __typeof__ (((TYPE){}).MEMBER) + +/* Essentially ((TYPE *) THIS)->MEMBER, but avoiding the aliasing + violation in case THIS has a different pointer type. */ +#define _IO_CAST_FIELD_ACCESS(THIS, TYPE, MEMBER) \ + (*(_IO_MEMBER_TYPE (TYPE, MEMBER) *)(((char *) (THIS)) \ + + offsetof(TYPE, MEMBER))) + #define _IO_JUMPS(THIS) (THIS)->vtable -#define _IO_WIDE_JUMPS(THIS) ((struct _IO_FILE *) (THIS))->_wide_data->_wide_vtable -#define _IO_CHECK_WIDE(THIS) (((struct _IO_FILE *) (THIS))->_wide_data != NULL) +#define _IO_JUMPS_FILE_plus(THIS) \ + _IO_CAST_FIELD_ACCESS ((THIS), struct _IO_FILE_plus, vtable) +#define _IO_WIDE_JUMPS(THIS) \ + _IO_CAST_FIELD_ACCESS ((THIS), struct _IO_FILE, _wide_data)->_wide_vtable +#define _IO_CHECK_WIDE(THIS) \ + (_IO_CAST_FIELD_ACCESS ((THIS), struct _IO_FILE, _wide_data) != NULL) #if _IO_JUMPS_OFFSET # define _IO_JUMPS_FUNC(THIS) \ - (*(struct _IO_jump_t **) ((void *) &_IO_JUMPS ((struct _IO_FILE_plus *) (THIS)) \ + (*(struct _IO_jump_t **) ((void *) &_IO_JUMPS_FILE_plus (THIS) \ + (THIS)->_vtable_offset)) # define _IO_vtable_offset(THIS) (THIS)->_vtable_offset #else -# define _IO_JUMPS_FUNC(THIS) _IO_JUMPS ((struct _IO_FILE_plus *) (THIS)) +# define _IO_JUMPS_FUNC(THIS) _IO_JUMPS_FILE_plus (THIS) # define _IO_vtable_offset(THIS) 0 #endif #define _IO_WIDE_JUMPS_FUNC(THIS) _IO_WIDE_JUMPS(THIS) -- cgit v1.2.3