| // RUN: %clang_cc1 -std=c++11 -fcuda-is-device -verify -fsyntax-only -verify-ignore-unexpected=warning -verify-ignore-unexpected=note %s |
| // RUN: %clang_cc1 -std=c++11 -verify -fsyntax-only -verify-ignore-unexpected=warning -verify-ignore-unexpected=note %s |
| |
| #include "Inputs/cuda.h" |
| |
| __device__ void device_fn() { |
| auto f1 = [&] {}; |
| f1(); // implicitly __device__ |
| |
| auto f2 = [&] __device__ {}; |
| f2(); |
| |
| auto f3 = [&] __host__ {}; |
| f3(); // expected-error {{no matching function}} |
| |
| auto f4 = [&] __host__ __device__ {}; |
| f4(); |
| |
| // Now do it all again with '()'s in the lambda declarations: This is a |
| // different parse path. |
| auto g1 = [&]() {}; |
| g1(); // implicitly __device__ |
| |
| auto g2 = [&]() __device__ {}; |
| g2(); |
| |
| auto g3 = [&]() __host__ {}; |
| g3(); // expected-error {{no matching function}} |
| |
| auto g4 = [&]() __host__ __device__ {}; |
| g4(); |
| |
| // Once more, with the '()'s in a different place. |
| auto h1 = [&]() {}; |
| h1(); // implicitly __device__ |
| |
| auto h2 = [&] __device__ () {}; |
| h2(); |
| |
| auto h3 = [&] __host__ () {}; |
| h3(); // expected-error {{no matching function}} |
| |
| auto h4 = [&] __host__ __device__ () {}; |
| h4(); |
| } |
| |
| // Behaves identically to device_fn. |
| __global__ void kernel_fn() { |
| auto f1 = [&] {}; |
| f1(); // implicitly __device__ |
| |
| auto f2 = [&] __device__ {}; |
| f2(); |
| |
| auto f3 = [&] __host__ {}; |
| f3(); // expected-error {{no matching function}} |
| |
| auto f4 = [&] __host__ __device__ {}; |
| f4(); |
| |
| // No need to re-test all the parser contortions we test in the device |
| // function. |
| } |
| |
| __host__ void host_fn() { |
| auto f1 = [&] {}; |
| f1(); // implicitly __host__ (i.e., no magic) |
| |
| auto f2 = [&] __device__ {}; |
| f2(); // expected-error {{no matching function}} |
| |
| auto f3 = [&] __host__ {}; |
| f3(); |
| |
| auto f4 = [&] __host__ __device__ {}; |
| f4(); |
| } |
| |
| __host__ __device__ void hd_fn() { |
| auto f1 = [&] {}; |
| f1(); // implicitly __host__ __device__ |
| |
| auto f2 = [&] __device__ {}; |
| f2(); |
| #ifndef __CUDA_ARCH__ |
| // expected-error@-2 {{reference to __device__ function}} |
| #endif |
| |
| auto f3 = [&] __host__ {}; |
| f3(); |
| #ifdef __CUDA_ARCH__ |
| // expected-error@-2 {{reference to __host__ function}} |
| #endif |
| |
| auto f4 = [&] __host__ __device__ {}; |
| f4(); |
| } |
| |
| // The special treatment above only applies to lambdas. |
| __device__ void foo() { |
| struct X { |
| void foo() {} |
| }; |
| X x; |
| x.foo(); // expected-error {{reference to __host__ function 'foo' in __device__ function}} |
| } |