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