Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / clang / test / CodeGenCXX / uncopyable-args.cpp
blob31192b65cc3622c6f2676462930f3ab93e1cbead
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
8 namespace trivial {
9 // Trivial structs should be passed directly.
10 struct A {
11 void *p;
13 void foo(A);
14 void bar() {
15 foo({});
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 {
27 struct A {
28 A();
29 void *p;
31 void foo(A);
32 void bar() {
33 // Core issue 1590. We can pass this type in registers, even though C++
34 // normally doesn't permit copies when using braced initialization.
35 foo({});
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)
47 namespace move_ctor {
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.
50 struct A {
51 A();
52 A(A &&o);
53 void *p;
55 void foo(A);
56 void bar() {
57 foo({});
59 // CHECK-LABEL: define{{.*}} void @_ZN9move_ctor3barEv()
60 // CHECK: call void @_Z{{.*}}C1Ev(
61 // CHECK-NOT: call
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 {
71 struct A {
72 A();
73 A(const A &o) = delete;
74 A(A &&o) = delete;
75 void *p;
77 void foo(A);
78 void bar() {
79 foo({});
81 // CHECK-LABEL: define{{.*}} void @_ZN11all_deleted3barEv()
82 // CHECK: call void @_Z{{.*}}C1Ev(
83 // CHECK-NOT: call
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 {
93 struct A {
94 A();
95 A &operator=(A &&o);
96 void *p;
98 void foo(A);
99 void bar() {
100 foo({});
102 // CHECK-LABEL: define{{.*}} void @_ZN18implicitly_deleted3barEv()
103 // CHECK: call void @_Z{{.*}}C1Ev(
104 // CHECK-NOT: call
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 {
116 struct A {
117 A();
118 A(A &&o) = delete;
119 void *p;
121 void foo(A);
122 void bar() {
123 foo({});
125 // CHECK-LABEL: define{{.*}} void @_ZN11one_deleted3barEv()
126 // CHECK: call void @_Z{{.*}}C1Ev(
127 // CHECK-NOT: call
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 {
137 struct A {
138 A();
139 A(const A &o) = default;
140 A(A &&o) = delete;
141 void *p;
143 void foo(A);
144 void bar() {
145 foo({});
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 {
157 struct A {
158 A();
159 A(const A &o) = delete;
160 A(A &&o) = default;
161 void *p;
163 void foo(A);
164 void bar() {
165 foo({});
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 {
177 struct A {
178 A();
179 A(const A &o) = default;
180 void *p;
182 void foo(A);
183 void bar() {
184 foo({});
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 {
196 struct A {
197 A();
198 A(const A &) = default;
199 A(const A &, int = 0);
200 void *p;
202 struct B : A {};
204 void foo(B);
205 void bar() {
206 foo({});
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 {
219 struct A {
220 A();
221 A(A &&o);
222 void *p;
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 {
231 struct B {
232 B();
233 B(B &&o);
234 void *p;
236 struct A {
237 A();
238 B b;
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 {
247 struct B {
248 B();
249 B(B &&o);
250 void *p;
252 struct A : B {
253 A();
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 {
262 struct B {
263 B();
264 B(const B &o) = delete;
265 void *p;
267 struct A {
268 A();
269 B b;
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 {
278 struct B {
279 B();
280 B(const B &o) = delete;
281 void *p;
283 struct A : B {
284 A();
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 {
293 struct A {
294 A();
295 A(const A &o) = delete;
296 void *p;
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 {
305 struct A {
306 // No move ctor due to copy assignment.
307 A &operator=(const A&);
308 // Deleted copy ctor due to rvalue ref member.
309 int &&ref;
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; }
316 struct B {
317 // Passed direct: has non-deleted trivial copy ctor.
318 B &operator=(const B&);
319 int &ref;
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; };
328 union C {
329 C &operator=(const C&);
330 // Passed indirect: copy ctor deleted due to variant member with nontrivial copy ctor.
331 X x;
332 int n;
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
338 struct D {
339 D &operator=(const D&);
340 // Passed indirect: copy ctor deleted due to variant member with nontrivial copy ctor.
341 union {
342 X x;
343 int n;
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
350 union E {
351 // Passed direct: has non-deleted trivial copy ctor.
352 E &operator=(const E&);
353 Y y;
354 int n;
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
360 struct F {
361 // Passed direct: has non-deleted trivial copy ctor.
362 F &operator=(const F&);
363 union {
364 Y y;
365 int n;
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