On Tuesday, February 10th, 2026 at 4:49 PM, Marek Polacek <[email protected]> wrote:
> On Tue, Feb 10, 2026 at 03:26:37PM +0000, Boris Staletic wrote: > > On Tuesday, February 10th, 2026 at 2:05 PM, Jason Merrill > > <[email protected]> wrote: > > > > > > > > > > > > Snipped older discussions for brevity. > > > > > > > > > > Here's a v2 of the patch, bootstrapped and tested on > > > > x86_64-pc-linux-gnu. > > > > -- >8 -- > > > > In case of expressions like `&[:expr:]` where `expr` depends on a > > > > template parameter, and the splice expression represents a `FIELD_DECL` > > > > or > > > > a non-static member `FUNCTION_DECL`, that's exactly what we'd pass on. > > > > However, `build_x_unary_op()` for these expressions is expecting an > > > > `OFFSET_REF`. `OFFSET_REF` is also what gets passed to > > > > `build_x_unary_op()` when templates are not involved. > > > > > > > > There's also a difference between the template argument being a type and > > > > using `members_of()` to get to the reflections of members (in which case > > > > evaluating the `SPLICE_EXPR` returns a `FUNCTION_DECL` - `splice10.C` > > > > test) and passing `^^T::member` as the template argument (in which case > > > > evaluating the `SPLICE_EXPR` returns a `BASELINK` - `splice11.C`). > > > > > > > > Signed-off-by: Boris Staletic [email protected] > > > > > > > > PR c++/123660 > > > > PR c++/123661 > > > > > > > > gcc/cp/ChangeLog: > > > > > > > > * pt.cc (tsubst_splice_expr): Handle pointers to non-static members > > > > from splice expressions > > > > > > > > gcc/testsuite/ChangeLog: > > > > > > > > * g++.dg/reflect/splice10.C: New test. > > > > * g++.dg/reflect/splice11.C: New test. > > > > --- > > > > gcc/cp/pt.cc | 14 ++++++++++++ > > > > gcc/testsuite/g++.dg/reflect/splice10.C | 28 ++++++++++++++++++++++++ > > > > gcc/testsuite/g++.dg/reflect/splice11.C | 29 +++++++++++++++++++++++++ > > > > 3 files changed, 71 insertions(+) > > > > create mode 100644 gcc/testsuite/g++.dg/reflect/splice10.C > > > > create mode 100644 gcc/testsuite/g++.dg/reflect/splice11.C > > > > > > > > diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc > > > > index 049bbf07e0..0c0076c9a4 100644 > > > > --- a/gcc/cp/pt.cc > > > > +++ b/gcc/cp/pt.cc > > > > @@ -16755,6 +16755,20 @@ tsubst_splice_expr (tree t, tree args, > > > > tsubst_flags_t complain, tree in_decl) > > > > op = splice (op); > > > > if (op == error_mark_node) > > > > return error_mark_node; > > > > + > > > > + if (SPLICE_EXPR_ADDRESS_P (t) && !TREE_STATIC (TREE_TYPE (op))) > > > > > > > > > TREE_STATIC on a type isn't meaningful, the checks below are enough. > > > > I thought that was fishy... You're right, everything works without that > > check. > > > > > > > > > + { > > > > + if (TREE_CODE (op) == BASELINK > > > > + && TREE_CODE (TREE_TYPE (op)) == METHOD_TYPE) > > > > > > > > > It shouldn't be necessary to check for METHOD_TYPE; any class member is > > > suitable for passing to build_offset_ref. If the argument is static, > > > it'll return it unchanged rather than actually build an OFFSET_REF. > > > > If I drop the METHOD_TYPE check, I get an ICE in both splice10.C and > > splice11.C. > > splice10.C ICEs when calling `build_offset_ref()` on a static member > > function (s::get_y). > > splice11.C ICEs when calling `build_offset_ref()` on a free function (::f). > > > > That's why I was initially looking for a way to do this only for non-static > > members. > > I think Jason meant the check for METHOD_TYPE for a BASELINK, which > is certainly not needed. Please also use BASELINK_P instead of > TREE_CODE == BASELINK. > > We shouldn't call build_offset_ref on static member functions or > free functions. So I think the second call to build_offset_ref > should be guarded by > > TREE_CODE (op) == FIELD_DECL || DECL_OBJECT_MEMBER_FUNCTION_P (op) > > But maybe Jason prefers something else. > > > I would also move the SPLICE_EXPR_ADDRESS_P block after checking > dependent_splice_p and after check_splice_expr. Okay, all of that works. One question: Would it be more correct to guard the whole block with if (SPLICE_EXPR_ADDRESS_P (t)) or if (SPLICE_EXPR_ADDRESS_P (op)) Given what's in the dependent_splice_p block, I'm thinking latter, but I'm not sure. > > > In case of free functions in splice11.C, the ICE happens here: > > https://gcc.gnu.org/git/?p=gcc.git;a=blob;f=gcc/cp/init.cc;h=437797fef0c637b5a7d988eee8f8b5c710bd2d11;hb=HEAD#l2428 > > > > In case of static member functions in splice10.C, we get a bit further, > > here's the traceback: > > > > splice10.C: In instantiation of ‘constexpr auto test() [with T = s; long > > unsigned int I = 1]’: > > required from here > > splice10.C:25:27: > > 25 | static_assert(test<s, 1uz>() == &s::get_y); > > | ~~~~~~~~~~~~^~ > > splice10.C:21:10: internal compiler error: in build_ptrmem_type, at > > cp/decl.cc:12978 > > 21 | return &[:members_of(^^T, ctx)[I]:]; > > | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > 0x2a92a3f internal_error(char const*, ...) > > ../../gcc/diagnostic-global-context.cc:787 > > 0xaff8c1 fancy_abort(char const*, int, char const*) > > ../../gcc/diagnostics/context.cc:1812 > > 0x7b9b70 build_ptrmem_type(tree_node*, tree_node*) > > ../../gcc/cp/decl.cc:12978 > > 0xe4b7a9 cp_build_addr_expr_1 > > ../../gcc/cp/typeck.cc:7638 > > 0xe4c728 cp_build_addr_expr_strict > > ../../gcc/cp/typeck.cc:7726 > > 0xe4c728 build_x_unary_op(unsigned long, tree_code, cp_expr, tree_node*, > > int) > > ../../gcc/cp/typeck.cc:7318 > > 0xd859b6 tsubst_expr(tree_node*, tree_node*, int, tree_node*) > > ../../gcc/cp/pt.cc:21470 > > 0xdb36bf tsubst_stmt > > ../../gcc/cp/pt.cc:20614 > > 0xdb49e3 tsubst_stmt > > ../../gcc/cp/pt.cc:19397 > > 0xdb49a0 tsubst_stmt > > ../../gcc/cp/pt.cc:19387 > > 0xdb50ed tsubst_stmt > > ../../gcc/cp/pt.cc:19808 > > 0xdbc4a6 tsubst_stmt > > ../../gcc/cp/pt.cc:19373 > > 0xdbc4a6 instantiate_body > > ../../gcc/cp/pt.cc:28418 > > 0xdbd27c instantiate_decl(tree_node*, bool, bool) > > ../../gcc/cp/pt.cc:28711 > > 0xc156e0 maybe_instantiate_decl(tree_node*) > > ../../gcc/cp/decl2.cc:6432 > > 0xc156e0 maybe_instantiate_decl(tree_node*) > > ../../gcc/cp/decl2.cc:6420 > > 0xc17587 mark_used(tree_node*, int) > > ../../gcc/cp/decl2.cc:6788 > > 0xb17c1b build_over_call > > ../../gcc/cp/call.cc:11024 > > 0xb2c405 build_new_function_call(tree_node*, vec<tree_node*, va_gc, > > vl_embed>**, int) > > ../../gcc/cp/call.cc:5310 > > 0xdfbc09 finish_call_expr(tree_node*, vec<tree_node*, va_gc, vl_embed>**, > > bool, bool, int) > > ../../gcc/cp/semantics.cc:3542 > > > > Marek > >
