diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2016-12-27 07:56:27 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2016-12-27 07:56:27 +0000 |
commit | 0e617ecdd115984ce6729554e17ea20a2783194f (patch) | |
tree | 77c399296d5527dc2f9b725c035c59a1e7773a06 /clang/test/SemaTemplate/class-template-spec.cpp | |
parent | 625038d5d5f406385f44983ac2a442b20ad7b241 (diff) | |
download | bcm5719-llvm-0e617ecdd115984ce6729554e17ea20a2783194f.tar.gz bcm5719-llvm-0e617ecdd115984ce6729554e17ea20a2783194f.zip |
DR1495: A partial specialization is ill-formed if it is not (strictly) more
specialized than the primary template. (Put another way, if we imagine there
were a partial specialization matching the primary template, we should never
select it if some other partial specialization also matches.)
llvm-svn: 290593
Diffstat (limited to 'clang/test/SemaTemplate/class-template-spec.cpp')
-rw-r--r-- | clang/test/SemaTemplate/class-template-spec.cpp | 29 |
1 files changed, 27 insertions, 2 deletions
diff --git a/clang/test/SemaTemplate/class-template-spec.cpp b/clang/test/SemaTemplate/class-template-spec.cpp index 86cace19dbf..cee84a750b6 100644 --- a/clang/test/SemaTemplate/class-template-spec.cpp +++ b/clang/test/SemaTemplate/class-template-spec.cpp @@ -167,10 +167,16 @@ namespace PR16519 { // expected-warning@-2 {{variadic templates are a C++11 extension}} #endif - template<typename T, T ...N, T ...Extra> struct __make_integer_sequence_impl<integer_sequence<T, N...>, Extra...> { + // Note that the following seemingly-equivalent template parameter list is + // not OK; it would result in a partial specialization that is not more + // specialized than the primary template. (See NTTPTypeVsPartialOrder below.) + // + // template<typename T, T ...N, T ...Extra> + template<typename T, T ...N, typename integer_sequence<T, N...>::value_type ...Extra> #if __cplusplus <= 199711L - // expected-warning@-2 2 {{variadic templates are a C++11 extension}} + // expected-warning@-2 2{{variadic templates are a C++11 extension}} #endif + struct __make_integer_sequence_impl<integer_sequence<T, N...>, Extra...> { typedef integer_sequence<T, N..., sizeof...(N) + N..., Extra...> type; }; @@ -193,6 +199,25 @@ namespace PR16519 { #endif } +namespace NTTPTypeVsPartialOrder { + struct X { typedef int value_type; }; + template<typename T> struct Y { typedef T value_type; }; + + template<typename T, typename T::value_type N> struct A; // expected-note {{template}} + template<int N> struct A<X, N> {}; + template<typename T, T N> struct A<Y<T>, N> {}; // expected-error {{not more specialized}} expected-note {{'T' vs 'typename Y<type-parameter-0-0>::value_type'}} + A<X, 0> ax; + A<Y<int>, 0> ay; + + + template<int, typename T, typename T::value_type> struct B; // expected-note {{template}} + template<typename T, typename T::value_type N> struct B<0, T, N>; // expected-note {{matches}} + template<int N> struct B<0, X, N> {}; + template<typename T, T N> struct B<0, Y<T>, N> {}; // expected-error {{not more specialized}} expected-note {{'T' vs 'typename Y<type-parameter-0-0>::value_type'}} expected-note {{matches}} + B<0, X, 0> bx; + B<0, Y<int>, 0> by; // expected-error {{ambiguous}} +} + namespace DefaultArgVsPartialSpec { // Check that the diagnostic points at the partial specialization, not just at // the default argument. |