This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [C++ PATCH] Fix tsubst of structured bindings (PR c++/86836)


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]