linux/bug.h: Add BUILD_BUG_ON_NON_CONST macros

From: Daniel Santos
Date: Fri May 04 2012 - 01:09:10 EST


---
include/linux/bug.h | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 62 insertions(+), 0 deletions(-)

diff --git a/include/linux/bug.h b/include/linux/bug.h
index 72961c3..9352ff3 100644
--- a/include/linux/bug.h
+++ b/include/linux/bug.h
@@ -56,6 +56,68 @@ extern int __build_bug_on_failed;
} while(0)
#endif

+
+/**
+ * BUILD_BUG_ON_NON_CONST - break compile if expression cannot be determined
+ * to be a compile-time constant.
+ * @exp: value to test for compile-time constness
+ *
+ * __builtin_constant_p() is a work in progress and is broken in various ways
+ * on various versions of gcc and optimization levels. It can fail, even when
+ * gcc otherwise determines that the expression is compile-time constant when
+ * performing actual optimizations and thus, compile out the value anyway. Do
+ * not use this macro for struct members or dereferenced pointers and arrays,
+ * as these are broken in many versions of gcc -- use BUILD_BUG_ON_NON_CONST2
+ * instead.
+ *
+ * As long as you are passing a variable delcared const (and not modified),
+ * this macro should never fail.
+ */
+#ifdef __OPTIMIZE__
+#define BUILD_BUG_ON_NON_CONST(exp) \
+ BUILD_BUG_ON(!__builtin_constant_p(exp))
+#else
+#define BUILD_BUG_ON_NON_CONST(exp)
+#endif
+
+
+/**
+ * BUILD_BUG_ON_NON_CONST2 - break compile if expression cannot be determined
+ * to be a compile-time constant.
+ * @exp: value to test for compile-time constness
+ *
+ * Use this macro instead of BUILD_BUG_ON_NON_CONST when testing struct
+ * members or dereferenced arrays and pointers.
+ *
+ * Gory Details:
+ *
+ * Normal primitive variables
+ * - global non-static non-const values are never compile-time constants (but
+ * you should already know that)
+ * - all const values (global/local, non/static) should never fail this test
+ * (3.4+)
+ * - global non-static const broken until 4.2 (-O1 broken until 4.4)
+ * - local static non-const broken until 4.2 (-O1 broken until 4.3)
+ * - local non-static non-const broken until 4.0
+ *
+ * Dereferencing pointers & arrays
+ * - all static const derefs broken until 4.4 (except arrays at -O2 or better,
+ * which are fixed in 4.2)
+ * - global non-static const pointer derefs always fail (<=4.7)
+ * - local non-static const derefs broken until 4.3, except for array derefs
+ * to a zero value, which works from 4.0+
+ * - local static non-const pointers always fail (<=4.7)
+ * - local static non-const arrays broken until 4.4
+ * - local non-static non-const arrays broken until 4.0 (unless zero deref,
+ * works in 3.4+)
+ */
+#if __GNUC__ > 4 || __GNUC__ == 4 && __GNUC_MINOR__ >= 4
+#define BUILD_BUG_ON_NON_CONST2(exp) BUILD_BUG_ON_NON_CONST(exp)
+#else
+#define BUILD_BUG_ON_NON_CONST2(exp)
+#endif
+
+
/**
* BUILD_BUG - break compile if used.
*
--
1.7.3.4


--------------010808030702000103020805--
--
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/