Blob Blame History Raw
From 6e8efe88a07008a9f7f14de5b7f79dca2ba14602 Mon Sep 17 00:00:00 2001
From: Mamoru TASAKA <mtasaka@fedoraproject.org>
Date: Sat, 30 Jan 2016 23:29:00 +0900
Subject: [PATCH] async_netdb: kill gcc6 strict aliasing warning

POSIX.1-2008 sys/socket.h says "When a pointer to a
sockaddr_storage structure is cast as a pointer to
a protocol-specific address structure, ...",
but now gcc 6 warns about breaking strict aliasing
rules like:

./../utils/async_netdb.c: In function 'async_name_from_addr_finish':
../../utils/async_netdb.c:239:36: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
         raw_addr = &((const struct sockaddr_in *)&self->addr)->sin_addr;
                                    ^~~~~~~~~~~
../../utils/async_netdb.c:244:36: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
         raw_addr = &((const struct sockaddr_in6 *)&self->addr)->sin6_addr;
---
 utils/async_netdb.c | 12 ++++++------
 utils/async_netdb.h | 16 ++++++++++++++--
 2 files changed, 20 insertions(+), 8 deletions(-)

diff --git a/utils/async_netdb.c b/utils/async_netdb.c
index 5c52161..930da40 100644
--- a/utils/async_netdb.c
+++ b/utils/async_netdb.c
@@ -31,8 +31,8 @@
 
 #if ASYNC_NETDB_USE_GAI
 
-# define _get_addr_family(addr) ((addr)->ss_family)
-# define _get_addr_len(addr) ((addr)->ss_len)
+# define _get_addr_family(addr) ((addr)->x_sockaddr_storage.ss_family)
+# define _get_addr_len(addr) ((addr)->x_sockaddr_storage.ss_len)
 
 static int _has_threads;
 
@@ -45,8 +45,8 @@ int _async_netdb_is_done (struct io_thread *io)
 
 #else /* ASYNC_NETDB_USE_GAI */
 
-# define _get_addr_family(addr) ((addr)->sin_family)
-# define _get_addr_len(addr) ((addr)->sin_len)
+# define _get_addr_family(addr) ((addr)->x_sockaddr_in.sin_family)
+# define _get_addr_len(addr) ((addr)->x_sockaddr_in.sin_len)
 
 static const int _has_threads = -1;
 
@@ -236,12 +236,12 @@ async_name_from_addr_finish (async_name_from_addr_t self_raw,
     switch (_get_addr_family (&self->addr))
       {
       case AF_INET:
-        raw_addr = &((const struct sockaddr_in *)&self->addr)->sin_addr;
+        raw_addr = &self->addr.x_sockaddr_in.sin_addr;
         addrlen = 4;
         break;
 #if ASYNC_NETDB_USE_GAI
       case AF_INET6:
-        raw_addr = &((const struct sockaddr_in6 *)&self->addr)->sin6_addr;
+        raw_addr = &self->addr.x_sockaddr_in6.sin6_addr;
         addrlen = 16;
         break;
 #endif /* ASYNC_NETDB_USE_GAI */
diff --git a/utils/async_netdb.h b/utils/async_netdb.h
index df6c59c..3d3101f 100644
--- a/utils/async_netdb.h
+++ b/utils/async_netdb.h
@@ -53,13 +53,25 @@
 
 #if ASYNC_NETDB_USE_GAI
 
-typedef struct sockaddr_storage async_netdb_sockaddr_storage_t;
+/* Without using union, gcc-6 warns for
+   breaking strict aliasing rules
+ */
+typedef union {
+	struct sockaddr_storage x_sockaddr_storage;
+	struct sockaddr_in x_sockaddr_in;
+	struct sockaddr_in6 x_sockaddr_in6;
+} async_netdb_sockaddr_storage_t;
 
 int _async_netdb_is_done (struct io_thread *io);
 
 #else
 
-typedef struct sockaddr_in async_netdb_sockaddr_storage_t;
+/* Because the definition for the above case is now union,
+   the definition for this case must also be union...
+*/
+typedef union {
+	struct sockaddr_in;
+} async_netdb_sockaddr_storage_t;
 
 # ifndef EAI_SYSTEM
 /* The EAI_* codes are specified specifically as preprocessor macros, so
-- 
2.7.0