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