/src/test/ui/asm/naked-functions.rs

https://gitlab.com/rust-lang/rust · Rust · 218 lines · 151 code · 28 blank · 39 comment · 0 complexity · 659da1c0c2b684fd3fa0622cc8eec906 MD5 · raw file

  1. // needs-asm-support
  2. // ignore-nvptx64
  3. // ignore-spirv
  4. // ignore-wasm32
  5. #![feature(naked_functions)]
  6. #![feature(asm_const, asm_sym, asm_unwind)]
  7. #![crate_type = "lib"]
  8. use std::arch::asm;
  9. #[repr(C)]
  10. pub struct P {
  11. x: u8,
  12. y: u16,
  13. }
  14. #[naked]
  15. pub unsafe extern "C" fn patterns(
  16. mut a: u32,
  17. //~^ ERROR patterns not allowed in naked function parameters
  18. &b: &i32,
  19. //~^ ERROR patterns not allowed in naked function parameters
  20. (None | Some(_)): Option<std::ptr::NonNull<u8>>,
  21. //~^ ERROR patterns not allowed in naked function parameters
  22. P { x, y }: P,
  23. //~^ ERROR patterns not allowed in naked function parameters
  24. ) {
  25. asm!("", options(noreturn))
  26. }
  27. #[naked]
  28. pub unsafe extern "C" fn inc(a: u32) -> u32 {
  29. //~^ ERROR naked functions must contain a single asm block
  30. a + 1
  31. //~^ ERROR referencing function parameters is not allowed in naked functions
  32. }
  33. #[naked]
  34. #[allow(asm_sub_register)]
  35. pub unsafe extern "C" fn inc_asm(a: u32) -> u32 {
  36. asm!("/* {0} */", in(reg) a, options(noreturn));
  37. //~^ ERROR referencing function parameters is not allowed in naked functions
  38. //~| ERROR only `const` and `sym` operands are supported in naked functions
  39. }
  40. #[naked]
  41. pub unsafe extern "C" fn inc_closure(a: u32) -> u32 {
  42. //~^ ERROR naked functions must contain a single asm block
  43. (|| a + 1)()
  44. }
  45. #[naked]
  46. pub unsafe extern "C" fn unsupported_operands() {
  47. //~^ ERROR naked functions must contain a single asm block
  48. let mut a = 0usize;
  49. let mut b = 0usize;
  50. let mut c = 0usize;
  51. let mut d = 0usize;
  52. let mut e = 0usize;
  53. const F: usize = 0usize;
  54. static G: usize = 0usize;
  55. asm!("/* {0} {1} {2} {3} {4} {5} {6} */",
  56. //~^ ERROR asm in naked functions must use `noreturn` option
  57. in(reg) a,
  58. //~^ ERROR only `const` and `sym` operands are supported in naked functions
  59. inlateout(reg) b,
  60. inout(reg) c,
  61. lateout(reg) d,
  62. out(reg) e,
  63. const F,
  64. sym G,
  65. );
  66. }
  67. #[naked]
  68. pub extern "C" fn missing_assembly() {
  69. //~^ ERROR naked functions must contain a single asm block
  70. }
  71. #[naked]
  72. pub extern "C" fn too_many_asm_blocks() {
  73. //~^ ERROR naked functions must contain a single asm block
  74. asm!("");
  75. //~^ ERROR asm in naked functions must use `noreturn` option
  76. asm!("");
  77. //~^ ERROR asm in naked functions must use `noreturn` option
  78. asm!("");
  79. //~^ ERROR asm in naked functions must use `noreturn` option
  80. asm!("", options(noreturn));
  81. }
  82. pub fn outer(x: u32) -> extern "C" fn(usize) -> usize {
  83. #[naked]
  84. pub extern "C" fn inner(y: usize) -> usize {
  85. //~^ ERROR naked functions must contain a single asm block
  86. *&y
  87. //~^ ERROR referencing function parameters is not allowed in naked functions
  88. }
  89. inner
  90. }
  91. #[naked]
  92. unsafe extern "C" fn invalid_options() {
  93. asm!("", options(nomem, preserves_flags, noreturn));
  94. //~^ ERROR asm options unsupported in naked functions: `nomem`, `preserves_flags`
  95. }
  96. #[naked]
  97. unsafe extern "C" fn invalid_options_continued() {
  98. asm!("", options(readonly, nostack), options(pure));
  99. //~^ ERROR asm with the `pure` option must have at least one output
  100. //~| ERROR asm options unsupported in naked functions: `nostack`, `pure`, `readonly`
  101. //~| ERROR asm in naked functions must use `noreturn` option
  102. }
  103. #[naked]
  104. unsafe extern "C" fn invalid_may_unwind() {
  105. asm!("", options(noreturn, may_unwind));
  106. //~^ ERROR asm options unsupported in naked functions: `may_unwind`
  107. }
  108. #[naked]
  109. pub unsafe fn default_abi() {
  110. //~^ WARN Rust ABI is unsupported in naked functions
  111. asm!("", options(noreturn));
  112. }
  113. #[naked]
  114. pub unsafe fn rust_abi() {
  115. //~^ WARN Rust ABI is unsupported in naked functions
  116. asm!("", options(noreturn));
  117. }
  118. #[naked]
  119. pub extern "C" fn valid_a<T>() -> T {
  120. unsafe {
  121. asm!("", options(noreturn));
  122. }
  123. }
  124. #[naked]
  125. pub extern "C" fn valid_b() {
  126. unsafe {
  127. {
  128. {
  129. asm!("", options(noreturn));
  130. };
  131. };
  132. }
  133. }
  134. #[naked]
  135. pub unsafe extern "C" fn valid_c() {
  136. asm!("", options(noreturn));
  137. }
  138. #[cfg(target_arch = "x86_64")]
  139. #[naked]
  140. pub unsafe extern "C" fn valid_att_syntax() {
  141. asm!("", options(noreturn, att_syntax));
  142. }
  143. #[naked]
  144. pub unsafe extern "C" fn inline_none() {
  145. asm!("", options(noreturn));
  146. }
  147. #[naked]
  148. #[inline]
  149. //~^ ERROR naked functions cannot be inlined
  150. pub unsafe extern "C" fn inline_hint() {
  151. asm!("", options(noreturn));
  152. }
  153. #[naked]
  154. #[inline(always)]
  155. //~^ ERROR naked functions cannot be inlined
  156. pub unsafe extern "C" fn inline_always() {
  157. asm!("", options(noreturn));
  158. }
  159. #[naked]
  160. #[inline(never)]
  161. //~^ ERROR naked functions cannot be inlined
  162. pub unsafe extern "C" fn inline_never() {
  163. asm!("", options(noreturn));
  164. }
  165. #[naked]
  166. #[inline]
  167. //~^ ERROR naked functions cannot be inlined
  168. #[inline(always)]
  169. //~^ ERROR naked functions cannot be inlined
  170. #[inline(never)]
  171. //~^ ERROR naked functions cannot be inlined
  172. pub unsafe extern "C" fn inline_all() {
  173. asm!("", options(noreturn));
  174. }
  175. #[naked]
  176. pub unsafe extern "C" fn allow_compile_error(a: u32) -> u32 {
  177. compile_error!("this is a user specified error")
  178. //~^ ERROR this is a user specified error
  179. }
  180. #[naked]
  181. pub unsafe extern "C" fn allow_compile_error_and_asm(a: u32) -> u32 {
  182. compile_error!("this is a user specified error");
  183. //~^ ERROR this is a user specified error
  184. asm!("", options(noreturn))
  185. }
  186. #[naked]
  187. pub unsafe extern "C" fn invalid_asm_syntax(a: u32) -> u32 {
  188. asm!(invalid_syntax)
  189. //~^ ERROR asm template must be a string literal
  190. }