https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71120
Bug ID: 71120 Summary: Aliasing "struct sockaddr_storage" produces invalid code Product: gcc Version: 6.1.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: bernat at luffy dot cx Target Milestone: --- Hello, Starting with gcc-6, the following code (PoC found by Cyril Bonté) will produce an unexpected result: #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <arpa/inet.h> struct dbg_listener { struct sockaddr_storage addr; }; int main(int argc, char **argv) { struct dbg_listener *l; struct sockaddr_storage ss, *ss2, ss3; memset(&ss3, 0, sizeof(ss3)); ss3.ss_family = AF_INET; ((struct sockaddr_in *)&ss3)->sin_addr.s_addr = inet_addr("127.0.0.1"); ss2 = &ss3; ss = *ss2; l = calloc(1, sizeof(*l)); l->addr = ss; printf("%x\n", ntohl(((struct sockaddr_in *)(&l->addr))->sin_addr.s_addr)); exit(0); } This is a common pattern when handling socket addresses in a generic way. Even when the code is compiled with -fno-strict-aliasing, the output is 0 while it should be 7f000001. $ gcc-6 -O2 -Wall -fno-strict-aliasing debug.c -o debug && ./debug 0 Using -O0 fixes the problem. Fixing the aliasing violation with an union fixes the problem too. Using -fno-tree-sra fixes the problem too. Compiling with gcc-5.3.1 fixes the problem too. Here is a good starting point for the context of this bug (in HAProxy): http://article.gmane.org/gmane.comp.web.haproxy/27924