xref: /aosp_15_r20/external/clang/test/SemaCUDA/implicit-member-target.cu (revision 67e74705e28f6214e480b399dd47ea732279e315)
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 Li void 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 Li void 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 Li void 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 Li void 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 Li void 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 Li void 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 Li void 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