blob: 8adeb849570b983fd91c1dcc0b4584ce1ce52e37 [file] [log] [blame]
Artem Belevich13e9b4d2016-12-07 19:27:16 +00001// 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
6struct HType {}; // expected-note-re 6 {{candidate constructor {{.*}} not viable: no known conversion from 'DType'}}
7struct DType {}; // expected-note-re 6 {{candidate constructor {{.*}} not viable: no known conversion from 'HType'}}
8struct HDType {};
9
10template <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}}
13template <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.
18template __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}}
20template __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}}
22template __device__ DType overload_h_d(int a); // OK. instantiates D
23template __host__ HType overload_h_d(int a); // OK. instantiates H
24
25// Check explicit specialization.
26template <> __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'}}
28template <> __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'}}
30template <> __device__ DType overload_h_d(long a); // OK. instantiates D
31template <> __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.
35template <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'}}
38template <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.
44template <> __host__ HType overload_hd(int a);
45// expected-error@-1 {{no function template matches function template specialization 'overload_hd'}}
46template __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
50template <typename T> __host__ T overload_h(T a); // expected-note {{previous declaration is here}}
51template <typename T> __host__ __device__ T overload_h(T a);
52// expected-error@-1 {{__host__ __device__ function 'overload_h' cannot overload __host__ function 'overload_h'}}
53template <typename T> __device__ T overload_h(T a); // OK. D can overload H.
54
55template <typename T> __host__ HType overload_h_d2(T a) { return HType(); }
56template <typename T> __host__ __device__ HDType overload_h_d2(T a) { return HDType(); }
57template <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}