On Wed, Aug 06, 2025 at 11:53:55AM -0700, Jason Merrill wrote:
> > And one thing still unresolved is debug info, I've just added DECL_IGNORED_P
> > on the structured binding pack VAR_DECL because there were ICEs with -g
> > for now, hope it can be fixed incrementally but am not sure what exactly
> > we should emit in the debug info for that.
> 
> The Clang mangling of the underlying variable seems fine, just mentioning
> the bound names; we can't get mangling collisions between pack and non-pack
> versions of the same name.
> 
> But It looks like they use .N discriminators for the individual elements,
> which is wrong because . is reserved for implementation details.  But I'd
> think it should be fine to use [<discriminator>] instead.

If you want the whole structured bindings to be mangled normally as if the
pack isn't a pack and the individual vars of the structured binding pack
mangled as multiple occurrences of the named entities, the following
patch does that.

2025-08-07  Jakub Jelinek  <ja...@redhat.com>
    
        PR c++/117783
        * decl.cc (cp_finish_decomp): Don't sorry on tuple static
        structured bindings with a pack, instead temporarily reset
        DECL_NAME of the individual vars in the pack to the name
        of the pack for cp_finish_decl time and force mangling.

        * g++.dg/cpp26/decomp19.C: Don't expect sorry on tuple static
        structured bindings with a pack.
        * g++.dg/cpp26/decomp26.C: New test.

--- gcc/cp/decl.cc.jj   2025-08-07 09:29:37.056498988 +0200
+++ gcc/cp/decl.cc      2025-08-07 15:53:48.167219127 +0200
@@ -10223,14 +10223,6 @@ cp_finish_decomp (tree decl, cp_decomp *
                              "pack %qD", v[pack]);
                      goto error_out;
                    }
-                 if (j == 0
-                     && !processing_template_decl
-                     && TREE_STATIC (decl))
-                   {
-                     sorry_at (dloc, "mangling of structured binding pack "
-                                     "elements not implemented yet");
-                     goto error_out;
-                   }
                  maybe_push_decl (t);
                  /* Save the decltype away before reference collapse.  */
                  hash_map_safe_put<hm_ggc> (decomp_type_table, t, eltype);
@@ -10241,8 +10233,16 @@ cp_finish_decomp (tree decl, cp_decomp *
                  if (!processing_template_decl)
                    {
                      copy_linkage (t, decl);
+                     tree name = DECL_NAME (t);
+                     if (TREE_STATIC (decl))
+                       DECL_NAME (t) = DECL_NAME (v[pack]);
                      cp_finish_decl (t, init, /*constexpr*/false,
                                      /*asm*/NULL_TREE, LOOKUP_NORMAL);
+                     if (TREE_STATIC (decl))
+                       {
+                         DECL_ASSEMBLER_NAME (t);
+                         DECL_NAME (t) = name;
+                       }
                    }
                }
              continue;
--- gcc/testsuite/g++.dg/cpp26/decomp19.C.jj    2025-08-07 09:13:54.501195628 
+0200
+++ gcc/testsuite/g++.dg/cpp26/decomp19.C       2025-08-07 16:18:22.449507549 
+0200
@@ -24,7 +24,6 @@ foo ()
   static auto [ta, ...tb, tc] = t;     // { dg-warning "structured binding 
packs only available with" "" { target { c++17 && c++23_down } } }
                                        // { dg-warning "structured bindings 
only available with" "" { target c++14_down } .-1 }
                                        // { dg-warning "structured binding 
declaration can be 'static' only in" "" { target c++17_down } .-2 }
-                                       // { dg-message "mangling of structured 
binding pack elements not implemented yet" "" { target *-*-* } .-3 }
 }
 
 template <int N>
@@ -35,7 +34,6 @@ bar ()
   thread_local auto [...ta] = t;       // { dg-warning "structured binding 
packs only available with" "" { target { c++17 && c++23_down } } }
                                        // { dg-warning "structured bindings 
only available with" "" { target c++14_down } .-1 }
                                        // { dg-warning "structured binding 
declaration can be 'thread_local' only in" "" { target c++17_down } .-2 }
-                                       // { dg-message "mangling of structured 
binding pack elements not implemented yet" "" { target *-*-* } .-3 }
 }
 
 int
--- gcc/testsuite/g++.dg/cpp26/decomp26.C.jj    2025-08-07 16:18:39.548289896 
+0200
+++ gcc/testsuite/g++.dg/cpp26/decomp26.C       2025-08-07 16:29:21.129123164 
+0200
@@ -0,0 +1,77 @@
+// P1061R10 - Structured Bindings can introduce a Pack
+// { dg-do compile { target c++11 } }
+// { dg-options "" }
+// { dg-final { scan-assembler "_ZZ3fooI1AEivE1a:" } }
+// { dg-final { scan-assembler "_ZZ3fooI1AEivE1b:" } }
+// { dg-final { scan-assembler "_ZZ3fooI1AEivE1c:" } }
+// { dg-final { scan-assembler "_ZZ3fooI1AEivE1a_0:" } }
+// { dg-final { scan-assembler "_ZZ3fooI1AEivE1b_0:" } }
+// { dg-final { scan-assembler "_ZZ3fooI1AEivE1c_0:" } }
+// { dg-final { scan-assembler "_ZZ3fooI1AEivEDC1a1b1cE:" } }
+// { dg-final { scan-assembler "_ZZ3fooI1AEivE1a_1:" } }
+// { dg-final { scan-assembler "_ZZ3fooI1AEivE1b_1:" } }
+// { dg-final { scan-assembler "_ZZ3fooI1AEivE1c_1:" } }
+// { dg-final { scan-assembler "_ZZ3fooI1BEivE1a:" } }
+// { dg-final { scan-assembler "_ZZ3fooI1BEivE1b:" } }
+// { dg-final { scan-assembler "_ZZ3fooI1BEivE1c:" } }
+// { dg-final { scan-assembler "_ZZ3fooI1BEivE1a_0:" } }
+// { dg-final { scan-assembler "_ZZ3fooI1BEivE1b_0:" } }
+// { dg-final { scan-assembler "_ZZ3fooI1BEivE1c_0:" } }
+// { dg-final { scan-assembler "_ZZ3fooI1BEivEDC1a1b1cE:" } }
+// { dg-final { scan-assembler "_ZZ3fooI1BEivE1a_1:" } }
+// { dg-final { scan-assembler "_ZZ3fooI1BEivE1b_1:" } }
+// { dg-final { scan-assembler "_ZZ3fooI1BEivE1b_2:" } }
+// { dg-final { scan-assembler "_ZZ3fooI1BEivE1b_3:" } }
+// { dg-final { scan-assembler "_ZZ3fooI1BEivE1c_1:" } }
+// { dg-final { scan-assembler "_ZZ3fooI1BEivE1a_2:" } }
+// { dg-final { scan-assembler "_ZZ3fooI1BEivE1b_4:" } }
+// { dg-final { scan-assembler "_ZZ3fooI1BEivE1c_2:" } }
+
+template <typename T>
+int
+foo ()
+{
+  static int a = 1, b = 2, c = 3;
+  int d = a++ + b++ + c++;
+  {
+    static int a = 1, b = 2, c = 3;
+    d += a++ + b++ + c++;
+    {
+      static auto [a, ...b, c] = T {}; // { dg-warning "structured binding 
packs only available with" "" { target { c++17 && c++23_down } } }
+                                       // { dg-warning "structured bindings 
only available with" "" { target c++14_down } .-1 }
+                                       // { dg-warning "structured binding 
declaration can be 'static' only in" "" { target c++17_down } .-2 }
+      d += a++ + b...[0]++ + c++;      // { dg-warning "pack indexing only 
available with" "" { target c++23_down } }
+      {
+       static int a = 1, b = 2, c = 3;
+       return d + a++ + b++ + c++;
+      }
+    }
+  }
+}
+
+struct A { int a, b, c, d, e; };
+
+void
+bar ()
+{
+  foo <A> ();
+}
+
+namespace std {
+  template<typename T> struct tuple_size;
+  template<int, typename> struct tuple_element;
+}
+
+struct B {
+  int a[5];
+  template <int I> int &get () { return a[I]; }
+};
+         
+template<> struct std::tuple_size<B> { static const int value = 5; };
+template<int I> struct std::tuple_element<I,B> { using type = int; };
+
+void
+baz ()
+{
+  foo <B> ();
+}

        Jakub

Reply via email to