[c++1z] Add some more tests for class template argument deduction, add

feature-test macro, and mark feature as done on status page.

llvm-svn: 295011
This commit is contained in:
Richard Smith 2017-02-14 00:55:25 +00:00
parent dc169759ca
commit cbe079321e
6 changed files with 72 additions and 3 deletions

View File

@ -522,6 +522,8 @@ static void InitializeCPlusPlusFeatureTestMacros(const LangOptions &LangOpts,
Builder.defineMacro("__cpp_structured_bindings", "201606");
Builder.defineMacro("__cpp_nontype_template_args", "201411");
Builder.defineMacro("__cpp_fold_expressions", "201603");
// FIXME: This is not yet listed in SD-6.
Builder.defineMacro("__cpp_deduction_guides", "201611");
}
if (LangOpts.AlignedAllocation)
Builder.defineMacro("__cpp_aligned_new", "201606");

View File

@ -1,4 +1,4 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s
// RUN: %clang_cc1 -fsyntax-only -verify -std=c++1z %s
// expected-no-diagnostics
template<typename T> int &f0(T*, int);
@ -12,6 +12,28 @@ void test_f0(int* ip, void *vp) {
float &fr = f0(vp, 0);
}
namespace deduction_guide_example {
template<typename T> struct A {
A(T, int*);
A(A<T>&, int*);
enum { value };
};
template<typename T> struct remove_ref_impl;
template<typename T> struct remove_ref_impl<T&> { using type = T; };
template<typename T> using remove_ref = typename remove_ref_impl<T>::type;
// FIXME: The standard's example is wrong; we add a remove_ref<...> here to
// fix it.
template<typename T, int N = remove_ref<T>::value> A(T&&, int*) -> A<T>;
A a{1, 0};
extern A<int> a;
A b{a, 0};
A<int> *pa = &a;
A<A<int>&> *pb = &b;
}
// Partial ordering of function template specializations will be tested
// elsewhere
// FIXME: Initialization by user-defined conversion is tested elsewhere

View File

@ -73,4 +73,21 @@ namespace std_example {
int n1 = f(i);
int n2 = f(0);
int n3 = g(i); // expected-error{{no matching function for call to 'g'}}
#if __cplusplus > 201402L
template<class T> struct A { // expected-note {{candidate}}
template<class U>
A(T &&, U &&, int *); // expected-note {{[with T = int, U = int] not viable: no known conversion from 'int' to 'int &&'}}
A(T &&, int *); // expected-note {{requires 2}}
};
template<class T> A(T &&, int *) -> A<T>; // expected-note {{requires 2}}
int *ip;
A a{i, 0, ip}; // expected-error {{no viable constructor or deduction guide}}
A a0{0, 0, ip};
A a2{i, ip};
A<int> &a0r = a0;
A<int&> &a2r = a2;
#endif
}

View File

@ -92,6 +92,14 @@
#error "wrong value for __cpp_nontype_template_args"
#endif
#if check(template_template_args, 0, 0, 0, 0) // FIXME: should be 201611 when feature is enabled
#error "wrong value for __cpp_template_template_args"
#endif
#if check(deduction_guides, 0, 0, 0, 201611) // FIXME: provisional name
#error "wrong value for __cpp_deduction_guides"
#endif
// --- C++14 features ---
#if check(binary_literals, 0, 0, 201304, 201304)

View File

@ -117,3 +117,23 @@ namespace dependent {
g("foo"); // expected-note {{instantiation of}}
}
}
namespace look_into_current_instantiation {
template<typename U> struct Q {};
template<typename T> struct A {
using U = T;
template<typename> using V = Q<A<T>::U>;
template<typename W = int> A(V<W>);
};
A a = Q<float>(); // ok, can look through class-scope typedefs and alias
// templates, and members of the current instantiation
A<float> &r = a;
template<typename T> struct B { // expected-note {{could not match 'B<T>' against 'int'}}
struct X {
typedef T type;
};
B(typename X::type); // expected-note {{couldn't infer template argument 'T'}}
};
B b = 0; // expected-error {{no viable}}
}

View File

@ -684,11 +684,11 @@ as the draft C++1z standard evolves.
<tr>
<td rowspan="2">Template argument deduction for class templates</td>
<td><a href="http://wg21.link/p0091r3">P0091R3</a></td>
<td class="partial" align="center">Partial</td>
<td class="svn" align="center">SVN</td>
</tr>
<tr> <!-- from Issaquah -->
<td><a href="http://wg21.link/p0512r0">P0512R0</a></td>
<td class="partial" align="center">Partial</td>
<td class="svn" align="center">SVN</td>
</tr>
<tr>
<td>Non-type template parameters with <tt>auto</tt> type</td>