diff options
author | Daniel Santos <daniel.santos@pobox.com> | 2013-02-21 19:41:55 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-02-21 20:22:16 -0500 |
commit | 9a8ab1c39970a4938a72d94e6fd13be88a797590 (patch) | |
tree | e95f9f02d7000dc6a79f5374f9adf6c85f936ad7 /include/linux/bug.h | |
parent | c361d3e54364d19bb5e803d6e766e94674da7b0e (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>
Diffstat (limited to 'include/linux/bug.h')
-rw-r--r-- | include/linux/bug.h | 28 |
1 files changed, 13 insertions, 15 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 | ||