Subject: Re: next-20151007 perf build error "tools/include/linux/compiler.h:66: error: dereferencing pointer ‘res.41’ does break strict-aliasing rules"

From: Jiri Olsa <[email-masked]>
Date: Thu, 8 Oct 2015 11:12:21 +0200

On Wed, Oct 07, 2015 at 11:28:26AM -0700, Vinson Lee wrote:
> Hi.
> 
> I hit this perf build error with next-20151007 with GCC 4.4.
> 
>   CC       util/annotate.o
> cc1: warnings being treated as errors
> util/annotate.c: In function ‘disasm__purge’:
> linux-next/tools/include/linux/compiler.h:66: error: dereferencing
> pointer ‘res.41’ does break strict-aliasing rules
> linux-next/tools/include/linux/compiler.h:66: note: initialized from here
> util/annotate.c: In function ‘symbol__annotate’:
> linux-next/tools/include/linux/compiler.h:66: error: dereferencing
> pointer ‘res.41’ does break strict-aliasing rules
> linux-next/tools/include/linux/compiler.h:66: note: initialized from here
> linux-next/tools/include/linux/compiler.h:52: error: dereferencing
> pointer ‘res.32’ does break strict-aliasing rules
> linux-next/tools/include/linux/compiler.h:52: note: initialized from here
> 
> Cheers,
> Vinson

we took this stuff from kernel, which is built with -fno-strict-aliasing
which we use -Wstrict-aliasing=3

we need something like below defined for all the types, but I'm still
hoping for some nicer solution.. however patch below fixed the build
for me.. could you please test?

thanks,
jirka

---
diff --git a/tools/include/linux/compiler.h b/tools/include/linux/compiler.h
index 9098083..0ed624f 100644
--- a/tools/include/linux/compiler.h
+++ b/tools/include/linux/compiler.h
@@ -43,13 +43,18 @@
 
 #include <linux/types.h>
 
+typedef u64 __attribute__((__may_alias__)) u64_alias_t;
+
 static __always_inline void __read_once_size(const volatile void *p, void *res, int size)
 {
+	u64_alias_t *u64_p = (u64_alias_t*) p;
+	u64_alias_t *u64_res = (u64_alias_t*) res;
+
 	switch (size) {
 	case 1: *(__u8 *)res = *(volatile __u8 *)p; break;
 	case 2: *(__u16 *)res = *(volatile __u16 *)p; break;
 	case 4: *(__u32 *)res = *(volatile __u32 *)p; break;
-	case 8: *(__u64 *)res = *(volatile __u64 *)p; break;
+	case 8: *u64_res = *u64_p; break;
 	default:
 		barrier();
 		__builtin_memcpy((void *)res, (const void *)p, size);
@@ -59,11 +64,14 @@ static __always_inline void __read_once_size(const volatile void *p, void *res,
 
 static __always_inline void __write_once_size(volatile void *p, void *res, int size)
 {
+	u64_alias_t *u64_p = (u64_alias_t*) p;
+	u64_alias_t *u64_res = (u64_alias_t*) res;
+
 	switch (size) {
 	case 1: *(volatile __u8 *)p = *(__u8 *)res; break;
 	case 2: *(volatile __u16 *)p = *(__u16 *)res; break;
 	case 4: *(volatile __u32 *)p = *(__u32 *)res; break;
-	case 8: *(volatile __u64 *)p = *(__u64 *)res; break;
+	case 8: *u64_p = *u64_res; break;
 	default:
 		barrier();
 		__builtin_memcpy((void *)p, (const void *)res, size);