diff options
Diffstat (limited to 'test/CXX/drs/dr13xx.cpp')
-rw-r--r-- | test/CXX/drs/dr13xx.cpp | 130 |
1 files changed, 130 insertions, 0 deletions
diff --git a/test/CXX/drs/dr13xx.cpp b/test/CXX/drs/dr13xx.cpp index 28bebcbb607e..28e667f77f84 100644 --- a/test/CXX/drs/dr13xx.cpp +++ b/test/CXX/drs/dr13xx.cpp @@ -174,3 +174,133 @@ namespace dr1359 { // dr1359: 3.5 constexpr Y y = Y(); // expected-error {{no matching}} #endif } + +namespace dr1388 { // dr1388: 4.0 + template<typename A, typename ...T> void f(T..., A); // expected-note 1+{{candidate}} expected-error 0-1{{C++11}} + template<typename ...T> void g(T..., int); // expected-note 1+{{candidate}} expected-error 0-1{{C++11}} + template<typename ...T, typename A> void h(T..., A); // expected-note 1+{{candidate}} expected-error 0-1{{C++11}} + + void test_f() { + f(0); // ok, trailing parameter pack deduced to empty + f(0, 0); // expected-error {{no matching}} + f<int>(0); + f<int>(0, 0); // expected-error {{no matching}} + f<int, int>(0, 0); + f<int, int, int>(0, 0); // expected-error {{no matching}} + + g(0); + g(0, 0); // expected-error {{no matching}} + g<>(0); + g<int>(0); // expected-error {{no matching}} + g<int>(0, 0); + + h(0); + h(0, 0); // expected-error {{no matching}} + h<int>(0, 0); + h<int, int>(0, 0); // expected-error {{no matching}} + } + + // A non-trailing parameter pack is still a non-deduced context, even though + // we know exactly how many arguments correspond to it. + template<typename T, typename U> struct pair {}; + template<typename ...T> struct tuple { typedef char type; }; // expected-error 0-2{{C++11}} + template<typename ...T, typename ...U> void f_pair_1(pair<T, U>..., int); // expected-error 0-2{{C++11}} expected-note {{different lengths (2 vs. 0)}} + template<typename ...T, typename U> void f_pair_2(pair<T, char>..., U); // expected-error 0-2{{C++11}} + template<typename ...T, typename ...U> void f_pair_3(pair<T, U>..., tuple<U...>); // expected-error 0-2{{C++11}} expected-note {{different lengths (2 vs. 1)}} + template<typename ...T> void f_pair_4(pair<T, char>..., T...); // expected-error 0-2{{C++11}} expected-note {{<int, long> vs. <int, long, const char *>}} + void g(pair<int, char> a, pair<long, char> b, tuple<char, char> c) { + f_pair_1<int, long>(a, b, 0); // expected-error {{no match}} + f_pair_2<int, long>(a, b, 0); + f_pair_3<int, long>(a, b, c); + f_pair_3<int, long>(a, b, tuple<char>()); // expected-error {{no match}} + f_pair_4<int, long>(a, b, 0, 0L); + f_pair_4<int, long>(a, b, 0, 0L, "foo"); // expected-error {{no match}} + } +} + +namespace dr1391 { // dr1391: partial + struct A {}; struct B : A {}; + template<typename T> struct C { C(int); typename T::error error; }; // expected-error 2{{'::'}} + template<typename T> struct D {}; + + // No deduction is performed for parameters with no deducible template-parameters, therefore types do not need to match. + template<typename T> void a(T, int T::*); + void test_a(int A::*p) { a(A(), p); } // ok, type of second parameter does not need to match + + namespace dr_example_1 { + template<typename T, typename U> void f(C<T>); + template<typename T> void f(D<T>); + + void g(D<int> d) { + f(d); // ok, first 'f' eliminated by deduction failure + f<int>(d); // ok, first 'f' eliminated because 'U' cannot be deduced + } + } + + namespace dr_example_2 { + template<typename T> typename C<T>::error f(int, T); + template<typename T> T f(T, T); + + void g(A a) { + f(a, a); // ok, no conversion from A to int for first parameter of first candidate + } + } + + namespace std_example { + template<typename T> struct Z { + typedef typename T::x xx; + }; + template<typename T> typename Z<T>::xx f(void *, T); + template<typename T> void f(int, T); + struct A {} a; + void g() { f(1, a); } + } + + template<typename T> void b(C<int> ci, T *p); + void b(...); + void test_b() { + b(0, 0); // ok, deduction fails prior to forming a conversion sequence and instantiating C<int> + // FIXME: The "while substituting" note should point at the overload candidate. + b<int>(0, 0); // expected-note {{instantiation of}} expected-note {{while substituting}} + } + + template<typename T> struct Id { typedef T type; }; + template<typename T> void c(T, typename Id<C<T> >::type); + void test_c() { + // Implicit conversion sequences for dependent types are checked later. + c(0.0, 0); // expected-note {{instantiation of}} + } + + namespace partial_ordering { + // FIXME: Second template should be considered more specialized because non-dependent parameter is ignored. + template<typename T> int a(T, short) = delete; // expected-error 0-1{{extension}} expected-note {{candidate}} + template<typename T> int a(T*, char); // expected-note {{candidate}} + int test_a = a((int*)0, 0); // FIXME: expected-error {{ambiguous}} + + // FIXME: Second template should be considered more specialized: + // deducing #1 from #2 ignores the second P/A pair, so deduction succeeds, + // deducing #2 from #1 fails to deduce T, so deduction fails. + template<typename T> int b(T, int) = delete; // expected-error 0-1{{extension}} expected-note {{candidate}} + template<typename T, typename U> int b(T*, U); // expected-note {{candidate}} + int test_b = b((int*)0, 0); // FIXME: expected-error {{ambiguous}} + + // Unintended consequences: because partial ordering does not consider + // explicit template arguments, and deduction from a non-dependent type + // vacuously succeeds, a non-dependent template is less specialized than + // anything else! + // According to DR1391, this is ambiguous! + template<typename T> int c(int); + template<typename T> int c(T); + int test_c1 = c(0); // ok + int test_c2 = c<int>(0); // FIXME: apparently ambiguous + } +} + +namespace dr1399 { // dr1399: dup 1388 + template<typename ...T> void f(T..., int, T...) {} // expected-note {{candidate}} expected-error 0-1{{C++11}} + void g() { + f(0); + f<int>(0, 0, 0); + f(0, 0, 0); // expected-error {{no match}} + } +} |