https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97942
Bug ID: 97942 Summary: [C++20][P0692R1] Access checking not waived for declarations of explicit specializations of function and variable templates Product: gcc Version: 11.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: davveston at gmail dot com Target Milestone: --- [temp.spec]/6[1] was added to the C++20 spec by implementation of P0692R1[2]: "The usual access checking rules do not apply to names in a declaration of an explicit instantiation or explicit specialization, with the exception of names appearing in a function body, default argument, base-clause, member-specification, enumerator-list, or static data member or variable template initializer." Meaning that programs (A) through (C) below are (arguably) well-formed: (A) (DEMO: https://wandbox.org/permlink/No9RdUGRQFinIPie) class A { class B {}; }; template<typename T> struct S {}; template<> struct S<A::B> {}; int main() {} (B) (DEMO: https://wandbox.org/permlink/Ki1iLlje2raKJoEb): class A { class B {}; }; template<typename T> void foo() {}; template<> void foo<A::B>() {} int main() {} (C) (DEMO: https://wandbox.org/permlink/AN06msZgJNmxB0HS) class A { class B {}; }; template<typename T> constexpr bool v = false; template<> constexpr bool v<A::B> = true; int main() {} However whilst GCC accepts (A), it rejects (B) and (C). > (gcc HEAD 11.0.0 20201121 (experimental)) > g++ prog.cc -Wall -Wextra -std=c++2a > error: 'class A::B' is private within this context As per [3], P0692R1 has been implemented in GCC ("Available in GCC: Yes"). --- References [1] https://timsong-cpp.github.io/cppwp/n4861/temp.spec#6 [2] P0692R1 - Access Checking on Specializations http://open-std.org/JTC1/SC22/WG21/docs/papers/2017/p0692r1.html) [3] https://gcc.gnu.org/projects/cxx-status.html