1// RUN: %clang_cc1 -fsyntax-only -verify %s
2
3template<typename T>
4struct X0 {
5  template<typename U> T f0(U);
6  template<typename U> U& f1(T*, U); // expected-error{{pointer to a reference}} \
7                                     // expected-note{{candidate}}
8};
9
10X0<int> x0i;
11X0<void> x0v;
12X0<int&> x0ir; // expected-note{{instantiation}}
13
14void test_X0(int *ip, double *dp) {
15  X0<int> xi;
16  int i1 = xi.f0(ip);
17  double *&dpr = xi.f1(ip, dp);
18  xi.f1(dp, dp); // expected-error{{no matching}}
19
20  X0<void> xv;
21  double *&dpr2 = xv.f1(ip, dp);
22}
23
24template<typename T>
25struct X1 {
26  template<typename U>
27  struct Inner0 {
28    U x;
29    T y; // expected-error{{void}}
30  };
31
32  template<typename U>
33  struct Inner1 {
34    U x; // expected-error{{void}}
35    T y;
36  };
37
38  template<typename U>
39  struct Inner2 {
40    struct SuperInner {
41      U z; // expected-error{{void}}
42    };
43  };
44
45  template<typename U>
46  struct Inner3 {
47    void f0(T t, U u) { // expected-note{{passing argument to parameter 't' here}}
48      (void)(t + u); // expected-error{{invalid operands}}
49    }
50
51    template<typename V>
52    V f1(T t, U u, V) {
53      return t + u; // expected-error{{cannot initialize return object}}
54    }
55  };
56
57  template<typename U>
58  struct Inner4;
59};
60
61template<typename T>
62template<typename U>
63struct X1<T>::Inner4 {
64  template<typename V>
65  V f2(T t, U u, V);
66
67  static U value;
68};
69
70template<typename T>
71template<typename U>
72U X1<T>::Inner4<U>::value; // expected-error{{reference variable}}
73
74template<typename T>
75template<typename U>
76template<typename V>
77V X1<T>::Inner4<U>::f2(T t, U u, V) {
78  return t + u; // expected-error{{cannot initialize return object}}
79}
80
81void test_X1(int *ip, int i, double *dp) {
82  X1<void>::Inner0<int> *xvip; // okay
83  X1<void>::Inner0<int> xvi; // expected-note{{instantiation}}
84
85  X1<int>::Inner1<void> *xivp; // okay
86  X1<int>::Inner1<void> xiv; // expected-note{{instantiation}}
87
88  X1<int>::Inner2<void>::SuperInner *xisivp; // okay
89  X1<int>::Inner2<void>::SuperInner xisiv; // expected-note{{instantiation}}
90
91  X1<int*>::Inner3<int> id3;
92  id3.f0(ip, i);
93  id3.f0(dp, i); // expected-error{{cannot initialize a parameter of type 'int *' with an lvalue of type 'double *'}}
94  id3.f1(ip, i, ip);
95  id3.f1(ip, i, dp); // expected-note{{instantiation}}
96
97  X1<int*>::Inner3<double*> id3b;
98  id3b.f0(ip, dp); // expected-note{{instantiation}}
99
100  X1<int*>::Inner4<int> id4;
101  id4.f2(ip, i, dp); // expected-note{{instantiation}}
102
103  X1<int*>::Inner4<int>::value = 17;
104  i = X1<int*>::Inner4<int&>::value; // expected-note{{instantiation}}
105}
106
107
108template<typename T>
109struct X2 {
110  template<T *Ptr> // expected-error{{pointer to a reference}}
111  struct Inner;
112
113  template<T Value> // expected-error{{cannot have type 'float'}}
114  struct Inner2;
115};
116
117X2<int&> x2a; // expected-note{{instantiation}}
118X2<float> x2b; // expected-note{{instantiation}}
119
120namespace N0 {
121  template<typename T>
122  struct X0 { };
123
124  struct X1 {
125    template<typename T> void f(X0<T>& vals) { g(vals); }
126    template<typename T> void g(X0<T>& vals) { }
127  };
128
129  void test(X1 x1, X0<int> x0i, X0<long> x0l) {
130    x1.f(x0i);
131    x1.f(x0l);
132  }
133}
134
135namespace PR6239 {
136  template <typename T>
137  struct X0 {
138    class type {
139      typedef T E;
140      template <E e>  // subsitute T for E and bug goes away
141      struct sfinae {  };
142
143      template <class U>
144      typename sfinae<&U::operator=>::type test(int);
145    };
146  };
147
148  template <typename T>
149  struct X1 {
150    typedef T E;
151    template <E e>  // subsitute T for E and bug goes away
152    struct sfinae {  };
153
154    template <class U>
155    typename sfinae<&U::operator=>::type test(int);
156  };
157
158}
159
160namespace PR7587 {
161  template<typename> class X0;
162  template<typename> struct X1;
163  template<typename> class X2;
164
165  template<typename T> class X3
166  {
167    template<
168      template<typename> class TT,
169      typename U = typename X1<T>::type
170    >
171    struct Inner {
172      typedef X2<TT<typename X1<T>::type> > Type;
173    };
174
175    const typename Inner<X0>::Type minCoeff() const;
176  };
177
178  template<typename T> class X3<T*>
179  {
180    template<
181      template<typename> class TT,
182      typename U = typename X1<T>::type
183    >
184    struct Inner {
185      typedef X2<TT<typename X1<T>::type> > Type;
186    };
187
188    const typename Inner<X0>::Type minCoeff() const;
189  };
190
191}
192
193namespace PR7669 {
194  template<class> struct X {
195    template<class> struct Y {
196      template<int,class> struct Z;
197      template<int Dummy> struct Z<Dummy,int> {};
198    };
199  };
200
201  void a()
202  {
203    X<int>::Y<int>::Z<0,int>();
204  }
205}
206
207namespace PR8489 {
208  template <typename CT>
209  class C {
210    template<typename FT>
211    void F() {} // expected-note{{FT}}
212  };
213  void f() {
214    C<int> c;
215    c.F(); // expected-error{{no matching member function}}
216  }
217}
218
219namespace rdar8986308 {
220  template <bool> struct __static_assert_test;
221  template <> struct __static_assert_test<true> {};
222  template <unsigned> struct __static_assert_check {};
223
224  namespace std {
225
226    template <class _Tp, class _Up>
227    struct __has_rebind
228    {
229    private:
230      struct __two {char _; char __;};
231      template <class _Xp> static __two __test(...);
232      template <class _Xp> static char __test(typename _Xp::template rebind<_Up>* = 0);
233    public:
234      static const bool value = sizeof(__test<_Tp>(0)) == 1;
235    };
236
237  }
238
239  template <class T> struct B1 {};
240
241  template <class T>
242  struct B
243  {
244    template <class U> struct rebind {typedef B1<U> other;};
245  };
246
247  template <class T, class U> struct D1 {};
248
249  template <class T, class U>
250  struct D
251  {
252    template <class V> struct rebind {typedef D1<V, U> other;};
253  };
254
255  int main()
256  {
257    typedef __static_assert_check<sizeof(__static_assert_test<((std::__has_rebind<B<int>, double>::value))>)> __t64;
258    typedef __static_assert_check<sizeof(__static_assert_test<((std::__has_rebind<D<char, int>, double>::value))>)> __t64;
259  }
260
261}
262