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> ();

Reply via email to