Re: [PATCH v3] c++/reflection: ICE with &template [:members_of():] [PR124794]
Jason Merrill <[email protected]> Mon, 3 Aug 2026 17:05:39 -0400
| Newsgroups | gmane.comp.gcc.patches |
|---|---|
| Message-ID | <[email protected]> |
On 7/31/26 6:21 PM, Marek Polacek wrote:
> On Fri, Jul 31, 2026 at 12:47:08PM -0400, Jason Merrill wrote:
>> On 7/31/26 12:38 PM, Marek Polacek wrote:
>>> On Thu, Jul 30, 2026 at 09:35:26AM -0400, Jason Merrill wrote:
>>>> 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 ->?
>>>
>>> We test a splice after -> in e.g. member1.C and member3.C and they still pass.
>>>
>>> And given
>>>
>>> struct C {
>>> void g (int);
>>> };
>>>
>>> C *pc = ...;
>>>
>>> this
>>>
>>> auto a = &pc->[: ^^C::g :];
>>>
>>> is invalid (clang++ also rejects).
>>>
>>> ...but we don't have a test for a valid &p->[: x :] so this
>>> version adds it.
>>>
>>> +void
>>> +g (C *pc)
>>> +{
>>> + const int *p = &pc->[: ^^C::val :];
>>> +}
>> That tests the case where currently_open_derived_class is null, so it
>> doesn't matter. How about a case where we're in a member function of a
>> class derived from C and the object argument is a different derived class?
>
> Ah, that's a great catch. This is where it breaks:
>
> struct C {
> void g (int);
> };
>
> constexpr auto ac = std::meta::access_context::current();
> constexpr auto g1 = members_of(^^C, ac)[0];
>
> struct D1 : C { };
>
> struct D2 : C {
> void mfn (D1 *pd)
> {
> pd->[:g1:] (42);
> }
> };
>
> because the BASELINK has D2 as the access_binfo, but it should be
> C which is what it was when the reflection was formed.
>
> So perhaps baselink_for_fns should ignore currently_open_derived_class
> which is what this patch does.
>
> Tested reflect/* on x86_64-pc-linux-gnu, ok for trunk/16?
OK for trunk and 16 after it reopens.
Jason