• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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-windows-msvc -emit-llvm -o - %s -fms-compatibility -fms-compatibility-version=18 | FileCheck %s -check-prefix=WIN64 -check-prefix=WIN64-18
5 // 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
6 
7 namespace trivial {
8 // Trivial structs should be passed directly.
9 struct A {
10   void *p;
11 };
12 void foo(A);
bar()13 void bar() {
14   foo({});
15 }
16 // CHECK-LABEL: define void @_ZN7trivial3barEv()
17 // CHECK: alloca %"struct.trivial::A"
18 // CHECK: load i8*, i8**
19 // CHECK: call void @_ZN7trivial3fooENS_1AE(i8* %{{.*}})
20 // CHECK-LABEL: declare void @_ZN7trivial3fooENS_1AE(i8*)
21 
22 // WIN64-LABEL: declare dso_local void @"?foo@trivial@@YAXUA@1@@Z"(i64)
23 }
24 
25 namespace default_ctor {
26 struct A {
27   A();
28   void *p;
29 };
30 void foo(A);
bar()31 void bar() {
32   // Core issue 1590.  We can pass this type in registers, even though C++
33   // normally doesn't permit copies when using braced initialization.
34   foo({});
35 }
36 // CHECK-LABEL: define void @_ZN12default_ctor3barEv()
37 // CHECK: alloca %"struct.default_ctor::A"
38 // CHECK: call void @_Z{{.*}}C1Ev(
39 // CHECK: load i8*, i8**
40 // CHECK: call void @_ZN12default_ctor3fooENS_1AE(i8* %{{.*}})
41 // CHECK-LABEL: declare void @_ZN12default_ctor3fooENS_1AE(i8*)
42 
43 // WIN64-LABEL: declare dso_local void @"?foo@default_ctor@@YAXUA@1@@Z"(i64)
44 }
45 
46 namespace move_ctor {
47 // The presence of a move constructor implicitly deletes the trivial copy ctor
48 // and means that we have to pass this struct by address.
49 struct A {
50   A();
51   A(A &&o);
52   void *p;
53 };
54 void foo(A);
bar()55 void bar() {
56   foo({});
57 }
58 // CHECK-LABEL: define void @_ZN9move_ctor3barEv()
59 // CHECK: call void @_Z{{.*}}C1Ev(
60 // CHECK-NOT: call
61 // NEWABI: call void @_ZN9move_ctor3fooENS_1AE(%"struct.move_ctor::A"* %{{.*}})
62 // OLDABI: call void @_ZN9move_ctor3fooENS_1AE(i8* %{{.*}})
63 // NEWABI-LABEL: declare void @_ZN9move_ctor3fooENS_1AE(%"struct.move_ctor::A"*)
64 // OLDABI-LABEL: declare void @_ZN9move_ctor3fooENS_1AE(i8*)
65 
66 // WIN64-LABEL: declare dso_local void @"?foo@move_ctor@@YAXUA@1@@Z"(%"struct.move_ctor::A"*)
67 }
68 
69 namespace all_deleted {
70 struct A {
71   A();
72   A(const A &o) = delete;
73   A(A &&o) = delete;
74   void *p;
75 };
76 void foo(A);
bar()77 void bar() {
78   foo({});
79 }
80 // CHECK-LABEL: define void @_ZN11all_deleted3barEv()
81 // CHECK: call void @_Z{{.*}}C1Ev(
82 // CHECK-NOT: call
83 // NEWABI: call void @_ZN11all_deleted3fooENS_1AE(%"struct.all_deleted::A"* %{{.*}})
84 // OLDABI: call void @_ZN11all_deleted3fooENS_1AE(i8* %{{.*}})
85 // NEWABI-LABEL: declare void @_ZN11all_deleted3fooENS_1AE(%"struct.all_deleted::A"*)
86 // OLDABI-LABEL: declare void @_ZN11all_deleted3fooENS_1AE(i8*)
87 
88 // WIN64-LABEL: declare dso_local void @"?foo@all_deleted@@YAXUA@1@@Z"(%"struct.all_deleted::A"*)
89 }
90 
91 namespace implicitly_deleted {
92 struct A {
93   A();
94   A &operator=(A &&o);
95   void *p;
96 };
97 void foo(A);
bar()98 void bar() {
99   foo({});
100 }
101 // CHECK-LABEL: define void @_ZN18implicitly_deleted3barEv()
102 // CHECK: call void @_Z{{.*}}C1Ev(
103 // CHECK-NOT: call
104 // NEWABI: call void @_ZN18implicitly_deleted3fooENS_1AE(%"struct.implicitly_deleted::A"* %{{.*}})
105 // OLDABI: call void @_ZN18implicitly_deleted3fooENS_1AE(i8* %{{.*}})
106 // NEWABI-LABEL: declare void @_ZN18implicitly_deleted3fooENS_1AE(%"struct.implicitly_deleted::A"*)
107 // OLDABI-LABEL: declare void @_ZN18implicitly_deleted3fooENS_1AE(i8*)
108 
109 // In MSVC 2013, the copy ctor is not deleted by a move assignment. In MSVC 2015, it is.
110 // WIN64-18-LABEL: declare dso_local void @"?foo@implicitly_deleted@@YAXUA@1@@Z"(i64
111 // WIN64-19-LABEL: declare dso_local void @"?foo@implicitly_deleted@@YAXUA@1@@Z"(%"struct.implicitly_deleted::A"*)
112 }
113 
114 namespace one_deleted {
115 struct A {
116   A();
117   A(A &&o) = delete;
118   void *p;
119 };
120 void foo(A);
bar()121 void bar() {
122   foo({});
123 }
124 // CHECK-LABEL: define void @_ZN11one_deleted3barEv()
125 // CHECK: call void @_Z{{.*}}C1Ev(
126 // CHECK-NOT: call
127 // NEWABI: call void @_ZN11one_deleted3fooENS_1AE(%"struct.one_deleted::A"* %{{.*}})
128 // OLDABI: call void @_ZN11one_deleted3fooENS_1AE(i8* %{{.*}})
129 // NEWABI-LABEL: declare void @_ZN11one_deleted3fooENS_1AE(%"struct.one_deleted::A"*)
130 // OLDABI-LABEL: declare void @_ZN11one_deleted3fooENS_1AE(i8*)
131 
132 // WIN64-LABEL: declare dso_local void @"?foo@one_deleted@@YAXUA@1@@Z"(%"struct.one_deleted::A"*)
133 }
134 
135 namespace copy_defaulted {
136 struct A {
137   A();
138   A(const A &o) = default;
139   A(A &&o) = delete;
140   void *p;
141 };
142 void foo(A);
bar()143 void bar() {
144   foo({});
145 }
146 // CHECK-LABEL: define void @_ZN14copy_defaulted3barEv()
147 // CHECK: call void @_Z{{.*}}C1Ev(
148 // CHECK: load i8*, i8**
149 // CHECK: call void @_ZN14copy_defaulted3fooENS_1AE(i8* %{{.*}})
150 // CHECK-LABEL: declare void @_ZN14copy_defaulted3fooENS_1AE(i8*)
151 
152 // WIN64-LABEL: declare dso_local void @"?foo@copy_defaulted@@YAXUA@1@@Z"(i64)
153 }
154 
155 namespace move_defaulted {
156 struct A {
157   A();
158   A(const A &o) = delete;
159   A(A &&o) = default;
160   void *p;
161 };
162 void foo(A);
bar()163 void bar() {
164   foo({});
165 }
166 // CHECK-LABEL: define void @_ZN14move_defaulted3barEv()
167 // CHECK: call void @_Z{{.*}}C1Ev(
168 // CHECK: load i8*, i8**
169 // CHECK: call void @_ZN14move_defaulted3fooENS_1AE(i8* %{{.*}})
170 // CHECK-LABEL: declare void @_ZN14move_defaulted3fooENS_1AE(i8*)
171 
172 // WIN64-LABEL: declare dso_local void @"?foo@move_defaulted@@YAXUA@1@@Z"(%"struct.move_defaulted::A"*)
173 }
174 
175 namespace trivial_defaulted {
176 struct A {
177   A();
178   A(const A &o) = default;
179   void *p;
180 };
181 void foo(A);
bar()182 void bar() {
183   foo({});
184 }
185 // CHECK-LABEL: define void @_ZN17trivial_defaulted3barEv()
186 // CHECK: call void @_Z{{.*}}C1Ev(
187 // CHECK: load i8*, i8**
188 // CHECK: call void @_ZN17trivial_defaulted3fooENS_1AE(i8* %{{.*}})
189 // CHECK-LABEL: declare void @_ZN17trivial_defaulted3fooENS_1AE(i8*)
190 
191 // WIN64-LABEL: declare dso_local void @"?foo@trivial_defaulted@@YAXUA@1@@Z"(i64)
192 }
193 
194 namespace two_copy_ctors {
195 struct A {
196   A();
197   A(const A &) = default;
198   A(const A &, int = 0);
199   void *p;
200 };
201 struct B : A {};
202 
203 void foo(B);
bar()204 void bar() {
205   foo({});
206 }
207 // CHECK-LABEL: define void @_ZN14two_copy_ctors3barEv()
208 // CHECK: call void @_Z{{.*}}C1Ev(
209 // NEWABI: call void @_ZN14two_copy_ctors3fooENS_1BE(%"struct.two_copy_ctors::B"* %{{.*}})
210 // OLDABI: call void @_ZN14two_copy_ctors3fooENS_1BE(%"struct.two_copy_ctors::B"* byval
211 // NEWABI-LABEL: declare void @_ZN14two_copy_ctors3fooENS_1BE(%"struct.two_copy_ctors::B"*)
212 // OLDABI-LABEL: declare void @_ZN14two_copy_ctors3fooENS_1BE(%"struct.two_copy_ctors::B"* byval
213 
214 // WIN64-LABEL: declare dso_local void @"?foo@two_copy_ctors@@YAXUB@1@@Z"(%"struct.two_copy_ctors::B"*)
215 }
216 
217 namespace definition_only {
218 struct A {
219   A();
220   A(A &&o);
221   void *p;
222 };
foo(A a)223 void *foo(A a) { return a.p; }
224 // NEWABI-LABEL: define i8* @_ZN15definition_only3fooENS_1AE(%"struct.definition_only::A"*
225 // OLDABI-LABEL: define i8* @_ZN15definition_only3fooENS_1AE(i8*
226 // WIN64-LABEL: define dso_local i8* @"?foo@definition_only@@YAPEAXUA@1@@Z"(%"struct.definition_only::A"*
227 }
228 
229 namespace deleted_by_member {
230 struct B {
231   B();
232   B(B &&o);
233   void *p;
234 };
235 struct A {
236   A();
237   B b;
238 };
foo(A a)239 void *foo(A a) { return a.b.p; }
240 // NEWABI-LABEL: define i8* @_ZN17deleted_by_member3fooENS_1AE(%"struct.deleted_by_member::A"*
241 // OLDABI-LABEL: define i8* @_ZN17deleted_by_member3fooENS_1AE(i8*
242 // WIN64-LABEL: define dso_local i8* @"?foo@deleted_by_member@@YAPEAXUA@1@@Z"(%"struct.deleted_by_member::A"*
243 }
244 
245 namespace deleted_by_base {
246 struct B {
247   B();
248   B(B &&o);
249   void *p;
250 };
251 struct A : B {
252   A();
253 };
foo(A a)254 void *foo(A a) { return a.p; }
255 // NEWABI-LABEL: define i8* @_ZN15deleted_by_base3fooENS_1AE(%"struct.deleted_by_base::A"*
256 // OLDABI-LABEL: define i8* @_ZN15deleted_by_base3fooENS_1AE(i8*
257 // WIN64-LABEL: define dso_local i8* @"?foo@deleted_by_base@@YAPEAXUA@1@@Z"(%"struct.deleted_by_base::A"*
258 }
259 
260 namespace deleted_by_member_copy {
261 struct B {
262   B();
263   B(const B &o) = delete;
264   void *p;
265 };
266 struct A {
267   A();
268   B b;
269 };
foo(A a)270 void *foo(A a) { return a.b.p; }
271 // NEWABI-LABEL: define i8* @_ZN22deleted_by_member_copy3fooENS_1AE(%"struct.deleted_by_member_copy::A"*
272 // OLDABI-LABEL: define i8* @_ZN22deleted_by_member_copy3fooENS_1AE(i8*
273 // WIN64-LABEL: define dso_local i8* @"?foo@deleted_by_member_copy@@YAPEAXUA@1@@Z"(%"struct.deleted_by_member_copy::A"*
274 }
275 
276 namespace deleted_by_base_copy {
277 struct B {
278   B();
279   B(const B &o) = delete;
280   void *p;
281 };
282 struct A : B {
283   A();
284 };
foo(A a)285 void *foo(A a) { return a.p; }
286 // NEWABI-LABEL: define i8* @_ZN20deleted_by_base_copy3fooENS_1AE(%"struct.deleted_by_base_copy::A"*
287 // OLDABI-LABEL: define i8* @_ZN20deleted_by_base_copy3fooENS_1AE(i8*
288 // WIN64-LABEL: define dso_local i8* @"?foo@deleted_by_base_copy@@YAPEAXUA@1@@Z"(%"struct.deleted_by_base_copy::A"*
289 }
290 
291 namespace explicit_delete {
292 struct A {
293   A();
294   A(const A &o) = delete;
295   void *p;
296 };
297 // NEWABI-LABEL: define i8* @_ZN15explicit_delete3fooENS_1AE(%"struct.explicit_delete::A"*
298 // OLDABI-LABEL: define i8* @_ZN15explicit_delete3fooENS_1AE(i8*
299 // WIN64-LABEL: define dso_local i8* @"?foo@explicit_delete@@YAPEAXUA@1@@Z"(%"struct.explicit_delete::A"*
foo(A a)300 void *foo(A a) { return a.p; }
301 }
302 
303 namespace implicitly_deleted_copy_ctor {
304 struct A {
305   // No move ctor due to copy assignment.
306   A &operator=(const A&);
307   // Deleted copy ctor due to rvalue ref member.
308   int &&ref;
309 };
310 // NEWABI-LABEL: define {{.*}} @_ZN28implicitly_deleted_copy_ctor3fooENS_1AE(%"struct.implicitly_deleted_copy_ctor::A"*
311 // OLDABI-LABEL: define {{.*}} @_ZN28implicitly_deleted_copy_ctor3fooENS_1AE(i32*
312 // WIN64-LABEL: define {{.*}} @"?foo@implicitly_deleted_copy_ctor@@YAAEAHUA@1@@Z"(%"struct.implicitly_deleted_copy_ctor::A"*
foo(A a)313 int &foo(A a) { return a.ref; }
314 
315 struct B {
316   // Passed direct: has non-deleted trivial copy ctor.
317   B &operator=(const B&);
318   int &ref;
319 };
foo(B b)320 int &foo(B b) { return b.ref; }
321 // CHECK-LABEL: define {{.*}} @_ZN28implicitly_deleted_copy_ctor3fooENS_1BE(i32*
322 // WIN64-LABEL: define {{.*}} @"?foo@implicitly_deleted_copy_ctor@@YAAEAHUB@1@@Z"(i64
323 
324 struct X { X(const X&); };
325 struct Y { Y(const Y&) = default; };
326 
327 union C {
328   C &operator=(const C&);
329   // Passed indirect: copy ctor deleted due to variant member with nontrivial copy ctor.
330   X x;
331   int n;
332 };
foo(C c)333 int foo(C c) { return c.n; }
334 // CHECK-LABEL: define {{.*}} @_ZN28implicitly_deleted_copy_ctor3fooENS_1CE(%"union.implicitly_deleted_copy_ctor::C"*
335 // WIN64-LABEL: define {{.*}} @"?foo@implicitly_deleted_copy_ctor@@YAHTC@1@@Z"(%"union.implicitly_deleted_copy_ctor::C"*
336 
337 struct D {
338   D &operator=(const D&);
339   // Passed indirect: copy ctor deleted due to variant member with nontrivial copy ctor.
340   union {
341     X x;
342     int n;
343   };
344 };
foo(D d)345 int foo(D d) { return d.n; }
346 // CHECK-LABEL: define {{.*}} @_ZN28implicitly_deleted_copy_ctor3fooENS_1DE(%"struct.implicitly_deleted_copy_ctor::D"*
347 // WIN64-LABEL: define {{.*}} @"?foo@implicitly_deleted_copy_ctor@@YAHUD@1@@Z"(%"struct.implicitly_deleted_copy_ctor::D"*
348 
349 union E {
350   // Passed direct: has non-deleted trivial copy ctor.
351   E &operator=(const E&);
352   Y y;
353   int n;
354 };
foo(E e)355 int foo(E e) { return e.n; }
356 // CHECK-LABEL: define {{.*}} @_ZN28implicitly_deleted_copy_ctor3fooENS_1EE(i32
357 // WIN64-LABEL: define {{.*}} @"?foo@implicitly_deleted_copy_ctor@@YAHTE@1@@Z"(i32
358 
359 struct F {
360   // Passed direct: has non-deleted trivial copy ctor.
361   F &operator=(const F&);
362   union {
363     Y y;
364     int n;
365   };
366 };
foo(F f)367 int foo(F f) { return f.n; }
368 // CHECK-LABEL: define {{.*}} @_ZN28implicitly_deleted_copy_ctor3fooENS_1FE(i32
369 // WIN64-LABEL: define {{.*}} @"?foo@implicitly_deleted_copy_ctor@@YAHUF@1@@Z"(i32
370 }
371