1*67e74705SXin Li // RUN: %clang_cc1 -std=gnu++11 -fsyntax-only -verify %s 2*67e74705SXin Li 3*67e74705SXin Li #include "Inputs/cuda.h" 4*67e74705SXin Li 5*67e74705SXin Li //------------------------------------------------------------------------------ 6*67e74705SXin Li // Test 1: infer default ctor to be host. 7*67e74705SXin Li 8*67e74705SXin Li struct A1_with_host_ctor { A1_with_host_ctorA1_with_host_ctor9*67e74705SXin Li A1_with_host_ctor() {} 10*67e74705SXin Li }; 11*67e74705SXin Li 12*67e74705SXin Li // The implicit default constructor is inferred to be host because it only needs 13*67e74705SXin Li // to invoke a single host constructor (A1_with_host_ctor's). So we'll encounter 14*67e74705SXin Li // an error when calling it from a __device__ function, but not from a __host__ 15*67e74705SXin Li // function. 16*67e74705SXin Li struct B1_with_implicit_default_ctor : A1_with_host_ctor { 17*67e74705SXin Li }; 18*67e74705SXin Li 19*67e74705SXin Li // expected-note@-3 {{call to __host__ function from __device__}} 20*67e74705SXin Li // expected-note@-4 {{candidate constructor (the implicit copy constructor) not viable}} 21*67e74705SXin Li // expected-note@-5 {{candidate constructor (the implicit move constructor) not viable}} 22*67e74705SXin Li hostfoo()23*67e74705SXin Livoid hostfoo() { 24*67e74705SXin Li B1_with_implicit_default_ctor b; 25*67e74705SXin Li } 26*67e74705SXin Li devicefoo()27*67e74705SXin Li__device__ void devicefoo() { 28*67e74705SXin Li B1_with_implicit_default_ctor b; // expected-error {{no matching constructor}} 29*67e74705SXin Li } 30*67e74705SXin Li 31*67e74705SXin Li //------------------------------------------------------------------------------ 32*67e74705SXin Li // Test 2: infer default ctor to be device. 33*67e74705SXin Li 34*67e74705SXin Li struct A2_with_device_ctor { A2_with_device_ctorA2_with_device_ctor35*67e74705SXin Li __device__ A2_with_device_ctor() {} 36*67e74705SXin Li }; 37*67e74705SXin Li 38*67e74705SXin Li struct B2_with_implicit_default_ctor : A2_with_device_ctor { 39*67e74705SXin Li }; 40*67e74705SXin Li 41*67e74705SXin Li // expected-note@-3 {{call to __device__ function from __host__}} 42*67e74705SXin Li // expected-note@-4 {{candidate constructor (the implicit copy constructor) not viable}} 43*67e74705SXin Li // expected-note@-5 {{candidate constructor (the implicit move constructor) not viable}} 44*67e74705SXin Li hostfoo2()45*67e74705SXin Livoid hostfoo2() { 46*67e74705SXin Li B2_with_implicit_default_ctor b; // expected-error {{no matching constructor}} 47*67e74705SXin Li } 48*67e74705SXin Li devicefoo2()49*67e74705SXin Li__device__ void devicefoo2() { 50*67e74705SXin Li B2_with_implicit_default_ctor b; 51*67e74705SXin Li } 52*67e74705SXin Li 53*67e74705SXin Li //------------------------------------------------------------------------------ 54*67e74705SXin Li // Test 3: infer copy ctor 55*67e74705SXin Li 56*67e74705SXin Li struct A3_with_device_ctors { A3_with_device_ctorsA3_with_device_ctors57*67e74705SXin Li __host__ A3_with_device_ctors() {} A3_with_device_ctorsA3_with_device_ctors58*67e74705SXin Li __device__ A3_with_device_ctors(const A3_with_device_ctors&) {} 59*67e74705SXin Li }; 60*67e74705SXin Li 61*67e74705SXin Li struct B3_with_implicit_ctors : A3_with_device_ctors { 62*67e74705SXin Li }; 63*67e74705SXin Li // expected-note@-2 2{{call to __device__ function from __host__ function}} 64*67e74705SXin Li // expected-note@-3 {{default constructor}} 65*67e74705SXin Li 66*67e74705SXin Li hostfoo3()67*67e74705SXin Livoid hostfoo3() { 68*67e74705SXin Li B3_with_implicit_ctors b; // this is OK because the inferred default ctor 69*67e74705SXin Li // here is __host__ 70*67e74705SXin Li B3_with_implicit_ctors b2 = b; // expected-error {{no matching constructor}} 71*67e74705SXin Li 72*67e74705SXin Li } 73*67e74705SXin Li 74*67e74705SXin Li //------------------------------------------------------------------------------ 75*67e74705SXin Li // Test 4: infer default ctor from a field, not a base 76*67e74705SXin Li 77*67e74705SXin Li struct A4_with_host_ctor { A4_with_host_ctorA4_with_host_ctor78*67e74705SXin Li A4_with_host_ctor() {} 79*67e74705SXin Li }; 80*67e74705SXin Li 81*67e74705SXin Li struct B4_with_implicit_default_ctor { 82*67e74705SXin Li A4_with_host_ctor field; 83*67e74705SXin Li }; 84*67e74705SXin Li 85*67e74705SXin Li // expected-note@-4 {{call to __host__ function from __device__}} 86*67e74705SXin Li // expected-note@-5 {{candidate constructor (the implicit copy constructor) not viable}} 87*67e74705SXin Li // expected-note@-6 {{candidate constructor (the implicit move constructor) not viable}} 88*67e74705SXin Li hostfoo4()89*67e74705SXin Livoid hostfoo4() { 90*67e74705SXin Li B4_with_implicit_default_ctor b; 91*67e74705SXin Li } 92*67e74705SXin Li devicefoo4()93*67e74705SXin Li__device__ void devicefoo4() { 94*67e74705SXin Li B4_with_implicit_default_ctor b; // expected-error {{no matching constructor}} 95*67e74705SXin Li } 96*67e74705SXin Li 97*67e74705SXin Li //------------------------------------------------------------------------------ 98*67e74705SXin Li // Test 5: copy ctor with non-const param 99*67e74705SXin Li 100*67e74705SXin Li struct A5_copy_ctor_constness { A5_copy_ctor_constnessA5_copy_ctor_constness101*67e74705SXin Li __host__ A5_copy_ctor_constness() {} A5_copy_ctor_constnessA5_copy_ctor_constness102*67e74705SXin Li __host__ A5_copy_ctor_constness(A5_copy_ctor_constness&) {} 103*67e74705SXin Li }; 104*67e74705SXin Li 105*67e74705SXin Li struct B5_copy_ctor_constness : A5_copy_ctor_constness { 106*67e74705SXin Li }; 107*67e74705SXin Li 108*67e74705SXin Li // expected-note@-3 {{candidate constructor (the implicit copy constructor) not viable: call to __host__ function from __device__ function}} 109*67e74705SXin Li // expected-note@-4 {{candidate constructor (the implicit default constructor) not viable}} 110*67e74705SXin Li hostfoo5(B5_copy_ctor_constness & b_arg)111*67e74705SXin Livoid hostfoo5(B5_copy_ctor_constness& b_arg) { 112*67e74705SXin Li B5_copy_ctor_constness b = b_arg; 113*67e74705SXin Li } 114*67e74705SXin Li devicefoo5(B5_copy_ctor_constness & b_arg)115*67e74705SXin Li__device__ void devicefoo5(B5_copy_ctor_constness& b_arg) { 116*67e74705SXin Li B5_copy_ctor_constness b = b_arg; // expected-error {{no matching constructor}} 117*67e74705SXin Li } 118*67e74705SXin Li 119*67e74705SXin Li //------------------------------------------------------------------------------ 120*67e74705SXin Li // Test 6: explicitly defaulted ctor: since they are spelled out, they have 121*67e74705SXin Li // a host/device designation explicitly so no inference needs to be done. 122*67e74705SXin Li 123*67e74705SXin Li struct A6_with_device_ctor { A6_with_device_ctorA6_with_device_ctor124*67e74705SXin Li __device__ A6_with_device_ctor() {} 125*67e74705SXin Li }; 126*67e74705SXin Li 127*67e74705SXin Li struct B6_with_defaulted_ctor : A6_with_device_ctor { 128*67e74705SXin Li __host__ B6_with_defaulted_ctor() = default; 129*67e74705SXin Li }; 130*67e74705SXin Li 131*67e74705SXin Li // expected-note@-3 {{candidate constructor not viable: call to __host__ function from __device__ function}} 132*67e74705SXin Li // expected-note@-5 {{candidate constructor (the implicit copy constructor) not viable}} 133*67e74705SXin Li // expected-note@-6 {{candidate constructor (the implicit move constructor) not viable}} 134*67e74705SXin Li devicefoo6()135*67e74705SXin Li__device__ void devicefoo6() { 136*67e74705SXin Li B6_with_defaulted_ctor b; // expected-error {{no matching constructor}} 137*67e74705SXin Li } 138*67e74705SXin Li 139*67e74705SXin Li //------------------------------------------------------------------------------ 140*67e74705SXin Li // Test 7: copy assignment operator 141*67e74705SXin Li 142*67e74705SXin Li struct A7_with_copy_assign { A7_with_copy_assignA7_with_copy_assign143*67e74705SXin Li A7_with_copy_assign() {} operator =A7_with_copy_assign144*67e74705SXin Li __device__ A7_with_copy_assign& operator=(const A7_with_copy_assign&) {} 145*67e74705SXin Li }; 146*67e74705SXin Li 147*67e74705SXin Li struct B7_with_copy_assign : A7_with_copy_assign { 148*67e74705SXin Li }; 149*67e74705SXin Li 150*67e74705SXin Li // expected-note@-3 {{candidate function (the implicit copy assignment operator) not viable: call to __device__ function from __host__ function}} 151*67e74705SXin Li // expected-note@-4 {{candidate function (the implicit move assignment operator) not viable: call to __device__ function from __host__ function}} 152*67e74705SXin Li hostfoo7()153*67e74705SXin Livoid hostfoo7() { 154*67e74705SXin Li B7_with_copy_assign b1, b2; 155*67e74705SXin Li b1 = b2; // expected-error {{no viable overloaded '='}} 156*67e74705SXin Li } 157*67e74705SXin Li 158*67e74705SXin Li //------------------------------------------------------------------------------ 159*67e74705SXin Li // Test 8: move assignment operator 160*67e74705SXin Li 161*67e74705SXin Li // definitions for std::move 162*67e74705SXin Li namespace std { 163*67e74705SXin Li inline namespace foo { 164*67e74705SXin Li template <class T> struct remove_reference { typedef T type; }; 165*67e74705SXin Li template <class T> struct remove_reference<T&> { typedef T type; }; 166*67e74705SXin Li template <class T> struct remove_reference<T&&> { typedef T type; }; 167*67e74705SXin Li 168*67e74705SXin Li template <class T> typename remove_reference<T>::type&& move(T&& t); 169*67e74705SXin Li } 170*67e74705SXin Li } 171*67e74705SXin Li 172*67e74705SXin Li struct A8_with_move_assign { A8_with_move_assignA8_with_move_assign173*67e74705SXin Li A8_with_move_assign() {} operator =A8_with_move_assign174*67e74705SXin Li __device__ A8_with_move_assign& operator=(A8_with_move_assign&&) {} operator =A8_with_move_assign175*67e74705SXin Li __device__ A8_with_move_assign& operator=(const A8_with_move_assign&) {} 176*67e74705SXin Li }; 177*67e74705SXin Li 178*67e74705SXin Li struct B8_with_move_assign : A8_with_move_assign { 179*67e74705SXin Li }; 180*67e74705SXin Li 181*67e74705SXin Li // expected-note@-3 {{candidate function (the implicit copy assignment operator) not viable: call to __device__ function from __host__ function}} 182*67e74705SXin Li // expected-note@-4 {{candidate function (the implicit move assignment operator) not viable: call to __device__ function from __host__ function}} 183*67e74705SXin Li hostfoo8()184*67e74705SXin Livoid hostfoo8() { 185*67e74705SXin Li B8_with_move_assign b1, b2; 186*67e74705SXin Li b1 = std::move(b2); // expected-error {{no viable overloaded '='}} 187*67e74705SXin Li } 188