1 // RUN: %clang_cc1 -fsyntax-only -verify %s 2 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s 3 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s 4 template<typename T, int N = 2> struct X; // expected-note{{template is declared here}} 5 6 X<int, 1> *x1; 7 X<int> *x2; 8 9 X<> *x3; // expected-error{{too few template arguments for class template 'X'}} 10 11 template<typename U = float, int M> struct X; 12 13 X<> *x4; 14 15 template<typename T = int> struct Z { }; 16 template struct Z<>; 17 18 // PR4362 19 template<class T> struct a { }; 20 template<> struct a<int> { static const bool v = true; }; 21 22 template<class T, bool = a<T>::v> struct p { }; // expected-error {{no member named 'v'}} 23 24 template struct p<bool>; // expected-note {{in instantiation of default argument for 'p<bool>' required here}} 25 template struct p<int>; 26 27 // PR5187 28 template<typename T, typename U> 29 struct A; 30 31 template<typename T, typename U = T> 32 struct A; 33 34 template<typename T, typename U> 35 struct A { 36 void f(A<T>); 37 }; 38 39 template<typename T> 40 struct B { }; 41 42 template<> 43 struct B<void> { 44 typedef B<void*> type; 45 }; 46 47 // Nested default arguments for template parameters. 48 template<typename T> struct X1 { }; 49 50 template<typename T> 51 struct X2 { 52 template<typename U = typename X1<T>::type> // expected-error{{no type named 'type' in 'X1<int>'}} \ 53 // expected-error{{no type named 'type' in 'X1<char>'}} 54 struct Inner1 { }; // expected-note{{template is declared here}} 55 56 template<T Value = X1<T>::value> // expected-error{{no member named 'value' in 'X1<int>'}} \ 57 // expected-error{{no member named 'value' in 'X1<char>'}} 58 struct NonType1 { }; // expected-note{{template is declared here}} 59 60 template<T Value> 61 struct Inner2 { }; 62 63 template<typename U> 64 struct Inner3 { 65 template<typename X = T, typename V = U> 66 struct VeryInner { }; 67 68 template<T Value1 = sizeof(T), T Value2 = sizeof(U), 69 T Value3 = Value1 + Value2> 70 struct NonType2 { }; 71 }; 72 }; 73 74 X2<int> x2i; // expected-note{{in instantiation of template class 'X2<int>' requested here}} 75 X2<int>::Inner1<float> x2iif; 76 77 X2<int>::Inner1<> x2bad; // expected-error{{too few template arguments for class template 'Inner1'}} 78 79 X2<int>::NonType1<'a'> x2_nontype1; 80 X2<int>::NonType1<> x2_nontype1_bad; // expected-error{{too few template arguments for class template 'NonType1'}} 81 82 // Check multi-level substitution into template type arguments 83 X2<int>::Inner3<float>::VeryInner<> vi; 84 X2<char>::Inner3<int>::NonType2<> x2_deep_nontype; // expected-note{{in instantiation of template class 'X2<char>' requested here}} 85 86 template<typename T, typename U> 87 struct is_same { static const bool value = false; }; 88 89 template<typename T> 90 struct is_same<T, T> { static const bool value = true; }; 91 92 int array1[is_same<__typeof__(vi), 93 X2<int>::Inner3<float>::VeryInner<int, float> >::value? 1 : -1]; 94 95 int array2[is_same<__typeof(x2_deep_nontype), 96 X2<char>::Inner3<int>::NonType2<sizeof(char), sizeof(int), 97 sizeof(char)+sizeof(int)> >::value? 1 : -1]; 98 99 // Template template parameter defaults 100 template<template<typename T> class X = X2> struct X3 { }; 101 int array3[is_same<X3<>, X3<X2> >::value? 1 : -1]; 102 103 struct add_pointer { 104 template<typename T> 105 struct apply { 106 typedef T* type; 107 }; 108 }; 109 110 template<typename T, template<typename> class X = T::template apply> 111 struct X4; 112 int array4[is_same<X4<add_pointer>, 113 X4<add_pointer, add_pointer::apply> >::value? 1 : -1]; 114 115 template<int> struct X5 {}; 116 template<long long> struct X5b {}; 117 template<typename T, 118 template<T> class B = X5> // expected-error {{cannot be narrowed from type 'long long' to 'int'}} 119 // expected-note@-1 {{has different template parameters}} 120 // expected-note@-2 {{previous template template parameter is here}} 121 struct X6 {}; 122 123 X6<int> x6a; 124 X6<long long> x6b; // expected-note {{while checking a default template argument used here}} 125 X6<long long, X5b> x6c; 126 127 128 template<template<class> class X = B<int> > struct X7; // expected-error{{must be a class template}} 129 130 namespace PR9643 { 131 template<typename T> class allocator {}; 132 template<typename T, typename U = allocator<T> > class vector {}; 133 134 template<template<typename U, typename = allocator<U> > class container, 135 typename DT> 136 container<DT> initializer(const DT& d) { 137 return container<DT>(); 138 } 139 140 void f() { 141 vector<int, allocator<int> > v = initializer<vector>(5); 142 } 143 } 144 145 namespace PR16288 { 146 template<typename X> 147 struct S { 148 template<typename T = int, typename U> 149 #if __cplusplus <= 199711L // C++03 or earlier modes 150 // expected-warning@-2 {{default template arguments for a function template are a C++11 extension}} 151 #endif 152 void f(); 153 }; 154 template<typename X> 155 template<typename T, typename U> 156 void S<X>::f() {} 157 } 158 159 namespace DR1635 { 160 template <class T> struct X { 161 template <class U = typename T::type> static void f(int) {} // expected-error {{type 'int' cannot be used prior to '::' because it has no members}} 162 #if __cplusplus <= 199711L // C++03 or earlier modes 163 // expected-warning@-2 {{default template arguments for a function template are a C++11 extension}} 164 #endif 165 static void f(...) {} 166 }; 167 168 int g() { X<int>::f(0); } // expected-note {{in instantiation of template class 'DR1635::X<int>' requested here}} 169 } 170 171 namespace NondefDecls { 172 template<typename T> void f1() { 173 int g1(int defarg = T::error); // expected-error{{type 'int' cannot be used prior to '::' because it has no members}} \ 174 // expected-note {{in instantiation of default function argument expression for 'g1<int>' required here}} 175 } 176 template void f1<int>(); // expected-note{{in instantiation of function template specialization 'NondefDecls::f1<int>' requested here}} 177 } 178 179 template <typename T> 180 struct C { 181 C(T t = ); // expected-error {{expected expression}} 182 }; 183 C<int> obj; 184 185 namespace PR26134 { 186 // Make sure when substituting default template arguments we do it in the current context. 187 template<class T, bool Val = T::value> 188 struct X {}; 189 190 template<bool B> struct Y { 191 void f() { X<Y> xy; } 192 static const bool value = B; 193 }; 194 195 namespace ns1 { 196 template<class T0> 197 struct X { 198 template<bool B = T0::value> struct XInner { static const bool value = B; }; 199 }; 200 template<bool B> struct S { static const bool value = B; }; 201 #if __cplusplus > 199711L 202 template<bool B> struct Y { 203 static constexpr bool f() { return typename X<S<B>>::template XInner<>{}.value; } 204 static_assert(f() == B, ""); 205 }; 206 Y<true> y; 207 Y<false> y2; 208 #endif 209 210 } // end ns1 211 } // end ns PR26134 212 213 namespace friends { 214 namespace ns { 215 template<typename> struct A { 216 template<typename> friend void f(); 217 template<typename> friend struct X; 218 }; 219 template<typename = int> void f(); // expected-warning 0-1{{extension}} 220 template<typename = int> struct X; 221 A<int> a; 222 } 223 namespace ns { 224 void g() { f(); } 225 X<int> *p; 226 } 227 } 228 229 namespace unevaluated { 230 int a; 231 template<int = 0> int f(int = a); // expected-warning 0-1{{extension}} 232 int k = sizeof(f()); 233 } 234 235 #if __cplusplus >= 201103L 236 namespace GH68490 { 237 238 template <typename T> struct S { 239 template <typename U> 240 constexpr int SizeOfU(int param = sizeof(U)) const; 241 242 template <typename U> 243 constexpr int SizeOfT(int param = sizeof(T)) const; 244 }; 245 246 template <typename T> struct S<T *> { 247 template <typename U> 248 constexpr int SizeOfU(int param = sizeof(U)) const; 249 250 template <typename U> 251 constexpr int SizeOfT(int param = sizeof(T *)) const; 252 }; 253 254 template <typename T> 255 template <typename U> 256 constexpr int S<T *>::SizeOfU(int param) const { 257 return param; 258 } 259 260 template <typename T> 261 template <typename U> 262 constexpr int S<T *>::SizeOfT(int param) const { 263 return param; 264 } 265 266 template <> 267 template <typename T> 268 constexpr int S<int>::SizeOfU(int param) const { 269 return param; 270 } 271 272 template <> 273 template <typename T> 274 constexpr int S<int>::SizeOfT(int param) const { 275 return param; 276 } 277 278 static_assert(S<int>().SizeOfU<char>() == sizeof(char), ""); 279 static_assert(S<int>().SizeOfT<char>() == sizeof(int), ""); 280 static_assert(S<short *>().SizeOfU<char>() == sizeof(char), ""); 281 static_assert(S<short *>().SizeOfT<char>() == sizeof(short *), ""); 282 283 } // namespace GH68490 284 285 #endif 286