summaryrefslogtreecommitdiffstats
path: root/test/Parser/cxx1z-class-template-argument-deduction.cpp
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2017-02-14 00:25:28 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2017-02-14 00:25:28 +0000
commit5b38d7133e9cd36796e369aaa8f58b51dfe972d1 (patch)
treeeb21ceb0e35fab5fe4e3a6821082ce1e01ce757f /test/Parser/cxx1z-class-template-argument-deduction.cpp
parent515451d31036344d4a58d8145eeb5795d0d3980a (diff)
[c++1z] Synthesize implicit deduction guides from constructors on demand. Rank
such guides below explicit ones, and ensure that references to the class's template parameters are not treated as forwarding references. We make a few tweaks to the wording in the current standard: 1) The constructor parameter list is copied faithfully to the deduction guide, without losing default arguments or a varargs ellipsis (which the standard wording loses by omission). 2) If the class template declares no constructors, we add a T() -> T<...> guide (which will only ever work if T has default arguments for all non-pack template parameters). 3) If the class template declares nothing that looks like a copy or move constructor, we add a T(T<...>) -> T<...> guide. #2 and #3 follow from the "pretend we had a class type with these constructors" philosophy for deduction guides. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@295007 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/Parser/cxx1z-class-template-argument-deduction.cpp')
-rw-r--r--test/Parser/cxx1z-class-template-argument-deduction.cpp28
1 files changed, 13 insertions, 15 deletions
diff --git a/test/Parser/cxx1z-class-template-argument-deduction.cpp b/test/Parser/cxx1z-class-template-argument-deduction.cpp
index ab8c867f60..b7c7ef7500 100644
--- a/test/Parser/cxx1z-class-template-argument-deduction.cpp
+++ b/test/Parser/cxx1z-class-template-argument-deduction.cpp
@@ -31,11 +31,11 @@ namespace template_template_arg {
namespace injected_class_name {
template<typename T> struct A {
A(T);
- void f(int) {
+ void f(int) { // expected-note {{previous}}
A a = 1;
- injected_class_name::A b = 1; // expected-error {{no viable constructor or deduction guide}}
+ injected_class_name::A b = 1; // expected-note {{in instantiation of template class 'injected_class_name::A<int>'}}
}
- void f(T);
+ void f(T); // expected-error {{multiple overloads of 'f' instantiate to the same signature 'void (int)'}}
};
A<short> ai = 1;
A<double>::A b(1); // expected-error {{constructor name}}
@@ -165,19 +165,17 @@ namespace typename_specifier {
typename ::A (*fp)() = 0; // expected-error {{cannot form function returning deduced class template specialization type}}
typename ::A [x, y] = 0; // expected-error {{cannot be declared with type 'typename ::A'}} expected-error {{type 'typename ::A<int>' (aka 'A<int>') decomposes into 0}}
- struct X { template<typename T> struct A {}; }; // expected-note 8{{template}}
+ struct X { template<typename T> struct A { A(T); }; }; // expected-note 8{{declared here}}
- // FIXME: We do not yet properly support class template argument deduction
- // during template instantiation.
template<typename T> void f() {
- (void) typename T::A(0); // expected-error {{no viable}}
- (void) typename T::A{0}; // expected-error {{no viable}}
- new typename T::A(0); // expected-error {{no viable}}
- new typename T::A{0}; // expected-error {{no viable}}
- typename T::A a = 0; // expected-error {{no viable}}
- const typename T::A b = 0; // expected-error {{no viable}}
- if (typename T::A a = 0) {} // expected-error {{no viable}}
- for (typename T::A a = 0; typename T::A b = 0; /**/) {} // expected-error 2{{no viable}}
+ (void) typename T::A(0);
+ (void) typename T::A{0};
+ new typename T::A(0);
+ new typename T::A{0};
+ typename T::A a = 0;
+ const typename T::A b = 0;
+ if (typename T::A a = 0) {} // expected-error {{value of type 'typename X::A<int>' (aka 'typename_specifier::X::A<int>') is not contextually convertible to 'bool'}}
+ for (typename T::A a = 0; typename T::A b = 0; /**/) {} // expected-error {{value of type 'typename X::A<int>' (aka 'typename_specifier::X::A<int>') is not contextually convertible to 'bool'}}
{(void)(typename T::A)(0);} // expected-error{{refers to class template member}}
{(void)(typename T::A){0};} // expected-error{{refers to class template member}}
@@ -187,7 +185,7 @@ namespace typename_specifier {
{typename T::A arr[3] = 0;} // expected-error {{refers to class template member}}
{typename T::A F::*pm = 0;} // expected-error {{refers to class template member}}
{typename T::A (*fp)() = 0;} // expected-error {{refers to class template member}}
- {typename T::A [x, y] = 0;} // expected-error {{cannot be declared with type 'typename T::A'}} expected-error {{no viable}}
+ {typename T::A [x, y] = 0;} // expected-error {{cannot be declared with type 'typename T::A'}} expected-error {{type 'typename X::A<int>' (aka 'typename_specifier::X::A<int>') decomposes into 0}}
}
template void f<X>(); // expected-note {{instantiation of}}