host-device-constexpr.cu 2.5 KB

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