re PR c++/86836 (internal compiler error on structured bindings with shadow parameter...
authorJakub Jelinek <jakub@redhat.com>
Wed, 8 Aug 2018 08:32:51 +0000 (10:32 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Wed, 8 Aug 2018 08:32:51 +0000 (10:32 +0200)
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
gcc/cp/pt.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp1z/decomp46.C [new file with mode: 0644]

index ed3ad71a94ac827461bfedc60338a33e954f5faf..a6bdc043b05004a7c816155bfeb7732046eddf0d 100644 (file)
@@ -1,5 +1,9 @@
 2018-08-08  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.
+
        PR c++/86738
        * constexpr.c (cxx_eval_binary_expression): For arithmetics involving
        NULL pointer set *non_constant_p to true.
index 27805040ddb09cac30de578695e2e4a6dbe170cf..0a5d112986fc3d366fb301c444f44aac0ce36324 100644 (file)
@@ -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);
                  }
              }
          }
index 6eb02bb3decef86e8b949bbff640beb24480ff7f..e614fed960ae65fbe52fe9043e0d58a6936f13ff 100644 (file)
@@ -1,5 +1,8 @@
 2018-08-08  Jakub Jelinek  <jakub@redhat.com>
 
+       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 (file)
index 0000000..e159b6a
--- /dev/null
@@ -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);
+}