Re: [PATCH] debug: fix BUILD_BUG_ON() for non-constant expressions

From: Ingo Molnar
Date: Sun Aug 17 2008 - 13:34:14 EST



* Linus Torvalds <torvalds@xxxxxxxxxxxxxxxxxxxx> wrote:

>
>
> On Sun, 17 Aug 2008, Ingo Molnar wrote:
> > +/*
> > + * Force a compilation error if condition is true [array index becomes
> > + * negative], and a linker error if condition is not constant [non-defined
> > + * variable is used as an array index]:
> > + *
> > + * ( The linker trick relies on gcc optimizing out a multiplication with
> > + * constant zero - which should be reasonable enough. )
> > + */
> > +extern unsigned int __BUILD_BUG_ON_non_constant;
> > +
> > +#define BUILD_BUG_ON(condition) \
> > +do { \
> > + (void)sizeof(char[1 - 2*!!(condition)]); \
> > + if (!__builtin_constant_p(condition)) \
> > + __BUILD_BUG_ON_non_constant++; \
> > +} while (0)
>
> Gag me now.
>
> Why not just do
>
> #define __BBO(c) sizeof(const char[1 - 2*!!(c)])
> #define __BBONC(c) __BBO(!__builtin_constant_p(c))
> #define BUILD_BUG_ON_ZERO(c) (__BBO(c) - __BBONC(c))
> #define BUILD_BUG_ON(c) (void)BUILD_BUG_ON_ZERO(c)
>
> and be done with it?

yeah, i first tried a few variants of that (compile-time warnings are
much better than link time warnings), but none worked when i tested
various failure modes.

try the patch below - it only gives this error during build:

kernel/sched.c: In function âtest':
kernel/sched.c:9193: error: size of array âtype name' is negative
make[1]: *** [kernel/sched.o] Error 1

it doesnt notice the error on the next line. I suspect this is because
__builtin_constant_p() is special (or broken). I tried it with gcc 4.2.3
and 4.3.0.

Ingo

Index: linux/kernel/sched.c
===================================================================
--- linux.orig/kernel/sched.c
+++ linux/kernel/sched.c
@@ -9181,3 +9181,16 @@ struct cgroup_subsys cpuacct_subsys = {
.subsys_id = cpuacct_subsys_id,
};
#endif /* CONFIG_CGROUP_CPUACCT */
+
+#define __BBO(c) sizeof(const char[1 - 2*!!(c)])
+#define __BBONC(c) __BBO(!__builtin_constant_p(c))
+#define BUILD_BUG_ON_ZERO2(c) (__BBO(c) - __BBONC(c))
+#define BUILD_BUG_ON2(c) (void)BUILD_BUG_ON_ZERO(c)
+
+void test(void)
+{
+ BUILD_BUG_ON2(0);
+ BUILD_BUG_ON2(1);
+ BUILD_BUG_ON2(panic_timeout);
+}
+
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/