https://gcc.gnu.org/g:847ae1d2c7038c5015f706393b69201ad6919693

commit r15-11376-g847ae1d2c7038c5015f706393b69201ad6919693
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                          | 10 +++++++++-
 gcc/testsuite/g++.dg/cpp2a/decomp11.C | 12 ++++++++++++
 3 files changed, 22 insertions(+), 2 deletions(-)

diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc
index 9d67a25ec908..81027e1840c2 100644
--- a/gcc/cp/decl.cc
+++ b/gcc/cp/decl.cc
@@ -9837,7 +9837,7 @@ cp_finish_decomp (tree decl, cp_decomp *decomp, bool 
test_p)
            }
          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 false;
     }
diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index df9e479c9fc5..a2a885b9effe 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -19141,7 +19141,15 @@ tsubst_stmt (tree t, tree args, tsubst_flags_t 
complain, tree in_decl)
                        if (tsubst_decomp_names (decl, pattern_decl, args,
                                                 complain, in_decl, decomp)
                            == error_mark_node)
-                         decomp = NULL;
+                         {
+                           decomp = NULL;
+                           /* As in cp_finish_decomp.  */
+                           if (TREE_STATIC (decl))
+                             {
+                               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