Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk/15/14?

-- >8 --
In r15-3933 I started using a CONSTRUCTOR to signal direct-init
to build_vec_init rather than a TREE_LIST.  That broke

  struct S {
    int a = 1;
  };
  void foo() {
    S arr[2];
    auto [x, y](arr);
  }

because we pass that new CONSTRUCTOR not to build_vec_init but to
build_aggr_init which then crashes in digest_init_r because the
new CONSTRUCTOR wasn't reshaped.  It should work to reshape it if
its type is CP_AGGREGATE_TYPE_P but it might be safer to resort
back to building up a list if we're not going to go to build_vec_init.

        PR c++/120285

gcc/cp/ChangeLog:

        * init.cc (build_vec_init): Only build up a CONSTRUCTOR for
        arrays, otherwise use a TREE_LIST like prior to r15-3933.

gcc/testsuite/ChangeLog:

        * g++.dg/cpp1z/decomp68.C: New test.
---
 gcc/cp/init.cc                        | 16 +++++++++++-----
 gcc/testsuite/g++.dg/cpp1z/decomp68.C | 20 ++++++++++++++++++++
 2 files changed, 31 insertions(+), 5 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/cpp1z/decomp68.C

diff --git a/gcc/cp/init.cc b/gcc/cp/init.cc
index 437797fef0c..022485c3258 100644
--- a/gcc/cp/init.cc
+++ b/gcc/cp/init.cc
@@ -5079,11 +5079,17 @@ build_vec_init (tree base, tree maxindex, tree init,
                from = move (from);
              if (direct_init)
                {
-                 /* Wrap the initializer in a CONSTRUCTOR so that
-                    build_vec_init recognizes it as direct-initialization.  */
-                 from = build_constructor_single (init_list_type_node,
-                                                  NULL_TREE, from);
-                 CONSTRUCTOR_IS_DIRECT_INIT (from) = true;
+                 if (TREE_CODE (type) == ARRAY_TYPE)
+                   {
+                     /* Wrap the initializer in a CONSTRUCTOR so that
+                        build_vec_init recognizes it as
+                        direct-initialization.  */
+                     from = build_constructor_single (init_list_type_node,
+                                                      NULL_TREE, from);
+                     CONSTRUCTOR_IS_DIRECT_INIT (from) = true;
+                   }
+                 else
+                   from = build_tree_list (NULL_TREE, from);
                }
            }
          else
diff --git a/gcc/testsuite/g++.dg/cpp1z/decomp68.C 
b/gcc/testsuite/g++.dg/cpp1z/decomp68.C
new file mode 100644
index 00000000000..d3d909a33a9
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1z/decomp68.C
@@ -0,0 +1,20 @@
+// PR c++/120285
+// { dg-do compile { target c++17 } }
+
+struct S {
+  int a = 1;
+};
+
+void
+g ()
+{
+  S arr[2];
+  auto [a, b] = arr;
+  auto [c, d](arr);
+  S arr2[2][2];
+  auto [e, f] = arr2;
+  auto [g, h](arr2);
+  S arr3[2][2];
+  auto [i, j] = arr3;
+  auto [k, l](arr3);
+}

base-commit: 7ab4f9cc72b48b341ce52da099ee38112647d644
-- 
2.53.0

Reply via email to