blob: c1d284a74185b192bfbdf0ada79a915f8a5802ad [file] [log] [blame]
Reid Klecknercf87e102014-05-14 16:02:09 +00001// RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-unknown -emit-llvm -o - %s | FileCheck %s
2// RUN: %clang_cc1 -std=c++11 -triple x86_64-windows-msvc -emit-llvm -o - %s | FileCheck %s -check-prefix=WIN64
3
4namespace trivial {
5// Trivial structs should be passed directly.
6struct A {
7 void *p;
8};
9void foo(A);
10void bar() {
11 foo({});
12}
13// CHECK-LABEL: define void @_ZN7trivial3barEv()
14// CHECK: alloca %"struct.trivial::A"
David Blaikiea953f282015-02-27 21:19:58 +000015// CHECK: load i8*, i8**
Reid Klecknercf87e102014-05-14 16:02:09 +000016// CHECK: call void @_ZN7trivial3fooENS_1AE(i8* %{{.*}})
17// CHECK-LABEL: declare void @_ZN7trivial3fooENS_1AE(i8*)
18
19// WIN64-LABEL: declare void @"\01?foo@trivial@@YAXUA@1@@Z"(i64)
20}
21
22namespace default_ctor {
23struct A {
24 A();
25 void *p;
26};
27void foo(A);
28void bar() {
29 // Core issue 1590. We can pass this type in registers, even though C++
30 // normally doesn't permit copies when using braced initialization.
31 foo({});
32}
33// CHECK-LABEL: define void @_ZN12default_ctor3barEv()
34// CHECK: alloca %"struct.default_ctor::A"
35// CHECK: call void @_Z{{.*}}C1Ev(
David Blaikiea953f282015-02-27 21:19:58 +000036// CHECK: load i8*, i8**
Reid Klecknercf87e102014-05-14 16:02:09 +000037// CHECK: call void @_ZN12default_ctor3fooENS_1AE(i8* %{{.*}})
38// CHECK-LABEL: declare void @_ZN12default_ctor3fooENS_1AE(i8*)
39
40// WIN64-LABEL: declare void @"\01?foo@default_ctor@@YAXUA@1@@Z"(i64)
41}
42
43namespace move_ctor {
44// The presence of a move constructor implicitly deletes the trivial copy ctor
45// and means that we have to pass this struct by address.
46struct A {
47 A();
48 A(A &&o);
49 void *p;
50};
51void foo(A);
52void bar() {
53 foo({});
54}
Reid Klecknerd355ca72014-05-15 01:26:32 +000055// FIXME: The copy ctor is implicitly deleted.
56// CHECK-DISABLED-LABEL: define void @_ZN9move_ctor3barEv()
57// CHECK-DISABLED: call void @_Z{{.*}}C1Ev(
58// CHECK-DISABLED-NOT: call
59// CHECK-DISABLED: call void @_ZN9move_ctor3fooENS_1AE(%"struct.move_ctor::A"* %{{.*}})
60// CHECK-DISABLED-LABEL: declare void @_ZN9move_ctor3fooENS_1AE(%"struct.move_ctor::A"*)
Reid Klecknercf87e102014-05-14 16:02:09 +000061
62// WIN64-LABEL: declare void @"\01?foo@move_ctor@@YAXUA@1@@Z"(%"struct.move_ctor::A"*)
63}
64
65namespace all_deleted {
66struct A {
67 A();
68 A(const A &o) = delete;
69 A(A &&o) = delete;
70 void *p;
71};
72void foo(A);
73void bar() {
74 foo({});
75}
Reid Klecknerd355ca72014-05-15 01:26:32 +000076// FIXME: The copy ctor is deleted.
77// CHECK-DISABLED-LABEL: define void @_ZN11all_deleted3barEv()
78// CHECK-DISABLED: call void @_Z{{.*}}C1Ev(
Hans Wennborg2151d122015-08-31 21:48:52 +000079// CHECK-DISABLED-NOT: call
Reid Klecknerd355ca72014-05-15 01:26:32 +000080// CHECK-DISABLED: call void @_ZN11all_deleted3fooENS_1AE(%"struct.all_deleted::A"* %{{.*}})
81// CHECK-DISABLED-LABEL: declare void @_ZN11all_deleted3fooENS_1AE(%"struct.all_deleted::A"*)
Reid Klecknercf87e102014-05-14 16:02:09 +000082
83// WIN64-LABEL: declare void @"\01?foo@all_deleted@@YAXUA@1@@Z"(%"struct.all_deleted::A"*)
84}
85
86namespace implicitly_deleted {
87struct A {
88 A();
89 A &operator=(A &&o);
90 void *p;
91};
92void foo(A);
93void bar() {
94 foo({});
95}
Reid Klecknerd355ca72014-05-15 01:26:32 +000096// FIXME: The copy and move ctors are implicitly deleted.
97// CHECK-DISABLED-LABEL: define void @_ZN18implicitly_deleted3barEv()
98// CHECK-DISABLED: call void @_Z{{.*}}C1Ev(
Hans Wennborg2151d122015-08-31 21:48:52 +000099// CHECK-DISABLED-NOT: call
Reid Klecknerd355ca72014-05-15 01:26:32 +0000100// CHECK-DISABLED: call void @_ZN18implicitly_deleted3fooENS_1AE(%"struct.implicitly_deleted::A"* %{{.*}})
101// CHECK-DISABLED-LABEL: declare void @_ZN18implicitly_deleted3fooENS_1AE(%"struct.implicitly_deleted::A"*)
Reid Klecknercf87e102014-05-14 16:02:09 +0000102
103// WIN64-LABEL: declare void @"\01?foo@implicitly_deleted@@YAXUA@1@@Z"(%"struct.implicitly_deleted::A"*)
104}
105
106namespace one_deleted {
107struct A {
108 A();
109 A(A &&o) = delete;
110 void *p;
111};
112void foo(A);
113void bar() {
114 foo({});
115}
Reid Klecknerd355ca72014-05-15 01:26:32 +0000116// FIXME: The copy constructor is implicitly deleted.
117// CHECK-DISABLED-LABEL: define void @_ZN11one_deleted3barEv()
118// CHECK-DISABLED: call void @_Z{{.*}}C1Ev(
Hans Wennborg2151d122015-08-31 21:48:52 +0000119// CHECK-DISABLED-NOT: call
Reid Klecknerd355ca72014-05-15 01:26:32 +0000120// CHECK-DISABLED: call void @_ZN11one_deleted3fooENS_1AE(%"struct.one_deleted::A"* %{{.*}})
121// CHECK-DISABLED-LABEL: declare void @_ZN11one_deleted3fooENS_1AE(%"struct.one_deleted::A"*)
Reid Klecknercf87e102014-05-14 16:02:09 +0000122
123// WIN64-LABEL: declare void @"\01?foo@one_deleted@@YAXUA@1@@Z"(%"struct.one_deleted::A"*)
124}
125
126namespace copy_defaulted {
127struct A {
128 A();
129 A(const A &o) = default;
130 A(A &&o) = delete;
131 void *p;
132};
133void foo(A);
134void bar() {
135 foo({});
136}
137// CHECK-LABEL: define void @_ZN14copy_defaulted3barEv()
138// CHECK: call void @_Z{{.*}}C1Ev(
David Blaikiea953f282015-02-27 21:19:58 +0000139// CHECK: load i8*, i8**
Reid Klecknercf87e102014-05-14 16:02:09 +0000140// CHECK: call void @_ZN14copy_defaulted3fooENS_1AE(i8* %{{.*}})
141// CHECK-LABEL: declare void @_ZN14copy_defaulted3fooENS_1AE(i8*)
142
143// WIN64-LABEL: declare void @"\01?foo@copy_defaulted@@YAXUA@1@@Z"(i64)
144}
145
146namespace move_defaulted {
147struct A {
148 A();
149 A(const A &o) = delete;
150 A(A &&o) = default;
151 void *p;
152};
153void foo(A);
154void bar() {
155 foo({});
156}
157// CHECK-LABEL: define void @_ZN14move_defaulted3barEv()
158// CHECK: call void @_Z{{.*}}C1Ev(
David Blaikiea953f282015-02-27 21:19:58 +0000159// CHECK: load i8*, i8**
Reid Klecknercf87e102014-05-14 16:02:09 +0000160// CHECK: call void @_ZN14move_defaulted3fooENS_1AE(i8* %{{.*}})
161// CHECK-LABEL: declare void @_ZN14move_defaulted3fooENS_1AE(i8*)
162
163// WIN64-LABEL: declare void @"\01?foo@move_defaulted@@YAXUA@1@@Z"(%"struct.move_defaulted::A"*)
164}
165
166namespace trivial_defaulted {
167struct A {
168 A();
169 A(const A &o) = default;
170 void *p;
171};
172void foo(A);
173void bar() {
174 foo({});
175}
176// CHECK-LABEL: define void @_ZN17trivial_defaulted3barEv()
177// CHECK: call void @_Z{{.*}}C1Ev(
David Blaikiea953f282015-02-27 21:19:58 +0000178// CHECK: load i8*, i8**
Reid Klecknercf87e102014-05-14 16:02:09 +0000179// CHECK: call void @_ZN17trivial_defaulted3fooENS_1AE(i8* %{{.*}})
180// CHECK-LABEL: declare void @_ZN17trivial_defaulted3fooENS_1AE(i8*)
181
182// WIN64-LABEL: declare void @"\01?foo@trivial_defaulted@@YAXUA@1@@Z"(i64)
183}
184
185namespace two_copy_ctors {
186struct A {
187 A();
188 A(const A &) = default;
189 A(const A &, int = 0);
190 void *p;
191};
192struct B : A {};
193
194void foo(B);
195void bar() {
196 foo({});
197}
Reid Klecknerd355ca72014-05-15 01:26:32 +0000198// FIXME: This class has a non-trivial copy ctor and a trivial copy ctor. It's
199// not clear whether we should pass by address or in registers.
200// CHECK-DISABLED-LABEL: define void @_ZN14two_copy_ctors3barEv()
201// CHECK-DISABLED: call void @_Z{{.*}}C1Ev(
202// CHECK-DISABLED: call void @_ZN14two_copy_ctors3fooENS_1BE(%"struct.two_copy_ctors::B"* %{{.*}})
203// CHECK-DISABLED-LABEL: declare void @_ZN14two_copy_ctors3fooENS_1BE(%"struct.two_copy_ctors::B"*)
Reid Klecknercf87e102014-05-14 16:02:09 +0000204
205// WIN64-LABEL: declare void @"\01?foo@two_copy_ctors@@YAXUB@1@@Z"(%"struct.two_copy_ctors::B"*)
206}