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