1 // SPDX-License-Identifier: GPL-2.0 1 // SPDX-License-Identifier: GPL-2.0 2 2 3 //! Build-time assert. 3 //! Build-time assert. 4 4 5 /// Fails the build if the code path calling ` 5 /// Fails the build if the code path calling `build_error!` can possibly be executed. 6 /// 6 /// 7 /// If the macro is executed in const context, 7 /// If the macro is executed in const context, `build_error!` will panic. 8 /// If the compiler or optimizer cannot guaran 8 /// If the compiler or optimizer cannot guarantee that `build_error!` can never 9 /// be called, a build error will be triggered 9 /// be called, a build error will be triggered. 10 /// 10 /// 11 /// # Examples 11 /// # Examples 12 /// 12 /// 13 /// ``` 13 /// ``` 14 /// # use kernel::build_error; 14 /// # use kernel::build_error; 15 /// #[inline] 15 /// #[inline] 16 /// fn foo(a: usize) -> usize { 16 /// fn foo(a: usize) -> usize { 17 /// a.checked_add(1).unwrap_or_else(|| bui 17 /// a.checked_add(1).unwrap_or_else(|| build_error!("overflow")) 18 /// } 18 /// } 19 /// 19 /// 20 /// assert_eq!(foo(usize::MAX - 1), usize::MAX 20 /// assert_eq!(foo(usize::MAX - 1), usize::MAX); // OK. 21 /// // foo(usize::MAX); // Fails to compile. 21 /// // foo(usize::MAX); // Fails to compile. 22 /// ``` 22 /// ``` 23 #[macro_export] 23 #[macro_export] 24 macro_rules! build_error { 24 macro_rules! build_error { 25 () => {{ 25 () => {{ 26 $crate::build_error("") 26 $crate::build_error("") 27 }}; 27 }}; 28 ($msg:expr) => {{ 28 ($msg:expr) => {{ 29 $crate::build_error($msg) 29 $crate::build_error($msg) 30 }}; 30 }}; 31 } 31 } 32 32 33 /// Asserts that a boolean expression is `true 33 /// Asserts that a boolean expression is `true` at compile time. 34 /// 34 /// 35 /// If the condition is evaluated to `false` i 35 /// If the condition is evaluated to `false` in const context, `build_assert!` 36 /// will panic. If the compiler or optimizer c 36 /// will panic. If the compiler or optimizer cannot guarantee the condition will 37 /// be evaluated to `true`, a build error will 37 /// be evaluated to `true`, a build error will be triggered. 38 /// 38 /// 39 /// [`static_assert!`] should be preferred to 39 /// [`static_assert!`] should be preferred to `build_assert!` whenever possible. 40 /// 40 /// 41 /// # Examples 41 /// # Examples 42 /// 42 /// 43 /// These examples show that different types o 43 /// These examples show that different types of [`assert!`] will trigger errors 44 /// at different stage of compilation. It is p 44 /// at different stage of compilation. It is preferred to err as early as 45 /// possible, so [`static_assert!`] should be 45 /// possible, so [`static_assert!`] should be used whenever possible. 46 /// ```ignore 46 /// ```ignore 47 /// fn foo() { 47 /// fn foo() { 48 /// static_assert!(1 > 1); // Compile-time 48 /// static_assert!(1 > 1); // Compile-time error 49 /// build_assert!(1 > 1); // Build-time er 49 /// build_assert!(1 > 1); // Build-time error 50 /// assert!(1 > 1); // Run-time error 50 /// assert!(1 > 1); // Run-time error 51 /// } 51 /// } 52 /// ``` 52 /// ``` 53 /// 53 /// 54 /// When the condition refers to generic param 54 /// When the condition refers to generic parameters or parameters of an inline function, 55 /// [`static_assert!`] cannot be used. Use `bu 55 /// [`static_assert!`] cannot be used. Use `build_assert!` in this scenario. 56 /// ``` 56 /// ``` 57 /// fn foo<const N: usize>() { 57 /// fn foo<const N: usize>() { 58 /// // `static_assert!(N > 1);` is not all 58 /// // `static_assert!(N > 1);` is not allowed 59 /// build_assert!(N > 1); // Build-time ch 59 /// build_assert!(N > 1); // Build-time check 60 /// assert!(N > 1); // Run-time check 60 /// assert!(N > 1); // Run-time check 61 /// } 61 /// } 62 /// 62 /// 63 /// #[inline] 63 /// #[inline] 64 /// fn bar(n: usize) { 64 /// fn bar(n: usize) { 65 /// // `static_assert!(n > 1);` is not all 65 /// // `static_assert!(n > 1);` is not allowed 66 /// build_assert!(n > 1); // Build-time ch 66 /// build_assert!(n > 1); // Build-time check 67 /// assert!(n > 1); // Run-time check 67 /// assert!(n > 1); // Run-time check 68 /// } 68 /// } 69 /// ``` 69 /// ``` 70 /// << 71 /// [`static_assert!`]: crate::static_assert! << 72 #[macro_export] 70 #[macro_export] 73 macro_rules! build_assert { 71 macro_rules! build_assert { 74 ($cond:expr $(,)?) => {{ 72 ($cond:expr $(,)?) => {{ 75 if !$cond { 73 if !$cond { 76 $crate::build_error(concat!("asser 74 $crate::build_error(concat!("assertion failed: ", stringify!($cond))); 77 } 75 } 78 }}; 76 }}; 79 ($cond:expr, $msg:expr) => {{ 77 ($cond:expr, $msg:expr) => {{ 80 if !$cond { 78 if !$cond { 81 $crate::build_error($msg); 79 $crate::build_error($msg); 82 } 80 } 83 }}; 81 }}; 84 } 82 }
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.