blob: adf488b5eea3736e6c0c151fb4a93d88b7a3bd18 [file] [log] [blame]
Artem Belevich94a55e82015-09-22 17:22:59 +00001// REQUIRES: x86-registered-target
2// REQUIRES: nvptx-registered-target
3
Justin Lebar25c4a812016-03-29 16:24:16 +00004// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fsyntax-only -verify %s
5// RUN: %clang_cc1 -triple nvptx64-nvidia-cuda -fsyntax-only -fcuda-is-device -verify %s
Artem Belevich94a55e82015-09-22 17:22:59 +00006
7#include "Inputs/cuda.h"
8
Justin Lebare5eed042016-03-23 22:42:30 +00009// Opaque return types used to check that we pick the right overloads.
10struct HostReturnTy {};
11struct HostReturnTy2 {};
12struct DeviceReturnTy {};
13struct DeviceReturnTy2 {};
14struct HostDeviceReturnTy {};
15struct TemplateReturnTy {};
16
17typedef HostReturnTy (*HostFnPtr)();
18typedef DeviceReturnTy (*DeviceFnPtr)();
19typedef HostDeviceReturnTy (*HostDeviceFnPtr)();
20typedef void (*GlobalFnPtr)(); // __global__ functions must return void.
21
22// CurrentReturnTy is {HostReturnTy,DeviceReturnTy} during {host,device}
23// compilation.
24#ifdef __CUDA_ARCH__
25typedef DeviceReturnTy CurrentReturnTy;
26#else
27typedef HostReturnTy CurrentReturnTy;
28#endif
29
30// CurrentFnPtr is a function pointer to a {host,device} function during
31// {host,device} compilation.
32typedef CurrentReturnTy (*CurrentFnPtr)();
Artem Belevich94a55e82015-09-22 17:22:59 +000033
Justin Lebare82caa32016-03-23 22:42:28 +000034// Host and unattributed functions can't be overloaded.
35__host__ void hh() {} // expected-note {{previous definition is here}}
36void hh() {} // expected-error {{redefinition of 'hh'}}
Artem Belevich94a55e82015-09-22 17:22:59 +000037
Justin Lebare82caa32016-03-23 22:42:28 +000038// H/D overloading is OK.
Justin Lebare5eed042016-03-23 22:42:30 +000039__host__ HostReturnTy dh() { return HostReturnTy(); }
40__device__ DeviceReturnTy dh() { return DeviceReturnTy(); }
Artem Belevich94a55e82015-09-22 17:22:59 +000041
Justin Lebare82caa32016-03-23 22:42:28 +000042// H/HD and D/HD are not allowed.
Artem Belevich13e9b4d2016-12-07 19:27:16 +000043__host__ __device__ int hdh() { return 0; } // expected-note {{previous declaration is here}}
44__host__ int hdh() { return 0; }
45// expected-error@-1 {{__host__ function 'hdh' cannot overload __host__ __device__ function 'hdh'}}
Artem Belevich94a55e82015-09-22 17:22:59 +000046
Artem Belevich13e9b4d2016-12-07 19:27:16 +000047__host__ int hhd() { return 0; } // expected-note {{previous declaration is here}}
48__host__ __device__ int hhd() { return 0; }
49// expected-error@-1 {{__host__ __device__ function 'hhd' cannot overload __host__ function 'hhd'}}
Artem Belevich94a55e82015-09-22 17:22:59 +000050
Artem Belevich13e9b4d2016-12-07 19:27:16 +000051__host__ __device__ int hdd() { return 0; } // expected-note {{previous declaration is here}}
52__device__ int hdd() { return 0; }
53// expected-error@-1 {{__device__ function 'hdd' cannot overload __host__ __device__ function 'hdd'}}
Artem Belevich94a55e82015-09-22 17:22:59 +000054
Artem Belevich13e9b4d2016-12-07 19:27:16 +000055__device__ int dhd() { return 0; } // expected-note {{previous declaration is here}}
56__host__ __device__ int dhd() { return 0; }
57// expected-error@-1 {{__host__ __device__ function 'dhd' cannot overload __device__ function 'dhd'}}
Artem Belevich94a55e82015-09-22 17:22:59 +000058
Justin Lebare82caa32016-03-23 22:42:28 +000059// Same tests for extern "C" functions.
Justin Lebare5eed042016-03-23 22:42:30 +000060extern "C" __host__ int chh() { return 0; } // expected-note {{previous definition is here}}
61extern "C" int chh() { return 0; } // expected-error {{redefinition of 'chh'}}
Artem Belevich94a55e82015-09-22 17:22:59 +000062
Justin Lebare82caa32016-03-23 22:42:28 +000063// H/D overloading is OK.
Justin Lebare5eed042016-03-23 22:42:30 +000064extern "C" __device__ DeviceReturnTy cdh() { return DeviceReturnTy(); }
65extern "C" __host__ HostReturnTy cdh() { return HostReturnTy(); }
Artem Belevich94a55e82015-09-22 17:22:59 +000066
67// H/HD and D/HD overloading is not allowed.
Artem Belevich13e9b4d2016-12-07 19:27:16 +000068extern "C" __host__ __device__ int chhd1() { return 0; } // expected-note {{previous declaration is here}}
69extern "C" __host__ int chhd1() { return 0; }
70// expected-error@-1 {{__host__ function 'chhd1' cannot overload __host__ __device__ function 'chhd1'}}
Artem Belevich94a55e82015-09-22 17:22:59 +000071
Artem Belevich13e9b4d2016-12-07 19:27:16 +000072extern "C" __host__ int chhd2() { return 0; } // expected-note {{previous declaration is here}}
73extern "C" __host__ __device__ int chhd2() { return 0; }
74// expected-error@-1 {{__host__ __device__ function 'chhd2' cannot overload __host__ function 'chhd2'}}
Artem Belevich94a55e82015-09-22 17:22:59 +000075
76// Helper functions to verify calling restrictions.
Justin Lebare5eed042016-03-23 22:42:30 +000077__device__ DeviceReturnTy d() { return DeviceReturnTy(); }
Justin Lebare82caa32016-03-23 22:42:28 +000078// expected-note@-1 1+ {{'d' declared here}}
79// expected-note@-2 1+ {{candidate function not viable: call to __device__ function from __host__ function}}
80// expected-note@-3 0+ {{candidate function not viable: call to __device__ function from __host__ __device__ function}}
Artem Belevich94a55e82015-09-22 17:22:59 +000081
Justin Lebare5eed042016-03-23 22:42:30 +000082__host__ HostReturnTy h() { return HostReturnTy(); }
Justin Lebare82caa32016-03-23 22:42:28 +000083// expected-note@-1 1+ {{'h' declared here}}
84// expected-note@-2 1+ {{candidate function not viable: call to __host__ function from __device__ function}}
85// expected-note@-3 0+ {{candidate function not viable: call to __host__ function from __host__ __device__ function}}
86// expected-note@-4 1+ {{candidate function not viable: call to __host__ function from __global__ function}}
87
88__global__ void g() {}
89// expected-note@-1 1+ {{'g' declared here}}
90// expected-note@-2 1+ {{candidate function not viable: call to __global__ function from __device__ function}}
91// expected-note@-3 0+ {{candidate function not viable: call to __global__ function from __host__ __device__ function}}
92// expected-note@-4 1+ {{candidate function not viable: call to __global__ function from __global__ function}}
93
Justin Lebare5eed042016-03-23 22:42:30 +000094extern "C" __device__ DeviceReturnTy cd() { return DeviceReturnTy(); }
Justin Lebare82caa32016-03-23 22:42:28 +000095// expected-note@-1 1+ {{'cd' declared here}}
96// expected-note@-2 1+ {{candidate function not viable: call to __device__ function from __host__ function}}
97// expected-note@-3 0+ {{candidate function not viable: call to __device__ function from __host__ __device__ function}}
98
Justin Lebare5eed042016-03-23 22:42:30 +000099extern "C" __host__ HostReturnTy ch() { return HostReturnTy(); }
Justin Lebare82caa32016-03-23 22:42:28 +0000100// expected-note@-1 1+ {{'ch' declared here}}
101// expected-note@-2 1+ {{candidate function not viable: call to __host__ function from __device__ function}}
102// expected-note@-3 0+ {{candidate function not viable: call to __host__ function from __host__ __device__ function}}
103// expected-note@-4 1+ {{candidate function not viable: call to __host__ function from __global__ function}}
104
105__host__ void hostf() {
Justin Lebare5eed042016-03-23 22:42:30 +0000106 DeviceFnPtr fp_d = d; // expected-error {{reference to __device__ function 'd' in __host__ function}}
107 DeviceReturnTy ret_d = d(); // expected-error {{no matching function for call to 'd'}}
108 DeviceFnPtr fp_cd = cd; // expected-error {{reference to __device__ function 'cd' in __host__ function}}
109 DeviceReturnTy ret_cd = cd(); // expected-error {{no matching function for call to 'cd'}}
Artem Belevich94a55e82015-09-22 17:22:59 +0000110
Justin Lebare5eed042016-03-23 22:42:30 +0000111 HostFnPtr fp_h = h;
112 HostReturnTy ret_h = h();
113 HostFnPtr fp_ch = ch;
114 HostReturnTy ret_ch = ch();
115
116 HostFnPtr fp_dh = dh;
117 HostReturnTy ret_dh = dh();
118 HostFnPtr fp_cdh = cdh;
119 HostReturnTy ret_cdh = cdh();
120
121 GlobalFnPtr fp_g = g;
Artem Belevich94a55e82015-09-22 17:22:59 +0000122 g(); // expected-error {{call to global function g not configured}}
Justin Lebare5eed042016-03-23 22:42:30 +0000123 g<<<0, 0>>>();
Artem Belevich94a55e82015-09-22 17:22:59 +0000124}
125
Justin Lebare82caa32016-03-23 22:42:28 +0000126__device__ void devicef() {
Justin Lebare5eed042016-03-23 22:42:30 +0000127 DeviceFnPtr fp_d = d;
128 DeviceReturnTy ret_d = d();
129 DeviceFnPtr fp_cd = cd;
130 DeviceReturnTy ret_cd = cd();
Artem Belevich94a55e82015-09-22 17:22:59 +0000131
Justin Lebare5eed042016-03-23 22:42:30 +0000132 HostFnPtr fp_h = h; // expected-error {{reference to __host__ function 'h' in __device__ function}}
133 HostReturnTy ret_h = h(); // expected-error {{no matching function for call to 'h'}}
134 HostFnPtr fp_ch = ch; // expected-error {{reference to __host__ function 'ch' in __device__ function}}
135 HostReturnTy ret_ch = ch(); // expected-error {{no matching function for call to 'ch'}}
136
137 DeviceFnPtr fp_dh = dh;
138 DeviceReturnTy ret_dh = dh();
139 DeviceFnPtr fp_cdh = cdh;
140 DeviceReturnTy ret_cdh = cdh();
141
142 GlobalFnPtr fp_g = g; // expected-error {{reference to __global__ function 'g' in __device__ function}}
Artem Belevich94a55e82015-09-22 17:22:59 +0000143 g(); // expected-error {{no matching function for call to 'g'}}
Artem Belevich94a55e82015-09-22 17:22:59 +0000144 g<<<0,0>>>(); // expected-error {{reference to __global__ function 'g' in __device__ function}}
Artem Belevich94a55e82015-09-22 17:22:59 +0000145}
146
Justin Lebare82caa32016-03-23 22:42:28 +0000147__global__ void globalf() {
Justin Lebare5eed042016-03-23 22:42:30 +0000148 DeviceFnPtr fp_d = d;
149 DeviceReturnTy ret_d = d();
150 DeviceFnPtr fp_cd = cd;
151 DeviceReturnTy ret_cd = cd();
Artem Belevich94a55e82015-09-22 17:22:59 +0000152
Justin Lebare5eed042016-03-23 22:42:30 +0000153 HostFnPtr fp_h = h; // expected-error {{reference to __host__ function 'h' in __global__ function}}
154 HostReturnTy ret_h = h(); // expected-error {{no matching function for call to 'h'}}
155 HostFnPtr fp_ch = ch; // expected-error {{reference to __host__ function 'ch' in __global__ function}}
156 HostReturnTy ret_ch = ch(); // expected-error {{no matching function for call to 'ch'}}
157
158 DeviceFnPtr fp_dh = dh;
159 DeviceReturnTy ret_dh = dh();
160 DeviceFnPtr fp_cdh = cdh;
161 DeviceReturnTy ret_cdh = cdh();
162
163 GlobalFnPtr fp_g = g; // expected-error {{reference to __global__ function 'g' in __global__ function}}
Artem Belevich94a55e82015-09-22 17:22:59 +0000164 g(); // expected-error {{no matching function for call to 'g'}}
Artem Belevich94a55e82015-09-22 17:22:59 +0000165 g<<<0,0>>>(); // expected-error {{reference to __global__ function 'g' in __global__ function}}
Artem Belevich94a55e82015-09-22 17:22:59 +0000166}
167
Justin Lebare82caa32016-03-23 22:42:28 +0000168__host__ __device__ void hostdevicef() {
Justin Lebare5eed042016-03-23 22:42:30 +0000169 DeviceFnPtr fp_d = d;
170 DeviceReturnTy ret_d = d();
171 DeviceFnPtr fp_cd = cd;
172 DeviceReturnTy ret_cd = cd();
Justin Lebar23d95422016-10-13 20:52:12 +0000173#if !defined(__CUDA_ARCH__)
174 // expected-error@-5 {{reference to __device__ function 'd' in __host__ __device__ function}}
175 // expected-error@-5 {{reference to __device__ function 'd' in __host__ __device__ function}}
176 // expected-error@-5 {{reference to __device__ function 'cd' in __host__ __device__ function}}
177 // expected-error@-5 {{reference to __device__ function 'cd' in __host__ __device__ function}}
178#endif
Justin Lebare82caa32016-03-23 22:42:28 +0000179
Justin Lebare5eed042016-03-23 22:42:30 +0000180 HostFnPtr fp_h = h;
181 HostReturnTy ret_h = h();
182 HostFnPtr fp_ch = ch;
183 HostReturnTy ret_ch = ch();
Justin Lebar23d95422016-10-13 20:52:12 +0000184#if defined(__CUDA_ARCH__)
185 // expected-error@-5 {{reference to __host__ function 'h' in __host__ __device__ function}}
186 // expected-error@-5 {{reference to __host__ function 'h' in __host__ __device__ function}}
187 // expected-error@-5 {{reference to __host__ function 'ch' in __host__ __device__ function}}
188 // expected-error@-5 {{reference to __host__ function 'ch' in __host__ __device__ function}}
189#endif
Justin Lebare82caa32016-03-23 22:42:28 +0000190
Justin Lebare5eed042016-03-23 22:42:30 +0000191 CurrentFnPtr fp_dh = dh;
192 CurrentReturnTy ret_dh = dh();
193 CurrentFnPtr fp_cdh = cdh;
194 CurrentReturnTy ret_cdh = cdh();
195
Justin Lebard3fd70d2016-10-19 00:06:49 +0000196 GlobalFnPtr fp_g = g;
197#if defined(__CUDA_ARCH__)
198 // expected-error@-2 {{reference to __global__ function 'g' in __host__ __device__ function}}
199#endif
200
Justin Lebar23d95422016-10-13 20:52:12 +0000201 g();
202#if defined (__CUDA_ARCH__)
203 // expected-error@-2 {{reference to __global__ function 'g' in __host__ __device__ function}}
204#else
205 // expected-error@-4 {{call to global function g not configured}}
206#endif
Justin Lebard3fd70d2016-10-19 00:06:49 +0000207
208 g<<<0,0>>>();
209#if defined(__CUDA_ARCH__)
210 // expected-error@-2 {{reference to __global__ function 'g' in __host__ __device__ function}}
211#endif
Artem Belevich94a55e82015-09-22 17:22:59 +0000212}
213
214// Test for address of overloaded function resolution in the global context.
Justin Lebare5eed042016-03-23 22:42:30 +0000215HostFnPtr fp_h = h;
216HostFnPtr fp_ch = ch;
217CurrentFnPtr fp_dh = dh;
218CurrentFnPtr fp_cdh = cdh;
219GlobalFnPtr fp_g = g;
Artem Belevich94a55e82015-09-22 17:22:59 +0000220
221
222// Test overloading of destructors
223// Can't mix H and unattributed destructors
224struct d_h {
Richard Smith6c7161162017-08-12 01:46:03 +0000225 ~d_h() {} // expected-note {{previous definition is here}}
Artem Belevich94a55e82015-09-22 17:22:59 +0000226 __host__ ~d_h() {} // expected-error {{destructor cannot be redeclared}}
227};
228
Artem Belevich94a55e82015-09-22 17:22:59 +0000229// HD is OK
230struct d_hd {
231 __host__ __device__ ~d_hd() {}
232};
233
Artem Belevich94a55e82015-09-22 17:22:59 +0000234// Test overloading of member functions
235struct m_h {
236 void operator delete(void *ptr); // expected-note {{previous declaration is here}}
237 __host__ void operator delete(void *ptr); // expected-error {{class member cannot be redeclared}}
238};
239
240// D/H overloading is OK
241struct m_dh {
242 __device__ void operator delete(void *ptr);
243 __host__ void operator delete(void *ptr);
244};
245
246// HD by itself is OK
247struct m_hd {
248 __device__ __host__ void operator delete(void *ptr);
249};
250
251struct m_hhd {
252 __host__ void operator delete(void *ptr) {} // expected-note {{previous declaration is here}}
Artem Belevich13e9b4d2016-12-07 19:27:16 +0000253 __host__ __device__ void operator delete(void *ptr) {}
254 // expected-error@-1 {{__host__ __device__ function 'operator delete' cannot overload __host__ function 'operator delete'}}
Artem Belevich94a55e82015-09-22 17:22:59 +0000255};
256
257struct m_hdh {
258 __host__ __device__ void operator delete(void *ptr) {} // expected-note {{previous declaration is here}}
Artem Belevich13e9b4d2016-12-07 19:27:16 +0000259 __host__ void operator delete(void *ptr) {}
260 // expected-error@-1 {{__host__ function 'operator delete' cannot overload __host__ __device__ function 'operator delete'}}
Artem Belevich94a55e82015-09-22 17:22:59 +0000261};
262
263struct m_dhd {
264 __device__ void operator delete(void *ptr) {} // expected-note {{previous declaration is here}}
Artem Belevich13e9b4d2016-12-07 19:27:16 +0000265 __host__ __device__ void operator delete(void *ptr) {}
266 // expected-error@-1 {{__host__ __device__ function 'operator delete' cannot overload __device__ function 'operator delete'}}
Artem Belevich94a55e82015-09-22 17:22:59 +0000267};
268
269struct m_hdd {
270 __host__ __device__ void operator delete(void *ptr) {} // expected-note {{previous declaration is here}}
Artem Belevich13e9b4d2016-12-07 19:27:16 +0000271 __device__ void operator delete(void *ptr) {}
272 // expected-error@-1 {{__device__ function 'operator delete' cannot overload __host__ __device__ function 'operator delete'}}
Artem Belevich94a55e82015-09-22 17:22:59 +0000273};
Artem Belevich1ef9b592016-02-24 21:54:45 +0000274
275// __global__ functions can't be overloaded based on attribute
276// difference.
277struct G {
Artem Belevich13e9b4d2016-12-07 19:27:16 +0000278 friend void friend_of_g(G &arg); // expected-note {{previous declaration is here}}
Artem Belevich1ef9b592016-02-24 21:54:45 +0000279private:
Artem Belevich13e9b4d2016-12-07 19:27:16 +0000280 int x; // expected-note {{declared private here}}
Artem Belevich1ef9b592016-02-24 21:54:45 +0000281};
Artem Belevich13e9b4d2016-12-07 19:27:16 +0000282__global__ void friend_of_g(G &arg) { int x = arg.x; }
283// expected-error@-1 {{__global__ function 'friend_of_g' cannot overload __host__ function 'friend_of_g'}}
284// expected-error@-2 {{'x' is a private member of 'G'}}
285void friend_of_g(G &arg) { int x = arg.x; }
Justin Lebare5eed042016-03-23 22:42:30 +0000286
287// HD functions are sometimes allowed to call H or D functions -- this
288// is an artifact of the source-to-source splitting performed by nvcc
289// that we need to mimic. During device mode compilation in nvcc, host
290// functions aren't present at all, so don't participate in
291// overloading. But in clang, H and D functions are present in both
292// compilation modes. Clang normally uses the target attribute as a
293// tiebreaker between overloads with otherwise identical priority, but
294// in order to match nvcc's behavior, we sometimes need to wholly
295// discard overloads that would not be present during compilation
296// under nvcc.
297
298template <typename T> TemplateReturnTy template_vs_function(T arg) {
299 return TemplateReturnTy();
300}
301__device__ DeviceReturnTy template_vs_function(float arg) {
302 return DeviceReturnTy();
303}
304
305// Here we expect to call the templated function during host compilation, even
306// if -fcuda-disable-target-call-checks is passed, and even though C++ overload
307// rules prefer the non-templated function.
308__host__ __device__ void test_host_device_calls_template(void) {
309#ifdef __CUDA_ARCH__
310 typedef DeviceReturnTy ExpectedReturnTy;
311#else
312 typedef TemplateReturnTy ExpectedReturnTy;
313#endif
314
315 ExpectedReturnTy ret1 = template_vs_function(1.0f);
316 ExpectedReturnTy ret2 = template_vs_function(2.0);
317}
318
319// Calls from __host__ and __device__ functions should always call the
320// overloaded function that matches their mode.
321__host__ void test_host_calls_template_fn() {
322 TemplateReturnTy ret1 = template_vs_function(1.0f);
323 TemplateReturnTy ret2 = template_vs_function(2.0);
324}
325
326__device__ void test_device_calls_template_fn() {
327 DeviceReturnTy ret1 = template_vs_function(1.0f);
328 DeviceReturnTy ret2 = template_vs_function(2.0);
329}
330
331// If we have a mix of HD and H-only or D-only candidates in the overload set,
332// normal C++ overload resolution rules apply first.
Justin Lebar23d95422016-10-13 20:52:12 +0000333template <typename T> TemplateReturnTy template_vs_hd_function(T arg)
334#ifdef __CUDA_ARCH__
335//expected-note@-2 {{declared here}}
336#endif
337{
Justin Lebare5eed042016-03-23 22:42:30 +0000338 return TemplateReturnTy();
339}
340__host__ __device__ HostDeviceReturnTy template_vs_hd_function(float arg) {
341 return HostDeviceReturnTy();
342}
343
344__host__ __device__ void test_host_device_calls_hd_template() {
345 HostDeviceReturnTy ret1 = template_vs_hd_function(1.0f);
Justin Lebar25c4a812016-03-29 16:24:16 +0000346 TemplateReturnTy ret2 = template_vs_hd_function(1);
Justin Lebar23d95422016-10-13 20:52:12 +0000347#ifdef __CUDA_ARCH__
348 // expected-error@-2 {{reference to __host__ function 'template_vs_hd_function<int>' in __host__ __device__ function}}
349#endif
Justin Lebare5eed042016-03-23 22:42:30 +0000350}
351
352__host__ void test_host_calls_hd_template() {
353 HostDeviceReturnTy ret1 = template_vs_hd_function(1.0f);
354 TemplateReturnTy ret2 = template_vs_hd_function(1);
355}
356
357__device__ void test_device_calls_hd_template() {
358 HostDeviceReturnTy ret1 = template_vs_hd_function(1.0f);
359 // Host-only function template is not callable with strict call checks,
360 // so for device side HD function will be the only choice.
361 HostDeviceReturnTy ret2 = template_vs_hd_function(1);
362}
363
364// Check that overloads still work the same way on both host and
365// device side when the overload set contains only functions from one
366// side of compilation.
367__device__ DeviceReturnTy device_only_function(int arg) { return DeviceReturnTy(); }
368__device__ DeviceReturnTy2 device_only_function(float arg) { return DeviceReturnTy2(); }
Justin Lebar23d95422016-10-13 20:52:12 +0000369#ifndef __CUDA_ARCH__
370 // expected-note@-3 {{'device_only_function' declared here}}
371 // expected-note@-3 {{'device_only_function' declared here}}
372#endif
Justin Lebare5eed042016-03-23 22:42:30 +0000373__host__ HostReturnTy host_only_function(int arg) { return HostReturnTy(); }
374__host__ HostReturnTy2 host_only_function(float arg) { return HostReturnTy2(); }
Justin Lebar23d95422016-10-13 20:52:12 +0000375#ifdef __CUDA_ARCH__
376 // expected-note@-3 {{'host_only_function' declared here}}
377 // expected-note@-3 {{'host_only_function' declared here}}
378#endif
Justin Lebare5eed042016-03-23 22:42:30 +0000379
Justin Lebar25c4a812016-03-29 16:24:16 +0000380__host__ __device__ void test_host_device_single_side_overloading() {
Justin Lebare5eed042016-03-23 22:42:30 +0000381 DeviceReturnTy ret1 = device_only_function(1);
382 DeviceReturnTy2 ret2 = device_only_function(1.0f);
Justin Lebar23d95422016-10-13 20:52:12 +0000383#ifndef __CUDA_ARCH__
384 // expected-error@-3 {{reference to __device__ function 'device_only_function' in __host__ __device__ function}}
385 // expected-error@-3 {{reference to __device__ function 'device_only_function' in __host__ __device__ function}}
386#endif
Justin Lebare5eed042016-03-23 22:42:30 +0000387 HostReturnTy ret3 = host_only_function(1);
388 HostReturnTy2 ret4 = host_only_function(1.0f);
Justin Lebar23d95422016-10-13 20:52:12 +0000389#ifdef __CUDA_ARCH__
390 // expected-error@-3 {{reference to __host__ function 'host_only_function' in __host__ __device__ function}}
391 // expected-error@-3 {{reference to __host__ function 'host_only_function' in __host__ __device__ function}}
392#endif
Justin Lebare5eed042016-03-23 22:42:30 +0000393}
Artem Belevichbed18e92016-09-13 22:16:30 +0000394
395// Verify that we allow overloading function templates.
396template <typename T> __host__ T template_overload(const T &a) { return a; };
397template <typename T> __device__ T template_overload(const T &a) { return a; };
398
399__host__ void test_host_template_overload() {
400 template_overload(1); // OK. Attribute-based overloading picks __host__ variant.
401}
402__device__ void test_device_template_overload() {
403 template_overload(1); // OK. Attribute-based overloading picks __device__ variant.
404}