https://gcc.gnu.org/g:e36bd73d7030b3efb182821f06c48c5258809766

commit r16-9812-ge36bd73d7030b3efb182821f06c48c5258809766
Author: Marek Polacek <[email protected]>
Date:   Mon Oct 12 17:04:24 2026 -0400

    c++/reflection: ICE with reflection and sb packs [PR126680]
    
    We mark consteval-only vars DECL_EXTERNAL, which confused the
    code in set_decl_context_in_fn:
    
      if (TREE_CODE (decl) == FUNCTION_DECL
          || (VAR_P (decl) && DECL_EXTERNAL (decl)))
        /* Make sure local externs are marked as such.  OMP UDRs really
           are nested functions.  */
        gcc_checking_assert (DECL_LOCAL_DECL_P (decl) /*...*/ );
    
    for code with:
    
      static constexpr auto [...a] = std::array { ^^int };
    
    where there is no local extern.  This reminded me of r17-392, and
    I think here we can use DECL_THIS_EXTERN.
    
    I think we shouldn't lose any relevant coverage because of this change.
    We set DECL_THIS_EXTERN in grokvardecl:
    
          DECL_THIS_EXTERN (decl) = 1;
          DECL_EXTERNAL (decl) = !initialized;
    
    and in grokdeclarator, which sets DECL_THIS_EXTERN only after grokvardecl
    has been called.  A local extern with an initializer is rejected in
    grokdeclarator.  So a block-scope VAR_DECL with DECL_THIS_EXTERN always
    has DECL_EXTERNAL set.
    
            PR c++/126680
    
    gcc/cp/ChangeLog:
    
            * name-lookup.cc (set_decl_context_in_fn): Check DECL_THIS_EXTERN
            instead of DECL_EXTERNAL.
    
    gcc/testsuite/ChangeLog:
    
            * g++.dg/reflect/decomp1.C: New test.
    
    Reviewed-by: Jason Merrill <[email protected]>
    (cherry picked from commit eb5375341a4743fa565626a0d1ffc51f87dba577)

Diff:
---
 gcc/cp/name-lookup.cc                  |  2 +-
 gcc/testsuite/g++.dg/reflect/decomp1.C | 17 +++++++++++++++++
 2 files changed, 18 insertions(+), 1 deletion(-)

diff --git a/gcc/cp/name-lookup.cc b/gcc/cp/name-lookup.cc
index 45c2976d698b..15ab3d5095f9 100644
--- a/gcc/cp/name-lookup.cc
+++ b/gcc/cp/name-lookup.cc
@@ -3669,7 +3669,7 @@ static void
 set_decl_context_in_fn (tree ctx, tree decl)
 {
   if (TREE_CODE (decl) == FUNCTION_DECL
-      || (VAR_P (decl) && DECL_EXTERNAL (decl)))
+      || (VAR_P (decl) && DECL_THIS_EXTERN (decl)))
     /* Make sure local externs are marked as such.  OMP UDRs really
        are nested functions.  */
     gcc_checking_assert (DECL_LOCAL_DECL_P (decl)
diff --git a/gcc/testsuite/g++.dg/reflect/decomp1.C 
b/gcc/testsuite/g++.dg/reflect/decomp1.C
new file mode 100644
index 000000000000..281affea27c1
--- /dev/null
+++ b/gcc/testsuite/g++.dg/reflect/decomp1.C
@@ -0,0 +1,17 @@
+// PR c++/126680
+// { dg-do compile { target c++26 } }
+// { dg-additional-options "-freflection" }
+
+#include <array>
+
+template<int = 0>
+void f ()
+{
+  static constexpr auto [...a] = std::array { ^^int };
+}
+
+void
+g ()
+{
+  f ();
+}

Reply via email to