ef0f4e834c
[Linux commit 6bab69c65013bed5fce9f101a64a84d0385b3946] BUILD_BUG_ON() is a little annoying, since it cannot be used outside function scope. So one cannot put assertions about the sizeof() a struct next to the struct definition, but has to hide that in some more or less arbitrary function. Since gcc 4.6 (which is now also the required minimum), there is support for the C11 _Static_assert in all C modes, including gnu89. So add a simple wrapper for that. _Static_assert() requires a message argument, which is usually quite redundant (and I believe that bug got fixed at least in newer C++ standards), but we can easily work around that with a little macro magic, making it optional. For example, adding static_assert(sizeof(struct printf_spec) == 8); in vsprintf.c and modifying that struct to violate it, one gets ./include/linux/build_bug.h:78:41: error: static assertion failed: "sizeof(struct printf_spec) == 8" #define __static_assert(expr, msg, ...) _Static_assert(expr, "" msg "") godbolt.org suggests that _Static_assert() has been support by clang since at least 3.0.0. Signed-off-by: Rasmus Villemoes <rasmus.villemoes@prevas.dk> Reviewed-by: Simon Glass <sjg@chromium.org>
104 lines
3.8 KiB
C
104 lines
3.8 KiB
C
#ifndef _LINUX_BUILD_BUG_H
|
|
#define _LINUX_BUILD_BUG_H
|
|
|
|
#include <linux/compiler.h>
|
|
|
|
#ifdef __CHECKER__
|
|
#define __BUILD_BUG_ON_NOT_POWER_OF_2(n) (0)
|
|
#define BUILD_BUG_ON_NOT_POWER_OF_2(n) (0)
|
|
#define BUILD_BUG_ON_ZERO(e) (0)
|
|
#define BUILD_BUG_ON_NULL(e) ((void *)0)
|
|
#define BUILD_BUG_ON_INVALID(e) (0)
|
|
#define BUILD_BUG_ON_MSG(cond, msg) (0)
|
|
#define BUILD_BUG_ON(condition) (0)
|
|
#define BUILD_BUG() (0)
|
|
#else /* __CHECKER__ */
|
|
|
|
/* Force a compilation error if a constant expression is not a power of 2 */
|
|
#define __BUILD_BUG_ON_NOT_POWER_OF_2(n) \
|
|
BUILD_BUG_ON(((n) & ((n) - 1)) != 0)
|
|
#define BUILD_BUG_ON_NOT_POWER_OF_2(n) \
|
|
BUILD_BUG_ON((n) == 0 || (((n) & ((n) - 1)) != 0))
|
|
|
|
/*
|
|
* Force a compilation error if condition is true, but also produce a
|
|
* result (of value 0 and type size_t), so the expression can be used
|
|
* e.g. in a structure initializer (or where-ever else comma expressions
|
|
* aren't permitted).
|
|
*/
|
|
#define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:(-!!(e)); }))
|
|
#define BUILD_BUG_ON_NULL(e) ((void *)sizeof(struct { int:(-!!(e)); }))
|
|
|
|
/*
|
|
* BUILD_BUG_ON_INVALID() permits the compiler to check the validity of the
|
|
* expression but avoids the generation of any code, even if that expression
|
|
* has side-effects.
|
|
*/
|
|
#define BUILD_BUG_ON_INVALID(e) ((void)(sizeof((__force long)(e))))
|
|
|
|
/**
|
|
* BUILD_BUG_ON_MSG - break compile if a condition is true & emit supplied
|
|
* error message.
|
|
* @condition: the condition which the compiler should know is false.
|
|
*
|
|
* See BUILD_BUG_ON for description.
|
|
*/
|
|
#define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg)
|
|
|
|
/**
|
|
* BUILD_BUG_ON - break compile if a condition is true.
|
|
* @condition: the condition which the compiler should know is false.
|
|
*
|
|
* If you have some code which relies on certain constants being equal, or
|
|
* some other compile-time-evaluated condition, you should use BUILD_BUG_ON to
|
|
* detect if someone changes it.
|
|
*
|
|
* The implementation uses gcc's reluctance to create a negative array, but gcc
|
|
* (as of 4.4) only emits that error for obvious cases (e.g. not arguments to
|
|
* inline functions). Luckily, in 4.3 they added the "error" function
|
|
* attribute just for this type of case. Thus, we use a negative sized array
|
|
* (should always create an error on gcc versions older than 4.4) and then call
|
|
* an undefined function with the error attribute (should always create an
|
|
* error on gcc 4.3 and later). If for some reason, neither creates a
|
|
* compile-time error, we'll still have a link-time error, which is harder to
|
|
* track down.
|
|
*/
|
|
#ifndef __OPTIMIZE__
|
|
#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))
|
|
#else
|
|
#define BUILD_BUG_ON(condition) \
|
|
BUILD_BUG_ON_MSG(condition, "BUILD_BUG_ON failed: " #condition)
|
|
#endif
|
|
|
|
/**
|
|
* BUILD_BUG - break compile if used.
|
|
*
|
|
* If you have some code that you expect the compiler to eliminate at
|
|
* build time, you should use BUILD_BUG to detect if it is
|
|
* unexpectedly used.
|
|
*/
|
|
#define BUILD_BUG() BUILD_BUG_ON_MSG(1, "BUILD_BUG failed")
|
|
|
|
/**
|
|
* static_assert - check integer constant expression at build time
|
|
*
|
|
* static_assert() is a wrapper for the C11 _Static_assert, with a
|
|
* little macro magic to make the message optional (defaulting to the
|
|
* stringification of the tested expression).
|
|
*
|
|
* Contrary to BUILD_BUG_ON(), static_assert() can be used at global
|
|
* scope, but requires the expression to be an integer constant
|
|
* expression (i.e., it is not enough that __builtin_constant_p() is
|
|
* true for expr).
|
|
*
|
|
* Also note that BUILD_BUG_ON() fails the build if the condition is
|
|
* true, while static_assert() fails the build if the expression is
|
|
* false.
|
|
*/
|
|
#define static_assert(expr, ...) __static_assert(expr, ##__VA_ARGS__, #expr)
|
|
#define __static_assert(expr, msg, ...) _Static_assert(expr, msg)
|
|
|
|
#endif /* __CHECKER__ */
|
|
|
|
#endif /* _LINUX_BUILD_BUG_H */
|