On 7/28/26 1:34 PM, Marek Polacek wrote:
Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk/16?

-- >8 --
Given

   struct C { template <class T> void f(T); };

we handle "&template [:^^C::f:]" correctly because the spliced
expression is

   BASELINK<OVERLOAD<TEMPLATE_DECL f>>, binfo C>

which is fine: we have an OVERLOAD around the TEMPLATE_DECL and
lookup_member wrapped the whole thing in a BASELINK.  But when
we're splicing members_of(^^C, ac)[0], we ended up with

   OVERLOAD<TEMPLATE_DECL f>>

and then go down the wrong path in cp_parser_splice_expression.

splice already correctly adds the missing OVERLOAD but it also
needs to (maybe) add a BASELINK.

Yes, though I'm nervous about the use of currently_open_derived_class in baselink_for_fns. Does that cause trouble with a splice after ->?

        PR c++/124794

gcc/cp/ChangeLog:

        * reflect.cc (splice): Call baselink_for_fns.

gcc/testsuite/ChangeLog:

        * g++.dg/reflect/splice17.C: New test.
---
  gcc/cp/reflect.cc                       |  3 +++
  gcc/testsuite/g++.dg/reflect/splice17.C | 20 ++++++++++++++++++++
  2 files changed, 23 insertions(+)
  create mode 100644 gcc/testsuite/g++.dg/reflect/splice17.C

diff --git a/gcc/cp/reflect.cc b/gcc/cp/reflect.cc
index 989d7cebc77..4677672526b 100644
--- a/gcc/cp/reflect.cc
+++ b/gcc/cp/reflect.cc
@@ -8790,6 +8790,9 @@ splice (tree refl)
       it comes from e.g. members_of it is not.  */
    if (DECL_FUNCTION_TEMPLATE_P (refl))
      refl = ovl_make (refl, NULL_TREE);
+  /* Also add a BASELINK so that we handle &[:R:].  */
+  if (is_overloaded_fn (refl))
+    refl = baselink_for_fns (refl);
return refl;
  }
diff --git a/gcc/testsuite/g++.dg/reflect/splice17.C 
b/gcc/testsuite/g++.dg/reflect/splice17.C
new file mode 100644
index 00000000000..5f5cc5060e1
--- /dev/null
+++ b/gcc/testsuite/g++.dg/reflect/splice17.C
@@ -0,0 +1,20 @@
+// PR c++/124794
+// { dg-do compile { target c++26 } }
+// { dg-additional-options "-freflection" }
+
+#include <meta>
+
+struct C {
+  template <class T> void f(T);
+  void g (int);
+};
+constexpr auto ac = std::meta::access_context::current();
+constexpr auto f1 = members_of(^^C, ac)[0];
+constexpr auto f2 = ^^C::f;
+void (C::*p1)(int) = &template [:f1:];
+void (C::*p2)(int) = &template [:f2:];
+
+constexpr auto g1 = members_of(^^C, ac)[1];
+constexpr auto g2 = ^^C::g;
+void (C::*p3)(int) = &[:g1:];
+void (C::*p4)(int) = &[:g2:];

base-commit: bbf71b94fc1af926cb9dfe3934e716ced755dc8b

Reply via email to