diff options
author | Jakub Jelinek <jakub@redhat.com> | 2025-08-11 08:54:57 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2025-08-11 09:05:23 +0200 |
commit | 5274f490fa72830aafd278bc752145f1225b08e0 (patch) | |
tree | eaae25c0fa22455f725dd22b4d07ae271ba222e8 | |
parent | af31db6461110dfb81efaf2a287327226ae5a7a8 (diff) | |
download | gcc-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.cc | 16 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp26/decomp19.C | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp26/decomp26.C | 77 |
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> (); +} |