From f0fbe57d54af9234f441f1332050ef36d0787653 Mon Sep 17 00:00:00 2001 From: Nathan Sidwell Date: Wed, 17 Jan 2018 15:39:35 +0000 Subject: [PATCH] [C++/83739] bogus error tsubsting range for in generic lambda https://gcc.gnu.org/ml/gcc-patches/2018-01/msg01554.html PR c++/83739 * pt.c (tsubst_expr) : Rebuild a range_for if this not a final instantiation. PR c++/83739 * g++.dg/cpp1y/pr83739.C: New. From-SVN: r256795 --- gcc/cp/ChangeLog | 6 +++++ gcc/cp/pt.c | 36 +++++++++++++++++++--------- gcc/testsuite/ChangeLog | 5 ++++ gcc/testsuite/g++.dg/cpp1y/pr83739.C | 16 +++++++++++++ 4 files changed, 52 insertions(+), 11 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp1y/pr83739.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index d378cb2ff3f..9a48abab6af 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2018-01-17 Nathan Sidwell + + PR c++/83739 + * pt.c (tsubst_expr) : Rebuild a range_for if + this not a final instantiation. + 2018-01-16 Jason Merrill PR c++/83714 - ICE checking return in template. diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 322408d92ec..01778820793 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -16153,26 +16153,40 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl, case RANGE_FOR_STMT: { + /* Construct another range_for, if this is not a final + substitution (for inside inside a generic lambda of a + template). Otherwise convert to a regular for. */ tree decl, expr; - stmt = begin_for_stmt (NULL_TREE, NULL_TREE); + stmt = (processing_template_decl + ? begin_range_for_stmt (NULL_TREE, NULL_TREE) + : begin_for_stmt (NULL_TREE, NULL_TREE)); decl = RANGE_FOR_DECL (t); decl = tsubst (decl, args, complain, in_decl); maybe_push_decl (decl); expr = RECUR (RANGE_FOR_EXPR (t)); - const unsigned short unroll - = RANGE_FOR_UNROLL (t) ? tree_to_uhwi (RANGE_FOR_UNROLL (t)) : 0; + + tree decomp_first = NULL_TREE; + unsigned decomp_cnt = 0; if (VAR_P (decl) && DECL_DECOMPOSITION_P (decl)) + decl = tsubst_decomp_names (decl, RANGE_FOR_DECL (t), args, + complain, in_decl, + &decomp_first, &decomp_cnt); + + if (processing_template_decl) { - unsigned int cnt; - tree first; - decl = tsubst_decomp_names (decl, RANGE_FOR_DECL (t), args, - complain, in_decl, &first, &cnt); - stmt = cp_convert_range_for (stmt, decl, expr, first, cnt, - RANGE_FOR_IVDEP (t), unroll); + RANGE_FOR_IVDEP (stmt) = RANGE_FOR_IVDEP (t); + RANGE_FOR_UNROLL (stmt) = RANGE_FOR_UNROLL (t); + finish_range_for_decl (stmt, decl, expr); } else - stmt = cp_convert_range_for (stmt, decl, expr, NULL_TREE, 0, - RANGE_FOR_IVDEP (t), unroll); + { + unsigned short unroll = (RANGE_FOR_UNROLL (t) + ? tree_to_uhwi (RANGE_FOR_UNROLL (t)) : 0); + stmt = cp_convert_range_for (stmt, decl, expr, + decomp_first, decomp_cnt, + RANGE_FOR_IVDEP (t), unroll); + } + bool prev = note_iteration_stmt_body_start (); RECUR (RANGE_FOR_BODY (t)); note_iteration_stmt_body_end (prev); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index a577e6f88d5..04a1ffcc882 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2018-01-17 Nathan Sidwell + + PR c++/83739 + * g++.dg/cpp1y/pr83739.C: New. + 2018-01-17 Eric Botcazou * gcc.target/visium/overflow8.c: Pass -fno-if-conversion. diff --git a/gcc/testsuite/g++.dg/cpp1y/pr83739.C b/gcc/testsuite/g++.dg/cpp1y/pr83739.C new file mode 100644 index 00000000000..4761220c057 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/pr83739.C @@ -0,0 +1,16 @@ +// { dg-do compile { target c++14 } } + +// PR 83739, deduced range-for in lambda in template + +template void f() +{ + int x[2]; + auto delegate = [](auto & foo) + { + for (auto bar : foo); + }; + delegate(x); +} +int main() { + f(); +} -- 2.30.2