https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79960
Bug ID: 79960
Summary: [5/6/7 Regression] Class template partial
specializations for const volatile types don't match
Product: gcc
Version: 7.0.1
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
Target Milestone: ---
using size_t = decltype(sizeof(0));
template<typename T> struct tuple_size;
template<typename T, size_t U = tuple_size<T>::value>
using __has_tuple_size = T;
template<typename T> struct tuple_size<const __has_tuple_size<T>> {
static constexpr size_t value = tuple_size<T>::value;
};
template<typename T> struct tuple_size<volatile __has_tuple_size<T>> {
static constexpr size_t value = tuple_size<T>::value;
};
template<typename T> struct tuple_size<const volatile __has_tuple_size<T>> {
static constexpr size_t value = tuple_size<T>::value;
};
template<typename... T> struct tuple { };
template<typename... T> struct tuple_size<tuple<T...>> {
static constexpr size_t value = sizeof...(T);
};
static_assert( tuple_size<const tuple<>>::value == 0, "" ); // OK
static_assert( tuple_size<volatile tuple<>>::value == 0, "" ); // OK
static_assert( tuple_size<const volatile tuple<>>::value == 0, "" ); // FAIL
GCC trunk fails to match the specialization:
cv.cc:27:50: error: ambiguous template instantiation for ‘struct
tuple_size<const volatile tuple<> >’
static_assert( tuple_size<const volatile tuple<>>::value == 0, "" ); // FAIL
^~
cv.cc:8:29: note: candidates are: template<class T> struct
tuple_size<__has_tuple_size<T> > [with T = volatile tuple<>]
template<typename T> struct tuple_size<const __has_tuple_size<T>> {
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
cv.cc:12:29: note: template<class T> struct
tuple_size<__has_tuple_size<T> > [with T = const tuple<>]
template<typename T> struct tuple_size<volatile __has_tuple_size<T>> {
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
cv.cc:16:29: note: template<class T> struct
tuple_size<__has_tuple_size<T> > [with T = tuple<>]
template<typename T> struct tuple_size<const volatile __has_tuple_size<T>> {
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
cv.cc:27:52: error: incomplete type ‘tuple_size<const volatile tuple<> >’ used
in nested name specifier
static_assert( tuple_size<const volatile tuple<>>::value == 0, "" ); // FAIL
^~~~~