aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorNathan Sidwell <nathan@acm.org>2018-01-17 15:39:35 +0000
committerNathan Sidwell <nathan@gcc.gnu.org>2018-01-17 15:39:35 +0000
commitf0fbe57d54af9234f441f1332050ef36d0787653 (patch)
tree5ef4ecb3766aa95801d7aaca21e21760deb9cd88 /gcc
parentc6d6367f848cfd8381aba41e035c5e7e873667c5 (diff)
downloadgcc-f0fbe57d54af9234f441f1332050ef36d0787653.zip
gcc-f0fbe57d54af9234f441f1332050ef36d0787653.tar.gz
gcc-f0fbe57d54af9234f441f1332050ef36d0787653.tar.bz2
[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) <case RANGE_FOR_STMT>: Rebuild a range_for if this not a final instantiation. PR c++/83739 * g++.dg/cpp1y/pr83739.C: New. From-SVN: r256795
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/pt.c36
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/pr83739.C16
4 files changed, 52 insertions, 11 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index d378cb2..9a48aba 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,9 @@
+2018-01-17 Nathan Sidwell <nathan@acm.org>
+
+ PR c++/83739
+ * pt.c (tsubst_expr) <case RANGE_FOR_STMT>: Rebuild a range_for if
+ this not a final instantiation.
+
2018-01-16 Jason Merrill <jason@redhat.com>
PR c++/83714 - ICE checking return in template.
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 322408d..0177882 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 a577e6f..04a1ffc 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2018-01-17 Nathan Sidwell <nathan@acm.org>
+
+ PR c++/83739
+ * g++.dg/cpp1y/pr83739.C: New.
+
2018-01-17 Eric Botcazou <ebotcazou@adacore.com>
* 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 0000000..4761220
--- /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 <bool> void f()
+{
+ int x[2];
+ auto delegate = [](auto & foo)
+ {
+ for (auto bar : foo);
+ };
+ delegate(x);
+}
+int main() {
+ f<true>();
+}