1 | // RUN: %clang_cc1 -fsyntax-only -verify %s |
2 | template<typename T> |
3 | class X { |
4 | public: |
5 | void f(T x); // expected-error{{argument may not have 'void' type}} |
6 | void g(T*); |
7 | |
8 | static int h(T, T); // expected-error {{argument may not have 'void' type}} |
9 | }; |
10 | |
11 | int identity(int x) { return x; } |
12 | |
13 | void test(X<int> *xi, int *ip, X<int(int)> *xf) { |
14 | xi->f(17); |
15 | xi->g(ip); |
16 | xf->f(&identity); |
17 | xf->g(identity); |
18 | X<int>::h(17, 25); |
19 | X<int(int)>::h(identity, &identity); |
20 | } |
21 | |
22 | void test_bad() { |
23 | X<void> xv; // expected-note{{in instantiation of template class 'X<void>' requested here}} |
24 | } |
25 | |
26 | template<typename T, typename U> |
27 | class Overloading { |
28 | public: |
29 | int& f(T, T); // expected-note{{previous declaration is here}} |
30 | float& f(T, U); // expected-error{{functions that differ only in their return type cannot be overloaded}} |
31 | }; |
32 | |
33 | void test_ovl(Overloading<int, long> *oil, int i, long l) { |
34 | int &ir = oil->f(i, i); |
35 | float &fr = oil->f(i, l); |
36 | } |
37 | |
38 | void test_ovl_bad() { |
39 | Overloading<float, float> off; // expected-note{{in instantiation of template class 'Overloading<float, float>' requested here}} |
40 | } |
41 | |
42 | template<typename T> |
43 | class HasDestructor { |
44 | public: |
45 | virtual ~HasDestructor() = 0; |
46 | }; |
47 | |
48 | int i = sizeof(HasDestructor<int>); // FIXME: forces instantiation, but |
49 | // the code below should probably instantiate by itself. |
50 | int abstract_destructor[__is_abstract(HasDestructor<int>)? 1 : -1]; |
51 | |
52 | |
53 | template<typename T> |
54 | class Constructors { |
55 | public: |
56 | Constructors(const T&); |
57 | Constructors(const Constructors &other); |
58 | }; |
59 | |
60 | void test_constructors() { |
61 | Constructors<int> ci1(17); |
62 | Constructors<int> ci2 = ci1; |
63 | } |
64 | |
65 | |
66 | template<typename T> |
67 | struct ConvertsTo { |
68 | operator T(); |
69 | }; |
70 | |
71 | void test_converts_to(ConvertsTo<int> ci, ConvertsTo<int *> cip) { |
72 | int i = ci; |
73 | int *ip = cip; |
74 | } |
75 | |
76 | // PR4660 |
77 | template<class T> struct A0 { operator T*(); }; |
78 | template<class T> struct A1; |
79 | |
80 | int *a(A0<int> &x0, A1<int> &x1) { |
81 | int *y0 = x0; |
82 | int *y1 = x1; // expected-error{{no viable conversion}} |
83 | } |
84 | |
85 | struct X0Base { |
86 | int &f(); |
87 | int& g(int); |
88 | static double &g(double); |
89 | }; |
90 | |
91 | template<typename T> |
92 | struct X0 : X0Base { |
93 | }; |
94 | |
95 | template<typename U> |
96 | struct X1 : X0<U> { |
97 | int &f2() { |
98 | return X0Base::f(); |
99 | } |
100 | }; |
101 | |
102 | void test_X1(X1<int> x1i) { |
103 | int &ir = x1i.f2(); |
104 | } |
105 | |
106 | template<typename U> |
107 | struct X2 : X0Base, U { |
108 | int &f2() { return X0Base::f(); } |
109 | }; |
110 | |
111 | template<typename T> |
112 | struct X3 { |
113 | void test(T x) { |
114 | double& d1 = X0Base::g(x); |
115 | } |
116 | }; |
117 | |
118 | |
119 | template struct X3<double>; |
120 | |
121 | // Don't try to instantiate this, it's invalid. |
122 | namespace test1 { |
123 | template <class T> class A {}; |
124 | template <class T> class B { |
125 | void foo(A<test1::Undeclared> &a) // expected-error {{no member named 'Undeclared' in namespace 'test1'}} |
126 | {} |
127 | }; |
128 | template class B<int>; |
129 | } |
130 | |
131 | namespace PR6947 { |
132 | template< class T > |
133 | struct X { |
134 | int f0( ) |
135 | { |
136 | typedef void ( X::*impl_fun_ptr )( ); |
137 | impl_fun_ptr pImpl = &X::template |
138 | f0_impl1<int>; |
139 | } |
140 | private: |
141 | int f1() { |
142 | } |
143 | template< class Processor> |
144 | void f0_impl1( ) |
145 | { |
146 | } |
147 | }; |
148 | |
149 | char g0() { |
150 | X<int> pc; |
151 | pc.f0(); |
152 | } |
153 | |
154 | } |
155 | |
156 | namespace PR7022 { |
157 | template <typename > |
158 | struct X1 |
159 | { |
160 | typedef int state_t( ); |
161 | state_t g ; |
162 | }; |
163 | |
164 | template < typename U = X1<int> > struct X2 |
165 | { |
166 | X2( U = U()) |
167 | { |
168 | } |
169 | }; |
170 | |
171 | void m(void) |
172 | { |
173 | typedef X2<> X2_type; |
174 | X2_type c; |
175 | } |
176 | } |
177 | |
178 | namespace SameSignatureAfterInstantiation { |
179 | template<typename T> struct S { |
180 | void f(T *); // expected-note {{previous}} |
181 | void f(const T*); // expected-error-re {{multiple overloads of 'f' instantiate to the same signature 'void (const int *){{( __attribute__\(\(thiscall\)\))?}}'}} |
182 | }; |
183 | S<const int> s; // expected-note {{instantiation}} |
184 | } |
185 | |
186 | namespace PR22040 { |
187 | template <typename T> struct Foobar { |
188 | template <> void bazqux(typename T::type) {} // expected-error 2{{cannot be used prior to '::' because it has no members}} |
189 | }; |
190 | |
191 | void test() { |
192 | // FIXME: we should suppress the "no member" errors |
193 | Foobar<void>::bazqux(); // expected-error{{no member named 'bazqux' in }} expected-note{{in instantiation of template class }} |
194 | Foobar<int>::bazqux(); // expected-error{{no member named 'bazqux' in }} expected-note{{in instantiation of template class }} |
195 | Foobar<int>::bazqux(3); // expected-error{{no member named 'bazqux' in }} |
196 | } |
197 | } |
198 | |
199 | template <typename> |
200 | struct SpecializationOfGlobalFnInClassScope { |
201 | template <> |
202 | void ::Fn(); // expected-error{{cannot have a qualified name}} |
203 | }; |
204 | |
205 | class AbstractClassWithGlobalFn { |
206 | template <typename> |
207 | void ::f(); // expected-error{{cannot have a qualified name}} |
208 | virtual void f1() = 0; |
209 | }; |
210 | |