This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [C++ PATCH] Fix tsubst of structured bindings (PR c++/86836)
- From: Jason Merrill <jason at redhat dot com>
- To: Jakub Jelinek <jakub at redhat dot com>
- Cc: Nathan Sidwell <nathan at acm dot org>, gcc-patches List <gcc-patches at gcc dot gnu dot org>
- Date: Mon, 6 Aug 2018 00:34:45 +1000
- Subject: Re: [C++ PATCH] Fix tsubst of structured bindings (PR c++/86836)
- References: <20180803155435.GQ17988@tucnak>
OK.
On Sat, Aug 4, 2018 at 1:54 AM, Jakub Jelinek <jakub@redhat.com> wrote:
> Hi!
>
> As mentioned in the PR, for valid structured bindings this patch should be
> unnecessary, because the identifiers from the structured binding shouldn't
> be used in the initializer of the structured binding, but for invalid source
> it can matter. When tsubst_init is called before tsubst_decomp_names,
> the local specializations for the decomp id VAR_DECLs aren't created and
> so the tsubst of those VAR_DECLs gives the PARM_DECL in this testcase, or
> something else unrelated to the decomp.
>
> Fixed by doing tsubst_decomp_names first, then tsubst_init the initializer
> and then the rest.
>
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk and 8.3
> after a while?
>
> 2018-08-03 Jakub Jelinek <jakub@redhat.com>
>
> 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.
>
> --- gcc/cp/pt.c.jj 2018-08-03 11:36:25.550755429 +0200
> +++ gcc/cp/pt.c 2018-08-03 11:48:51.144567965 +0200
> @@ -16740,7 +16740,17 @@ tsubst_expr (tree t, tree args, tsubst_f
> 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_f
> 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);
> }
> }
> }
> --- gcc/testsuite/g++.dg/cpp1z/decomp46.C.jj 2018-08-03 12:00:10.524066454 +0200
> +++ gcc/testsuite/g++.dg/cpp1z/decomp46.C 2018-08-03 11:59:49.925018174 +0200
> @@ -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 <typename> class map {
> +public:
> + A begin();
> + A end();
> +};
> +
> +template <typename T> void mergemap(map<T> orig, map<T> 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<double> x, y;
> + mergemap(x, y);
> +}
>
> Jakub