summaryrefslogtreecommitdiffstats
path: root/test/CXX
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2018-07-12 23:32:39 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2018-07-12 23:32:39 +0000
commitfb6fe237ce9a38b43c0eb39bbd6afa63c01ac70f (patch)
tree19351dc5ce16bebf45a4f3c643050f6e924c6492 /test/CXX
parent0e073980598008bb839173d40f1b1306b16bc902 (diff)
PR38136: improve handling of template argument deduction of non-trailing
function parameter packs. This makes our handling of non-trailing function parameter packs consistent between the case of deduction at the top level in a function call and other cases where deduction encounters a non-trailing function parameter pack. Instead of treating a non-trailing pack and all later parameters as being non-deduced, we treat a non-trailing pack as exactly matching any explicitly-specified template arguments (or being an empty pack if there are no such arguments). This corresponds to the "never deduced" rule in [temp.deduct.call]p1, but generalized to all deduction contexts. Non-trailing template argument packs still result in the entire template argument list being treated as non-deduced, as specified in [temp.deduct.type]p9. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@336962 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/CXX')
-rw-r--r--test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p5-0x.cpp18
-rw-r--r--test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p9-0x.cpp38
2 files changed, 54 insertions, 2 deletions
diff --git a/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p5-0x.cpp b/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p5-0x.cpp
index d239a5e172..697412995b 100644
--- a/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p5-0x.cpp
+++ b/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p5-0x.cpp
@@ -1,5 +1,4 @@
// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
-// expected-no-diagnostics
// FIXME: More bullets to go!
@@ -16,8 +15,23 @@ struct has_nondeduced_pack_test<R(FirstType, Types..., int),
// - A function parameter pack that does not occur at the end of the
// parameter-declaration-clause.
+//
+// We interpret [temp.deduct.call]p1's
+//
+// "When a function parameter pack appears in a non-deduced context
+// (12.9.2.5), the type of that pack is never deduced."
+//
+// as applying in all deduction contexts, not just [temp.deduct.call],
+// so we do *not* deduce Types from the second argument here. (More
+// precisely, we deduce it as <> when processing the first argument,
+// and then fail because 'int' doesn't match 'double, int'.)
int check_nondeduced_pack_test0[
has_nondeduced_pack_test<int(float, double, int),
- int(float, double)>::value? 1 : -1];
+ int(float, double)>::value? -1 : 1];
+template<typename ...T> void has_non_trailing_pack(T ..., int);
+void (*ptr_has_non_trailing_pack)(char, int) = has_non_trailing_pack<char>;
+template<typename ...T, typename U> void has_non_trailing_pack_and_more(T ..., U); // expected-note {{failed}}
+void (*ptr_has_non_trailing_pack_and_more_1)(float, double, int) = &has_non_trailing_pack_and_more<float, double>;
+void (*ptr_has_non_trailing_pack_and_more_2)(float, double, int) = &has_non_trailing_pack_and_more<float>; // expected-error {{does not match}}
diff --git a/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p9-0x.cpp b/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p9-0x.cpp
index 54a54b0c48..fccac8f1e5 100644
--- a/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p9-0x.cpp
+++ b/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p9-0x.cpp
@@ -35,6 +35,44 @@ namespace PackExpansionNotAtEnd {
struct UselessPartialSpec<Types..., Tail>; // expected-error{{class template partial specialization contains template parameters that cannot be deduced; this partial specialization will never be used}}
}
+// When a pack expansion occurs within a template argument list, the entire
+// list is a non-deduced context. For the corresponding case in a function
+// parameter list, only that parameter is non-deduced.
+//
+// FIXME: It's not clear that this difference is intended, but the wording is
+// explicit.
+namespace PackExpansionNotAtEndFunctionVersusTemplate {
+ template<typename ...T> struct X {};
+ template<typename ...T, typename U> void f1(void(T..., U));
+ // expected-note@+1 {{couldn't infer template argument 'U'}}
+ template<typename ...T, typename U> void f2(X<T..., U>); // FIXME: ill-formed, U is not deducible
+
+ void g(int, int, int);
+ X<int, int, int> h;
+ void test() {
+ // This is deducible: the T... parameter is a non-deduced context, but
+ // that's OK because we don't need to deduce it.
+ f1<int, int>(g);
+ // This is not deducible: the T... parameter renders the entire
+ // template-argument-list a non-deduced context, so U is not deducible.
+ f2<int, int>(h); // expected-error {{no matching function}}
+ }
+
+ template<typename T> struct Y;
+ template<typename ...T, // expected-note {{non-deducible template parameter 'T'}}
+ typename U>
+ struct Y<void(T..., U)> {}; // expected-error {{cannot be deduced}}
+ template<typename ...T, // expected-note {{non-deducible template parameter 'T'}}
+ typename U> // expected-note {{non-deducible template parameter 'U'}}
+ struct Y<X<T..., U>>; // expected-error {{cannot be deduced}}
+ // FIXME: T is not deducible here, due to [temp.deduct.call]p1:
+ // "When a function parameter pack appears in a non-deduced context,
+ // the type of that pack is never deduced."
+ template<typename ...T,
+ typename U>
+ struct Y<void(T..., U, T...)> {};
+}
+
namespace DeduceNonTypeTemplateArgsInArray {
template<typename ...ArrayTypes>
struct split_arrays;