diff options
author | Jason Merrill <jason@redhat.com> | 2016-02-25 10:23:47 -0500 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2016-02-25 10:23:47 -0500 |
commit | bd28a34f33a84524d8c61fbf23d88d1158c579a7 (patch) | |
tree | ff5719ec9900a39ee822f08421cd7494cf377051 /gcc | |
parent | 6a0cc1cd6c5f5fbc4675ac7c3e7a899a3d8d4475 (diff) | |
download | gcc-bd28a34f33a84524d8c61fbf23d88d1158c579a7.zip gcc-bd28a34f33a84524d8c61fbf23d88d1158c579a7.tar.gz gcc-bd28a34f33a84524d8c61fbf23d88d1158c579a7.tar.bz2 |
re PR c++/69842 (Parameter deduction in polymorphic lambdas)
PR c++/69842
* method.c (forward_parm): Handle parameter packs.
* lambda.c (maybe_add_lambda_conv_op): Use it for them.
From-SVN: r233719
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/cp/lambda.c | 30 | ||||
-rw-r--r-- | gcc/cp/method.c | 9 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp1y/lambda-generic-variadic4.C | 20 |
4 files changed, 43 insertions, 20 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 97296e4..ea4389d 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,9 @@ 2016-02-25 Jason Merrill <jason@redhat.com> + PR c++/69842 + * method.c (forward_parm): Handle parameter packs. + * lambda.c (maybe_add_lambda_conv_op): Use it for them. + PR c++/67364 * constexpr.c (cxx_eval_component_reference): Don't complain about unevaluated empty classes. diff --git a/gcc/cp/lambda.c b/gcc/cp/lambda.c index 296c6f7..cdc11fe 100644 --- a/gcc/cp/lambda.c +++ b/gcc/cp/lambda.c @@ -29,6 +29,7 @@ along with GCC; see the file COPYING3. If not see #include "cgraph.h" #include "tree-iterator.h" #include "toplev.h" +#include "gimplify.h" /* Constructor for a lambda expression. */ @@ -952,23 +953,18 @@ maybe_add_lambda_conv_op (tree type) if (generic_lambda_p) { - if (DECL_PACK_P (tgt)) - { - tree a = make_pack_expansion (tgt); - if (decltype_call) - CALL_EXPR_ARG (decltype_call, ix) = copy_node (a); - PACK_EXPANSION_LOCAL_P (a) = true; - CALL_EXPR_ARG (call, ix) = a; - } - else - { - ++processing_template_decl; - tree a = forward_parm (tgt); - --processing_template_decl; - CALL_EXPR_ARG (call, ix) = a; - if (decltype_call) - CALL_EXPR_ARG (decltype_call, ix) = copy_node (a); - } + ++processing_template_decl; + tree a = forward_parm (tgt); + --processing_template_decl; + + CALL_EXPR_ARG (call, ix) = a; + if (decltype_call) + CALL_EXPR_ARG (decltype_call, ix) = unshare_expr (a); + + if (PACK_EXPANSION_P (a)) + /* Set this after unsharing so it's not in decltype_call. */ + PACK_EXPANSION_LOCAL_P (a) = true; + ++ix; } else diff --git a/gcc/cp/method.c b/gcc/cp/method.c index f455b32..0235e6a 100644 --- a/gcc/cp/method.c +++ b/gcc/cp/method.c @@ -481,9 +481,12 @@ tree forward_parm (tree parm) { tree exp = convert_from_reference (parm); - if (TREE_CODE (TREE_TYPE (parm)) != REFERENCE_TYPE - || TYPE_REF_IS_RVALUE (TREE_TYPE (parm))) - exp = move (exp); + tree type = TREE_TYPE (parm); + if (DECL_PACK_P (parm)) + type = PACK_EXPANSION_PATTERN (type); + exp = build_static_cast (type, exp, tf_warning_or_error); + if (DECL_PACK_P (parm)) + exp = make_pack_expansion (exp); return exp; } diff --git a/gcc/testsuite/g++.dg/cpp1y/lambda-generic-variadic4.C b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-variadic4.C new file mode 100644 index 0000000..0b65f56 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-variadic4.C @@ -0,0 +1,20 @@ +// PR c++/69842 +// { dg-do compile { target c++14 } } + +template <class T, class U> struct assert_same; +template <class T> struct assert_same<T,T> {}; + +template<typename T> +void sink(T &&) +{ + assert_same<int,T> a; +} + +int main() +{ + auto const g([](auto &&... _var) { + sink(static_cast<decltype(_var)>(_var)...); + }); + + g(0); +} |