aboutsummaryrefslogtreecommitdiff
path: root/test/SemaTemplate/class-template-spec.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'test/SemaTemplate/class-template-spec.cpp')
-rw-r--r--test/SemaTemplate/class-template-spec.cpp47
1 files changed, 38 insertions, 9 deletions
diff --git a/test/SemaTemplate/class-template-spec.cpp b/test/SemaTemplate/class-template-spec.cpp
index 86cace19dbfbc..518ec78e6f7d0 100644
--- a/test/SemaTemplate/class-template-spec.cpp
+++ b/test/SemaTemplate/class-template-spec.cpp
@@ -137,12 +137,16 @@ namespace PR18009 {
A<int>::S<8, sizeof(int)> a; // ok
template <typename T> struct B {
- template <int N, int M> struct S; // expected-note {{declared here}}
- template <int N> struct S<N, sizeof(T) +
- N // expected-error {{non-type template argument depends on a template parameter of the partial specialization}}
- > {};
+ template <int N, int M> struct S;
+ template <int N> struct S<N, sizeof(T) + N> {}; // ok (dr1315)
};
- B<int>::S<8, sizeof(int) + 8> s; // expected-error {{undefined}}
+ B<int>::S<8, sizeof(int) + 8> b;
+
+ template <typename T> struct C {
+ template <int N, int M> struct S;
+ template <int N> struct S<N, N ? **(T(*)[N])0 : 0> {}; // expected-error {{depends on a template parameter of the partial specialization}}
+ };
+ C<int> c; // expected-note {{in instantiation of}}
template<int A> struct outer {
template<int B, int C> struct inner {};
@@ -167,10 +171,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,13 +203,32 @@ 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.
template<typename T, int N =
- sizeof(T) // expected-note {{template parameter is used in default argument declared here}}
+ sizeof(T) // ok (dr1315)
> struct X {};
- template<typename T> struct X<T> {}; // expected-error {{non-type template argument depends on a template parameter of the partial specialization}}
+ template<typename T> struct X<T> {};
template<typename T,
T N = 0 // expected-note {{template parameter is declared here}}