* [XEN PATCH] xen/typesafe: don't brace-initialize a scalar TYPE_SAFE value
@ 2026-10-28 5:03 Shuaidong Chen
2026-10-28 7:42 ` Jan Beulich
0 siblings, 1 reply; 4+ messages in thread
From: Shuaidong Chen @ 2026-10-28 5:03 UTC (permalink / raw)
To: xen-devel
Cc: Nicola Vetrini, Stefano Stabellini, Michal Orzel, Jan Beulich,
Andrew Cooper, Anthony PERARD, Julien Grall, Roger Pau Monné,
Doug Goldstein, Alejandro Vallejo, Grygorii Strashko, Penny Zheng,
Ray Huang, Shuaidong Chen
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@amd.com>
Reviewed-by: Alejandro Vallejo <alejandro.garciavallejo@amd.com>
---
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
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [XEN PATCH] xen/typesafe: don't brace-initialize a scalar TYPE_SAFE value
2026-10-28 5:03 [XEN PATCH] xen/typesafe: don't brace-initialize a scalar TYPE_SAFE value Shuaidong Chen
@ 2026-10-28 7:42 ` Jan Beulich
2026-10-28 10:40 ` Nicola Vetrini
2026-10-29 4:55 ` Chen, Shuaidong
0 siblings, 2 replies; 4+ messages in thread
From: Jan Beulich @ 2026-10-28 7:42 UTC (permalink / raw)
To: Shuaidong Chen
Cc: Nicola Vetrini, Stefano Stabellini, Michal Orzel, Andrew Cooper,
Anthony PERARD, Julien Grall, Roger Pau Monné,
Doug Goldstein, Alejandro Vallejo, Grygorii Strashko, Penny Zheng,
Ray Huang, xen-devel
On 28.10.2026 06:03, Shuaidong Chen wrote:
> 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.
Wait - the rule says the opposite; it says nothing about initializers of
scalars. The rule is clean in all analysis jobs we do. On staging we only
ever have debug builds analyzed, but on release branches *-allcode have
DEBUG=n. No 9.2 violation shows up there. You also don't point at Eclair
output supporting your claim, so I wonder what is going on here.
Further, "That is valid C" contradicts ...
> --- 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.
> */
... the new wording used here.
Also, in the earlier insertion above, isn't there "used" missing? Possibly, to
avoid the double use of "use", with the earlier "use" replaced by "cases"? Yet
maybe this is legal grammar anyway, and it merely feels odd to me as a non-
native speaker. A native speaker may want consulting.
I also wonder why you CC-ed Roger with his old Citrix address.
Jan
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [XEN PATCH] xen/typesafe: don't brace-initialize a scalar TYPE_SAFE value
2026-10-28 7:42 ` Jan Beulich
@ 2026-10-28 10:40 ` Nicola Vetrini
2026-10-29 4:55 ` Chen, Shuaidong
1 sibling, 0 replies; 4+ messages in thread
From: Nicola Vetrini @ 2026-10-28 10:40 UTC (permalink / raw)
To: Jan Beulich
Cc: Shuaidong Chen, Stefano Stabellini, Michal Orzel, Andrew Cooper,
Anthony PERARD, Julien Grall, Roger Pau Monné,
Doug Goldstein, Alejandro Vallejo, Grygorii Strashko, Penny Zheng,
Ray Huang, xen-devel
On 2026-10-28 08:42, Jan Beulich wrote:
> On 28.10.2026 06:03, Shuaidong Chen wrote:
>> 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.
> Wait - the rule says the opposite; it says nothing about initializers
> of
> scalars. The rule is clean in all analysis jobs we do. On staging we
> only
> ever have debug builds analyzed, but on release branches *-allcode have
> DEBUG=n. No 9.2 violation shows up there. You also don't point at
> Eclair
> output supporting your claim, so I wonder what is going on here.
>
> Further, "That is valid C" contradicts ...
>
This was actually an FP present in ECLAIR 3.14.0 (used by Xen), not an
actual violation:
1|$ /opt/bugseng/eclair-3.14.0/bin/eclair_env
-enable=MC3A2.R9.2,B.REPORT.TXT -- gcc -c /tmp/fp.c -o /dev/null
violation for rule MC3A2.R9.2: (required) The initializer for an
aggregate or union shall be enclosed in braces. (untagged)
/tmp/fp.c:1.9-1.11: Loc #1 [culprit: to initialize `int' it was expected
a scalar but found a compound with 1 element]
int x = {2};
<~>
nicola@nico:~
0|$ eclair_env -enable=MC3A2.R9.2,B.REPORT.TXT -- gcc -c /tmp/fp.c -o
/dev/null
nicola@nico:~
0|$ cat /tmp/fp.c
int x = {2};
It has been fixed since ECLAIR 3.15.0. How to proceed (document as FP or
modify the source to avoid it) is up to the project.
>> --- 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.
>> */
>
> ... the new wording used here.
>
> Also, in the earlier insertion above, isn't there "used" missing?
> Possibly, to
> avoid the double use of "use", with the earlier "use" replaced by
> "cases"? Yet
> maybe this is legal grammar anyway, and it merely feels odd to me as a
> non-
> native speaker. A native speaker may want consulting.
>
> I also wonder why you CC-ed Roger with his old Citrix address.
>
> Jan
--
Nicola Vetrini, B.Sc.
Software Engineer
BUGSENG (https://bugseng.com)
LinkedIn: https://www.linkedin.com/in/nicola-vetrini-a42471253
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [XEN PATCH] xen/typesafe: don't brace-initialize a scalar TYPE_SAFE value
2026-10-28 7:42 ` Jan Beulich
2026-10-28 10:40 ` Nicola Vetrini
@ 2026-10-29 4:55 ` Chen, Shuaidong
1 sibling, 0 replies; 4+ messages in thread
From: Chen, Shuaidong @ 2026-10-29 4:55 UTC (permalink / raw)
To: Jan Beulich
Cc: Nicola Vetrini, Stefano Stabellini, Michal Orzel, Andrew Cooper,
Anthony PERARD, Julien Grall, Roger Pau Monné,
Doug Goldstein, Alejandro Vallejo, Grygorii Strashko, Penny Zheng,
Ray Huang, xen-devel
On 10/28/2026 3:42 PM, Jan Beulich wrote:
> On 28.10.2026 06:03, Shuaidong Chen wrote:
>> 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.
> Wait - the rule says the opposite; it says nothing about initializers of
> scalars. The rule is clean in all analysis jobs we do. On staging we only
> ever have debug builds analyzed, but on release branches *-allcode have
> DEBUG=n. No 9.2 violation shows up there. You also don't point at Eclair
> output supporting your claim, so I wonder what is going on here.
I came across this while working through MISRA violations on our safety
tree. As the code is not something the safety work introduced, I sent
the fix here rather than keeping it downstream.
I have now found that upstream already dealt with these two macros, in
e6b68789d42c ("xen/mm: Remove INVALID_{MFN,GFN}_INITIALIZER"). So you
are right that there is no violation upstream - our tree simply predates
that commit and still has INVALID_{MFN,GFN}_INITIALIZER. What we need
is to backport it, not this patch.
Please drop this one. Sorry for the noise.
>
> Further, "That is valid C" contradicts ...
>
>> --- 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.
>> */
> ... the new wording used here.
>
> Also, in the earlier insertion above, isn't there "used" missing? Possibly, to
> avoid the double use of "use", with the earlier "use" replaced by "cases"? Yet
> maybe this is legal grammar anyway, and it merely feels odd to me as a non-
> native speaker. A native speaker may want consulting.
>
> I also wonder why you CC-ed Roger with his old Citrix address.
>
> Jan
On your other points, briefly: you are right that "That is valid C"
contradicted the comment I added - C11 6.7.9p11 permits the braces, so
"must not" was wrong; and "for cases where _$FOO() cannot be used" does
read better. The stale Citrix address for Roger was a hand-maintained
CC list on my side; I will use scripts/get_maintainer.pl in future.
Thanks for the review.
--
Thx and BRs,
Shuaidong Chen
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-10-29 4:59 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-28 5:03 [XEN PATCH] xen/typesafe: don't brace-initialize a scalar TYPE_SAFE value Shuaidong Chen
2026-10-28 7:42 ` Jan Beulich
2026-10-28 10:40 ` Nicola Vetrini
2026-10-29 4:55 ` Chen, Shuaidong
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.