|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [XEN PATCH] xen/typesafe: don't brace-initialize a scalar TYPE_SAFE value
TYPE_SAFE() degrades to a plain typedef in non-debug builds (NDEBUG), so
mfn_t is then `unsigned long' rather than a one-member struct.
INVALID_MFN_INITIALIZER and INVALID_GFN_INITIALIZER, however, always
expand to `{ ... }', which leaves
mfn_t first_valid_mfn = { ~0UL };
initializing a scalar from a braced list. That is valid C, but MISRA
C:2012 Rule 9.2 (required) - "The initializer for an aggregate or union
shall be enclosed in braces" - is reported against it, twice in the
x86_64 build: common/page_alloc.c and arch/x86/efi/runtime.h.
Give TYPE_SAFE() a companion TYPE_SAFE_INIT(), so that the shape of the
initializer follows the shape of the type, and use it for both
initializers. The debug arm is unchanged; the non-debug one drops the
braces.
No functional change: with CONFIG_DEBUG_INFO=n, common/page_alloc.o and
arch/x86/efi/runtime.o are bit-for-bit identical, both with CONFIG_DEBUG=y
and with it unset. With CONFIG_DEBUG_INFO=y they differ only in
.debug_info and .debug_line, because typesafe.h gains nine lines and the
inline functions defined there move with it; .text and .data are
unchanged.
Signed-off-by: Shuaidong Chen <shuaidong.chen@xxxxxxx>
Reviewed-by: Alejandro Vallejo <alejandro.garciavallejo@xxxxxxx>
---
xen/include/xen/mm-frame.h | 4 ++--
xen/include/xen/typesafe.h | 11 ++++++++++-
2 files changed, 12 insertions(+), 3 deletions(-)
diff --git a/xen/include/xen/mm-frame.h b/xen/include/xen/mm-frame.h
index d973aec901f..e41d2680af5 100644
--- a/xen/include/xen/mm-frame.h
+++ b/xen/include/xen/mm-frame.h
@@ -12,7 +12,7 @@ TYPE_SAFE(unsigned long, mfn);
* To be used for global variable initialization. This workaround a bug
* in GCC < 5.0.
*/
-#define INVALID_MFN_INITIALIZER { INVALID_MFN_RAW }
+#define INVALID_MFN_INITIALIZER TYPE_SAFE_INIT(INVALID_MFN_RAW)
#if 0
#define mfn_t /* Grep fodder: mfn_t, _mfn() and mfn_x() are defined above */
@@ -48,7 +48,7 @@ TYPE_SAFE(unsigned long, gfn);
* To be used for global variable initialization. This workaround a bug
* in GCC < 5.0 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64856
*/
-#define INVALID_GFN_INITIALIZER { INVALID_GFN_RAW }
+#define INVALID_GFN_INITIALIZER TYPE_SAFE_INIT(INVALID_GFN_RAW)
#if 0
#define gfn_t /* Grep fodder: gfn_t, _gfn() and gfn_x() are defined above */
diff --git a/xen/include/xen/typesafe.h b/xen/include/xen/typesafe.h
index 7ecd3b4a8d5..258404bb915 100644
--- a/xen/include/xen/typesafe.h
+++ b/xen/include/xen/typesafe.h
@@ -9,12 +9,17 @@
* * _$FOO() which boxes a $TYPE as a $FOO_t
* * $FOO_x() which unboxes a $FOO_t to $TYPE
*
+ * TYPE_SAFE_INIT($VAL) spells a constant initializer for a $FOO_t, for use
+ * where _$FOO() cannot be (an object of static storage duration).
+ *
* This makes a $FOO_t and a $BAR_t incompatible even when the box the same
* $TYPE.
*
* It does have some performance cost because the types now have a different
* storage attribute, so type safety is only enforced in a debug build.
- * Non-debug builds degrade to a simple typedef and noops for the functions.
+ * Non-debug builds degrade to a simple typedef and noops for the functions,
+ * and with it TYPE_SAFE_INIT() loses its braces: a scalar must not be
+ * brace-initialized.
*/
#ifndef NDEBUG
@@ -24,6 +29,8 @@
static inline _name##_t _##_name(_type n) { return (_name##_t) { n }; } \
static inline _type _name##_x(_name##_t n) { return n._name; }
+#define TYPE_SAFE_INIT(val) { val }
+
#else
#define TYPE_SAFE(_type, _name) \
@@ -31,6 +38,8 @@
static inline _name##_t _##_name(_type n) { return n; } \
static inline _type _name##_x(_name##_t n) { return n; }
+#define TYPE_SAFE_INIT(val) (val)
+
#endif
#endif /* __XEN_TYPESAFE_H__ */
--
2.34.1
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |