diff --git a/CODING_STYLE b/CODING_STYLE index 7bf3848444..aae5a47ac2 100644 --- a/CODING_STYLE +++ b/CODING_STYLE @@ -129,6 +129,11 @@ Fixed width types should only be used when a fixed width quantity is meant (which for example may be a value read from or to be written to a register). +Macros which otherwise would use "typeof(arg) newarg =" to avoid double +evaluation of side effects should use "auto newarg =" per it's C23 behaviour, +to also avoid double textural expansion. The use of "auto" outside of macros +is discouraged. + Especially with pointer types, whenever the pointed to object is not (supposed to be) modified, qualify the pointed to type with "const". diff --git a/automation/eclair_analysis/ECLAIR/toolchain.ecl b/automation/eclair_analysis/ECLAIR/toolchain.ecl index da00c2198a..153e96f2b2 100644 --- a/automation/eclair_analysis/ECLAIR/toolchain.ecl +++ b/automation/eclair_analysis/ECLAIR/toolchain.ecl @@ -15,6 +15,7 @@ __alignof__, __alignof: see Sections \"6.48 Alternate Keywords\" and \"6.44 Determining the Alignment of Functions, Types or Variables\" of "GCC_MANUAL". asm, __asm__: see Sections \"6.48 Alternate Keywords\" and \"6.47 How to Use Inline Assembly Language in C Code\" of "GCC_MANUAL". __attribute__: see Section \"6.39 Attribute Syntax\" of "GCC_MANUAL". + __auto_type: see Section \"6.7 Referring to a Type with typeof\" of "GCC_MANUAL". __builtin_offsetof: see Section \"6.53 Support for offsetof\" of "GCC_MANUAL". __builtin_types_compatible_p: see Section \"6.59 Other Built-in Functions Provided by GCC\" of "GCC_MANUAL". __builtin_va_arg: non-documented GCC extension. @@ -26,6 +27,7 @@ -name_selector+={alignof, "^(__alignof__|__alignof)$"} -name_selector+={asm, "^(__asm__|asm)$"} -name_selector+={attribute, "^__attribute__$"} +-name_selector+={auto_type, "^__auto_type$"} -name_selector+={builtin_offsetof, "^__builtin_offsetof$"} -name_selector+={builtin_types_p, "^__builtin_types_compatible_p$"} -name_selector+={builtin_va_arg, "^__builtin_va_arg$"} @@ -39,6 +41,7 @@ "alignof|| asm|| attribute|| +auto_type|| builtin_offsetof|| builtin_types_p|| builtin_va_arg|| @@ -114,6 +117,7 @@ volatile" -doc_end -doc_begin=" + ext_auto_type: see Section \"6.7 Referring to a Type with typeof\" of "GCC_MANUAL". ext_c_missing_varargs_arg: see Section \"6.21 Macros with a Variable Number of Arguments\" of "GCC_MANUAL". ext_enum_value_not_int: non-documented GCC extension. ext_flexible_array_in_array: see Section \"6.18 Arrays of Length Zero\" of "GCC_MANUAL". @@ -126,6 +130,7 @@ volatile" ext_return_has_void_expr: see the documentation for -Wreturn-type in Section \"3.8 Options to Request or Suppress Warnings\" of "GCC_MANUAL". ext_sizeof_alignof_void_type: see Section \"6.24 Arithmetic on void- and Function-Pointers\" of "GCC_MANUAL". " +-name_selector+={ext_auto_type, "^ext_auto_type$"} -name_selector+={ext_c_missing_varargs_arg, "^ext_c_missing_varargs_arg$"} -name_selector+={ext_enum_value_not_int, "^ext_enum_value_not_int$"} -name_selector+={ext_flexible_array_in_array, "^ext_flexible_array_in_array$"} @@ -139,7 +144,8 @@ volatile" -name_selector+={ext_sizeof_alignof_void_type, "^ext_sizeof_alignof_void_type$"} -config=STD.diag,behavior+={c99,GCC_ARM64, -"ext_c_missing_varargs_arg|| +"ext_auto_type|| +ext_c_missing_varargs_arg|| ext_forward_ref_enum_def|| ext_gnu_array_range|| ext_gnu_statement_expr_macro|| @@ -149,7 +155,8 @@ ext_return_has_void_expr|| ext_sizeof_alignof_void_type" } -config=STD.diag,behavior+={c99,GCC_X86_64, -"ext_c_missing_varargs_arg|| +"ext_auto_type|| +ext_c_missing_varargs_arg|| ext_enum_value_not_int|| ext_flexible_array_in_array|| ext_flexible_array_in_struct|| diff --git a/docs/misra/C-language-toolchain.rst b/docs/misra/C-language-toolchain.rst index 5d418e262a..982c5c6676 100644 --- a/docs/misra/C-language-toolchain.rst +++ b/docs/misra/C-language-toolchain.rst @@ -94,6 +94,8 @@ The table columns are as follows: see Sections "6.48 Alternate Keywords" and "6.44 Determining the Alignment of Functions, Types or Variables" of GCC_MANUAL. __attribute__: see Section "6.39 Attribute Syntax" of GCC_MANUAL. + __auto_type: + see Section "6.7 Referring to a Type with typeof" of GCC_MANUAL. __builtin_types_compatible_p: see Section "6.59 Other Built-in Functions Provided by GCC" of GCC_MANUAL. __builtin_va_arg: diff --git a/docs/misra/deviations.rst b/docs/misra/deviations.rst index 17c21537f2..b048309596 100644 --- a/docs/misra/deviations.rst +++ b/docs/misra/deviations.rst @@ -599,6 +599,11 @@ Deviations related to MISRA C:2012 Rules: - The override of the keyword \"inline\" in xen/compiler.h is present so that section contents checks pass when the compiler chooses not to inline a particular function. + + Xen does not use the \"auto\" keyword as a storage qualifier. The + override of the keyword \"auto\" in xen/compiler.h is to give it it's + C23 behaviour of type inference. + - Comment-based deviation. * - R20.7 diff --git a/xen/include/xen/compiler.h b/xen/include/xen/compiler.h index 88bf26bc51..38ef5d82ad 100644 --- a/xen/include/xen/compiler.h +++ b/xen/include/xen/compiler.h @@ -64,6 +64,20 @@ # define asm_inline asm #endif +/* + * In C23, the auto keyword has been repurposed to perform type inference. + * + * This behaviour is available via the __auto_type extension in supported + * toolchains. + * + * https://www.gnu.org/software/c-intro-and-ref/manual/html_node/Auto-Type.html + * https://clang.llvm.org/docs/LanguageExtensions.html#auto-type + */ +#if !defined(__STDC_VERSION__) || __STDC_VERSION__ < 202311L +/* SAF-3-safe MISRA C Rule 20.4: Giving the keyword it's C23 meaning. */ +#define auto __auto_type +#endif + /* * Add the pseudo keyword 'fallthrough' so case statement blocks * must end with any of these keywords: diff --git a/xen/include/xen/macros.h b/xen/include/xen/macros.h index 6e8ac8b452..714a644f4e 100644 --- a/xen/include/xen/macros.h +++ b/xen/include/xen/macros.h @@ -63,18 +63,18 @@ /* Hide a value from the optimiser. */ #define HIDE(x) \ ({ \ - typeof(x) _x = (x); \ + auto _x = (x); \ asm volatile ( "" : "+r" (_x) ); \ _x; \ }) #define ABS(x) ({ \ - typeof(x) x_ = (x); \ + auto x_ = (x); \ (x_ < 0) ? -x_ : x_; \ }) #define SWAP(a, b) \ - do { typeof(a) t_ = (a); (a) = (b); (b) = t_; } while ( 0 ) + do { auto t_ = (a); (a) = (b); (b) = t_; } while ( 0 ) #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]) + __must_be_array(x)) @@ -104,15 +104,15 @@ */ #define min(x, y) \ ({ \ - const typeof(x) _x = (x); \ - const typeof(y) _y = (y); \ + const auto _x = (x); \ + const auto _y = (y); \ (void)(&_x == &_y); /* typecheck */ \ _x < _y ? _x : _y; \ }) #define max(x, y) \ ({ \ - const typeof(x) _x = (x); \ - const typeof(y) _y = (y); \ + const auto _x = (x); \ + const auto _y = (y); \ (void)(&_x == &_y); /* typecheck */ \ _x > _y ? _x : _y; \ })