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