1 // RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-unknown -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK --check-prefix=NEWABI
2 // RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-unknown -fclang-abi-compat=4.0 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK --check-prefix=OLDABI
3 // RUN: %clang_cc1 -std=c++11 -triple x86_64-scei-ps4 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK --check-prefix=OLDABI
4 // RUN: %clang_cc1 -std=c++11 -triple x86_64-sie-ps5 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK --check-prefix=NEWABI
5 // RUN: %clang_cc1 -std=c++11 -triple x86_64-windows-msvc -emit-llvm -o - %s -fms-compatibility -fms-compatibility-version=18 | FileCheck %s -check-prefix=WIN64 -check-prefix=WIN64-18
6 // RUN: %clang_cc1 -std=c++11 -triple x86_64-windows-msvc -emit-llvm -o - %s -fms-compatibility -fms-compatibility-version=19 | FileCheck %s -check-prefix=WIN64 -check-prefix=WIN64-19
9 // Trivial structs should be passed directly.
17 // CHECK-LABEL: define{{.*}} void @_ZN7trivial3barEv()
18 // CHECK: alloca %"struct.trivial::A"
19 // CHECK: load ptr, ptr
20 // CHECK: call void @_ZN7trivial3fooENS_1AE(ptr %{{.*}})
21 // CHECK-LABEL: declare void @_ZN7trivial3fooENS_1AE(ptr)
23 // WIN64-LABEL: declare dso_local void @"?foo@trivial@@YAXUA@1@@Z"(i64)
26 namespace default_ctor
{
33 // Core issue 1590. We can pass this type in registers, even though C++
34 // normally doesn't permit copies when using braced initialization.
37 // CHECK-LABEL: define{{.*}} void @_ZN12default_ctor3barEv()
38 // CHECK: alloca %"struct.default_ctor::A"
39 // CHECK: call void @_Z{{.*}}C1Ev(
40 // CHECK: load ptr, ptr
41 // CHECK: call void @_ZN12default_ctor3fooENS_1AE(ptr %{{.*}})
42 // CHECK-LABEL: declare void @_ZN12default_ctor3fooENS_1AE(ptr)
44 // WIN64-LABEL: declare dso_local void @"?foo@default_ctor@@YAXUA@1@@Z"(i64)
48 // The presence of a move constructor implicitly deletes the trivial copy ctor
49 // and means that we have to pass this struct by address.
59 // CHECK-LABEL: define{{.*}} void @_ZN9move_ctor3barEv()
60 // CHECK: call void @_Z{{.*}}C1Ev(
62 // NEWABI: call void @_ZN9move_ctor3fooENS_1AE(ptr noundef %{{.*}})
63 // OLDABI: call void @_ZN9move_ctor3fooENS_1AE(ptr %{{.*}})
64 // NEWABI-LABEL: declare void @_ZN9move_ctor3fooENS_1AE(ptr noundef)
65 // OLDABI-LABEL: declare void @_ZN9move_ctor3fooENS_1AE(ptr)
67 // WIN64-LABEL: declare dso_local void @"?foo@move_ctor@@YAXUA@1@@Z"(ptr noundef)
70 namespace all_deleted
{
73 A(const A
&o
) = delete;
81 // CHECK-LABEL: define{{.*}} void @_ZN11all_deleted3barEv()
82 // CHECK: call void @_Z{{.*}}C1Ev(
84 // NEWABI: call void @_ZN11all_deleted3fooENS_1AE(ptr noundef %{{.*}})
85 // OLDABI: call void @_ZN11all_deleted3fooENS_1AE(ptr %{{.*}})
86 // NEWABI-LABEL: declare void @_ZN11all_deleted3fooENS_1AE(ptr noundef)
87 // OLDABI-LABEL: declare void @_ZN11all_deleted3fooENS_1AE(ptr)
89 // WIN64-LABEL: declare dso_local void @"?foo@all_deleted@@YAXUA@1@@Z"(ptr noundef)
92 namespace implicitly_deleted
{
102 // CHECK-LABEL: define{{.*}} void @_ZN18implicitly_deleted3barEv()
103 // CHECK: call void @_Z{{.*}}C1Ev(
105 // NEWABI: call void @_ZN18implicitly_deleted3fooENS_1AE(ptr noundef %{{.*}})
106 // OLDABI: call void @_ZN18implicitly_deleted3fooENS_1AE(ptr %{{.*}})
107 // NEWABI-LABEL: declare void @_ZN18implicitly_deleted3fooENS_1AE(ptr noundef)
108 // OLDABI-LABEL: declare void @_ZN18implicitly_deleted3fooENS_1AE(ptr)
110 // In MSVC 2013, the copy ctor is not deleted by a move assignment. In MSVC 2015, it is.
111 // WIN64-18-LABEL: declare dso_local void @"?foo@implicitly_deleted@@YAXUA@1@@Z"(i64
112 // WIN64-19-LABEL: declare dso_local void @"?foo@implicitly_deleted@@YAXUA@1@@Z"(ptr noundef)
115 namespace one_deleted
{
125 // CHECK-LABEL: define{{.*}} void @_ZN11one_deleted3barEv()
126 // CHECK: call void @_Z{{.*}}C1Ev(
128 // NEWABI: call void @_ZN11one_deleted3fooENS_1AE(ptr noundef %{{.*}})
129 // OLDABI: call void @_ZN11one_deleted3fooENS_1AE(ptr %{{.*}})
130 // NEWABI-LABEL: declare void @_ZN11one_deleted3fooENS_1AE(ptr noundef)
131 // OLDABI-LABEL: declare void @_ZN11one_deleted3fooENS_1AE(ptr)
133 // WIN64-LABEL: declare dso_local void @"?foo@one_deleted@@YAXUA@1@@Z"(ptr noundef)
136 namespace copy_defaulted
{
139 A(const A
&o
) = default;
147 // CHECK-LABEL: define{{.*}} void @_ZN14copy_defaulted3barEv()
148 // CHECK: call void @_Z{{.*}}C1Ev(
149 // CHECK: load ptr, ptr
150 // CHECK: call void @_ZN14copy_defaulted3fooENS_1AE(ptr %{{.*}})
151 // CHECK-LABEL: declare void @_ZN14copy_defaulted3fooENS_1AE(ptr)
153 // WIN64-LABEL: declare dso_local void @"?foo@copy_defaulted@@YAXUA@1@@Z"(i64)
156 namespace move_defaulted
{
159 A(const A
&o
) = delete;
167 // CHECK-LABEL: define{{.*}} void @_ZN14move_defaulted3barEv()
168 // CHECK: call void @_Z{{.*}}C1Ev(
169 // CHECK: load ptr, ptr
170 // CHECK: call void @_ZN14move_defaulted3fooENS_1AE(ptr %{{.*}})
171 // CHECK-LABEL: declare void @_ZN14move_defaulted3fooENS_1AE(ptr)
173 // WIN64-LABEL: declare dso_local void @"?foo@move_defaulted@@YAXUA@1@@Z"(ptr noundef)
176 namespace trivial_defaulted
{
179 A(const A
&o
) = default;
186 // CHECK-LABEL: define{{.*}} void @_ZN17trivial_defaulted3barEv()
187 // CHECK: call void @_Z{{.*}}C1Ev(
188 // CHECK: load ptr, ptr
189 // CHECK: call void @_ZN17trivial_defaulted3fooENS_1AE(ptr %{{.*}})
190 // CHECK-LABEL: declare void @_ZN17trivial_defaulted3fooENS_1AE(ptr)
192 // WIN64-LABEL: declare dso_local void @"?foo@trivial_defaulted@@YAXUA@1@@Z"(i64)
195 namespace two_copy_ctors
{
198 A(const A
&) = default;
199 A(const A
&, int = 0);
208 // CHECK-LABEL: define{{.*}} void @_ZN14two_copy_ctors3barEv()
209 // CHECK: call void @_Z{{.*}}C1Ev(
210 // NEWABI: call void @_ZN14two_copy_ctors3fooENS_1BE(ptr noundef %{{.*}})
211 // OLDABI: call void @_ZN14two_copy_ctors3fooENS_1BE(ptr noundef byval
212 // NEWABI-LABEL: declare void @_ZN14two_copy_ctors3fooENS_1BE(ptr noundef)
213 // OLDABI-LABEL: declare void @_ZN14two_copy_ctors3fooENS_1BE(ptr noundef byval
215 // WIN64-LABEL: declare dso_local void @"?foo@two_copy_ctors@@YAXUB@1@@Z"(ptr noundef)
218 namespace definition_only
{
224 void *foo(A a
) { return a
.p
; }
225 // NEWABI-LABEL: define{{.*}} ptr @_ZN15definition_only3fooENS_1AE(ptr
226 // OLDABI-LABEL: define{{.*}} ptr @_ZN15definition_only3fooENS_1AE(ptr
227 // WIN64-LABEL: define dso_local noundef ptr @"?foo@definition_only@@YAPEAXUA@1@@Z"(ptr
230 namespace deleted_by_member
{
240 void *foo(A a
) { return a
.b
.p
; }
241 // NEWABI-LABEL: define{{.*}} ptr @_ZN17deleted_by_member3fooENS_1AE(ptr
242 // OLDABI-LABEL: define{{.*}} ptr @_ZN17deleted_by_member3fooENS_1AE(ptr
243 // WIN64-LABEL: define dso_local noundef ptr @"?foo@deleted_by_member@@YAPEAXUA@1@@Z"(ptr
246 namespace deleted_by_base
{
255 void *foo(A a
) { return a
.p
; }
256 // NEWABI-LABEL: define{{.*}} ptr @_ZN15deleted_by_base3fooENS_1AE(ptr
257 // OLDABI-LABEL: define{{.*}} ptr @_ZN15deleted_by_base3fooENS_1AE(ptr
258 // WIN64-LABEL: define dso_local noundef ptr @"?foo@deleted_by_base@@YAPEAXUA@1@@Z"(ptr
261 namespace deleted_by_member_copy
{
264 B(const B
&o
) = delete;
271 void *foo(A a
) { return a
.b
.p
; }
272 // NEWABI-LABEL: define{{.*}} ptr @_ZN22deleted_by_member_copy3fooENS_1AE(ptr
273 // OLDABI-LABEL: define{{.*}} ptr @_ZN22deleted_by_member_copy3fooENS_1AE(ptr
274 // WIN64-LABEL: define dso_local noundef ptr @"?foo@deleted_by_member_copy@@YAPEAXUA@1@@Z"(ptr
277 namespace deleted_by_base_copy
{
280 B(const B
&o
) = delete;
286 void *foo(A a
) { return a
.p
; }
287 // NEWABI-LABEL: define{{.*}} ptr @_ZN20deleted_by_base_copy3fooENS_1AE(ptr
288 // OLDABI-LABEL: define{{.*}} ptr @_ZN20deleted_by_base_copy3fooENS_1AE(ptr
289 // WIN64-LABEL: define dso_local noundef ptr @"?foo@deleted_by_base_copy@@YAPEAXUA@1@@Z"(ptr
292 namespace explicit_delete
{
295 A(const A
&o
) = delete;
298 // NEWABI-LABEL: define{{.*}} ptr @_ZN15explicit_delete3fooENS_1AE(ptr
299 // OLDABI-LABEL: define{{.*}} ptr @_ZN15explicit_delete3fooENS_1AE(ptr
300 // WIN64-LABEL: define dso_local noundef ptr @"?foo@explicit_delete@@YAPEAXUA@1@@Z"(ptr
301 void *foo(A a
) { return a
.p
; }
304 namespace implicitly_deleted_copy_ctor
{
306 // No move ctor due to copy assignment.
307 A
&operator=(const A
&);
308 // Deleted copy ctor due to rvalue ref member.
311 // NEWABI-LABEL: define {{.*}} @_ZN28implicitly_deleted_copy_ctor3fooENS_1AE(ptr
312 // OLDABI-LABEL: define {{.*}} @_ZN28implicitly_deleted_copy_ctor3fooENS_1AE(ptr
313 // WIN64-LABEL: define {{.*}} @"?foo@implicitly_deleted_copy_ctor@@YAAEAHUA@1@@Z"(ptr
314 int &foo(A a
) { return a
.ref
; }
317 // Passed direct: has non-deleted trivial copy ctor.
318 B
&operator=(const B
&);
321 int &foo(B b
) { return b
.ref
; }
322 // CHECK-LABEL: define {{.*}} @_ZN28implicitly_deleted_copy_ctor3fooENS_1BE(ptr
323 // WIN64-LABEL: define {{.*}} @"?foo@implicitly_deleted_copy_ctor@@YAAEAHUB@1@@Z"(i64
325 struct X
{ X(const X
&); };
326 struct Y
{ Y(const Y
&) = default; };
329 C
&operator=(const C
&);
330 // Passed indirect: copy ctor deleted due to variant member with nontrivial copy ctor.
334 int foo(C c
) { return c
.n
; }
335 // CHECK-LABEL: define {{.*}} @_ZN28implicitly_deleted_copy_ctor3fooENS_1CE(ptr
336 // WIN64-LABEL: define {{.*}} @"?foo@implicitly_deleted_copy_ctor@@YAHTC@1@@Z"(ptr
339 D
&operator=(const D
&);
340 // Passed indirect: copy ctor deleted due to variant member with nontrivial copy ctor.
346 int foo(D d
) { return d
.n
; }
347 // CHECK-LABEL: define {{.*}} @_ZN28implicitly_deleted_copy_ctor3fooENS_1DE(ptr
348 // WIN64-LABEL: define {{.*}} @"?foo@implicitly_deleted_copy_ctor@@YAHUD@1@@Z"(ptr
351 // Passed direct: has non-deleted trivial copy ctor.
352 E
&operator=(const E
&);
356 int foo(E e
) { return e
.n
; }
357 // CHECK-LABEL: define {{.*}} @_ZN28implicitly_deleted_copy_ctor3fooENS_1EE(i32
358 // WIN64-LABEL: define {{.*}} @"?foo@implicitly_deleted_copy_ctor@@YAHTE@1@@Z"(i32
361 // Passed direct: has non-deleted trivial copy ctor.
362 F
&operator=(const F
&);
368 int foo(F f
) { return f
.n
; }
369 // CHECK-LABEL: define {{.*}} @_ZN28implicitly_deleted_copy_ctor3fooENS_1FE(i32
370 // WIN64-LABEL: define {{.*}} @"?foo@implicitly_deleted_copy_ctor@@YAHUF@1@@Z"(i32