// RUN: %clang_cc1 -fsyntax-only -verify %s // C++20 [temp.class.spec] 13.7.5/10 // The usual access checking rules do not apply to non-dependent names // used to specify template arguments of the simple-template-id of the // partial specialization. // // C++20 [temp.spec] 13.9/6: // The usual access checking rules do not apply to names in a declaration // of an explicit instantiation or explicit specialization... // TODO: add test cases for `enum` // class for tests class TestClass { public: class PublicClass {}; template class TemplatePublicClass {}; using AliasPublicClass = unsigned char; void publicFunc(); void publicFuncOverloaded(); void publicFuncOverloaded(int); static void publicStaticFunc(); static void publicStaticFuncOverloaded(); static void publicStaticFuncOverloaded(int); static constexpr int publicStaticInt = 42; protected: // expected-note@+1 8{{declared protected here}} class ProtectedClass {}; template class TemplateProtectedClass {}; // expected-note@+1 2{{declared protected here}} using AliasProtectedClass = const char; // expected-note@+1 3{{declared protected here}} void protectedFunc(); void protectedFuncOverloaded(); void protectedFuncOverloaded(int); // expected-note@+1 2{{declared protected here}} static void protectedStaticFunc(); // expected-note@+1 2{{declared protected here}} static void protectedStaticFuncOverloaded(); static void protectedStaticFuncOverloaded(int); // expected-note@+1 2{{declared protected here}} static constexpr int protectedStaticInt = 43; private: // expected-note@+1 10{{declared private here}} class PrivateClass {}; // expected-note@+1 {{declared private here}} template class TemplatePrivateClass {}; using AliasPrivateClass = char *; void privateFunc(); void privateFuncOverloaded(); void privateFuncOverloaded(int); static void privateStaticFunc(); static void privateStaticFuncOverloaded(); static void privateStaticFuncOverloaded(int); static constexpr int privateStaticInt = 44; }; void globalFunction() {} //----------------------------------------------------------// // template declarations for explicit instantiations template class IT1 {}; template class IT2 {}; template class IT3 {}; template class IT4 {}; template class IT5 {}; template class IT6 { template class NIT1 {}; }; template class IT7 {}; template class IT8 {}; template class IT9 {}; // explicit instantiations // public template class IT1; template struct IT1>; template class IT1; template struct IT2; template class IT3; template struct IT4<&TestClass::publicFunc>; template class IT4<&TestClass::publicFuncOverloaded>; template class IT5<&TestClass::publicStaticFunc>; template class IT5<&TestClass::publicStaticFuncOverloaded>; template class IT5<&globalFunction>; template class IT6::template NIT1; template class IT7; template struct IT7>; template class IT8<&TestClass::publicFunc, TestClass::publicStaticInt>; template class IT8<&TestClass::publicFuncOverloaded, TestClass::publicStaticInt>; template class IT9; template class IT9; template class IT9; // protected template class IT1; template struct IT1>; template class IT1; template struct IT2; template class IT3; template struct IT4<&TestClass::protectedFunc>; template class IT4<&TestClass::protectedFuncOverloaded>; template class IT5<&TestClass::protectedStaticFunc>; template class IT5<&TestClass::protectedStaticFuncOverloaded>; template class IT6::template NIT1; template class IT7; template struct IT7>; template class IT8<&TestClass::protectedFunc, TestClass::protectedStaticInt>; template class IT8<&TestClass::protectedFuncOverloaded, TestClass::protectedStaticInt>; template class IT9; template class IT9; template class IT9; // private template class IT1; template struct IT1>; template class IT1; template struct IT2; template class IT3; template struct IT4<&TestClass::privateFunc>; template class IT4<&TestClass::privateFuncOverloaded>; template class IT5<&TestClass::privateStaticFunc>; template class IT5<&TestClass::privateStaticFuncOverloaded>; template class IT6::template NIT1; template class IT7; template struct IT7>; template class IT8<&TestClass::privateFunc, TestClass::privateStaticInt>; template class IT8<&TestClass::privateFuncOverloaded, TestClass::privateStaticInt>; template class IT9; template class IT9; template class IT9; //----------------------------------------------------------// // template declarations for full specializations template class CT1 {}; template class CT2 {}; template class CT3 {}; template class CT4 {}; template class CT5 {}; template class CT6 { template class NCT1 {}; template class NCT2; // forward declaration }; // full specializations // public template <> class CT1; template class CT1>; // not full but let it be here template <> struct CT1>; template <> class CT1; template <> struct CT2; template <> class CT3; template <> struct CT4<&TestClass::publicFunc>; template <> class CT4<&TestClass::publicFuncOverloaded>; template <> struct CT5<&TestClass::publicStaticFunc>; template <> class CT5<&TestClass::publicStaticFuncOverloaded>; template <> class CT5<&globalFunction>; template <> template <> class CT6::NCT1; template <> class CT1 final {}; template class CT1> {}; template <> class CT1> final {}; template <> class CT1 {}; template <> class CT2 final {}; template <> class CT3 {}; template <> class CT4<&TestClass::publicFunc> final {}; template <> class CT4<&TestClass::publicFuncOverloaded> {}; template <> class CT5<&TestClass::publicStaticFunc> final {}; template <> class CT5<&TestClass::publicStaticFuncOverloaded> {}; template <> class CT5<&globalFunction> final {}; template <> template <> class CT6::NCT1 {}; template <> template class CT6::NCT2 final {}; // declaration // protected template <> class CT1; template class CT1>; // not full but let it be here template <> class CT1>; template <> struct CT1; template <> class CT2; template <> struct CT3; template <> class CT4<&TestClass::protectedFunc>; template <> struct CT4<&TestClass::protectedFuncOverloaded>; template <> class CT5<&TestClass::protectedStaticFunc>; template <> class CT5<&TestClass::protectedStaticFuncOverloaded>; template <> template <> class CT6::NCT1; template <> class CT1 {}; template class CT1> final {}; // not full but let it be here template <> class CT1> {}; template <> class CT1 final {}; template <> class CT2 {}; template <> class CT3 final {}; template <> class CT4<&TestClass::protectedFunc> {}; template <> class CT4<&TestClass::protectedFuncOverloaded> final {}; template <> class CT5<&TestClass::protectedStaticFunc> {}; template <> class CT5<&TestClass::protectedStaticFuncOverloaded> final {}; template <> template <> class CT6::NCT1 {}; template <> template class CT6::NCT2 final {}; // declaration // private template <> class CT1; template class CT1>; // not full but let it be here template <> struct CT1>; template <> class CT1; template <> struct CT2; template <> class CT3; template <> struct CT4<&TestClass::privateFunc>; template <> class CT4<&TestClass::privateFuncOverloaded>; template <> class CT5<&TestClass::privateStaticFunc>; template <> class CT5<&TestClass::privateStaticFuncOverloaded>; template <> template <> class CT6::NCT1; template <> class CT1 final {}; template class CT1> {}; // not full but let it be here template <> class CT1> final {}; template <> class CT1 {}; template <> class CT2 final {}; template <> class CT3 {}; template <> class CT4<&TestClass::privateFunc> final {}; // PR37424 template <> class CT4<&TestClass::privateFuncOverloaded> {}; // PR37424 template <> class CT5<&TestClass::privateStaticFunc> final {}; template <> class CT5<&TestClass::privateStaticFuncOverloaded> {}; template <> template <> class CT6::NCT1 final {}; template <> template class CT6::NCT2 {}; // declaration //----------------------------------------------------------// // template declarations for full specializations with parents class P1 {}; template class PCT1 {}; template class PCT2 {}; template class PCT3 {}; template class PCT4 {}; template class PCT5 {}; template class PCT6 { // expected-note@+1 3{{implicitly declared private here}} template class NPCT1 {}; // expected-note@+1 {{template is declared here}} template class NPCT2; // forward declaration }; // full specializations with parents // protected + public template <> class PCT1 : P1 {}; template class PCT1> : PCT2 {}; // not full but let it be here template <> struct PCT1> : PCT1 {}; template <> class PCT1 : PCT2 {}; template <> struct PCT2 : PCT3 {}; template <> class PCT3 : PCT4<&TestClass::publicFunc> {}; template <> struct PCT4<&TestClass::protectedFunc> : PCT5<&TestClass::publicStaticFunc> {}; template <> class PCT4<&TestClass::publicFuncOverloaded> : PCT5<&TestClass::publicStaticFuncOverloaded> {}; template <> class PCT5<&TestClass::protectedStaticFunc> : PCT5<&TestClass::publicStaticFuncOverloaded> {}; // expected-error@+1 {{is a private member of}} template <> class PCT5<&TestClass::protectedStaticFuncOverloaded> : PCT6::NPCT1 {}; // expected-error@+2 {{is a protected member of}} // expected-error@+1 {{is a private member of}} template <> class PCT5<&globalFunction> : PCT6::NPCT1 {}; template <> template class PCT6::NPCT2 : P1 {}; // declaration template <> template <> class PCT6::NPCT1 : PCT6::template NPCT2 {}; // protected + private template <> class PCT1 : P1 {}; // expected-error@+2 {{is a protected member of}} // expected-error@+1 {{is a private member of}} template class PCT1> : PCT2 {}; // not full but let it be here // expected-error@+1 {{is a protected member of}} template <> class PCT1> : PCT1 {}; // expected-error@+2 {{is a protected member of}} // expected-error@+1 {{is a private member of}} template <> class PCT1 : PCT2 {}; // expected-error@+1 {{is a protected member of}} template <> class PCT2 : PCT3 {}; // expected-error@+1 {{is a protected member of}} template <> class PCT3 : PCT4<&TestClass::protectedFunc> {}; // expected-error@+1 {{is a protected member of}} template <> class PCT4<&TestClass::privateFunc> : PCT5<&TestClass::protectedStaticFunc> {}; // expected-error@+1 {{is a protected member of}} template <> class PCT4<&TestClass::privateFuncOverloaded> : PCT5<&TestClass::protectedStaticFuncOverloaded> {}; template <> class PCT5<&TestClass::privateStaticFunc> : P1 {}; // expected-error@+2 {{implicit instantiation of undefined template}} // expected-error@+1 {{is a private member of}} template <> template <> class PCT6::NPCT1 : PCT6::NPCT2 {}; // expected-error@+1 3{{is a private member of}} template <> class PCT5<&TestClass::privateStaticFuncOverloaded> : PCT6::NPCT1 {}; template <> template class PCT6::NPCT2 : P1 {}; // declaration //----------------------------------------------------------// // template declarations for partial specializations template class CTT1 {}; template class CTT2 {}; template class CTT3 {}; template class CTT4 {}; template class CTT5 {}; template class CTT6 { template class NCT1 {}; template class NCT2; // forward declaration template class NCT3 {}; template class NCT4; // forward declaration }; // partial specializations // public template class CTT1 final {}; template class CTT1> {}; template struct CTT1> final {}; template class CTT1 {}; template struct CTT2 final {}; template struct CTT2 {}; template class CTT2 final {}; template class CTT3 {}; template class CTT4 final {}; template class CTT4 {}; template class CTT5 final {}; template class CTT5 {}; template class CTT5 final {}; // expected-error@+1 {{cannot specialize a dependent template}} template template class CTT6::template NCT1 {}; template template class CTT6::NCT1 final {}; template template class CTT6::NCT2 {}; // declaration template template class CTT6::NCT2 final {}; template template class CTT6::NCT3 {}; // expected-error@+1 {{cannot specialize a dependent template}} template template class CTT6::template NCT3 final {}; template template class CTT6::NCT4 {}; // declaration template template class CTT6::NCT4 final {}; template class CTT6 { template class NCT3 {}; template class NCT4; }; template template class CTT6::NCT3 {}; template template class CTT6::NCT4 final {}; template template class CTT6::NCT4 {}; // protected template class CTT1 {}; template class CTT1> final {}; template struct CTT1> {}; template class CTT1 final {}; template struct CTT2 {}; template class CTT2 final {}; template struct CTT2 {}; template class CTT3 final {}; template class CTT4 {}; template class CTT4 final {}; template class CTT5 {}; template class CTT5 final {}; // expected-error@+1 {{cannot specialize a dependent template}} template template class CTT6::template NCT1 {}; template template class CTT6::NCT3 final {}; // expected-error@+1 {{cannot specialize a dependent template}} template template class CTT6::template NCT3 {}; template template class CTT6::NCT4 final {}; template class CTT6 { template class NCT3 {}; template class NCT4; }; template template class CTT6::NCT3 final {}; template template class CTT6::NCT4 {}; template template class CTT6::NCT4 final {}; // private template class CTT1 final {}; template class CTT1> {}; template struct CTT1> final {}; template class CTT1 {}; template struct CTT2 final {}; template class CTT2 {}; template struct CTT2 final {}; template class CTT3 {}; template class CTT4 final {}; template class CTT4 {}; template class CTT5 final {}; template class CTT5 {}; // expected-error@+1 {{cannot specialize a dependent template}} template template class CTT6::template NCT1 final {}; template template class CTT6::NCT3 {}; // expected-error@+1 {{cannot specialize a dependent template}} template template class CTT6::template NCT3 final {}; template template class CTT6::NCT4 {}; template class CTT6 { template class NCT3 {}; template class NCT4; }; template template class CTT6::NCT3 {}; template template class CTT6::NCT4 final {}; template template class CTT6::NCT4 final {}; //----------------------------------------------------------// // template declarations for partial specializations with parents template class PCTT1 {}; template class PCTT2 {}; template class PCTT3 {}; template class PCTT4 {}; template class PCTT5 {}; template class PCTT6 { template class NCT1 {}; template class NCT2; // forward declaration template class NCT3 {}; template class NCT4; // forward declaration }; // partial specializations with parents // protected + public template class PCTT1 : P1 {}; template struct PCTT1> final : PCTT2 {}; // not full but let it be here template class PCTT1> : PCTT1 {}; // expected-error@+1 {{is a protected member of}} template class PCTT1>> final : PCTT1 {}; template struct PCTT1 : PCTT2 {}; template class PCTT2 final : PCTT3 {}; template class PCTT3 : PCTT4 {}; template struct PCTT4 final : PCTT5 {}; template class PCTT4 : PCTT5 {}; template class PCTT5 final : PCTT5 {}; template class PCTT5 : PCTT6::template NCT1 {}; // expected-error@+1 {{is a protected member of}} template class PCTT5 : PCTT6::template NCT1 {}; // expected-error@+1 {{is a protected member of}} template template class PCTT6::NCT2 final : PCTT4 {}; // declaration template template class PCTT6::NCT2 : P1 {}; // expected-error@+2 {{cannot specialize a dependent template}} // expected-error@+1 {{is a protected member of}} template template class PCTT6::template NCT1 : PCTT6::template NCT2 {}; // protected + private template class PCTT1 : P1 {}; // expected-error@+2 {{is a protected member of}} // expected-error@+1 {{is a private member of}} template struct PCTT1> final : PCTT2 {}; // not full but let it be here // expected-error@+1 {{is a protected member of}} template class PCTT1> : PCTT1 {}; // expected-error@+2 {{is a protected member of}} // expected-error@+1 {{is a private member of}} template struct PCTT1 final : PCTT2 {}; // expected-error@+1 {{is a protected member of}} template class PCTT2> : PCTT3 {}; // expected-error@+1 {{is a protected member of}} template class PCTT3 final : PCTT4 {}; // expected-error@+1 {{is a protected member of}} template struct PCTT4 : PCTT5 {}; // expected-error@+1 {{is a protected member of}} template class PCTT4 final : PCTT5 {}; template class PCTT5 : P1 {}; // expected-error@+2 {{cannot specialize a dependent template}} // expected-error@+1 {{is a private member of}} template class PCTT6::template PCTT1 : PCTT6::template NCT2 {}; // expected-error@+1 {{is a private member of}} template class PCTT5 final : PCTT6::template NCT1 {}; template class PCTT6 { template class NCT3 final {}; template class NCT4; }; template template class PCTT6::NCT4 final {}; // expected-error@+1 2{{is a private member of}} template template struct PCTT6::template NCT3>> : PCTT6::NCT4> {};