Hi!

The following testcase ICEs, because we decide to mangle the (for the time
being as workaround static constexpr variables created for expansion
statements).  And if there is more than one in the same function and we
mangle both, we ICE because they mangle the same.

The problem is that cp_finish_decl does not determine_local_discriminator
for DECL_ARTIFICIAL vars.
The following patch fixes that by calling that function for the TREE_STATIC
temporaries (will go away when we have proper full P2686R4 implementation).
The patch also sets DECL_IGNORED_P on those vars, I think there is no
value exposing those in the debug information, the iterating is done
at compile time and all user IMHO cares are the individual user variables
initialized to whatever was derived from the temporaries.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2026-05-25  Jakub Jelinek  <[email protected]>

        PR c++/125123
        * parser.cc (cp_build_range_for_decls): If range_temp or begin
        are static, set DECL_IGNORED_P on it and call
        determine_local_discriminator after pushdecl.
        * pt.cc (finish_expansion_stmt): Similarly for iter.

        * g++.dg/cpp26/expansion-stmt42.C: New test.

--- gcc/cp/parser.cc.jj 2026-05-23 01:23:05.072826742 +0200
+++ gcc/cp/parser.cc    2026-05-25 12:48:42.070467582 +0200
@@ -16063,6 +16063,7 @@ cp_build_range_for_decls (location_t loc
                  DECL_INTERFACE_KNOWN (range_temp) = 1;
                  DECL_DECLARED_CONSTEXPR_P (range_temp) = 1;
                  TREE_READONLY (range_temp) = 1;
+                 DECL_IGNORED_P (range_temp) = 1;
                }
            }
          else
@@ -16070,6 +16071,9 @@ cp_build_range_for_decls (location_t loc
            range_temp = build_range_temp (range_expr);
 
          pushdecl (range_temp);
+         if (expansion_stmt_decl
+             && DECL_DECLARED_CONSTEXPR_P (expansion_stmt_decl))
+           determine_local_discriminator (range_temp);
          cp_finish_decl (range_temp, range_expr,
                          /*is_constant_init*/false, NULL_TREE,
                          LOOKUP_ONLYCONVERTING);
@@ -16092,8 +16096,11 @@ cp_build_range_for_decls (location_t loc
       TREE_STATIC (begin) = 1;
       DECL_DECLARED_CONSTEXPR_P (begin) = 1;
       TREE_READONLY (begin) = 1;
+      DECL_IGNORED_P (begin) = 1;
     }
   pushdecl (begin);
+  if (expansion_stmt_decl && DECL_DECLARED_CONSTEXPR_P (expansion_stmt_decl))
+    determine_local_discriminator (begin);
   cp_finish_decl (begin, begin_expr,
                  /*is_constant_init*/false, NULL_TREE,
                  LOOKUP_ONLYCONVERTING);
--- gcc/cp/pt.cc.jj     2026-05-23 10:23:20.669068142 +0200
+++ gcc/cp/pt.cc        2026-05-25 12:48:00.390139881 +0200
@@ -33701,8 +33701,11 @@ finish_expansion_stmt (tree expansion_st
              TREE_STATIC (iter) = 1;
              DECL_DECLARED_CONSTEXPR_P (iter) = 1;
              TREE_READONLY (iter) = 1;
+             DECL_IGNORED_P (iter) = 1;
            }
          pushdecl (iter);
+         if (DECL_DECLARED_CONSTEXPR_P (range_decl))
+           determine_local_discriminator (iter);
          cp_finish_decl (iter, iter_init, /*is_constant_init*/false,
                          NULL_TREE, LOOKUP_ONLYCONVERTING);
          init = build_x_indirect_ref (loc, iter, RO_UNARY_STAR, NULL_TREE,
--- gcc/testsuite/g++.dg/cpp26/expansion-stmt42.C.jj    2026-05-25 
12:50:46.111466801 +0200
+++ gcc/testsuite/g++.dg/cpp26/expansion-stmt42.C       2026-05-25 
12:53:47.616539126 +0200
@@ -0,0 +1,22 @@
+// PR c++/125123
+// { dg-do compile { target c++20 } }
+// { dg-options "-g" }
+
+struct A
+{
+  int a[2];
+  constexpr int const *begin () const { return a; }
+  constexpr int const *end () const { return a + 2; }
+};
+
+template <typename T>
+requires true
+void
+foo ()
+{
+  template for (constexpr int i : A { 0, 1 })  // { dg-warning "'template for' 
only available with" "" { target c++23_down } }
+    ;
+  template for (constexpr int i : A { 0, 1 })  // { dg-warning "'template for' 
only available with" "" { target c++23_down } }
+    ;
+}
+template void foo <void> ();

        Jakub

Reply via email to