diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2018-07-12 23:32:39 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2018-07-12 23:32:39 +0000 |
commit | fb6fe237ce9a38b43c0eb39bbd6afa63c01ac70f (patch) | |
tree | 19351dc5ce16bebf45a4f3c643050f6e924c6492 /test/CXX | |
parent | 0e073980598008bb839173d40f1b1306b16bc902 (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.cpp | 18 | ||||
-rw-r--r-- | test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p9-0x.cpp | 38 |
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; |