/src/test/codegen/repr-transparent.rs

https://gitlab.com/jianglu/rust · Rust · 135 lines · 64 code · 36 blank · 35 comment · 1 complexity · 1f1ab18300f2d0f81d50515ebd10fb07 MD5 · raw file

  1. // Copyright 2017 The Rust Project Developers. See the COPYRIGHT
  2. // file at the top-level directory of this distribution and at
  3. // http://rust-lang.org/COPYRIGHT.
  4. //
  5. // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
  6. // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
  7. // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
  8. // option. This file may not be copied, modified, or distributed
  9. // except according to those terms.
  10. // compile-flags: -C no-prepopulate-passes
  11. #![crate_type="lib"]
  12. #![feature(repr_transparent, repr_simd)]
  13. use std::marker::PhantomData;
  14. pub struct Zst1;
  15. pub struct Zst2(());
  16. #[repr(transparent)]
  17. pub struct F32(f32);
  18. // CHECK: define float @test_F32(float %arg0)
  19. #[no_mangle]
  20. pub extern fn test_F32(_: F32) -> F32 { loop {} }
  21. #[repr(transparent)]
  22. pub struct Ptr(*mut u8);
  23. // CHECK: define i8* @test_Ptr(i8* %arg0)
  24. #[no_mangle]
  25. pub extern fn test_Ptr(_: Ptr) -> Ptr { loop {} }
  26. #[repr(transparent)]
  27. pub struct WithZst(u64, Zst1);
  28. // CHECK: define i64 @test_WithZst(i64 %arg0)
  29. #[no_mangle]
  30. pub extern fn test_WithZst(_: WithZst) -> WithZst { loop {} }
  31. #[repr(transparent)]
  32. pub struct WithZeroSizedArray(*const f32, [i8; 0]);
  33. // Apparently we use i32* when newtype-unwrapping f32 pointers. Whatever.
  34. // CHECK: define i32* @test_WithZeroSizedArray(i32* %arg0)
  35. #[no_mangle]
  36. pub extern fn test_WithZeroSizedArray(_: WithZeroSizedArray) -> WithZeroSizedArray { loop {} }
  37. #[repr(transparent)]
  38. pub struct Generic<T>(T);
  39. // CHECK: define double @test_Generic(double %arg0)
  40. #[no_mangle]
  41. pub extern fn test_Generic(_: Generic<f64>) -> Generic<f64> { loop {} }
  42. #[repr(transparent)]
  43. pub struct GenericPlusZst<T>(T, Zst2);
  44. #[repr(u8)]
  45. pub enum Bool { True, False, FileNotFound }
  46. // CHECK: define{{( zeroext)?}} i8 @test_Gpz(i8{{( zeroext)?}} %arg0)
  47. #[no_mangle]
  48. pub extern fn test_Gpz(_: GenericPlusZst<Bool>) -> GenericPlusZst<Bool> { loop {} }
  49. #[repr(transparent)]
  50. pub struct LifetimePhantom<'a, T: 'a>(*const T, PhantomData<&'a T>);
  51. // CHECK: define i16* @test_LifetimePhantom(i16* %arg0)
  52. #[no_mangle]
  53. pub extern fn test_LifetimePhantom(_: LifetimePhantom<i16>) -> LifetimePhantom<i16> { loop {} }
  54. // This works despite current alignment resrictions because PhantomData is always align(1)
  55. #[repr(transparent)]
  56. pub struct UnitPhantom<T, U> { val: T, unit: PhantomData<U> }
  57. pub struct Px;
  58. // CHECK: define float @test_UnitPhantom(float %arg0)
  59. #[no_mangle]
  60. pub extern fn test_UnitPhantom(_: UnitPhantom<f32, Px>) -> UnitPhantom<f32, Px> { loop {} }
  61. #[repr(transparent)]
  62. pub struct TwoZsts(Zst1, i8, Zst2);
  63. // CHECK: define{{( signext)?}} i8 @test_TwoZsts(i8{{( signext)?}} %arg0)
  64. #[no_mangle]
  65. pub extern fn test_TwoZsts(_: TwoZsts) -> TwoZsts { loop {} }
  66. #[repr(transparent)]
  67. pub struct Nested1(Zst2, Generic<f64>);
  68. // CHECK: define double @test_Nested1(double %arg0)
  69. #[no_mangle]
  70. pub extern fn test_Nested1(_: Nested1) -> Nested1 { loop {} }
  71. #[repr(transparent)]
  72. pub struct Nested2(Nested1, Zst1);
  73. // CHECK: define double @test_Nested2(double %arg0)
  74. #[no_mangle]
  75. pub extern fn test_Nested2(_: Nested2) -> Nested2 { loop {} }
  76. #[repr(simd)]
  77. struct f32x4(f32, f32, f32, f32);
  78. #[repr(transparent)]
  79. pub struct Vector(f32x4);
  80. // CHECK: define <4 x float> @test_Vector(<4 x float> %arg0)
  81. #[no_mangle]
  82. pub extern fn test_Vector(_: Vector) -> Vector { loop {} }
  83. trait Mirror { type It: ?Sized; }
  84. impl<T: ?Sized> Mirror for T { type It = Self; }
  85. #[repr(transparent)]
  86. pub struct StructWithProjection(<f32 as Mirror>::It);
  87. // CHECK: define float @test_Projection(float %arg0)
  88. #[no_mangle]
  89. pub extern fn test_Projection(_: StructWithProjection) -> StructWithProjection { loop {} }
  90. // All that remains to be tested are aggregates. They are tested in separate files called repr-
  91. // transparent-*.rs with `only-*` or `ignore-*` directives, because the expected LLVM IR
  92. // function signatures vary so much that it's not reasonably possible to cover all of them with a
  93. // single CHECK line.
  94. //
  95. // You may be wondering why we don't just compare the return types and argument types for equality
  96. // with FileCheck regex captures. Well, rustc doesn't perform newtype unwrapping on newtypes
  97. // containing aggregates. This is OK on all ABIs we support, but because LLVM has not gotten rid of
  98. // pointee types yet, the IR function signature will be syntactically different (%Foo* vs
  99. // %FooWrapper*).