Bug 97942 - [C++20][P0692R1] Access checking not waived for declarations of explicit specializations of function and variable templates
Summary: [C++20][P0692R1] Access checking not waived for declarations of explicit spec...
Status: NEW
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 11.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: rejects-valid
Depends on:
Blocks:
 
Reported: 2020-11-23 10:09 UTC by David Friberg
Modified: 2023-10-19 05:57 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2021-08-17 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description David Friberg 2020-11-23 10:09:22 UTC
[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
Comment 1 David Friberg 2020-12-03 11:20:06 UTC
Somewhat related, we may note that GCC accepts-valid the following program, say (D):

class A { class B {}; };

template<typename T, typename U> struct S {};
template<typename U> struct S<A::B, U> {};
template<typename T> struct S<T, A::B> {};

int main() {}


which is valid as per [temp.class.spec]/10 (https://timsong-cpp.github.io/cppwp/n4861/temp.class.spec#10), which covers waiving of access checking for template arguments in the simple-template-id of partial specializations, a paragraph that was also added as part of P0692R1.
Comment 2 Andrew Pinski 2021-08-17 18:55:55 UTC
Confirmed.