1 // RUN: %clang_cc1 -no-enable-noundef-analysis -triple x86_64-unknown-unknown -emit-llvm -o - %s | FileCheck %s
3 // Basic base class test.
4 struct f0_s0
{ unsigned a
; };
5 struct f0_s1
: public f0_s0
{ void *b
; };
6 // CHECK-LABEL: define{{.*}} void @_Z2f05f0_s1(i32 %a0.coerce0, ptr %a0.coerce1)
9 // Check with two eight-bytes in base class.
10 struct f1_s0
{ unsigned a
; unsigned b
; float c
; };
11 struct f1_s1
: public f1_s0
{ float d
;};
12 // CHECK-LABEL: define{{.*}} void @_Z2f15f1_s1(i64 %a0.coerce0, <2 x float> %a0.coerce1)
15 // Check with two eight-bytes in base class and merge.
16 struct f2_s0
{ unsigned a
; unsigned b
; float c
; };
17 struct f2_s1
: public f2_s0
{ char d
;};
18 // CHECK-LABEL: define{{.*}} void @_Z2f25f2_s1(i64 %a0.coerce0, i64 %a0.coerce1)
22 // CHECK-LABEL: define{{.*}} void @_Z2f34s3_1(i64 %x.coerce)
24 struct s3_1
{ struct s3_0 a
; long b
; };
25 void f3(struct s3_1 x
) {}
27 // CHECK-LABEL: define{{.*}} i64 @_Z4f4_0M2s4i(i64 %a)
28 // CHECK: define {{.*}} @_Z4f4_1M2s4FivE(i64 %a.coerce0, i64 %a.coerce1)
30 typedef int s4::* s4_mdp
;
31 typedef int (s4::*s4_mfp
)();
32 s4_mdp
f4_0(s4_mdp a
) { return a
; }
33 s4_mfp
f4_1(s4_mfp a
) { return a
; }
35 // A struct with <= one eightbyte before a member data pointer should still
36 // be allowed in registers.
37 // CHECK-LABEL: define{{.*}} void @{{.*}}f_struct_with_mdp{{.*}}(ptr %a.coerce0, i64 %a.coerce1)
38 struct struct_with_mdp
{ char *a
; s4_mdp b
; };
39 void f_struct_with_mdp(struct_with_mdp a
) { (void)a
; }
41 // A struct with anything before a member function will be too big and
43 // CHECK-LABEL: define{{.*}} void @{{.*}}f_struct_with_mfp_0{{.*}}(ptr byval(%struct{{.*}}) align 8 %a)
44 struct struct_with_mfp_0
{ char a
; s4_mfp b
; };
45 void f_struct_with_mfp_0(struct_with_mfp_0 a
) { (void)a
; }
47 // CHECK-LABEL: define{{.*}} void @{{.*}}f_struct_with_mfp_1{{.*}}(ptr byval(%struct{{.*}}) align 8 %a)
48 struct struct_with_mfp_1
{ void *a
; s4_mfp b
; };
49 void f_struct_with_mfp_1(struct_with_mfp_1 a
) { (void)a
; }
56 void AddKeyword(StringRef
, int x
);
59 // CHECK-LABEL: define{{.*}} void @_ZN6PR75233fooEv()
60 // CHECK: call void @_ZN6PR752310AddKeywordENS_9StringRefEi(ptr {{.*}}, i32 4)
61 AddKeyword(StringRef(), 4);
70 struct c2
: public s2
{};
72 // CHECK-LABEL: define{{.*}} <2 x float> @_ZN6PR77423fooEPNS_2c2E(ptr %P)
90 // CHECK-LABEL: define{{.*}} ptr @_ZN6PR51793barENS_2B2E(ptr %b2.coerce)
91 const void *bar(B2 b2
) {
100 struct X
: public Xbase
{
104 struct Y
: public X
{
108 int takeY(const Y
&, int y
);
110 // The temporary for the X object needs to have a defined address when
111 // passed into X::f as 'this'.
112 takeY(getX().f(), 42);
114 // CHECK: void @_ZN5test51gEv()
115 // CHECK: alloca %"struct.test5::Y"
116 // CHECK: alloca %"struct.test5::X"
117 // CHECK: alloca %"struct.test5::Y"
123 struct epsilon_matcher
{} e
;
130 // CHECK-LABEL: define{{.*}} i32 @_ZN5test64testENS_5outerE(i64 %x.coerce0, i32 %x.coerce1)
134 struct StringRef
{char* ptr
; long len
; };
135 class A
{ public: ~A(); };
136 A
x(A
, A
, long, long, StringRef
) { return A(); }
137 // Check that the StringRef is passed byval instead of expanded
138 // (which would split it between registers and memory).
139 // CHECK: define{{.*}} void @_ZN5test71xENS_1AES0_llNS_9StringRefE({{.*}} byval({{.*}}) align 8 {{%.*}})
141 // And a couple extra related tests:
142 A
y(A
, long double, long, long, StringRef
) { return A(); }
143 // CHECK: define{{.*}} void @_ZN5test71yENS_1AEellNS_9StringRefE({{.*}} ptr
144 struct StringDouble
{char * ptr
; double d
;};
145 A
z(A
, A
, A
, A
, A
, StringDouble
) { return A(); }
146 A
zz(A
, A
, A
, A
, StringDouble
) { return A(); }
147 // CHECK: define{{.*}} void @_ZN5test71zENS_1AES0_S0_S0_S0_NS_12StringDoubleE({{.*}} byval({{.*}}) align 8 {{%.*}})
148 // CHECK: define{{.*}} void @_ZN5test72zzENS_1AES0_S0_S0_NS_12StringDoubleE({{.*}} ptr
152 // CHECK: declare void @_ZN5test83fooENS_1BE(ptr byval(%"class.test8::B") align 8)
157 class B
: public A
{};
168 // Large enough to be passed indirectly.
169 struct S
{ void *data
[3]; };
171 struct T
{ void *data
[2]; };
173 // CHECK: define{{.*}} void @_ZN5test93fooEPNS_1SEPNS_1TE(ptr %0, ptr %1)
176 // CHECK: define{{.*}} void @_ZN5test91aEiiiiNS_1TEPv(ptr noalias sret([[S:%.*]]) align 8 {{%.*}}, i32 %0, i32 %1, i32 %2, i32 %3, ptr byval([[T:%.*]]) align 8 %4, ptr %5)
177 S
a(int, int, int, int, T
, void*) {
181 // CHECK: define{{.*}} ptr @_ZN5test91bEPNS_1SEiiiiNS_1TEPv(ptr {{%.*}}, i32 %0, i32 %1, i32 %2, i32 %3, ptr byval([[T]]) align 8 %4, ptr %5)
182 S
* b(S
* sret
, int, int, int, int, T
, void*) {
186 // CHECK: define{{.*}} void @_ZN5test91cEiiiNS_1TEPv(ptr noalias sret([[S]]) align 8 {{%.*}}, i32 %0, i32 %1, i32 %2, ptr {{%.*}}, ptr {{%.*}}, ptr %3)
187 S
c(int, int, int, T
, void*) {
191 // CHECK: define{{.*}} ptr @_ZN5test91dEPNS_1SEiiiNS_1TEPv(ptr {{%.*}}, i32 %0, i32 %1, i32 %2, ptr {{%.*}}, ptr {{%.*}}, ptr %3)
192 S
* d(S
* sret
, int, int, int, T
, void*) {
204 struct DerivedPacked
: public BasePacked
{
207 // CHECK-LABEL: define{{.*}} i32 @_ZN6test1020FuncForDerivedPackedENS_13DerivedPackedE(ptr byval({{.*}}) align 8
208 int FuncForDerivedPacked(DerivedPacked d
) {
216 char __attribute__((__vector_size__(1))) f2
;
218 int f(union U u
) { return u
.f2
[1]; }
219 // CHECK-LABEL: define{{.*}} i32 @_ZN6test111fENS_1UE(i32