286 lines · cpp
1// RUN: %clang_cc1 -fsyntax-only -verify %s2// RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s3// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s4template<typename T, int N = 2> struct X; // expected-note{{template is declared here}}5 6X<int, 1> *x1;7X<int> *x2;8 9X<> *x3; // expected-error{{too few template arguments for class template 'X'}}10 11template<typename U = float, int M> struct X;12 13X<> *x4;14 15template<typename T = int> struct Z { };16template struct Z<>;17 18// PR436219template<class T> struct a { };20template<> struct a<int> { static const bool v = true; };21 22template<class T, bool = a<T>::v> struct p { }; // expected-error {{no member named 'v'}}23 24template struct p<bool>; // expected-note {{in instantiation of default argument for 'p<bool>' required here}}25template struct p<int>;26 27// PR518728template<typename T, typename U>29struct A;30 31template<typename T, typename U = T>32struct A;33 34template<typename T, typename U>35struct A {36 void f(A<T>);37};38 39template<typename T>40struct B { };41 42template<>43struct B<void> {44 typedef B<void*> type;45};46 47// Nested default arguments for template parameters.48template<typename T> struct X1 { };49 50template<typename T>51struct 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 74X2<int> x2i; // expected-note{{in instantiation of template class 'X2<int>' requested here}}75X2<int>::Inner1<float> x2iif;76 77X2<int>::Inner1<> x2bad; // expected-error{{too few template arguments for class template 'Inner1'}}78 79X2<int>::NonType1<'a'> x2_nontype1;80X2<int>::NonType1<> x2_nontype1_bad; // expected-error{{too few template arguments for class template 'NonType1'}}81 82// Check multi-level substitution into template type arguments83X2<int>::Inner3<float>::VeryInner<> vi;84X2<char>::Inner3<int>::NonType2<> x2_deep_nontype; // expected-note{{in instantiation of template class 'X2<char>' requested here}}85 86template<typename T, typename U>87struct is_same { static const bool value = false; };88 89template<typename T>90struct is_same<T, T> { static const bool value = true; };91 92int array1[is_same<__typeof__(vi),93 X2<int>::Inner3<float>::VeryInner<int, float> >::value? 1 : -1];94 95int 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 defaults100template<template<typename T> class X = X2> struct X3 { };101int array3[is_same<X3<>, X3<X2> >::value? 1 : -1];102 103struct add_pointer {104 template<typename T>105 struct apply {106 typedef T* type;107 };108};109 110template<typename T, template<typename> class X = T::template apply>111 struct X4;112int array4[is_same<X4<add_pointer>,113 X4<add_pointer, add_pointer::apply> >::value? 1 : -1];114 115template<int> struct X5 {};116template<long long> struct X5b {};117template<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 123X6<int> x6a;124X6<long long> x6b; // expected-note {{while checking a default template argument used here}}125X6<long long, X5b> x6c;126 127 128template<template<class> class X = B<int> > struct X7; // expected-error{{must be a class template}}129 130namespace 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 145namespace PR16288 {146 template<typename X>147 struct S {148 template<typename T = int, typename U>149#if __cplusplus <= 199711L // C++03 or earlier modes150 // expected-warning@-2 {{default template arguments for a function template are a C++11 extension}}151#endif152 void f();153 };154 template<typename X>155 template<typename T, typename U>156 void S<X>::f() {}157}158 159namespace 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 modes163 // expected-warning@-2 {{default template arguments for a function template are a C++11 extension}}164#endif165 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 171namespace 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 179template <typename T>180struct C {181 C(T t = ); // expected-error {{expected expression}}182};183C<int> obj;184 185namespace PR26134 {186// Make sure when substituting default template arguments we do it in the current context.187template<class T, bool Val = T::value>188struct X {};189 190template<bool B> struct Y {191 void f() { X<Y> xy; }192 static const bool value = B;193};194 195namespace ns1 {196template<class T0>197struct X {198 template<bool B = T0::value> struct XInner { static const bool value = B; };199};200template<bool B> struct S { static const bool value = B; };201#if __cplusplus > 199711L202template<bool B> struct Y {203 static constexpr bool f() { return typename X<S<B>>::template XInner<>{}.value; }204 static_assert(f() == B, "");205};206Y<true> y;207Y<false> y2;208#endif209 210} // end ns1211} // end ns PR26134212 213namespace 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 229namespace 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 >= 201103L236namespace GH68490 {237 238template <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 246template <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 254template <typename T>255template <typename U>256constexpr int S<T *>::SizeOfU(int param) const {257 return param;258}259 260template <typename T>261template <typename U>262constexpr int S<T *>::SizeOfT(int param) const {263 return param;264}265 266template <>267template <typename T>268constexpr int S<int>::SizeOfU(int param) const {269 return param;270}271 272template <>273template <typename T>274constexpr int S<int>::SizeOfT(int param) const {275 return param;276}277 278static_assert(S<int>().SizeOfU<char>() == sizeof(char), "");279static_assert(S<int>().SizeOfT<char>() == sizeof(int), "");280static_assert(S<short *>().SizeOfU<char>() == sizeof(char), "");281static_assert(S<short *>().SizeOfT<char>() == sizeof(short *), "");282 283} // namespace GH68490284 285#endif286