1*67e74705SXin Li // RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify -isystem %S/Inputs %s 2*67e74705SXin Li // RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify -isystem %S/Inputs %s -fcuda-is-device 3*67e74705SXin Li 4*67e74705SXin Li #include "Inputs/cuda.h" 5*67e74705SXin Li 6*67e74705SXin Li // Declares one function and pulls it into namespace ns: 7*67e74705SXin Li // 8*67e74705SXin Li // __device__ int OverloadMe(); 9*67e74705SXin Li // namespace ns { using ::OverloadMe; } 10*67e74705SXin Li // 11*67e74705SXin Li // Clang cares that this is done in a system header. 12*67e74705SXin Li #include <overload.h> 13*67e74705SXin Li 14*67e74705SXin Li // Opaque type used to determine which overload we're invoking. 15*67e74705SXin Li struct HostReturnTy {}; 16*67e74705SXin Li 17*67e74705SXin Li // These shouldn't become host+device because they already have attributes. HostOnly()18*67e74705SXin Li__host__ constexpr int HostOnly() { return 0; } 19*67e74705SXin Li // expected-note@-1 0+ {{not viable}} DeviceOnly()20*67e74705SXin Li__device__ constexpr int DeviceOnly() { return 0; } 21*67e74705SXin Li // expected-note@-1 0+ {{not viable}} 22*67e74705SXin Li HostDevice()23*67e74705SXin Liconstexpr int HostDevice() { return 0; } 24*67e74705SXin Li 25*67e74705SXin Li // This should be a host-only function, because there's a previous __device__ 26*67e74705SXin Li // overload in <overload.h>. OverloadMe()27*67e74705SXin Liconstexpr HostReturnTy OverloadMe() { return HostReturnTy(); } 28*67e74705SXin Li 29*67e74705SXin Li namespace ns { 30*67e74705SXin Li // The "using" statement in overload.h should prevent OverloadMe from being 31*67e74705SXin Li // implicitly host+device. OverloadMe()32*67e74705SXin Liconstexpr HostReturnTy OverloadMe() { return HostReturnTy(); } 33*67e74705SXin Li } // namespace ns 34*67e74705SXin Li 35*67e74705SXin Li // This is an error, because NonSysHdrOverload was not defined in a system 36*67e74705SXin Li // header. NonSysHdrOverload()37*67e74705SXin Li__device__ int NonSysHdrOverload() { return 0; } 38*67e74705SXin Li // expected-note@-1 {{conflicting __device__ function declared here}} NonSysHdrOverload()39*67e74705SXin Liconstexpr int NonSysHdrOverload() { return 0; } 40*67e74705SXin Li // expected-error@-1 {{constexpr function 'NonSysHdrOverload' without __host__ or __device__ attributes}} 41*67e74705SXin Li 42*67e74705SXin Li // Variadic device functions are not allowed, so this is just treated as 43*67e74705SXin Li // host-only. 44*67e74705SXin Li constexpr void Variadic(const char*, ...); 45*67e74705SXin Li // expected-note@-1 {{call to __host__ function from __device__ function}} 46*67e74705SXin Li HostFn()47*67e74705SXin Li__host__ void HostFn() { 48*67e74705SXin Li HostOnly(); 49*67e74705SXin Li DeviceOnly(); // expected-error {{no matching function}} 50*67e74705SXin Li HostReturnTy x = OverloadMe(); 51*67e74705SXin Li HostReturnTy y = ns::OverloadMe(); 52*67e74705SXin Li Variadic("abc", 42); 53*67e74705SXin Li } 54*67e74705SXin Li DeviceFn()55*67e74705SXin Li__device__ void DeviceFn() { 56*67e74705SXin Li HostOnly(); // expected-error {{no matching function}} 57*67e74705SXin Li DeviceOnly(); 58*67e74705SXin Li int x = OverloadMe(); 59*67e74705SXin Li int y = ns::OverloadMe(); 60*67e74705SXin Li Variadic("abc", 42); // expected-error {{no matching function}} 61*67e74705SXin Li } 62*67e74705SXin Li HostDeviceFn()63*67e74705SXin Li__host__ __device__ void HostDeviceFn() { 64*67e74705SXin Li #ifdef __CUDA_ARCH__ 65*67e74705SXin Li int y = OverloadMe(); 66*67e74705SXin Li #else 67*67e74705SXin Li constexpr HostReturnTy y = OverloadMe(); 68*67e74705SXin Li #endif 69*67e74705SXin Li } 70