Justin Lebar | 20614e0 | 2016-09-30 20:17:37 +0000 | [diff] [blame] | 1 | // RUN: %clang_cc1 -std=c++11 -fcuda-is-device -verify -fsyntax-only -verify-ignore-unexpected=warning -verify-ignore-unexpected=note %s |
| 2 | // RUN: %clang_cc1 -std=c++11 -verify -fsyntax-only -verify-ignore-unexpected=warning -verify-ignore-unexpected=note %s |
Justin Lebar | 7ca116c | 2016-09-30 17:14:53 +0000 | [diff] [blame] | 3 | |
| 4 | #include "Inputs/cuda.h" |
| 5 | |
| 6 | __device__ void device_fn() { |
| 7 | auto f1 = [&] {}; |
| 8 | f1(); // implicitly __device__ |
| 9 | |
| 10 | auto f2 = [&] __device__ {}; |
| 11 | f2(); |
| 12 | |
| 13 | auto f3 = [&] __host__ {}; |
| 14 | f3(); // expected-error {{no matching function}} |
| 15 | |
| 16 | auto f4 = [&] __host__ __device__ {}; |
| 17 | f4(); |
| 18 | |
| 19 | // Now do it all again with '()'s in the lambda declarations: This is a |
| 20 | // different parse path. |
| 21 | auto g1 = [&]() {}; |
| 22 | g1(); // implicitly __device__ |
| 23 | |
| 24 | auto g2 = [&]() __device__ {}; |
| 25 | g2(); |
| 26 | |
| 27 | auto g3 = [&]() __host__ {}; |
| 28 | g3(); // expected-error {{no matching function}} |
| 29 | |
| 30 | auto g4 = [&]() __host__ __device__ {}; |
| 31 | g4(); |
| 32 | |
| 33 | // Once more, with the '()'s in a different place. |
| 34 | auto h1 = [&]() {}; |
| 35 | h1(); // implicitly __device__ |
| 36 | |
| 37 | auto h2 = [&] __device__ () {}; |
| 38 | h2(); |
| 39 | |
| 40 | auto h3 = [&] __host__ () {}; |
| 41 | h3(); // expected-error {{no matching function}} |
| 42 | |
| 43 | auto h4 = [&] __host__ __device__ () {}; |
| 44 | h4(); |
| 45 | } |
| 46 | |
| 47 | // Behaves identically to device_fn. |
| 48 | __global__ void kernel_fn() { |
| 49 | auto f1 = [&] {}; |
| 50 | f1(); // implicitly __device__ |
| 51 | |
| 52 | auto f2 = [&] __device__ {}; |
| 53 | f2(); |
| 54 | |
| 55 | auto f3 = [&] __host__ {}; |
| 56 | f3(); // expected-error {{no matching function}} |
| 57 | |
| 58 | auto f4 = [&] __host__ __device__ {}; |
| 59 | f4(); |
| 60 | |
| 61 | // No need to re-test all the parser contortions we test in the device |
| 62 | // function. |
| 63 | } |
| 64 | |
| 65 | __host__ void host_fn() { |
| 66 | auto f1 = [&] {}; |
| 67 | f1(); // implicitly __host__ (i.e., no magic) |
| 68 | |
| 69 | auto f2 = [&] __device__ {}; |
| 70 | f2(); // expected-error {{no matching function}} |
| 71 | |
| 72 | auto f3 = [&] __host__ {}; |
| 73 | f3(); |
| 74 | |
| 75 | auto f4 = [&] __host__ __device__ {}; |
| 76 | f4(); |
| 77 | } |
| 78 | |
Justin Lebar | d3fd70d | 2016-10-19 00:06:49 +0000 | [diff] [blame] | 79 | __host__ __device__ void hd_fn() { |
| 80 | auto f1 = [&] {}; |
| 81 | f1(); // implicitly __host__ __device__ |
| 82 | |
| 83 | auto f2 = [&] __device__ {}; |
| 84 | f2(); |
| 85 | #ifndef __CUDA_ARCH__ |
| 86 | // expected-error@-2 {{reference to __device__ function}} |
| 87 | #endif |
| 88 | |
| 89 | auto f3 = [&] __host__ {}; |
| 90 | f3(); |
| 91 | #ifdef __CUDA_ARCH__ |
| 92 | // expected-error@-2 {{reference to __host__ function}} |
| 93 | #endif |
| 94 | |
| 95 | auto f4 = [&] __host__ __device__ {}; |
| 96 | f4(); |
| 97 | } |
| 98 | |
Justin Lebar | 7ca116c | 2016-09-30 17:14:53 +0000 | [diff] [blame] | 99 | // The special treatment above only applies to lambdas. |
| 100 | __device__ void foo() { |
| 101 | struct X { |
| 102 | void foo() {} |
| 103 | }; |
| 104 | X x; |
| 105 | x.foo(); // expected-error {{reference to __host__ function 'foo' in __device__ function}} |
| 106 | } |