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.
This commit is contained in:
Jouni Malinen 2009-11-04 19:49:14 +02:00
parent eb999fefcb
commit 0ae7b08691
6 changed files with 28 additions and 7 deletions

View file

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

View file

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

View file

@ -185,7 +185,7 @@ int l2_packet_get_ip_addr(struct l2_packet_data *l2, char *buf, size_t len)
return -1; return -1;
} }
close(s); 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) if (saddr->sin_family != AF_INET)
return -1; return -1;
res = os_strlcpy(buf, inet_ntoa(saddr->sin_addr), len); res = os_strlcpy(buf, inet_ntoa(saddr->sin_addr), len);

View file

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

View file

@ -442,4 +442,17 @@ static inline int is_zero_ether_addr(const u8 *a)
#include "wpa_debug.h" #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 */ #endif /* COMMON_H */

View file

@ -799,11 +799,11 @@ int add_ssdp_network(char *net_if)
goto fail; goto fail;
rt.rt_dev = net_if; 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_family = AF_INET;
sin->sin_port = 0; sin->sin_port = 0;
sin->sin_addr.s_addr = inet_addr(SSDP_TARGET); 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_family = AF_INET;
sin->sin_port = 0; sin->sin_port = 0;
sin->sin_addr.s_addr = inet_addr(SSDP_NETMASK); sin->sin_addr.s_addr = inet_addr(SSDP_NETMASK);