GCC 4.4 produces more warnings relating to type-punning:

http://gcc.gnu.org/gcc-4.4/porting_to.html

which now causes Classpath builds with -Werror to fail.
This patch fixes the issues by replacing the use of a shared
pointer for the IPv4 and IPv6 socket types with a union.
It's not ideal either, but fixes the typing of these pointers.

Ok for HEAD?
-- 
Andrew :)

Free Java Software Engineer
Red Hat, Inc. (http://www.redhat.com)

Support Free Java!
Contribute to GNU Classpath and the OpenJDK
http://www.gnu.org/software/classpath
http://openjdk.java.net
PGP Key: 94EFD9D8 (http://subkeys.pgp.net)
Fingerprint = F8EF F1EA 401E 2E60 15FA  7927 142C 2591 94EF D9D8
Index: native/jni/java-net/gnu_java_net_VMPlainSocketImpl.c
===================================================================
RCS file: 
/sources/classpath/classpath/native/jni/java-net/gnu_java_net_VMPlainSocketImpl.c,v
retrieving revision 1.16
diff -u -u -r1.16 gnu_java_net_VMPlainSocketImpl.c
--- native/jni/java-net/gnu_java_net_VMPlainSocketImpl.c        28 Dec 2007 
17:49:56 -0000      1.16
+++ native/jni/java-net/gnu_java_net_VMPlainSocketImpl.c        18 Jun 2009 
19:44:42 -0000
@@ -399,7 +399,7 @@
     return;
 
   result = setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF,
-                      (struct sockaddr *) cpaddr->data, cpaddr->len);
+                      (struct sockaddr *) &(cpaddr->data.ipv4), cpaddr->len);
 
   cpnet_freeAddress (env, cpaddr);
   
Index: native/jni/java-nio/gnu_java_nio_VMChannel.c
===================================================================
RCS file: 
/sources/classpath/classpath/native/jni/java-nio/gnu_java_nio_VMChannel.c,v
retrieving revision 1.22
diff -u -u -r1.22 gnu_java_nio_VMChannel.c
--- native/jni/java-nio/gnu_java_nio_VMChannel.c        28 Dec 2007 17:49:56 
-0000      1.22
+++ native/jni/java-nio/gnu_java_nio_VMChannel.c        18 Jun 2009 19:44:43 
-0000
@@ -757,16 +757,15 @@
 #ifdef HAVE_RECVFROM
   char *addrPortPtr = (*env)->GetDirectBufferAddress (env, addrPort);
   struct JCL_buffer buf;
+union sockets
+{
 #ifdef HAVE_INET6
-  struct sockaddr_in6 sock_storage;
-  struct sockaddr_in6 *sock6;
-  socklen_t slen = sizeof (struct sockaddr_in6);
-#else
-  struct sockaddr_in sock_storage;
-  socklen_t slen = sizeof (struct sockaddr_in);
+  struct sockaddr_in6 sock6;
 #endif /* HAVE_INET6 */
-  struct sockaddr *sockaddr = (struct sockaddr *) &sock_storage;
-  struct sockaddr_in *sock4;
+  struct sockaddr_in sock4;
+} sock_storage;
+
+  socklen_t slen = sizeof (union sockets);
   int ret;
   jint result = -1;
 
@@ -779,7 +778,7 @@
 
   ret = cpnio_recvfrom (fd, &(buf.ptr[buf.position + buf.offset]),
                         buf.limit - buf.position, MSG_WAITALL,
-                        sockaddr, &slen);
+                        (struct sockaddr *) &sock_storage, &slen);
 
   if (-1 == ret)
     {
@@ -801,19 +800,17 @@
       return 0;
     }
 
-  if (sockaddr->sa_family == AF_INET)
+  if (sock_storage.sock4.sin_family == AF_INET)
     {
-      sock4 = (struct sockaddr_in *) sockaddr;
-      memcpy (addrPortPtr, &(sock4->sin_addr.s_addr), 4);
-      ;memcpy (addrPortPtr + 4, &(sock4->sin_port), 2);
+      memcpy (addrPortPtr, &(sock_storage.sock4.sin_addr.s_addr), 4);
+      ;memcpy (addrPortPtr + 4, &(sock_storage.sock4.sin_port), 2);
       result = 4;
     }
 #ifdef HAVE_INET6
-  else if (sockaddr->sa_family == AF_INET6)
+  else if (sock_storage.sock6.sin6_family == AF_INET6)
     {
-      sock6 = (struct sockaddr_in6 *) sockaddr;
-      memcpy (addrPortPtr, &(sock6->sin6_addr.s6_addr), 16);
-      memcpy (addrPortPtr + 16, &(sock6->sin6_port), 2);
+      memcpy (addrPortPtr, &(sock_storage.sock6.sin6_addr.s6_addr), 16);
+      memcpy (addrPortPtr + 16, &(sock_storage.sock6.sin6_port), 2);
       result = 16;
     }
 #endif /* HAVE_INET6 */
@@ -1358,42 +1355,38 @@
                                          jint fd, jobject name)
 {
 #ifdef HAVE_GETSOCKNAME
+union sockets
+{
 #ifdef HAVE_INET6
-  struct sockaddr_in6 *addr6;
-  struct sockaddr_in6 sock_storage;
-  socklen_t socklen = sizeof (struct sockaddr_in6);
-#else
-  struct sockaddr_in sock_storage;
-  socklen_t socklen = sizeof (struct sockaddr_in);
+  struct sockaddr_in6 ipv6;
 #endif /* HAVE_INET6 */
+  struct sockaddr_in ipv4;
+} sock_storage;
 
-  struct sockaddr *sockaddr = (struct sockaddr *) &sock_storage;
-  struct sockaddr_in *addr4;
+  socklen_t socklen = sizeof (union sockets);
   int ret;
   char *nameptr = (*env)->GetDirectBufferAddress (env, name);
 
-  ret = getsockname (fd, sockaddr, &socklen);
+  ret = getsockname (fd, (struct sockaddr *) &sock_storage, &socklen);
   if (ret == -1)
     {
       JCL_ThrowException (env, "java/net/SocketException", strerror (errno));
       return 0;
     }
 
-  if (sockaddr->sa_family == AF_INET)
+  if (sock_storage.ipv4.sin_family == AF_INET)
     {
-      addr4 = (struct sockaddr_in *) sockaddr;
-      memcpy (nameptr, &(addr4->sin_addr.s_addr), 4);
-      memcpy (nameptr + 4, &(addr4->sin_port), 2);
+      memcpy (nameptr, &(sock_storage.ipv4.sin_addr.s_addr), 4);
+      memcpy (nameptr + 4, &(sock_storage.ipv4.sin_port), 2);
       return 4;
     }
 
 #ifdef HAVE_INET6
   /* IPv6 */
-  if (sockaddr->sa_family == AF_INET6)
+  if (sock_storage.ipv6.sin6_family == AF_INET6)
     {
-      addr6 = (struct sockaddr_in6 *) sockaddr;
-      memcpy (nameptr, &(addr6->sin6_addr.s6_addr), 16);
-      memcpy (nameptr + 16, &(addr6->sin6_port), 2);
+      memcpy (nameptr, &(sock_storage.ipv6.sin6_addr.s6_addr), 16);
+      memcpy (nameptr + 16, &(sock_storage.ipv6.sin6_port), 2);
       return 16;
     }
 #endif /* HAVE_INET6 */
@@ -1418,21 +1411,19 @@
                                          jint fd, jobject name)
 {
 #ifdef HAVE_GETPEERNAME
+union sockets
+{
 #ifdef HAVE_INET6
-  struct sockaddr_in6 *addr6;
-  struct sockaddr_in6 sock_storage;
-  socklen_t socklen = sizeof (struct sockaddr_in6);
-#else
-  struct sockaddr_in sock_storage;
-  socklen_t socklen = sizeof (struct sockaddr_in);
+  struct sockaddr_in6 ipv6;
 #endif /* HAVE_INET6 */
+  struct sockaddr_in ipv4;
+} sock_storage;
 
-  struct sockaddr *sockaddr = (struct sockaddr *) &sock_storage;
-  struct sockaddr_in *addr4;
   int ret;
   char *nameptr = (*env)->GetDirectBufferAddress (env, name);
   
-  ret = getpeername (fd, sockaddr, &socklen);
+  socklen_t size = sizeof (union sockets);
+  ret = getpeername (fd, (struct sockaddr *) &sock_storage, &size);
   if (ret == -1)
     {
       if (ENOTCONN != errno)
@@ -1440,19 +1431,17 @@
       return 0;
     }
 
-  if (sockaddr->sa_family == AF_INET)
+  if (sock_storage.ipv4.sin_family == AF_INET)
     {
-      addr4 = (struct sockaddr_in *) sockaddr;
-      memcpy (nameptr, &(addr4->sin_addr.s_addr), 4);
-      memcpy (nameptr + 4, &(addr4->sin_port), 2);
+      memcpy (nameptr, &(sock_storage.ipv4.sin_addr.s_addr), 4);
+      memcpy (nameptr + 4, &(sock_storage.ipv4.sin_port), 2);
       return 4;
     }
 #ifdef HAVE_INET6
-  else if (sockaddr->sa_family == AF_INET6)
+  else if (sock_storage.ipv6.sin6_family == AF_INET6)
     {
-      addr6 = (struct sockaddr_in6 *) sockaddr;
-      memcpy (nameptr, &(addr6->sin6_addr.s6_addr), 16);
-      memcpy (nameptr + 16, &(addr6->sin6_port), 2);
+      memcpy (nameptr, &(sock_storage.ipv6.sin6_addr.s6_addr), 16);
+      memcpy (nameptr + 16, &(sock_storage.ipv6.sin6_port), 2);
       return 16;
     }
 #endif /* HAVE_INET6 */
Index: native/jni/native-lib/cpnet.c
===================================================================
RCS file: /sources/classpath/classpath/native/jni/native-lib/cpnet.c,v
retrieving revision 1.10
diff -u -u -r1.10 cpnet.c
--- native/jni/native-lib/cpnet.c       25 Jun 2007 09:44:36 -0000      1.10
+++ native/jni/native-lib/cpnet.c       18 Jun 2009 19:44:44 -0000
@@ -1,5 +1,5 @@
 /* cpnet.c -
-   Copyright (C) 2003, 2004, 2005, 2006  Free Software Foundation, Inc.
+   Copyright (C) 2003, 2004, 2005, 2006, 2009  Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -176,7 +176,7 @@
 {
   int ret;
 
-  ret = bind(fd, (struct sockaddr *)addr->data, addr->len);
+  ret = bind(fd, (struct sockaddr *) &(addr->data.ipv4), addr->len);
   if (ret != 0)
     return errno;
 
@@ -188,7 +188,7 @@
   int ret;
 
   /* TODO: implement socket time out */
-  ret = connect(fd, (struct sockaddr *)addr->data, addr->len);
+  ret = connect(fd, (struct sockaddr *) &(addr->data.ipv4), addr->len);
   if (ret != 0)
     return errno;
 
@@ -203,7 +203,7 @@
   *addr = JCL_malloc(env, slen);
 
   slen -= sizeof(jint);
-  ret = getsockname(fd, (struct sockaddr *)(*addr)->data, &slen );
+  ret = getsockname(fd, (struct sockaddr *) &((*addr)->data.ipv4), &slen );
   if (ret != 0)
     {
       int err = errno;
@@ -224,7 +224,7 @@
   *addr = JCL_malloc(env, slen);
 
   slen -= sizeof(jint);
-  ret = getpeername(fd, (struct sockaddr *)(*addr)->data, &slen );
+  ret = getpeername(fd, (struct sockaddr *) &((*addr)->data.ipv4), &slen );
   if (ret != 0)
     {
       int err = errno;
@@ -291,20 +291,20 @@
     return ETIMEDOUT;
 
 #if defined (HAVE_MSG_NOSIGNAL)
-  ret = sendto(fd, data, len, MSG_NOSIGNAL, (struct sockaddr *)addr->data,
+  ret = sendto(fd, data, len, MSG_NOSIGNAL, (struct sockaddr *) 
&(addr->data.ipv4),
               addr->len);
 #elif defined (HAVE_SO_NOSIGPIPE)
   ret = setsockopt_NOSIGPIPE(fd);
   if (ret == 0)
   {
-    ret = sendto(fd, data, len, 0, (struct sockaddr *)addr->data,
+    ret = sendto(fd, data, len, 0, addr->data.ipv4,
               addr->len);
   }
 #else
   /* We want SIGPIPE to be omitted. But this configuration does not have an
    * option for that.
    */
-  ret = sendto(fd, data, len, 0, (struct sockaddr *)addr->data,
+  ret = sendto(fd, data, len, 0, addr->data.ipv4,
               addr->len);
 #endif
 
@@ -342,7 +342,7 @@
   *addr = JCL_malloc(env, slen);
 
   slen -= sizeof(jint);
-  ret = recvfrom(fd, data, len, 0, (struct sockaddr *) (*addr)->data, &slen);
+  ret = recvfrom(fd, data, len, 0, (struct sockaddr *) &((*addr)->data.ipv4), 
&slen);
   if (ret < 0)
     {
       int err = errno;
@@ -504,7 +504,7 @@
 {
   int ret;
 
-  ret = setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, (struct sockaddr 
*)addr->data, addr->len);
+  ret = setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, &(addr->data.ipv4), 
addr->len);
   if (ret != 0)
     return errno;
 
@@ -519,7 +519,7 @@
   *addr = JCL_malloc(env, slen);
 
   slen -= sizeof(jint);
-  ret = getsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, (struct sockaddr 
*)(*addr)->data, &slen);
+  ret = getsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, &((*addr)->data.ipv4), 
&slen);
   (*addr)->len = slen;
 
   if (ret != 0)
@@ -580,7 +580,7 @@
   int ret;
   
   memset(&req, 0, sizeof(req));
-  req.imr_multiaddr = ((struct sockaddr_in *)addr->data)->sin_addr;
+  req.imr_multiaddr = addr->data.ipv4.sin_addr;
   req.imr_interface.s_addr = INADDR_ANY;
   ret = setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &req, sizeof(req));
   if (ret != 0)
@@ -595,7 +595,7 @@
   int ret;
   
   memset(&req, 0, sizeof(req));
-  req.imr_multiaddr = ((struct sockaddr_in *)addr->data)->sin_addr;
+  req.imr_multiaddr = addr->data.ipv4.sin_addr;
   req.imr_interface.s_addr = INADDR_ANY;
   ret = setsockopt(fd, IPPROTO_IP, IP_DROP_MEMBERSHIP, &req, sizeof(req));
   if (ret != 0)
@@ -715,31 +715,23 @@
 
 jint cpnet_getHostByAddr (JNIEnv *env UNUSED, cpnet_address *addr, char 
*hostname, jint hostname_len)
 {
-  union 
-  {
-    struct sockaddr_in *addr_v4;
-    struct sockaddr_in6 *addr_v6;
-    char *data;
-  } haddr;
   void *raw_addr;
   int addr_type;
   struct hostent *ret;
   int addr_len;
 
-  haddr.data = addr->data;
-  
-  if (haddr.addr_v4->sin_family == AF_INET)
+  if (addr->data.ipv4.sin_family == AF_INET)
     {
-      raw_addr = &haddr.addr_v4->sin_addr;
-      addr_len = sizeof(haddr.addr_v4->sin_addr);
+      raw_addr = &addr->data.ipv4.sin_addr;
+      addr_len = sizeof(addr->data.ipv4.sin_addr);
       addr_type = AF_INET;
     }
 #ifdef HAVE_INET6
-  else if (haddr.addr_v6->sin6_family == AF_INET6)
+  else if (addr->data.ipv6.sin6_family == AF_INET6)
     {
-      raw_addr = &haddr.addr_v6->sin6_addr;
+      raw_addr = &addr->data.ipv6.sin6_addr;
       addr_type = AF_INET6;
-      addr_len = sizeof(haddr.addr_v6->sin6_addr);
+      addr_len = sizeof(addr->data.ipv6.sin6_addr);
     }
 #endif
   else
Index: native/jni/native-lib/cpnet.h
===================================================================
RCS file: /sources/classpath/classpath/native/jni/native-lib/cpnet.h,v
retrieving revision 1.6
diff -u -u -r1.6 cpnet.h
--- native/jni/native-lib/cpnet.h       28 Dec 2007 17:49:56 -0000      1.6
+++ native/jni/native-lib/cpnet.h       18 Jun 2009 19:44:44 -0000
@@ -1,5 +1,5 @@
 /* cpnet.h -
-   Copyright (C) 2003, 2004, 2005, 2006  Free Software Foundation, Inc.
+   Copyright (C) 2003, 2004, 2005, 2006, 2009  Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -52,9 +52,14 @@
 #include <netinet/ip.h>
 #endif /* HAVE_NETINET_IP_H */
 
-typedef struct {
+typedef struct 
+{
   jint len;
-  char data[1];
+  union
+  {
+    struct sockaddr_in ipv4;
+    struct sockaddr_in6 ipv6;
+  } data;
 } cpnet_address;
 
 #define CPNET_SHUTDOWN_READ 1
@@ -105,8 +110,8 @@
 
 static inline cpnet_address *cpnet_newIPV4Address(JNIEnv * env)
 {
-  cpnet_address *addr = (cpnet_address *)JCL_malloc(env, sizeof(cpnet_address) 
+ sizeof(struct sockaddr_in));
-  struct sockaddr_in *netaddr = (struct sockaddr_in *)&(addr->data[0]);
+  cpnet_address *addr = (cpnet_address *)JCL_malloc(env, 
sizeof(cpnet_address));
+  struct sockaddr_in *netaddr = &(addr->data.ipv4);
 
   addr->len = sizeof(struct sockaddr_in);
   memset(netaddr, 0, addr->len);
@@ -116,7 +121,7 @@
 
 static inline void cpnet_setIPV4Any(cpnet_address *addr)
 {
-  struct sockaddr_in *netaddr = (struct sockaddr_in *)&(addr->data[0]);
+  struct sockaddr_in *netaddr = &(addr->data.ipv4);
   
   netaddr->sin_addr.s_addr = INADDR_ANY;
 }
@@ -124,8 +129,8 @@
 #ifdef HAVE_INET6
 static inline cpnet_address *cpnet_newIPV6Address(JNIEnv * env)
 {
-  cpnet_address * addr = (cpnet_address *)JCL_malloc(env, 
sizeof(cpnet_address) + sizeof(struct sockaddr_in6));
-  struct sockaddr_in6 *netaddr = (struct sockaddr_in6 *)&(addr->data[0]);
+  cpnet_address * addr = (cpnet_address *)JCL_malloc(env, 
sizeof(cpnet_address));
+  struct sockaddr_in6 *netaddr = &(addr->data.ipv6);
 
   addr->len = sizeof(struct sockaddr_in6);
   memset(netaddr, 0, addr->len);
@@ -142,14 +147,14 @@
 
 static inline void cpnet_addressSetPort(cpnet_address *addr, jint port)
 {
-  struct sockaddr_in *ipaddr = (struct sockaddr_in *)&(addr->data[0]);
+  struct sockaddr_in *ipaddr = &(addr->data.ipv4);
 
   ipaddr->sin_port = htons(port);
 }
 
 static inline jint cpnet_addressGetPort(cpnet_address *addr)
 {
-  struct sockaddr_in *ipaddr = (struct sockaddr_in *)&(addr->data[0]);
+  struct sockaddr_in *ipaddr = &(addr->data.ipv4);
 
   return ntohs(ipaddr->sin_port);
 }
@@ -159,13 +164,13 @@
   if (addr1->len != addr2->len)
     return JNI_FALSE;
 
-  return memcmp(addr1->data, addr2->data, addr1->len) == 0;
+  return memcmp(&addr1->data, &addr2->data, addr1->len) == 0;
 }
 
 #ifdef HAVE_INET6
 static inline jboolean cpnet_isIPV6Address(cpnet_address *addr)
 {
-  struct sockaddr_in *ipaddr = (struct sockaddr_in *)&(addr->data[0]);
+  struct sockaddr_in *ipaddr = &(addr->data.ipv4);
 
   return ipaddr->sin_family == AF_INET6;
 }
@@ -173,14 +178,14 @@
 
 static inline jboolean cpnet_isIPV4Address(cpnet_address *addr)
 {
-  struct sockaddr_in *ipaddr = (struct sockaddr_in *)&(addr->data[0]);
+  struct sockaddr_in *ipaddr = &(addr->data.ipv4);
 
   return ipaddr->sin_family == AF_INET;
 }
 
 static inline void cpnet_IPV4AddressToBytes(cpnet_address *netaddr, jbyte 
*octets)
 {
-  struct sockaddr_in *ipaddr = (struct sockaddr_in *)&(netaddr->data[0]);
+  struct sockaddr_in *ipaddr = &(netaddr->data.ipv4);
   unsigned long sysaddr = ntohl(ipaddr->sin_addr.s_addr);
 
   octets[0] = ((sysaddr >> 24) & 0xff);
@@ -192,7 +197,7 @@
 static inline void cpnet_bytesToIPV4Address(cpnet_address *netaddr, jbyte 
*octets)
 {
   jint sysaddr;
-  struct sockaddr_in *ipaddr = (struct sockaddr_in *)&(netaddr->data[0]);
+  struct sockaddr_in *ipaddr = &(netaddr->data.ipv4);
 
   sysaddr = ((jint)(unsigned char)octets[0]) << 24;
   sysaddr |= ((jint)(unsigned char)octets[1]) << 16;
@@ -205,14 +210,14 @@
 #ifdef HAVE_INET6
 static inline void cpnet_IPV6AddressToBytes(cpnet_address *netaddr, jbyte 
*octets)
 {
-  struct sockaddr_in6 *ipaddr = (struct sockaddr_in6 *)&(netaddr->data[0]);
+  struct sockaddr_in6 *ipaddr = &(netaddr->data.ipv6);
 
   memcpy(octets, &ipaddr->sin6_addr, 16);
 }
 
 static inline void cpnet_bytesToIPV6Address(cpnet_address *netaddr, jbyte 
*octets)
 {
-  struct sockaddr_in6 *ipaddr = (struct sockaddr_in6 *)&(netaddr->data[0]);
+  struct sockaddr_in6 *ipaddr = &(netaddr->data.ipv6);
 
   memcpy(&ipaddr->sin6_addr, octets, 16);
 }

Reply via email to