aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2025-08-11 08:54:57 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2025-08-11 09:05:23 +0200
commit5274f490fa72830aafd278bc752145f1225b08e0 (patch)
treeeaae25c0fa22455f725dd22b4d07ae271ba222e8
parentaf31db6461110dfb81efaf2a287327226ae5a7a8 (diff)
downloadgcc-5274f490fa72830aafd278bc752145f1225b08e0.zip
gcc-5274f490fa72830aafd278bc752145f1225b08e0.tar.gz
gcc-5274f490fa72830aafd278bc752145f1225b08e0.tar.bz2
c++: Implement mangling for structured binding packs [PR117783]
On Wed, Aug 06, 2025 at 11:53:55AM -0700, Jason Merrill wrote: > 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-11 Jakub Jelinek <jakub@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.
-rw-r--r--gcc/cp/decl.cc16
-rw-r--r--gcc/testsuite/g++.dg/cpp26/decomp19.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp26/decomp26.C77
3 files changed, 85 insertions, 10 deletions
diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc
index ab5b0c9..693cf65 100644
--- a/gcc/cp/decl.cc
+++ b/gcc/cp/decl.cc
@@ -10223,14 +10223,6 @@ cp_finish_decomp (tree decl, cp_decomp *decomp, bool test_p)
"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 *decomp, bool test_p)
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;
diff --git a/gcc/testsuite/g++.dg/cpp26/decomp19.C b/gcc/testsuite/g++.dg/cpp26/decomp19.C
index b4d97a1..3cec3c5 100644
--- a/gcc/testsuite/g++.dg/cpp26/decomp19.C
+++ b/gcc/testsuite/g++.dg/cpp26/decomp19.C
@@ -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
diff --git a/gcc/testsuite/g++.dg/cpp26/decomp26.C b/gcc/testsuite/g++.dg/cpp26/decomp26.C
new file mode 100644
index 0000000..24865ca
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp26/decomp26.C
@@ -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> ();
+}