/src/test/codegen/function-arguments.rs

https://gitlab.com/rust-lang/rust · Rust · 224 lines · 135 code · 39 blank · 50 comment · 0 complexity · c9fea170c18da6f53fddc700436903dc MD5 · raw file

  1. // compile-flags: -O -C no-prepopulate-passes
  2. #![crate_type = "lib"]
  3. #![feature(rustc_attrs)]
  4. use std::mem::MaybeUninit;
  5. use std::num::NonZeroU64;
  6. pub struct S {
  7. _field: [i32; 8],
  8. }
  9. pub struct UnsafeInner {
  10. _field: std::cell::UnsafeCell<i16>,
  11. }
  12. pub enum MyBool {
  13. True,
  14. False,
  15. }
  16. // CHECK: noundef zeroext i1 @boolean(i1 noundef zeroext %x)
  17. #[no_mangle]
  18. pub fn boolean(x: bool) -> bool {
  19. x
  20. }
  21. // CHECK: i8 @maybeuninit_boolean(i8 %x)
  22. #[no_mangle]
  23. pub fn maybeuninit_boolean(x: MaybeUninit<bool>) -> MaybeUninit<bool> {
  24. x
  25. }
  26. // CHECK: noundef zeroext i1 @enum_bool(i1 noundef zeroext %x)
  27. #[no_mangle]
  28. pub fn enum_bool(x: MyBool) -> MyBool {
  29. x
  30. }
  31. // CHECK: i8 @maybeuninit_enum_bool(i8 %x)
  32. #[no_mangle]
  33. pub fn maybeuninit_enum_bool(x: MaybeUninit<MyBool>) -> MaybeUninit<MyBool> {
  34. x
  35. }
  36. // CHECK: noundef i32 @char(i32 noundef %x)
  37. #[no_mangle]
  38. pub fn char(x: char) -> char {
  39. x
  40. }
  41. // CHECK: i32 @maybeuninit_char(i32 %x)
  42. #[no_mangle]
  43. pub fn maybeuninit_char(x: MaybeUninit<char>) -> MaybeUninit<char> {
  44. x
  45. }
  46. // CHECK: i64 @int(i64 %x)
  47. #[no_mangle]
  48. pub fn int(x: u64) -> u64 {
  49. x
  50. }
  51. // CHECK: noundef i64 @nonzero_int(i64 noundef %x)
  52. #[no_mangle]
  53. pub fn nonzero_int(x: NonZeroU64) -> NonZeroU64 {
  54. x
  55. }
  56. // CHECK: i64 @option_nonzero_int(i64 %x)
  57. #[no_mangle]
  58. pub fn option_nonzero_int(x: Option<NonZeroU64>) -> Option<NonZeroU64> {
  59. x
  60. }
  61. // CHECK: @readonly_borrow({{i32\*|ptr}} noalias noundef readonly align 4 dereferenceable(4) %_1)
  62. // FIXME #25759 This should also have `nocapture`
  63. #[no_mangle]
  64. pub fn readonly_borrow(_: &i32) {
  65. }
  66. // CHECK: @static_borrow({{i32\*|ptr}} noalias noundef readonly align 4 dereferenceable(4) %_1)
  67. // static borrow may be captured
  68. #[no_mangle]
  69. pub fn static_borrow(_: &'static i32) {
  70. }
  71. // CHECK: @named_borrow({{i32\*|ptr}} noalias noundef readonly align 4 dereferenceable(4) %_1)
  72. // borrow with named lifetime may be captured
  73. #[no_mangle]
  74. pub fn named_borrow<'r>(_: &'r i32) {
  75. }
  76. // CHECK: @unsafe_borrow({{i16\*|ptr}} noundef align 2 dereferenceable(2) %_1)
  77. // unsafe interior means this isn't actually readonly and there may be aliases ...
  78. #[no_mangle]
  79. pub fn unsafe_borrow(_: &UnsafeInner) {
  80. }
  81. // CHECK: @mutable_unsafe_borrow({{i16\*|ptr}} noalias noundef align 2 dereferenceable(2) %_1)
  82. // ... unless this is a mutable borrow, those never alias
  83. #[no_mangle]
  84. pub fn mutable_unsafe_borrow(_: &mut UnsafeInner) {
  85. }
  86. // CHECK: @mutable_borrow({{i32\*|ptr}} noalias noundef align 4 dereferenceable(4) %_1)
  87. // FIXME #25759 This should also have `nocapture`
  88. #[no_mangle]
  89. pub fn mutable_borrow(_: &mut i32) {
  90. }
  91. // CHECK: @indirect_struct({{%S\*|ptr}} noalias nocapture noundef dereferenceable(32) %_1)
  92. #[no_mangle]
  93. pub fn indirect_struct(_: S) {
  94. }
  95. // CHECK: @borrowed_struct({{%S\*|ptr}} noalias noundef readonly align 4 dereferenceable(32) %_1)
  96. // FIXME #25759 This should also have `nocapture`
  97. #[no_mangle]
  98. pub fn borrowed_struct(_: &S) {
  99. }
  100. // CHECK: @raw_struct({{%S\*|ptr}} %_1)
  101. #[no_mangle]
  102. pub fn raw_struct(_: *const S) {
  103. }
  104. // `Box` can get deallocated during execution of the function, so it should
  105. // not get `dereferenceable`.
  106. // CHECK: noalias noundef nonnull align 4 {{i32\*|ptr}} @_box({{i32\*|ptr}} noalias noundef nonnull align 4 %x)
  107. #[no_mangle]
  108. pub fn _box(x: Box<i32>) -> Box<i32> {
  109. x
  110. }
  111. // CHECK: @struct_return({{%S\*|ptr}} noalias nocapture noundef sret(%S) dereferenceable(32){{( %0)?}})
  112. #[no_mangle]
  113. pub fn struct_return() -> S {
  114. S {
  115. _field: [0, 0, 0, 0, 0, 0, 0, 0]
  116. }
  117. }
  118. // Hack to get the correct size for the length part in slices
  119. // CHECK: @helper([[USIZE:i[0-9]+]] %_1)
  120. #[no_mangle]
  121. pub fn helper(_: usize) {
  122. }
  123. // CHECK: @slice({{\[0 x i8\]\*|ptr}} noalias noundef nonnull readonly align 1 %_1.0, [[USIZE]] %_1.1)
  124. // FIXME #25759 This should also have `nocapture`
  125. #[no_mangle]
  126. pub fn slice(_: &[u8]) {
  127. }
  128. // CHECK: @mutable_slice({{\[0 x i8\]\*|ptr}} noalias noundef nonnull align 1 %_1.0, [[USIZE]] %_1.1)
  129. // FIXME #25759 This should also have `nocapture`
  130. #[no_mangle]
  131. pub fn mutable_slice(_: &mut [u8]) {
  132. }
  133. // CHECK: @unsafe_slice({{\[0 x i16\]\*|ptr}} noundef nonnull align 2 %_1.0, [[USIZE]] %_1.1)
  134. // unsafe interior means this isn't actually readonly and there may be aliases ...
  135. #[no_mangle]
  136. pub fn unsafe_slice(_: &[UnsafeInner]) {
  137. }
  138. // CHECK: @raw_slice({{\[0 x i8\]\*|ptr}} %_1.0, [[USIZE]] %_1.1)
  139. #[no_mangle]
  140. pub fn raw_slice(_: *const [u8]) {
  141. }
  142. // CHECK: @str({{\[0 x i8\]\*|ptr}} noalias noundef nonnull readonly align 1 %_1.0, [[USIZE]] %_1.1)
  143. // FIXME #25759 This should also have `nocapture`
  144. #[no_mangle]
  145. pub fn str(_: &[u8]) {
  146. }
  147. // CHECK: @trait_borrow({{\{\}\*|ptr}} noundef nonnull align 1 %_1.0, {{.+}} noalias noundef readonly align {{.*}} dereferenceable({{.*}}) %_1.1)
  148. // FIXME #25759 This should also have `nocapture`
  149. #[no_mangle]
  150. pub fn trait_borrow(_: &Drop) {
  151. }
  152. // CHECK: @trait_raw({{\{\}\*|ptr}} %_1.0, {{.+}} noalias noundef readonly align {{.*}} dereferenceable({{.*}}) %_1.1)
  153. #[no_mangle]
  154. pub fn trait_raw(_: *const Drop) {
  155. }
  156. // CHECK: @trait_box({{\{\}\*|ptr}} noalias noundef nonnull align 1{{( %0)?}}, {{.+}} noalias noundef readonly align {{.*}} dereferenceable({{.*}}){{( %1)?}})
  157. #[no_mangle]
  158. pub fn trait_box(_: Box<Drop>) {
  159. }
  160. // CHECK: { {{i8\*|ptr}}, {{i8\*|ptr}} } @trait_option({{i8\*|ptr}} noalias noundef align 1 %x.0, {{i8\*|ptr}} %x.1)
  161. #[no_mangle]
  162. pub fn trait_option(x: Option<Box<Drop>>) -> Option<Box<Drop>> {
  163. x
  164. }
  165. // CHECK: { {{\[0 x i16\]\*|ptr}}, [[USIZE]] } @return_slice({{\[0 x i16\]\*|ptr}} noalias noundef nonnull readonly align 2 %x.0, [[USIZE]] %x.1)
  166. #[no_mangle]
  167. pub fn return_slice(x: &[u16]) -> &[u16] {
  168. x
  169. }
  170. // CHECK: { i16, i16 } @enum_id_1(i16 noundef %x.0, i16 %x.1)
  171. #[no_mangle]
  172. pub fn enum_id_1(x: Option<Result<u16, u16>>) -> Option<Result<u16, u16>> {
  173. x
  174. }
  175. // CHECK: { i8, i8 } @enum_id_2(i1 noundef zeroext %x.0, i8 %x.1)
  176. #[no_mangle]
  177. pub fn enum_id_2(x: Option<u8>) -> Option<u8> {
  178. x
  179. }
  180. // CHECK: noalias {{i8\*|ptr}} @allocator()
  181. #[no_mangle]
  182. #[rustc_allocator]
  183. pub fn allocator() -> *const i8 {
  184. std::ptr::null()
  185. }