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
