Date: Mon, 28 Jul 2003 03:59:00 +0200 From: Thomas Moestl <t.moestl@tu-bs.de> To: Jun Kuriyama <kuriyama@imgsrc.co.jp> Cc: Current <freebsd-current@freebsd.org> Subject: Re: dereferencing type-punned pointer will break strict-aliasing rules Message-ID: <20030728015900.GB5628@crow.dom2ip.de> In-Reply-To: <7mwue3v6gf.wl@black.imgsrc.co.jp> References: <7mwue3v6gf.wl@black.imgsrc.co.jp>
next in thread | previous in thread | raw e-mail | index | archive | help
--jI8keyz6grp/JLjh Content-Type: text/plain; charset=us-ascii Content-Disposition: inline On Mon, 2003/07/28 at 09:30:08 +0900, Jun Kuriyama wrote: > > Is this caused by -oS option? > > ----- in making BOOTMFS in make release > cc -c -Os -pipe -Wall -Wredundant-decls -Wnested-externs -Wstrict-prototypes -Wmissing-prototypes -Wpointer-arith -Winline -Wcast-qual -fformat-extensions -std=c99 -nostdinc -I- -I. -I/usr/src/sys -I/usr/src/sys/dev -I/usr/src/sys/contrib/dev/acpica -I/usr/src/sys/contrib/ipfilter -I/usr/src/sys/contrib/dev/ath -I/usr/src/sys/contrib/dev/ath/freebsd -D_KERNEL -include opt_global.h -fno-common -finline-limit=15000 -mno-align-long-strings -mpreferred-stack-boundary=2 -ffreestanding -Werror /usr/src/sys/geom/geom_dev.c > /usr/src/sys/geom/geom_dev.c: In function `g_dev_open': > /usr/src/sys/geom/geom_dev.c:198: warning: dereferencing type-punned pointer will break strict-aliasing rules > [...] Yes, by implying -fstrict-aliasing, so using -fno-strict-aliasing is a workaround. The problem is caused by the i386 PCPU_GET/PCPU_SET implementation: #define __PCPU_GET(name) ({ \ __pcpu_type(name) __result; \ \ [...] } else if (sizeof(__result) == 4) { \ u_int __i; \ __asm __volatile("movl %%fs:%1,%0" \ : "=r" (__i) \ : "m" (*(u_int *)(__pcpu_offset(name)))); \ __result = *(__pcpu_type(name) *)&__i; \ [...] In this case, the PCPU_GET is used to retrieve curthread, causing sizeof(__result) to be 4, so the cast at the end of the code snippet is from a u_int * to struct thread *, and __i is accessed through the casted pointer, which violates the C99 aliasing rules. An alternative is to type-pun via a union, which is also a bit ugly, but explicitly allowed by C99. Patch attached (but only superficially tested). - Thomas -- Thomas Moestl <t.moestl@tu-bs.de> http://www.tu-bs.de/~y0015675/ <tmm@FreeBSD.org> http://people.FreeBSD.org/~tmm/ PGP fingerprint: 1C97 A604 2BD0 E492 51D0 9C0F 1FE6 4F1D 419C 776C --jI8keyz6grp/JLjh Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="pcpu.diff" Index: pcpu.h =================================================================== RCS file: /vol/ncvs/src/sys/i386/include/pcpu.h,v retrieving revision 1.36 diff -u -r1.36 pcpu.h --- pcpu.h 27 Jun 2003 21:50:52 -0000 1.36 +++ pcpu.h 28 Jul 2003 01:37:57 -0000 @@ -96,23 +96,32 @@ __pcpu_type(name) __result; \ \ if (sizeof(__result) == 1) { \ - u_char __b; \ + union { \ + u_char __b; \ + __pcpu_type(name) __r; \ + } __u; \ __asm __volatile("movb %%fs:%1,%0" \ - : "=r" (__b) \ + : "=r" (__u.__b) \ : "m" (*(u_char *)(__pcpu_offset(name)))); \ - __result = *(__pcpu_type(name) *)&__b; \ + __result = __u.__r; \ } else if (sizeof(__result) == 2) { \ - u_short __w; \ + union { \ + u_short __w; \ + __pcpu_type(name) __r; \ + } __u; \ __asm __volatile("movw %%fs:%1,%0" \ - : "=r" (__w) \ + : "=r" (__u.__w) \ : "m" (*(u_short *)(__pcpu_offset(name)))); \ - __result = *(__pcpu_type(name) *)&__w; \ + __result = __u.__r; \ } else if (sizeof(__result) == 4) { \ - u_int __i; \ + union { \ + u_int __i; \ + __pcpu_type(name) __r; \ + } __u; \ __asm __volatile("movl %%fs:%1,%0" \ - : "=r" (__i) \ + : "=r" (__u.__i) \ : "m" (*(u_int *)(__pcpu_offset(name)))); \ - __result = *(__pcpu_type(name) *)&__i; \ + __result = __u.__r; \ } else { \ __result = *__PCPU_PTR(name); \ } \ @@ -127,23 +136,32 @@ __pcpu_type(name) __val = (val); \ \ if (sizeof(__val) == 1) { \ - u_char __b; \ - __b = *(u_char *)&__val; \ + union { \ + u_char __b; \ + __pcpu_type(name) __v; \ + } __u; \ + __u.__v = __val; \ __asm __volatile("movb %1,%%fs:%0" \ : "=m" (*(u_char *)(__pcpu_offset(name))) \ - : "r" (__b)); \ + : "r" (__u.__b)); \ } else if (sizeof(__val) == 2) { \ - u_short __w; \ - __w = *(u_short *)&__val; \ + union { \ + u_short __w; \ + __pcpu_type(name) __v; \ + } __u; \ + __u.__v = __val; \ __asm __volatile("movw %1,%%fs:%0" \ : "=m" (*(u_short *)(__pcpu_offset(name))) \ - : "r" (__w)); \ + : "r" (__u.__w)); \ } else if (sizeof(__val) == 4) { \ - u_int __i; \ - __i = *(u_int *)&__val; \ + union { \ + u_int __i; \ + __pcpu_type(name) __v; \ + } __u; \ + __u.__v = __val; \ __asm __volatile("movl %1,%%fs:%0" \ : "=m" (*(u_int *)(__pcpu_offset(name))) \ - : "r" (__i)); \ + : "r" (__u.__i)); \ } else { \ *__PCPU_PTR(name) = __val; \ } \ --jI8keyz6grp/JLjh--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20030728015900.GB5628>