[gcc r15-11376] 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: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> ();
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.