Artem Belevich | 13e9b4d | 2016-12-07 19:27:16 +0000 | [diff] [blame] | 1 | // RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-linux-gnu -fsyntax-only -verify %s |
| 2 | // RUN: %clang_cc1 -std=c++11 -triple nvptx64-nvidia-cuda -fsyntax-only -fcuda-is-device -verify %s |
| 3 | |
| 4 | #include "Inputs/cuda.h" |
| 5 | |
| 6 | struct HType {}; // expected-note-re 6 {{candidate constructor {{.*}} not viable: no known conversion from 'DType'}} |
| 7 | struct DType {}; // expected-note-re 6 {{candidate constructor {{.*}} not viable: no known conversion from 'HType'}} |
| 8 | struct HDType {}; |
| 9 | |
| 10 | template <typename T> __host__ HType overload_h_d(T a) { return HType(); } |
| 11 | // expected-note@-1 2 {{candidate template ignored: could not match 'HType' against 'DType'}} |
| 12 | // expected-note@-2 2 {{candidate template ignored: target attributes do not match}} |
| 13 | template <typename T> __device__ DType overload_h_d(T a) { return DType(); } |
| 14 | // expected-note@-1 2 {{candidate template ignored: could not match 'DType' against 'HType'}} |
| 15 | // expected-note@-2 2 {{candidate template ignored: target attributes do not match}} |
| 16 | |
| 17 | // Check explicit instantiation. |
| 18 | template __device__ __host__ DType overload_h_d(int a); // There's no HD template... |
| 19 | // expected-error@-1 {{explicit instantiation of 'overload_h_d' does not refer to a function template, variable template, member function, member class, or static data member}} |
| 20 | template __device__ __host__ HType overload_h_d(int a); // There's no HD template... |
| 21 | // expected-error@-1 {{explicit instantiation of 'overload_h_d' does not refer to a function template, variable template, member function, member class, or static data member}} |
| 22 | template __device__ DType overload_h_d(int a); // OK. instantiates D |
| 23 | template __host__ HType overload_h_d(int a); // OK. instantiates H |
| 24 | |
| 25 | // Check explicit specialization. |
| 26 | template <> __device__ __host__ DType overload_h_d(long a); // There's no HD template... |
| 27 | // expected-error@-1 {{no function template matches function template specialization 'overload_h_d'}} |
| 28 | template <> __device__ __host__ HType overload_h_d(long a); // There's no HD template... |
| 29 | // expected-error@-1 {{no function template matches function template specialization 'overload_h_d'}} |
| 30 | template <> __device__ DType overload_h_d(long a); // OK. instantiates D |
| 31 | template <> __host__ HType overload_h_d(long a); // OK. instantiates H |
| 32 | |
| 33 | |
| 34 | // Can't overload HD template with H or D template, though functions are OK. |
| 35 | template <typename T> __host__ __device__ HDType overload_hd(T a) { return HDType(); } |
| 36 | // expected-note@-1 {{previous declaration is here}} |
| 37 | // expected-note@-2 2 {{candidate template ignored: could not match 'HDType' against 'HType'}} |
| 38 | template <typename T> __device__ HDType overload_hd(T a); |
| 39 | // expected-error@-1 {{__device__ function 'overload_hd' cannot overload __host__ __device__ function 'overload_hd'}} |
| 40 | __device__ HDType overload_hd(int a); // OK. |
| 41 | |
| 42 | // Verify that target attributes are taken into account when we |
| 43 | // explicitly specialize or instantiate function tempaltes. |
| 44 | template <> __host__ HType overload_hd(int a); |
| 45 | // expected-error@-1 {{no function template matches function template specialization 'overload_hd'}} |
| 46 | template __host__ HType overload_hd(long a); |
| 47 | // expected-error@-1 {{explicit instantiation of 'overload_hd' does not refer to a function template, variable template, member function, member class, or static data member}} |
| 48 | __host__ HType overload_hd(int a); // OK |
| 49 | |
| 50 | template <typename T> __host__ T overload_h(T a); // expected-note {{previous declaration is here}} |
| 51 | template <typename T> __host__ __device__ T overload_h(T a); |
| 52 | // expected-error@-1 {{__host__ __device__ function 'overload_h' cannot overload __host__ function 'overload_h'}} |
| 53 | template <typename T> __device__ T overload_h(T a); // OK. D can overload H. |
| 54 | |
| 55 | template <typename T> __host__ HType overload_h_d2(T a) { return HType(); } |
| 56 | template <typename T> __host__ __device__ HDType overload_h_d2(T a) { return HDType(); } |
| 57 | template <typename T1, typename T2 = int> __device__ DType overload_h_d2(T1 a) { T1 x; T2 y; return DType(); } |
| 58 | |
| 59 | __host__ void hf() { |
| 60 | overload_hd(13); |
| 61 | |
| 62 | HType h = overload_h_d(10); |
| 63 | HType h2i = overload_h_d2<int>(11); |
| 64 | HType h2ii = overload_h_d2<int>(12); |
| 65 | |
| 66 | // These should be implicitly instantiated from __host__ template returning HType. |
| 67 | DType d = overload_h_d(20); // expected-error {{no viable conversion from 'HType' to 'DType'}} |
| 68 | DType d2i = overload_h_d2<int>(21); // expected-error {{no viable conversion from 'HType' to 'DType'}} |
| 69 | DType d2ii = overload_h_d2<int>(22); // expected-error {{no viable conversion from 'HType' to 'DType'}} |
| 70 | } |
| 71 | __device__ void df() { |
| 72 | overload_hd(23); |
| 73 | |
| 74 | // These should be implicitly instantiated from __device__ template returning DType. |
| 75 | HType h = overload_h_d(10); // expected-error {{no viable conversion from 'DType' to 'HType'}} |
| 76 | HType h2i = overload_h_d2<int>(11); // expected-error {{no viable conversion from 'DType' to 'HType'}} |
| 77 | HType h2ii = overload_h_d2<int>(12); // expected-error {{no viable conversion from 'DType' to 'HType'}} |
| 78 | |
| 79 | DType d = overload_h_d(20); |
| 80 | DType d2i = overload_h_d2<int>(21); |
| 81 | DType d2ii = overload_h_d2<int>(22); |
| 82 | } |