]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - test/SemaCUDA/function-template-overload.cu
Vendor import of clang trunk r290819:
[FreeBSD/FreeBSD.git] / test / SemaCUDA / function-template-overload.cu
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 }