Fix WARN_ON() on bitfield ops
Linus Torvalds [Wed, 1 Aug 2007 04:12:07 +0000 (21:12 -0700)]
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>

include/asm-generic/bug.h
include/asm-powerpc/bug.h

index 344e309..d56fedb 100644 (file)
@@ -33,7 +33,7 @@ struct bug_entry {
 
 #ifndef HAVE_ARCH_WARN_ON
 #define WARN_ON(condition) ({                                          \
-       typeof(condition) __ret_warn_on = (condition);                  \
+       int __ret_warn_on = !!(condition);                              \
        if (unlikely(__ret_warn_on)) {                                  \
                printk("WARNING: at %s:%d %s()\n", __FILE__,            \
                        __LINE__, __FUNCTION__);                        \
@@ -54,7 +54,7 @@ struct bug_entry {
 
 #ifndef HAVE_ARCH_WARN_ON
 #define WARN_ON(condition) ({                                          \
-       typeof(condition) __ret_warn_on = (condition);                  \
+       int __ret_warn_on = !!(condition);                              \
        unlikely(__ret_warn_on);                                        \
 })
 #endif
@@ -62,7 +62,7 @@ struct bug_entry {
 
 #define WARN_ON_ONCE(condition)        ({                              \
        static int __warned;                                    \
-       typeof(condition) __ret_warn_once = (condition);        \
+       int __ret_warn_once = !!(condition);                    \
                                                                \
        if (unlikely(__ret_warn_once))                          \
                if (WARN_ON(!__warned))                         \
index a248b8b..e55d1f6 100644 (file)
@@ -93,7 +93,7 @@
 } while (0)
 
 #define WARN_ON(x) ({                                          \
-       typeof(x) __ret_warn_on = (x);                          \
+       int __ret_warn_on = !!(x);                              \
        if (__builtin_constant_p(__ret_warn_on)) {              \
                if (__ret_warn_on)                              \
                        __WARN();                               \