1*a6b41d7cSRichard Smith // RUN: %clang_cc1 -fsyntax-only -std=c++17 -verify %s -fcxx-exceptions
25013a7e4SDouglas Gregor template<typename T>
35013a7e4SDouglas Gregor struct X0 {
45013a7e4SDouglas Gregor   typedef T* type;
55013a7e4SDouglas Gregor 
65013a7e4SDouglas Gregor   void f0(T);
75013a7e4SDouglas Gregor   void f1(type);
85013a7e4SDouglas Gregor };
95013a7e4SDouglas Gregor 
105013a7e4SDouglas Gregor template<> void X0<char>::f0(char);
115013a7e4SDouglas Gregor template<> void X0<char>::f1(type);
1271ad477aSDouglas Gregor 
1371ad477aSDouglas Gregor namespace PR6161 {
1471ad477aSDouglas Gregor   template<typename _CharT>
1571ad477aSDouglas Gregor   class numpunct : public locale::facet // expected-error{{use of undeclared identifier 'locale'}} \
16869853eeSDouglas Gregor               // expected-error{{expected class name}}
1771ad477aSDouglas Gregor   {
184e150f8dSJeffrey Yasskin     static locale::id id; // expected-error{{use of undeclared identifier}}
1971ad477aSDouglas Gregor   };
2064e033f9SRichard Smith   numpunct<char>::~numpunct();
2171ad477aSDouglas Gregor }
225001ec91SRichard Smith 
235001ec91SRichard Smith namespace PR12331 {
245001ec91SRichard Smith   template<typename T> struct S {
255001ec91SRichard Smith     struct U { static const int n = 5; };
265001ec91SRichard Smith     enum E { e = U::n }; // expected-note {{implicit instantiation first required here}}
275001ec91SRichard Smith     int arr[e];
285001ec91SRichard Smith   };
295001ec91SRichard Smith   template<> struct S<int>::U { static const int n = sizeof(int); }; // expected-error {{explicit specialization of 'U' after instantiation}}
305001ec91SRichard Smith }
313298368dSRichard Smith 
323298368dSRichard Smith namespace PR18246 {
333298368dSRichard Smith   template<typename T>
343298368dSRichard Smith   class Baz {
353298368dSRichard Smith   public:
363298368dSRichard Smith     template<int N> void bar();
373298368dSRichard Smith   };
383298368dSRichard Smith 
393298368dSRichard Smith   template<typename T>
403298368dSRichard Smith   template<int N>
bar()41ddd279b9SAlex Lorenz   void Baz<T>::bar() {
423298368dSRichard Smith   }
433298368dSRichard Smith 
443298368dSRichard Smith   template<typename T>
bar()45ddd279b9SAlex Lorenz   void Baz<T>::bar<0>() { // expected-error {{cannot specialize a member of an unspecialized template}}
463298368dSRichard Smith   }
473298368dSRichard Smith }
4811a80dcbSRichard Smith 
4911a80dcbSRichard Smith namespace PR19340 {
5011a80dcbSRichard Smith template<typename T> struct Helper {
funcPR19340::Helper51ddd279b9SAlex Lorenz   template<int N> static void func(const T *m) {}
5211a80dcbSRichard Smith };
5311a80dcbSRichard Smith 
func()54ddd279b9SAlex Lorenz template<typename T> void Helper<T>::func<2>() {} // expected-error {{cannot specialize a member}}
5511a80dcbSRichard Smith }
5677e9e84aSRichard Smith 
5777e9e84aSRichard Smith namespace SpecLoc {
5877e9e84aSRichard Smith   template <typename T> struct A {
5977e9e84aSRichard Smith     static int n; // expected-note {{previous}}
6077e9e84aSRichard Smith     static void f(); // expected-note {{previous}}
6177e9e84aSRichard Smith   };
6277e9e84aSRichard Smith   template<> float A<int>::n; // expected-error {{different type}}
6377e9e84aSRichard Smith   template<> void A<int>::f() throw(); // expected-error {{does not match}}
6477e9e84aSRichard Smith }
6559d0500bSRichard Smith 
6659d0500bSRichard Smith namespace PR41607 {
6759d0500bSRichard Smith   template<int N> struct Outer {
6859d0500bSRichard Smith     template<typename...> struct Inner;
6959d0500bSRichard Smith     template<> struct Inner<> {
fPR41607::Outer::Inner7059d0500bSRichard Smith       static constexpr int f() { return N; }
7159d0500bSRichard Smith     };
7259d0500bSRichard Smith 
73*a6b41d7cSRichard Smith     template<typename...> static int a;
74*a6b41d7cSRichard Smith     template<> static constexpr int a<> = N;
75*a6b41d7cSRichard Smith 
76*a6b41d7cSRichard Smith     template<typename...> static inline int b;
77*a6b41d7cSRichard Smith     template<> static inline constexpr int b<> = N;
78*a6b41d7cSRichard Smith 
79*a6b41d7cSRichard Smith     template<typename...> static constexpr int f();
fPR41607::Outer80*a6b41d7cSRichard Smith     template<> static constexpr int f() {
81*a6b41d7cSRichard Smith       return N;
82*a6b41d7cSRichard Smith     }
8359d0500bSRichard Smith   };
8459d0500bSRichard Smith   static_assert(Outer<123>::Inner<>::f() == 123, "");
8559d0500bSRichard Smith   static_assert(Outer<123>::Inner<>::f() != 125, "");
86*a6b41d7cSRichard Smith 
87*a6b41d7cSRichard Smith   static_assert(Outer<123>::a<> == 123, "");
88*a6b41d7cSRichard Smith   static_assert(Outer<123>::a<> != 125, "");
89*a6b41d7cSRichard Smith 
90*a6b41d7cSRichard Smith   static_assert(Outer<123>::b<> == 123, "");
91*a6b41d7cSRichard Smith   static_assert(Outer<123>::b<> != 125, "");
92*a6b41d7cSRichard Smith 
93*a6b41d7cSRichard Smith   static_assert(Outer<123>::f<>() == 123, "");
94*a6b41d7cSRichard Smith   static_assert(Outer<123>::f<>() != 125, "");
9559d0500bSRichard Smith }
96