aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Santos <daniel.santos@pobox.com>2013-02-21 19:41:55 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2013-02-21 20:22:16 -0500
commit9a8ab1c39970a4938a72d94e6fd13be88a797590 (patch)
treee95f9f02d7000dc6a79f5374f9adf6c85f936ad7
parentc361d3e54364d19bb5e803d6e766e94674da7b0e (diff)
bug.h, compiler.h: introduce compiletime_assert & BUILD_BUG_ON_MSG
Introduce compiletime_assert to compiler.h, which moves the details of how to break a build and emit an error message for a specific compiler to the headers where these details should be. Following in the tradition of the POSIX assert macro, compiletime_assert creates a build-time error when the supplied condition is *false*. Next, we add BUILD_BUG_ON_MSG to bug.h which simply wraps compiletime_assert, inverting the logic, so that it fails when the condition is *true*, consistent with the language "build bug on." This macro allows you to specify the error message you want emitted when the supplied condition is true. Finally, we remove all other code from bug.h that mucks with these details (BUILD_BUG & BUILD_BUG_ON), and have them all call BUILD_BUG_ON_MSG. This not only reduces source code bloat, but also prevents the possibility of code being changed for one macro and not for the other (which was previously the case for BUILD_BUG and BUILD_BUG_ON). Since __compiletime_error_fallback is now only used in compiler.h, I'm considering it a private macro and removing the double negation that's now extraneous. [akpm@linux-foundation.org: checkpatch fixes] Signed-off-by: Daniel Santos <daniel.santos@pobox.com> Cc: Andi Kleen <ak@linux.intel.com> Cc: Borislav Petkov <bp@alien8.de> Cc: David Rientjes <rientjes@google.com> Cc: Joe Perches <joe@perches.com> Cc: Josh Triplett <josh@joshtriplett.org> Cc: Paul Gortmaker <paul.gortmaker@windriver.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--include/linux/bug.h28
-rw-r--r--include/linux/compiler.h26
2 files changed, 38 insertions, 16 deletions
diff --git a/include/linux/bug.h b/include/linux/bug.h
index dc11dc762fc3..7f4818673c41 100644
--- a/include/linux/bug.h
+++ b/include/linux/bug.h
@@ -17,6 +17,7 @@ struct pt_regs;
17#define BUILD_BUG_ON_ZERO(e) (0) 17#define BUILD_BUG_ON_ZERO(e) (0)
18#define BUILD_BUG_ON_NULL(e) ((void*)0) 18#define BUILD_BUG_ON_NULL(e) ((void*)0)
19#define BUILD_BUG_ON_INVALID(e) (0) 19#define BUILD_BUG_ON_INVALID(e) (0)
20#define BUILD_BUG_ON_MSG(cond, msg) (0)
20#define BUILD_BUG_ON(condition) (0) 21#define BUILD_BUG_ON(condition) (0)
21#define BUILD_BUG() (0) 22#define BUILD_BUG() (0)
22#else /* __CHECKER__ */ 23#else /* __CHECKER__ */
@@ -40,6 +41,15 @@ struct pt_regs;
40#define BUILD_BUG_ON_INVALID(e) ((void)(sizeof((__force long)(e)))) 41#define BUILD_BUG_ON_INVALID(e) ((void)(sizeof((__force long)(e))))
41 42
42/** 43/**
44 * BUILD_BUG_ON_MSG - break compile if a condition is true & emit supplied
45 * error message.
46 * @condition: the condition which the compiler should know is false.
47 *
48 * See BUILD_BUG_ON for description.
49 */
50#define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg)
51
52/**
43 * BUILD_BUG_ON - break compile if a condition is true. 53 * BUILD_BUG_ON - break compile if a condition is true.
44 * @condition: the condition which the compiler should know is false. 54 * @condition: the condition which the compiler should know is false.
45 * 55 *
@@ -60,15 +70,8 @@ struct pt_regs;
60#ifndef __OPTIMIZE__ 70#ifndef __OPTIMIZE__
61#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)])) 71#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))
62#else 72#else
63#define BUILD_BUG_ON(condition) \ 73#define BUILD_BUG_ON(condition) \
64 do { \ 74 BUILD_BUG_ON_MSG(condition, "BUILD_BUG_ON failed: " #condition)
65 bool __cond = !!(condition); \
66 extern void __build_bug_on_failed(void) \
67 __compiletime_error("BUILD_BUG_ON failed"); \
68 if (__cond) \
69 __build_bug_on_failed(); \
70 __compiletime_error_fallback(__cond); \
71 } while (0)
72#endif 75#endif
73 76
74/** 77/**
@@ -78,12 +81,7 @@ struct pt_regs;
78 * build time, you should use BUILD_BUG to detect if it is 81 * build time, you should use BUILD_BUG to detect if it is
79 * unexpectedly used. 82 * unexpectedly used.
80 */ 83 */
81#define BUILD_BUG() \ 84#define BUILD_BUG() BUILD_BUG_ON_MSG(1, "BUILD_BUG failed")
82 do { \
83 extern void __build_bug_failed(void) \
84 __compiletime_error("BUILD_BUG failed");\
85 __build_bug_failed(); \
86 } while (0)
87 85
88#endif /* __CHECKER__ */ 86#endif /* __CHECKER__ */
89 87
diff --git a/include/linux/compiler.h b/include/linux/compiler.h
index 423bb6bd660f..10b8f23fab0f 100644
--- a/include/linux/compiler.h
+++ b/include/linux/compiler.h
@@ -308,11 +308,35 @@ void ftrace_likely_update(struct ftrace_branch_data *f, int val, int expect);
308#ifndef __compiletime_error 308#ifndef __compiletime_error
309# define __compiletime_error(message) 309# define __compiletime_error(message)
310# define __compiletime_error_fallback(condition) \ 310# define __compiletime_error_fallback(condition) \
311 do { ((void)sizeof(char[1 - 2*!!(condition)])); } while (0) 311 do { ((void)sizeof(char[1 - 2 * condition])); } while (0)
312#else 312#else
313# define __compiletime_error_fallback(condition) do { } while (0) 313# define __compiletime_error_fallback(condition) do { } while (0)
314#endif 314#endif
315 315
316#define __compiletime_assert(condition, msg, prefix, suffix) \
317 do { \
318 bool __cond = !(condition); \
319 extern void prefix ## suffix(void) __compiletime_error(msg); \
320 if (__cond) \
321 prefix ## suffix(); \
322 __compiletime_error_fallback(__cond); \
323 } while (0)
324
325#define _compiletime_assert(condition, msg, prefix, suffix) \
326 __compiletime_assert(condition, msg, prefix, suffix)
327
328/**
329 * compiletime_assert - break build and emit msg if condition is false
330 * @condition: a compile-time constant condition to check
331 * @msg: a message to emit if condition is false
332 *
333 * In tradition of POSIX assert, this macro will break the build if the
334 * supplied condition is *false*, emitting the supplied error message if the
335 * compiler has support to do so.
336 */
337#define compiletime_assert(condition, msg) \
338 _compiletime_assert(condition, msg, __compiletime_assert_, __LINE__)
339
316/* 340/*
317 * Prevent the compiler from merging or refetching accesses. The compiler 341 * Prevent the compiler from merging or refetching accesses. The compiler
318 * is also forbidden from reordering successive instances of ACCESS_ONCE(), 342 * is also forbidden from reordering successive instances of ACCESS_ONCE(),