75 lines
2.5 KiB
Plaintext
75 lines
2.5 KiB
Plaintext
|
// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify -isystem %S/Inputs %s
|
||
|
// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify -isystem %S/Inputs %s \
|
||
|
// RUN: -fcuda-is-device
|
||
|
// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify -isystem %S/Inputs \
|
||
|
// RUN: -fopenmp %s
|
||
|
// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify -isystem %S/Inputs \
|
||
|
// RUN: -fopenmp %s -fcuda-is-device
|
||
|
|
||
|
#include "Inputs/cuda.h"
|
||
|
|
||
|
// Declares one function and pulls it into namespace ns:
|
||
|
//
|
||
|
// __device__ int OverloadMe();
|
||
|
// namespace ns { using ::OverloadMe; }
|
||
|
//
|
||
|
// Clang cares that this is done in a system header.
|
||
|
#include <overload.h>
|
||
|
|
||
|
// Opaque type used to determine which overload we're invoking.
|
||
|
struct HostReturnTy {};
|
||
|
|
||
|
// These shouldn't become host+device because they already have attributes.
|
||
|
__host__ constexpr int HostOnly() { return 0; }
|
||
|
// expected-note@-1 0+ {{not viable}}
|
||
|
__device__ constexpr int DeviceOnly() { return 0; }
|
||
|
// expected-note@-1 0+ {{not viable}}
|
||
|
|
||
|
constexpr int HostDevice() { return 0; }
|
||
|
|
||
|
// This should be a host-only function, because there's a previous __device__
|
||
|
// overload in <overload.h>.
|
||
|
constexpr HostReturnTy OverloadMe() { return HostReturnTy(); }
|
||
|
|
||
|
namespace ns {
|
||
|
// The "using" statement in overload.h should prevent OverloadMe from being
|
||
|
// implicitly host+device.
|
||
|
constexpr HostReturnTy OverloadMe() { return HostReturnTy(); }
|
||
|
} // namespace ns
|
||
|
|
||
|
// This is an error, because NonSysHdrOverload was not defined in a system
|
||
|
// header.
|
||
|
__device__ int NonSysHdrOverload() { return 0; }
|
||
|
// expected-note@-1 {{conflicting __device__ function declared here}}
|
||
|
constexpr int NonSysHdrOverload() { return 0; }
|
||
|
// expected-error@-1 {{constexpr function 'NonSysHdrOverload' without __host__ or __device__ attributes}}
|
||
|
|
||
|
// Variadic device functions are not allowed, so this is just treated as
|
||
|
// host-only.
|
||
|
constexpr void Variadic(const char*, ...);
|
||
|
// expected-note@-1 {{call to __host__ function from __device__ function}}
|
||
|
|
||
|
__host__ void HostFn() {
|
||
|
HostOnly();
|
||
|
DeviceOnly(); // expected-error {{no matching function}}
|
||
|
HostReturnTy x = OverloadMe();
|
||
|
HostReturnTy y = ns::OverloadMe();
|
||
|
Variadic("abc", 42);
|
||
|
}
|
||
|
|
||
|
__device__ void DeviceFn() {
|
||
|
HostOnly(); // expected-error {{no matching function}}
|
||
|
DeviceOnly();
|
||
|
int x = OverloadMe();
|
||
|
int y = ns::OverloadMe();
|
||
|
Variadic("abc", 42); // expected-error {{no matching function}}
|
||
|
}
|
||
|
|
||
|
__host__ __device__ void HostDeviceFn() {
|
||
|
#ifdef __CUDA_ARCH__
|
||
|
int y = OverloadMe();
|
||
|
#else
|
||
|
constexpr HostReturnTy y = OverloadMe();
|
||
|
#endif
|
||
|
}
|