about summary refs log tree commit diff
path: root/libio/libioP.h
diff options
context:
space:
mode:
authorFlorian Weimer <fweimer@redhat.com>2015-05-18 13:58:54 +0200
committerFlorian Weimer <fweimer@redhat.com>2015-05-22 11:40:04 +0200
commite69dcccbcb53b2c0f3fbe3f6c3e04aadae7e9265 (patch)
tree9f68baa8c17a343946e69357767909297843c5c1 /libio/libioP.h
parent9124ccf76abc5a2ffe4603e6424b1dc2b5a5db44 (diff)
downloadglibc-e69dcccbcb53b2c0f3fbe3f6c3e04aadae7e9265.tar.gz
glibc-e69dcccbcb53b2c0f3fbe3f6c3e04aadae7e9265.tar.xz
glibc-e69dcccbcb53b2c0f3fbe3f6c3e04aadae7e9265.zip
Avoid some aliasing violations in libio
Diffstat (limited to 'libio/libioP.h')
-rw-r--r--libio/libioP.h23
1 files changed, 19 insertions, 4 deletions
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 <stddef.h>
+
 #include <errno.h>
 #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)