From 5e539332c47faa6d6df728d27fae5d02805ca5ec Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Wed, 8 Aug 2018 10:32:51 +0200 Subject: [PATCH] re PR c++/86836 (internal compiler error on structured bindings with shadow parameter on templated function) PR c++/86836 * pt.c (tsubst_expr): For structured bindings, call tsubst_decomp_names before tsubst_init, not after it. * g++.dg/cpp1z/decomp46.C: New test. From-SVN: r263391 --- gcc/cp/ChangeLog | 4 +++ gcc/cp/pt.c | 35 ++++++++++++++------------- gcc/testsuite/ChangeLog | 3 +++ gcc/testsuite/g++.dg/cpp1z/decomp46.C | 25 +++++++++++++++++++ 4 files changed, 50 insertions(+), 17 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp1z/decomp46.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index ed3ad71a94a..a6bdc043b05 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,9 @@ 2018-08-08 Jakub Jelinek + PR c++/86836 + * pt.c (tsubst_expr): For structured bindings, call tsubst_decomp_names + before tsubst_init, not after it. + PR c++/86738 * constexpr.c (cxx_eval_binary_expression): For arithmetics involving NULL pointer set *non_constant_p to true. diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 27805040ddb..0a5d112986f 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -16740,7 +16740,17 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl, else { int const_init = false; + unsigned int cnt = 0; + tree first = NULL_TREE, ndecl = error_mark_node; maybe_push_decl (decl); + + if (VAR_P (decl) + && DECL_DECOMPOSITION_P (decl) + && TREE_TYPE (pattern_decl) != error_mark_node) + ndecl = tsubst_decomp_names (decl, pattern_decl, args, + complain, in_decl, &first, + &cnt); + if (VAR_P (decl) && DECL_PRETTY_FUNCTION_P (decl)) { @@ -16756,23 +16766,14 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl, if (VAR_P (decl)) const_init = (DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (pattern_decl)); - if (VAR_P (decl) - && DECL_DECOMPOSITION_P (decl) - && TREE_TYPE (pattern_decl) != error_mark_node) - { - unsigned int cnt; - tree first; - tree ndecl - = tsubst_decomp_names (decl, pattern_decl, args, - complain, in_decl, &first, &cnt); - if (ndecl != error_mark_node) - cp_maybe_mangle_decomp (ndecl, first, cnt); - cp_finish_decl (decl, init, const_init, NULL_TREE, 0); - if (ndecl != error_mark_node) - cp_finish_decomp (ndecl, first, cnt); - } - else - cp_finish_decl (decl, init, const_init, NULL_TREE, 0); + + if (ndecl != error_mark_node) + cp_maybe_mangle_decomp (ndecl, first, cnt); + + cp_finish_decl (decl, init, const_init, NULL_TREE, 0); + + if (ndecl != error_mark_node) + cp_finish_decomp (ndecl, first, cnt); } } } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 6eb02bb3dec..e614fed960a 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,8 @@ 2018-08-08 Jakub Jelinek + PR c++/86836 + * g++.dg/cpp1z/decomp46.C: New test. + PR c++/86738 * g++.dg/opt/pr86738.C: New test. diff --git a/gcc/testsuite/g++.dg/cpp1z/decomp46.C b/gcc/testsuite/g++.dg/cpp1z/decomp46.C new file mode 100644 index 00000000000..e159b6adb63 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1z/decomp46.C @@ -0,0 +1,25 @@ +// PR c++/86836 +// { dg-do compile { target c++11 } } +// { dg-options "" } + +struct A { + int operator*(); + void operator++(); + bool operator!=(A); +}; +template class map { +public: + A begin(); + A end(); +}; + +template void mergemap(map orig, map toadd) { + for (auto p : toadd) + auto [orig] = orig; // { dg-error "use of 'orig' before deduction of 'auto'" } +} // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + +int +main() { + map x, y; + mergemap(x, y); +} -- 2.30.2