]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c++: Fix structured binding redeclaration error recovery [PR121442]
authorJakub Jelinek <jakub@redhat.com>
Mon, 11 Aug 2025 06:53:26 +0000 (08:53 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Mon, 11 Aug 2025 07:05:20 +0000 (09:05 +0200)
My C++26 P2686R4 PR117784 caused ICE on the following testcase.
While the earlier conditions guarantee decl2 is not error_mark_node,
decl can be (that is used when something erroneous has been seen earlier
and the whole structured bindings will be ignored after parsing).

So, the following patch avoids the copying of constexpr/constinit flags
if decl is error_mark_node.

2025-08-11  Jakub Jelinek  <jakub@redhat.com>

PR c++/121442
* parser.cc (cp_parser_decomposition_declaration): Don't copy
DECL_DECLARED_CONST{EXPR,INIT}_P bits from decl to decl2 if
decl is error_mark_node.

* g++.dg/cpp1z/decomp65.C: New test.

gcc/cp/parser.cc
gcc/testsuite/g++.dg/cpp1z/decomp65.C [new file with mode: 0644]

index 743fd7498dec5178ff411e4ace8df2ed6cda1510..1dbe35b6c986a0e0f8e7eb5fd94942848611df26 100644 (file)
@@ -17002,8 +17002,13 @@ cp_parser_decomposition_declaration (cp_parser *parser,
       else
        {
          prev = decl2;
-         DECL_DECLARED_CONSTEXPR_P (decl2) = DECL_DECLARED_CONSTEXPR_P (decl);
-         DECL_DECLARED_CONSTINIT_P (decl2) = DECL_DECLARED_CONSTINIT_P (decl);
+         if (decl != error_mark_node)
+           {
+             DECL_DECLARED_CONSTEXPR_P (decl2)
+               = DECL_DECLARED_CONSTEXPR_P (decl);
+             DECL_DECLARED_CONSTINIT_P (decl2)
+               = DECL_DECLARED_CONSTINIT_P (decl);
+           }
          if (j == (unsigned) pack)
            {
              tree dtype = cxx_make_type (DECLTYPE_TYPE);
diff --git a/gcc/testsuite/g++.dg/cpp1z/decomp65.C b/gcc/testsuite/g++.dg/cpp1z/decomp65.C
new file mode 100644 (file)
index 0000000..5dd8eff
--- /dev/null
@@ -0,0 +1,13 @@
+// PR c++/121442
+// { dg-do compile { target c++11 } }
+// { dg-options "" }
+
+struct S { int a, b, c, d, e; };
+
+void
+foo ()
+{
+  auto [a, b, b, b, c ] = S {};                // { dg-warning "structured bindings only available with" "" { target c++14_down } }
+                                       // { dg-error "redeclaration of 'auto b'" "" { target *-*-* } .-1 }
+                                       // { dg-message "'auto b' previously declared here" "" { target *-*-* } .-2 }
+}