Browse Source

Work around some gcc 4.4 strict-aliasing warnings

gcc 4.4 ends up generating strict-aliasing warnings about some very common
networking socket uses that do not really result in a real problem and
cannot be easily avoided with union-based type-punning due to struct
definitions including another struct in system header files. To avoid having
to fully disable strict-aliasing warnings, provide a mechanism to hide the
typecast from aliasing for now. A cleaner solution will hopefully be found
in the future to handle these cases.
Jouni Malinen 15 years ago
parent
commit
0ae7b08691

+ 3 - 2
src/drivers/driver_nl80211.c

@@ -356,8 +356,9 @@ static int wpa_driver_nl80211_send_oper_ifla(
 	req.ifinfo.ifi_change = 0;
 
 	if (linkmode != -1) {
-		rta = (struct rtattr *)
-			((char *) &req + NLMSG_ALIGN(req.hdr.nlmsg_len));
+		rta = aliasing_hide_typecast(
+			((char *) &req + NLMSG_ALIGN(req.hdr.nlmsg_len)),
+			struct rtattr);
 		rta->rta_type = IFLA_LINKMODE;
 		rta->rta_len = RTA_LENGTH(sizeof(char));
 		*((char *) RTA_DATA(rta)) = linkmode;

+ 3 - 2
src/drivers/driver_wext.c

@@ -65,8 +65,9 @@ static int wpa_driver_wext_send_oper_ifla(struct wpa_driver_wext_data *drv,
 	req.ifinfo.ifi_change = 0;
 
 	if (linkmode != -1) {
-		rta = (struct rtattr *)
-			((char *) &req + NLMSG_ALIGN(req.hdr.nlmsg_len));
+		rta = aliasing_hide_typecast(
+			((char *) &req + NLMSG_ALIGN(req.hdr.nlmsg_len)),
+			struct rtattr);
 		rta->rta_type = IFLA_LINKMODE;
 		rta->rta_len = RTA_LENGTH(sizeof(char));
 		*((char *) RTA_DATA(rta)) = linkmode;

+ 1 - 1
src/l2_packet/l2_packet_linux.c

@@ -185,7 +185,7 @@ int l2_packet_get_ip_addr(struct l2_packet_data *l2, char *buf, size_t len)
 		return -1;
 	}
 	close(s);
-	saddr = (struct sockaddr_in *) &ifr.ifr_addr;
+	saddr = aliasing_hide_typecast(&ifr.ifr_addr, struct sockaddr_in);
 	if (saddr->sin_family != AF_INET)
 		return -1;
 	res = os_strlcpy(buf, inet_ntoa(saddr->sin_addr), len);

+ 6 - 0
src/utils/common.c

@@ -325,3 +325,9 @@ const char * wpa_ssid_txt(const u8 *ssid, size_t ssid_len)
 	}
 	return ssid_txt;
 }
+
+
+void * __hide_aliasing_typecast(void *foo)
+{
+	return foo;
+}

+ 13 - 0
src/utils/common.h

@@ -442,4 +442,17 @@ static inline int is_zero_ether_addr(const u8 *a)
 
 #include "wpa_debug.h"
 
+
+/*
+ * gcc 4.4 ends up generating strict-aliasing warnings about some very common
+ * networking socket uses that do not really result in a real problem and
+ * cannot be easily avoided with union-based type-punning due to struct
+ * definitions including another struct in system header files. To avoid having
+ * to fully disable strict-aliasing warnings, provide a mechanism to hide the
+ * typecast from aliasing for now. A cleaner solution will hopefully be found
+ * in the future to handle these cases.
+ */
+void * __hide_aliasing_typecast(void *foo);
+#define aliasing_hide_typecast(a,t) (t *) __hide_aliasing_typecast((a))
+
 #endif /* COMMON_H */

+ 2 - 2
src/wps/wps_upnp_ssdp.c

@@ -799,11 +799,11 @@ int add_ssdp_network(char *net_if)
 		goto fail;
 
 	rt.rt_dev = net_if;
-	sin = (struct sockaddr_in *) &rt.rt_dst;
+	sin = aliasing_hide_typecast(&rt.rt_dst, struct sockaddr_in);
 	sin->sin_family = AF_INET;
 	sin->sin_port = 0;
 	sin->sin_addr.s_addr = inet_addr(SSDP_TARGET);
-	sin = (struct sockaddr_in *) &rt.rt_genmask;
+	sin = aliasing_hide_typecast(&rt.rt_genmask, struct sockaddr_in);
 	sin->sin_family = AF_INET;
 	sin->sin_port = 0;
 	sin->sin_addr.s_addr = inet_addr(SSDP_NETMASK);