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 Sambucvoid 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 Sambucvoid 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 Sambucvoid 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 Sambucvoid 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 Sambucvoid 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 Sambucvoid 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 Sambucvoid 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 Sambucvoid 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 Sambucvoid 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 Sambucvoid 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