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