Tested x86_64-pc-linux-gnu, applying to trunk.

-- 8< --

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.
---
 gcc/cp/tree.cc                             |  4 ++++
 gcc/testsuite/g++.dg/cpp2a/lambda-targ33.C | 24 ++++++++++++++++++++++
 2 files changed, 28 insertions(+)
 create mode 100644 gcc/testsuite/g++.dg/cpp2a/lambda-targ33.C

diff --git a/gcc/cp/tree.cc b/gcc/cp/tree.cc
index c9b29900746..a99f5e19c0d 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 00000000000..3b42f322c77
--- /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>();

base-commit: e259a182e1f100a7693657cea20a207fd1323b82
-- 
2.54.0

Reply via email to