https://gcc.gnu.org/g:41006b6da54d2fd1b8e5fd81018a1ad6f61183d8

commit r17-1726-g41006b6da54d2fd1b8e5fd81018a1ad6f61183d8
Author: Jason Merrill <[email protected]>
Date:   Sat Jun 20 18:23:09 2026 -0400

    c++: typedef in lambda in pack expansion
    
    In trying to reduce the testcase for PR125408, I came across an older
    regression, dating back to r14-9938, though the problem wasn't in that
    commit.
    
    cp_walk_subtrees avoids walking into uses of typedefs because it wants to
    look at what's actually written.  But here we were also skipping over the
    definition of the typedef, so extract_locals_r never got to see the use of
    't', so later substitution failed.
    
    Fixed by specifically handling typedef DECL_EXPR.
    
            PR c++/125408
    
    gcc/cp/ChangeLog:
    
            * tree.cc (cp_walk_subtrees): Walk into the DECL_ORIGINAL_TYPE of a
            typedef DECL_EXPR.
    
    gcc/testsuite/ChangeLog:
    
            * g++.dg/cpp2a/lambda-targ33.C: New test.

Diff:
---
 gcc/cp/tree.cc                             |  4 ++++
 gcc/testsuite/g++.dg/cpp2a/lambda-targ33.C | 24 ++++++++++++++++++++++++
 2 files changed, 28 insertions(+)

diff --git a/gcc/cp/tree.cc b/gcc/cp/tree.cc
index c9b299007467..a99f5e19c0d8 100644
--- a/gcc/cp/tree.cc
+++ b/gcc/cp/tree.cc
@@ -6407,6 +6407,10 @@ cp_walk_subtrees (tree *tp, int *walk_subtrees_p, 
walk_tree_fn func,
          WALK_SUBTREE (DECL_SIZE (decl));
          WALK_SUBTREE (DECL_SIZE_UNIT (decl));
        }
+      if (is_typedef_decl (TREE_OPERAND (t, 0)))
+       /* We avoid walking into typedefs above, but we do want to walk
+          into them if we're looking at the actual declaration.  */
+       WALK_SUBTREE (DECL_ORIGINAL_TYPE (TREE_OPERAND (t, 0)));
       break;
 
     case LAMBDA_EXPR:
diff --git a/gcc/testsuite/g++.dg/cpp2a/lambda-targ33.C 
b/gcc/testsuite/g++.dg/cpp2a/lambda-targ33.C
new file mode 100644
index 000000000000..3b42f322c775
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/lambda-targ33.C
@@ -0,0 +1,24 @@
+// PR c++/125408
+// { dg-do compile { target c++20 } }
+
+struct Role {
+    long id;
+};
+
+template <typename T> T Obj;
+template<int... I> struct A { };
+void sink(...);
+
+template <auto Ptr, typename Table>
+constexpr int find_member_index() {
+  constexpr auto& t = Obj<Table>;
+  []<int... Idx>(A<Idx...>) {
+    sink([]() {
+      using T1 = decltype(&(t.*Ptr));
+      return Idx;
+    }() ...);
+  }(A<1,2>{});
+  return 42;
+}
+
+auto i = find_member_index<&Role::id, Role>();

Reply via email to