[gcc r14-12744] c++: Fix structured binding mangling during error recovery [PR126057]

Jakub Jelinek via Gcc-cvs <[email protected]>
Newsgroups gmane.comp.gcc.cvs
Message-ID <[email protected]>
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> ();
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.