https://gcc.gnu.org/g:c106ebf2f84d15e6033d7310fe21d193470e9751
commit r14-12744-gc106ebf2f84d15e6033d7310fe21d193470e9751 Author: Jakub Jelinek <[email protected]> Date: Fri Jul 3 20:45:07 2026 +0200 c++: Fix structured binding mangling during error recovery [PR126057] The following testcase ICEs during error recovery. We try to mangle a structured binding base variable, but because it has been erroneous, the mangling ICEs as it can't find the corresponding structured bindings. Now, we already have a hack in cp_finish_decomp when things are erroneous, we set assembler name to <decomp> so that mangling isn't done. But we do that only for DECL_NAMESPACE_SCOPE_P bases and block scope static structured bindings can be mangled too, and during instantiation, if tsubst_decomp_names fails, we don't call cp_finish_decomp at all, so in that case we need to also avoid the mangling of the structured binding base. 2026-07-03 Jakub Jelinek <[email protected]> PR c++/126057 * decl.cc (cp_finish_decomp): Set assembler name to <decomp> during error recovery whenever TREE_STATIC rather than just DECL_NAMESPACE_SCOPE_P. * pt.cc (tsubst_stmt): If tsubst_decomp_names fails, set assembler name to <decomp>. * g++.dg/cpp2a/decomp11.C: New test. Reviewed-by: Jason Merrill <[email protected]> (cherry picked from commit 0b533aa54d375d22a34cf34e6b35c75a317d65d3) Diff: --- gcc/cp/decl.cc | 2 +- gcc/cp/pt.cc | 6 ++++++ gcc/testsuite/g++.dg/cpp2a/decomp11.C | 12 ++++++++++++ 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc index 3497168b89ad..d1775c482133 100644 --- a/gcc/cp/decl.cc +++ b/gcc/cp/decl.cc @@ -9340,7 +9340,7 @@ cp_finish_decomp (tree decl, cp_decomp *decomp) } first = DECL_CHAIN (first); } - if (DECL_P (decl) && DECL_NAMESPACE_SCOPE_P (decl)) + if (DECL_P (decl) && TREE_STATIC (decl)) SET_DECL_ASSEMBLER_NAME (decl, get_identifier ("<decomp>")); return; } diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index 44a4b8bf476a..cafa3bbc0cfb 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -18707,6 +18707,12 @@ tsubst_stmt (tree t, tree args, tsubst_flags_t complain, tree in_decl) decomp = &decomp_d; ndecl = tsubst_decomp_names (decl, pattern_decl, args, complain, in_decl, decomp); + if (ndecl == error_mark_node && TREE_STATIC (decl)) + { + /* As in cp_finish_decomp. */ + tree id = get_identifier ("<decomp>"); + SET_DECL_ASSEMBLER_NAME (decl, id); + } } init = tsubst_init (init, decl, args, complain, in_decl); diff --git a/gcc/testsuite/g++.dg/cpp2a/decomp11.C b/gcc/testsuite/g++.dg/cpp2a/decomp11.C new file mode 100644 index 000000000000..624cc892fc4e --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/decomp11.C @@ -0,0 +1,12 @@ +// PR c++/126057 +// { dg-do compile { target c++20 } } + +template <typename T> +int +foo () +{ + static auto [a] = 0; // { dg-error "cannot decompose non-array non-class type 'int'" } + return 0; +} + +int a = foo <int> ();
