1 | // RUN: %clang_cc1 -fsyntax-only -verify %s |
2 | struct A { |
3 | template <class T> operator T*(); |
4 | }; |
5 | |
6 | template <class T> A::operator T*() { return 0; } |
7 | template <> A::operator char*(){ return 0; } // specialization |
8 | template A::operator void*(); // explicit instantiation |
9 | |
10 | int main() { |
11 | A a; |
12 | int *ip; |
13 | ip = a.operator int*(); |
14 | } |
15 | |
16 | // PR5742 |
17 | namespace PR5742 { |
18 | template <class T> struct A { }; |
19 | template <class T> struct B { }; |
20 | |
21 | struct S { |
22 | template <class T> operator T(); |
23 | } s; |
24 | |
25 | void f() { |
26 | s.operator A<A<int> >(); |
27 | s.operator A<B<int> >(); |
28 | s.operator A<B<A<int> > >(); |
29 | } |
30 | } |
31 | |
32 | // PR5762 |
33 | class Foo { |
34 | public: |
35 | template <typename T> operator T(); |
36 | |
37 | template <typename T> |
38 | T As() { |
39 | return this->operator T(); |
40 | } |
41 | |
42 | template <typename T> |
43 | T As2() { |
44 | return operator T(); |
45 | } |
46 | |
47 | int AsInt() { |
48 | return this->operator int(); |
49 | } |
50 | }; |
51 | |
52 | template float Foo::As(); |
53 | template double Foo::As2(); |
54 | |
55 | // Partial ordering with conversion function templates. |
56 | struct X0 { |
57 | template<typename T> operator T*() { |
58 | T x = 1; // expected-note{{variable 'x' declared const here}} |
59 | x = 17; // expected-error{{cannot assign to variable 'x' with const-qualified type 'const int'}} |
60 | } |
61 | |
62 | template<typename T> operator T*() const; // expected-note{{explicit instantiation refers here}} |
63 | |
64 | template<typename T> operator const T*() const { |
65 | T x = T(); |
66 | return x; // expected-error{{cannot initialize return object of type 'const char *' with an lvalue of type 'char'}} \ |
67 | // expected-error{{cannot initialize return object of type 'const int *' with an lvalue of type 'int'}} |
68 | } |
69 | }; |
70 | |
71 | template X0::operator const char*() const; // expected-note{{'X0::operator const char *<char>' requested here}} |
72 | template X0::operator const int*(); // expected-note{{'X0::operator const int *<const int>' requested here}} |
73 | template X0::operator float*() const; // expected-error{{explicit instantiation of undefined function template}} |
74 | |
75 | void test_X0(X0 x0, const X0 &x0c) { |
76 | x0.operator const int*(); // expected-note{{in instantiation of function template specialization}} |
77 | x0.operator float *(); |
78 | x0c.operator const char*(); |
79 | } |
80 | |
81 | namespace PR14211 { |
82 | template <class U> struct X { |
83 | void foo(U){} |
84 | template <class T> void foo(T){} |
85 | |
86 | template <class T> void bar(T){} |
87 | void bar(U){} |
88 | }; |
89 | |
90 | template void X<int>::foo(int); |
91 | template void X<int>::bar(int); |
92 | } |
93 | |