diff options
author | Mark Rutland <mark.rutland@arm.com> | 2018-04-04 12:34:45 -0400 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2018-04-12 08:30:09 -0400 |
commit | 4d3b57da1593c66835d8e3a757e4751b35493fb8 (patch) | |
tree | 83e082d0151837b0a8db73fa5429abcdcaf4905d /tools/include/linux/compiler.h | |
parent | 9dc9a95f03a69ab926d9ff1986ab2087f34a5dce (diff) |
tools headers: Restore READ_ONCE() C++ compatibility
Our userspace <linux/compiler.h> defines READ_ONCE() in a way that clang
doesn't like, as we have an anonymous union in which neither field is
initialized.
WRITE_ONCE() is fine since it initializes the __val field. For
READ_ONCE() we can keep clang and GCC happy with a dummy initialization
of the __c field, so let's do that.
At the same time, let's split READ_ONCE() and WRITE_ONCE() over several
lines for legibility, as we do in the in-kernel <linux/compiler.h>.
Reported-by: Li Zhijian <lizhijian@cn.fujitsu.com>
Reported-by: Sandipan Das <sandipan@linux.vnet.ibm.com>
Tested-by: Sandipan Das <sandipan@linux.vnet.ibm.com>
Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Fixes: 6aa7de059173a986 ("locking/atomics: COCCINELLE/treewide: Convert trivial ACCESS_ONCE() patterns to READ_ONCE()/WRITE_ONCE()")
Link: http://lkml.kernel.org/r/20180404163445.16492-1-mark.rutland@arm.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/include/linux/compiler.h')
-rw-r--r-- | tools/include/linux/compiler.h | 20 |
1 files changed, 15 insertions, 5 deletions
diff --git a/tools/include/linux/compiler.h b/tools/include/linux/compiler.h index 04e32f965ad7..1827c2f973f9 100644 --- a/tools/include/linux/compiler.h +++ b/tools/include/linux/compiler.h | |||
@@ -151,11 +151,21 @@ static __always_inline void __write_once_size(volatile void *p, void *res, int s | |||
151 | * required ordering. | 151 | * required ordering. |
152 | */ | 152 | */ |
153 | 153 | ||
154 | #define READ_ONCE(x) \ | 154 | #define READ_ONCE(x) \ |
155 | ({ union { typeof(x) __val; char __c[1]; } __u; __read_once_size(&(x), __u.__c, sizeof(x)); __u.__val; }) | 155 | ({ \ |
156 | 156 | union { typeof(x) __val; char __c[1]; } __u = \ | |
157 | #define WRITE_ONCE(x, val) \ | 157 | { .__c = { 0 } }; \ |
158 | ({ union { typeof(x) __val; char __c[1]; } __u = { .__val = (val) }; __write_once_size(&(x), __u.__c, sizeof(x)); __u.__val; }) | 158 | __read_once_size(&(x), __u.__c, sizeof(x)); \ |
159 | __u.__val; \ | ||
160 | }) | ||
161 | |||
162 | #define WRITE_ONCE(x, val) \ | ||
163 | ({ \ | ||
164 | union { typeof(x) __val; char __c[1]; } __u = \ | ||
165 | { .__val = (val) }; \ | ||
166 | __write_once_size(&(x), __u.__c, sizeof(x)); \ | ||
167 | __u.__val; \ | ||
168 | }) | ||
159 | 169 | ||
160 | 170 | ||
161 | #ifndef __fallthrough | 171 | #ifndef __fallthrough |