summaryrefslogtreecommitdiffstats
path: root/clang/test
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
commitc379d1a424badc74906db37c6c826e5b4a155b25 (patch)
treec175c59ce266c7875cf1b4592bc51fb81cbee039 /clang/test
parent73dd5f9c08b974b41754faf410be596e306478b2 (diff)
downloadbcm5719-llvm-c379d1a424badc74906db37c6c826e5b4a155b25.tar.gz
bcm5719-llvm-c379d1a424badc74906db37c6c826e5b4a155b25.zip
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. llvm-svn: 336962
Diffstat (limited to 'clang/test')
-rw-r--r--clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p5-0x.cpp18
-rw-r--r--clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p9-0x.cpp38
2 files changed, 54 insertions, 2 deletions
diff --git a/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p5-0x.cpp b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p5-0x.cpp
index d239a5e1720..697412995b3 100644
--- a/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p5-0x.cpp
+++ b/clang/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/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p9-0x.cpp b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p9-0x.cpp
index 54a54b0c486..fccac8f1e5a 100644
--- a/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p9-0x.cpp
+++ b/clang/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;
OpenPOWER on IntegriCloud