Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Fix WARN_ON() on bitfield ops

Alexey Dobriyan noticed that the new WARN_ON() semantics that were
introduced by commit 684f978347deb42d180373ac4c427f82ef963171 (to also
return the value to be warned on) didn't compile when given a bitfield,
because the typeof doesn't work for bitfields.

So instead of the typeof trick, use an "int" variable together with a
"!!(x)" expression, as suggested by Al Viro.

To make matters more interesting, Paul Mackerras points out that that is
sub-optimal on Power, but the old asm-coded comparison seems to be buggy
anyway on 32-bit Power if the conditional was 64-bit, so I think there
are more problems there.

Regardless, the new WARN_ON() semantics may have been a bad idea. But
this at least avoids the more serious complications.

Cc: Alexey Dobriyan <adobriyan@sw.ru>
Cc: Herbert Xu <herbert@gondor.apana.org.au>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Al Viro <viro@ftp.linux.org.uk>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

+4 -4
+3 -3
include/asm-generic/bug.h
··· 33 33 34 34 #ifndef HAVE_ARCH_WARN_ON 35 35 #define WARN_ON(condition) ({ \ 36 - typeof(condition) __ret_warn_on = (condition); \ 36 + int __ret_warn_on = !!(condition); \ 37 37 if (unlikely(__ret_warn_on)) { \ 38 38 printk("WARNING: at %s:%d %s()\n", __FILE__, \ 39 39 __LINE__, __FUNCTION__); \ ··· 54 54 55 55 #ifndef HAVE_ARCH_WARN_ON 56 56 #define WARN_ON(condition) ({ \ 57 - typeof(condition) __ret_warn_on = (condition); \ 57 + int __ret_warn_on = !!(condition); \ 58 58 unlikely(__ret_warn_on); \ 59 59 }) 60 60 #endif ··· 62 62 63 63 #define WARN_ON_ONCE(condition) ({ \ 64 64 static int __warned; \ 65 - typeof(condition) __ret_warn_once = (condition); \ 65 + int __ret_warn_once = !!(condition); \ 66 66 \ 67 67 if (unlikely(__ret_warn_once)) \ 68 68 if (WARN_ON(!__warned)) \
+1 -1
include/asm-powerpc/bug.h
··· 93 93 } while (0) 94 94 95 95 #define WARN_ON(x) ({ \ 96 - typeof(x) __ret_warn_on = (x); \ 96 + int __ret_warn_on = !!(x); \ 97 97 if (__builtin_constant_p(__ret_warn_on)) { \ 98 98 if (__ret_warn_on) \ 99 99 __WARN(); \