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 35 // non-template functions are OK. 36 template <typename T> __host__ __device__ HDType overload_hd(T a) { return HDType(); } 37 // expected-note@-1 {{previous declaration is here}} 38 // expected-note@-2 2 {{candidate template ignored: could not match 'HDType' against 'HType'}} 39 template <typename T> __device__ HDType overload_hd(T a); 40 // expected-error@-1 {{__device__ function 'overload_hd' cannot overload __host__ __device__ function 'overload_hd'}} 41 __device__ HDType overload_hd(int a); // OK. 42 43 // Verify that target attributes are taken into account when we 44 // explicitly specialize or instantiate function tempaltes. 45 template <> __host__ HType overload_hd(int a); 46 // expected-error@-1 {{no function template matches function template specialization 'overload_hd'}} 47 template __host__ HType overload_hd(long a); 48 // 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}} 49 __host__ HType overload_hd(int a); // OK 50 51 template <typename T> __host__ T overload_h(T a); // expected-note {{previous declaration is here}} 52 template <typename T> __host__ __device__ T overload_h(T a); 53 // expected-error@-1 {{__host__ __device__ function 'overload_h' cannot overload __host__ function 'overload_h'}} 54 template <typename T> __device__ T overload_h(T a); // OK. D can overload H. 55 56 template <typename T> __host__ HType overload_h_d2(T a) { return HType(); } 57 template <typename T> __host__ __device__ HDType overload_h_d2(T a) { return HDType(); } 58 template <typename T1, typename T2 = int> __device__ DType overload_h_d2(T1 a) { T1 x; T2 y; return DType(); } 59 60 // constexpr functions are implicitly HD, but explicit 61 // instantiation/specialization must use target attributes as written. 62 template <typename T> constexpr T overload_ce_implicit_hd(T a) { return a+1; } 63 // expected-note@-1 3 {{candidate template ignored: target attributes do not match}} 64 65 // These will not match the template. 66 template __host__ __device__ int overload_ce_implicit_hd(int a); 67 // expected-error@-1 {{explicit instantiation of 'overload_ce_implicit_hd' does not refer to a function template, variable template, member function, member class, or static data member}} 68 template <> __host__ __device__ long overload_ce_implicit_hd(long a); 69 // expected-error@-1 {{no function template matches function template specialization 'overload_ce_implicit_hd'}} 70 template <> __host__ __device__ constexpr long overload_ce_implicit_hd(long a); 71 // expected-error@-1 {{no function template matches function template specialization 'overload_ce_implicit_hd'}} 72 73 // These should work, because template matching ignores the implicit 74 // HD attributes the compiler gives to constexpr functions/templates, 75 // so 'overload_ce_implicit_hd' template will match __host__ functions 76 // only. 77 template __host__ int overload_ce_implicit_hd(int a); 78 template <> __host__ long overload_ce_implicit_hd(long a); 79 80 template float overload_ce_implicit_hd(float a); 81 template <> float* overload_ce_implicit_hd(float *a); 82 template <> constexpr double overload_ce_implicit_hd(double a) { return a + 3.0; }; 83 84 __host__ void hf() { 85 overload_hd(13); 86 overload_ce_implicit_hd('h'); // Implicitly instantiated 87 overload_ce_implicit_hd(1.0f); // Explicitly instantiated 88 overload_ce_implicit_hd(2.0); // Explicitly specialized 89 90 HType h = overload_h_d(10); 91 HType h2i = overload_h_d2<int>(11); 92 HType h2ii = overload_h_d2<int>(12); 93 94 // These should be implicitly instantiated from __host__ template returning HType. 95 DType d = overload_h_d(20); // expected-error {{no viable conversion from 'HType' to 'DType'}} 96 DType d2i = overload_h_d2<int>(21); // expected-error {{no viable conversion from 'HType' to 'DType'}} 97 DType d2ii = overload_h_d2<int>(22); // expected-error {{no viable conversion from 'HType' to 'DType'}} 98 } 99 __device__ void df() { 100 overload_hd(23); 101 overload_ce_implicit_hd('d'); // Implicitly instantiated 102 overload_ce_implicit_hd(1.0f); // Explicitly instantiated 103 overload_ce_implicit_hd(2.0); // Explicitly specialized 104 105 // These should be implicitly instantiated from __device__ template returning DType. 106 HType h = overload_h_d(10); // expected-error {{no viable conversion from 'DType' to 'HType'}} 107 HType h2i = overload_h_d2<int>(11); // expected-error {{no viable conversion from 'DType' to 'HType'}} 108 HType h2ii = overload_h_d2<int>(12); // expected-error {{no viable conversion from 'DType' to 'HType'}} 109 110 DType d = overload_h_d(20); 111 DType d2i = overload_h_d2<int>(21); 112 DType d2ii = overload_h_d2<int>(22); 113 } 114