[clang] Implement lifetime analysis for lifetime_capture_by(X) (#115921)
[llvm-project.git] / clang / test / SemaCUDA / implicit-member-target.cu
blobd87e69624043419c4f530abbc47fbd10719059d2
1 // RUN: %clang_cc1 -std=gnu++11 -fsyntax-only -verify %s -Wno-defaulted-function-deleted
3 #include "Inputs/cuda.h"
5 //------------------------------------------------------------------------------
6 // Test 1: infer default ctor to be host.
8 struct A1_with_host_ctor {
9   A1_with_host_ctor() {}
12 // The implicit default constructor is inferred to be host because it only needs
13 // to invoke a single host constructor (A1_with_host_ctor's). So we'll encounter
14 // an error when calling it from a __device__ function, but not from a __host__
15 // function.
16 struct B1_with_implicit_default_ctor : A1_with_host_ctor {
19 // expected-note@-3 {{call to __host__ function from __device__}}
20 // expected-note@-4 {{candidate constructor (the implicit copy constructor) not viable}}
21 // expected-note@-5 {{candidate constructor (the implicit move constructor) not viable}}
23 void hostfoo() {
24   B1_with_implicit_default_ctor b;
27 __device__ void devicefoo() {
28   B1_with_implicit_default_ctor b; // expected-error {{no matching constructor}}
31 //------------------------------------------------------------------------------
32 // Test 2: infer default ctor to be device.
34 struct A2_with_device_ctor {
35   __device__ A2_with_device_ctor() {}
38 struct B2_with_implicit_default_ctor : A2_with_device_ctor {
41 // expected-note@-3 {{call to __device__ function from __host__}}
42 // expected-note@-4 {{candidate constructor (the implicit copy constructor) not viable}}
43 // expected-note@-5 {{candidate constructor (the implicit move constructor) not viable}}
45 void hostfoo2() {
46   B2_with_implicit_default_ctor b;  // expected-error {{no matching constructor}}
49 __device__ void devicefoo2() {
50   B2_with_implicit_default_ctor b;
53 //------------------------------------------------------------------------------
54 // Test 3: infer copy ctor
56 struct A3_with_device_ctors {
57   __host__ A3_with_device_ctors() {}
58   __device__ A3_with_device_ctors(const A3_with_device_ctors&) {}
61 struct B3_with_implicit_ctors : A3_with_device_ctors {
63 // expected-note@-2 2{{call to __device__ function from __host__ function}}
64 // expected-note@-3 {{default constructor}}
67 void hostfoo3() {
68   B3_with_implicit_ctors b;  // this is OK because the inferred default ctor
69                              // here is __host__
70   B3_with_implicit_ctors b2 = b; // expected-error {{no matching constructor}}
74 //------------------------------------------------------------------------------
75 // Test 4: infer default ctor from a field, not a base
77 struct A4_with_host_ctor {
78   A4_with_host_ctor() {}
81 struct B4_with_implicit_default_ctor {
82   A4_with_host_ctor field;
85 // expected-note@-4 {{call to __host__ function from __device__}}
86 // expected-note@-5 {{candidate constructor (the implicit copy constructor) not viable}}
87 // expected-note@-6 {{candidate constructor (the implicit move constructor) not viable}}
89 void hostfoo4() {
90   B4_with_implicit_default_ctor b;
93 __device__ void devicefoo4() {
94   B4_with_implicit_default_ctor b; // expected-error {{no matching constructor}}
97 //------------------------------------------------------------------------------
98 // Test 5: copy ctor with non-const param
100 struct A5_copy_ctor_constness {
101   __host__ A5_copy_ctor_constness() {}
102   __host__ A5_copy_ctor_constness(A5_copy_ctor_constness&) {}
105 struct B5_copy_ctor_constness : A5_copy_ctor_constness {
108 // expected-note@-3 {{candidate constructor (the implicit copy constructor) not viable: call to __host__ function from __device__ function}}
109 // expected-note@-4 {{candidate constructor (the implicit default constructor) not viable}}
111 void hostfoo5(B5_copy_ctor_constness& b_arg) {
112   B5_copy_ctor_constness b = b_arg;
115 __device__ void devicefoo5(B5_copy_ctor_constness& b_arg) {
116   B5_copy_ctor_constness b = b_arg; // expected-error {{no matching constructor}}
119 //------------------------------------------------------------------------------
120 // Test 6: explicitly defaulted ctor: since they are spelled out, they have
121 // a host/device designation explicitly so no inference needs to be done.
123 struct A6_with_device_ctor {
124   __device__ A6_with_device_ctor() {}
127 struct B6_with_defaulted_ctor : A6_with_device_ctor {
128   __host__ B6_with_defaulted_ctor() = default;
131 // expected-note@-3 {{candidate constructor not viable: call to __host__ function from __device__ function}}
132 // expected-note@-5 {{candidate constructor (the implicit copy constructor) not viable}}
133 // expected-note@-6 {{candidate constructor (the implicit move constructor) not viable}}
135 __device__ void devicefoo6() {
136   B6_with_defaulted_ctor b; // expected-error {{no matching constructor}}
139 //------------------------------------------------------------------------------
140 // Test 7: copy assignment operator
142 struct A7_with_copy_assign {
143   A7_with_copy_assign() {}
144   __device__ A7_with_copy_assign& operator=(const A7_with_copy_assign&) {}
147 struct B7_with_copy_assign : A7_with_copy_assign {
150 // expected-note@-3 {{candidate function (the implicit copy assignment operator) not viable: call to __device__ function from __host__ function}}
151 // expected-note@-4 {{candidate function (the implicit move assignment operator) not viable: call to __device__ function from __host__ function}}
153 void hostfoo7() {
154   B7_with_copy_assign b1, b2;
155   b1 = b2; // expected-error {{no viable overloaded '='}}
158 //------------------------------------------------------------------------------
159 // Test 8: move assignment operator
161 // definitions for std::move
162 namespace std {
163 inline namespace foo {
164 template <class T> struct remove_reference { typedef T type; };
165 template <class T> struct remove_reference<T&> { typedef T type; };
166 template <class T> struct remove_reference<T&&> { typedef T type; };
168 template <class T> typename remove_reference<T>::type&& move(T&& t);
172 struct A8_with_move_assign {
173   A8_with_move_assign() {}
174   __device__ A8_with_move_assign& operator=(A8_with_move_assign&&) {}
175   __device__ A8_with_move_assign& operator=(const A8_with_move_assign&) {}
178 struct B8_with_move_assign : A8_with_move_assign {
181 // expected-note@-3 {{candidate function (the implicit copy assignment operator) not viable: call to __device__ function from __host__ function}}
182 // expected-note@-4 {{candidate function (the implicit move assignment operator) not viable: call to __device__ function from __host__ function}}
184 void hostfoo8() {
185   B8_with_move_assign b1, b2;
186   b1 = std::move(b2); // expected-error {{no viable overloaded '='}}