[Bug c++/79163] New: Access-checking not done in template argument list of partial specialization
redi at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Fri Jan 20 12:39:00 GMT 2017
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79163
Bug ID: 79163
Summary: Access-checking not done in template argument list of
partial specialization
Product: gcc
Version: 7.0
Status: UNCONFIRMED
Keywords: rejects-valid
Severity: normal
Priority: P3
Component: c++
Assignee: unassigned at gcc dot gnu.org
Reporter: redi at gcc dot gnu.org
Blocks: 59002
Target Milestone: ---
Access-checking is not done in the template-id of a class template partial
specialization, but is done in the body.
This breaks the "detection idiom" as used by std::allocator_traits and
std::pointer_traits, because the check for whether a substituted type is valid
ignores access, and then an invalid type gets used.
template<typename>
using void_t = void;
template<typename T, typename = void>
struct Detect
{ using type = int; };
template<typename T>
struct Detect<T, void_t<typename T::type>>
{ using type = typename T::type; };
class X { using type = long; };
Detect<X>::type i;
This should compile, but issues five very similar errors, but using three
different locations:
access.cc: In instantiation of ‘struct Detect<X>’:
access.cc:14:10: required from here
access.cc:10:3: error: ‘using type = long int’ is private within this context
{ using type = typename T::type; };
^
access.cc:12:28: note: declared private here
class X { using type = long; };
^
access.cc:10:3: error: ‘using type = long int’ is private within this context
{ using type = typename T::type; };
^
access.cc:12:28: note: declared private here
class X { using type = long; };
^
access.cc:10:34: error: ‘using type = long int’ is private within this context
{ using type = typename T::type; };
^
access.cc:12:28: note: declared private here
class X { using type = long; };
^
access.cc:10:34: error: ‘using type = long int’ is private within this context
{ using type = typename T::type; };
^
access.cc:12:28: note: declared private here
class X { using type = long; };
^
access.cc:14:1: error: ‘using type = long int’ is private within this context
Detect<X>::type i;
^~~~~~~~~
access.cc:12:28: note: declared private here
class X { using type = long; };
^
Clang compiles this successfully, although EDG fails in the same way as GCC
(but only issues one error):
"access.cc", line 10: error: type "X::type" (declared at line 12) is
inaccessible
{ using type = typename T::type; };
^
detected during instantiation of class "Detect<T, void> [with T=X]"
at line 14
1 error detected in the compilation of "access.cc".
This has some similarities to Bug 40901 but that was fixed in 4.9.0
Referenced Bugs:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59002
[Bug 59002] [meta-bug] Access checking in templates
More information about the Gcc-bugs
mailing list