]> git.proxmox.com Git - rustc.git/blame - src/test/codegen/repr-transparent.rs
Update unsuspicious file list
[rustc.git] / src / test / codegen / repr-transparent.rs
CommitLineData
5e7ed085 1// compile-flags: -O -C no-prepopulate-passes
2c00a5a8 2
f035d41b
XL
3// ignore-riscv64 riscv64 has an i128 type used with test_Vector
4// see codegen/riscv-abi for riscv functiona call tests
5
2c00a5a8 6#![crate_type="lib"]
dfeec247 7#![feature(repr_simd, transparent_unions)]
2c00a5a8
XL
8
9use std::marker::PhantomData;
10
dc9dc135 11#[derive(Copy, Clone)]
2c00a5a8 12pub struct Zst1;
dc9dc135 13#[derive(Copy, Clone)]
2c00a5a8
XL
14pub struct Zst2(());
15
dc9dc135 16#[derive(Copy, Clone)]
2c00a5a8
XL
17#[repr(transparent)]
18pub struct F32(f32);
19
cdc7bbd5 20// CHECK: define{{.*}}float @test_F32(float %_1)
2c00a5a8 21#[no_mangle]
5869c6ff 22pub extern "C" fn test_F32(_: F32) -> F32 { loop {} }
2c00a5a8
XL
23
24#[repr(transparent)]
25pub struct Ptr(*mut u8);
26
923072b8 27// CHECK: define{{.*}}{{i8\*|ptr}} @test_Ptr({{i8\*|ptr}} %_1)
2c00a5a8 28#[no_mangle]
5869c6ff 29pub extern "C" fn test_Ptr(_: Ptr) -> Ptr { loop {} }
2c00a5a8
XL
30
31#[repr(transparent)]
32pub struct WithZst(u64, Zst1);
33
cdc7bbd5 34// CHECK: define{{.*}}i64 @test_WithZst(i64 %_1)
2c00a5a8 35#[no_mangle]
5869c6ff 36pub extern "C" fn test_WithZst(_: WithZst) -> WithZst { loop {} }
2c00a5a8
XL
37
38#[repr(transparent)]
39pub struct WithZeroSizedArray(*const f32, [i8; 0]);
40
41// Apparently we use i32* when newtype-unwrapping f32 pointers. Whatever.
923072b8 42// CHECK: define{{.*}}{{i32\*|ptr}} @test_WithZeroSizedArray({{i32\*|ptr}} %_1)
2c00a5a8 43#[no_mangle]
5869c6ff 44pub extern "C" fn test_WithZeroSizedArray(_: WithZeroSizedArray) -> WithZeroSizedArray { loop {} }
2c00a5a8
XL
45
46#[repr(transparent)]
47pub struct Generic<T>(T);
48
cdc7bbd5 49// CHECK: define{{.*}}double @test_Generic(double %_1)
2c00a5a8 50#[no_mangle]
5869c6ff 51pub extern "C" fn test_Generic(_: Generic<f64>) -> Generic<f64> { loop {} }
2c00a5a8
XL
52
53#[repr(transparent)]
54pub struct GenericPlusZst<T>(T, Zst2);
55
56#[repr(u8)]
57pub enum Bool { True, False, FileNotFound }
58
5e7ed085 59// CHECK: define{{( dso_local)?}} noundef{{( zeroext)?}} i8 @test_Gpz(i8 noundef{{( zeroext)?}} %_1)
2c00a5a8 60#[no_mangle]
5869c6ff 61pub extern "C" fn test_Gpz(_: GenericPlusZst<Bool>) -> GenericPlusZst<Bool> { loop {} }
2c00a5a8
XL
62
63#[repr(transparent)]
64pub struct LifetimePhantom<'a, T: 'a>(*const T, PhantomData<&'a T>);
65
923072b8 66// CHECK: define{{.*}}{{i16\*|ptr}} @test_LifetimePhantom({{i16\*|ptr}} %_1)
2c00a5a8 67#[no_mangle]
5869c6ff 68pub extern "C" fn test_LifetimePhantom(_: LifetimePhantom<i16>) -> LifetimePhantom<i16> { loop {} }
2c00a5a8
XL
69
70// This works despite current alignment resrictions because PhantomData is always align(1)
71#[repr(transparent)]
72pub struct UnitPhantom<T, U> { val: T, unit: PhantomData<U> }
73
74pub struct Px;
75
cdc7bbd5 76// CHECK: define{{.*}}float @test_UnitPhantom(float %_1)
2c00a5a8 77#[no_mangle]
5869c6ff 78pub extern "C" fn test_UnitPhantom(_: UnitPhantom<f32, Px>) -> UnitPhantom<f32, Px> { loop {} }
2c00a5a8
XL
79
80#[repr(transparent)]
81pub struct TwoZsts(Zst1, i8, Zst2);
82
cdc7bbd5 83// CHECK: define{{( dso_local)?}}{{( signext)?}} i8 @test_TwoZsts(i8{{( signext)?}} %_1)
2c00a5a8 84#[no_mangle]
5869c6ff 85pub extern "C" fn test_TwoZsts(_: TwoZsts) -> TwoZsts { loop {} }
2c00a5a8
XL
86
87#[repr(transparent)]
88pub struct Nested1(Zst2, Generic<f64>);
89
cdc7bbd5 90// CHECK: define{{.*}}double @test_Nested1(double %_1)
2c00a5a8 91#[no_mangle]
5869c6ff 92pub extern "C" fn test_Nested1(_: Nested1) -> Nested1 { loop {} }
2c00a5a8
XL
93
94#[repr(transparent)]
95pub struct Nested2(Nested1, Zst1);
96
cdc7bbd5 97// CHECK: define{{.*}}double @test_Nested2(double %_1)
2c00a5a8 98#[no_mangle]
5869c6ff 99pub extern "C" fn test_Nested2(_: Nested2) -> Nested2 { loop {} }
2c00a5a8
XL
100
101#[repr(simd)]
102struct f32x4(f32, f32, f32, f32);
103
104#[repr(transparent)]
105pub struct Vector(f32x4);
106
cdc7bbd5 107// CHECK: define{{.*}}<4 x float> @test_Vector(<4 x float> %_1)
2c00a5a8 108#[no_mangle]
5869c6ff 109pub extern "C" fn test_Vector(_: Vector) -> Vector { loop {} }
2c00a5a8
XL
110
111trait Mirror { type It: ?Sized; }
112impl<T: ?Sized> Mirror for T { type It = Self; }
113
114#[repr(transparent)]
115pub struct StructWithProjection(<f32 as Mirror>::It);
116
cdc7bbd5 117// CHECK: define{{.*}}float @test_Projection(float %_1)
2c00a5a8 118#[no_mangle]
5869c6ff 119pub extern "C" fn test_Projection(_: StructWithProjection) -> StructWithProjection { loop {} }
2c00a5a8 120
dc9dc135
XL
121#[repr(transparent)]
122pub enum EnumF32 {
123 Variant(F32)
124}
125
cdc7bbd5 126// CHECK: define{{.*}}float @test_EnumF32(float %_1)
dc9dc135 127#[no_mangle]
5869c6ff 128pub extern "C" fn test_EnumF32(_: EnumF32) -> EnumF32 { loop {} }
dc9dc135
XL
129
130#[repr(transparent)]
131pub enum EnumF32WithZsts {
132 Variant(Zst1, F32, Zst2)
133}
134
cdc7bbd5 135// CHECK: define{{.*}}float @test_EnumF32WithZsts(float %_1)
dc9dc135 136#[no_mangle]
5869c6ff 137pub extern "C" fn test_EnumF32WithZsts(_: EnumF32WithZsts) -> EnumF32WithZsts { loop {} }
dc9dc135
XL
138
139#[repr(transparent)]
140pub union UnionF32 {
141 field: F32,
142}
143
cdc7bbd5 144// CHECK: define{{.*}}float @test_UnionF32(float %_1)
dc9dc135 145#[no_mangle]
5869c6ff 146pub extern "C" fn test_UnionF32(_: UnionF32) -> UnionF32 { loop {} }
dc9dc135
XL
147
148#[repr(transparent)]
149pub union UnionF32WithZsts {
150 zst1: Zst1,
151 field: F32,
152 zst2: Zst2,
153}
154
cdc7bbd5 155// CHECK: define{{.*}}float @test_UnionF32WithZsts(float %_1)
dc9dc135 156#[no_mangle]
5869c6ff 157pub extern "C" fn test_UnionF32WithZsts(_: UnionF32WithZsts) -> UnionF32WithZsts { loop {} }
dc9dc135 158
2c00a5a8
XL
159
160// All that remains to be tested are aggregates. They are tested in separate files called repr-
161// transparent-*.rs with `only-*` or `ignore-*` directives, because the expected LLVM IR
162// function signatures vary so much that it's not reasonably possible to cover all of them with a
163// single CHECK line.
164//
165// You may be wondering why we don't just compare the return types and argument types for equality
166// with FileCheck regex captures. Well, rustc doesn't perform newtype unwrapping on newtypes
167// containing aggregates. This is OK on all ABIs we support, but because LLVM has not gotten rid of
168// pointee types yet, the IR function signature will be syntactically different (%Foo* vs
169// %FooWrapper*).