On Thu, Dec 11, 2025 at 11:29:01PM +0700, Jason Merrill wrote:
> > same_type<decltype([: ^^S::i :]), int> s5b;
> > where it seems to be parsing [: ^^S::i :] tentatively, sets
> > parser->scope and parser->qualifying_scope to S during that
> > parsing and then when it is parsing it again sees that.
> > So guess the question is where to clear those 3 (e.g. whether
> > at the start of cp_parser_splice_expression and also at the end
> > of those?)
> 
> I think so.
> 
> > and/or if there are some spots where it should be temporarily
> > and where it should be reset back.
> 
> I don't think so.

Marek is looking at these right now.

> > And then there is also parser->context->object_type, guess for that one
> > we should save it and restore it, so that it can be taken into account
> > for s.[: ^^S::foo :] <int> (); etc. parsing.
> ...
> > The following WIP patch fixes that.
> > The reason for saving/restoring rather than just clearing is so that
> > it can be used for the splice-specialization-specifier case later on
> > if the splice-specifier is non-dependent.
> 
> Why is this needed?  The template arguments aren't member-qualified, e.g.
> this is properly rejected:
> 
> struct A {
>   static const int i = 42;
>   template <int I> void f();
> };
> 
> int main()
> {
>   A().f<i>(); // error, no 'i' in scope
> }

I wanted to make it behave similarly to the non-splice parsing and without
that lots of things in member18.C testcase (which I finally got to work
fully a few minutes ago) didn't work.
For A().f<i>(); *dot_deref* sets parser->context->object_type and then
cp_parser_template_id is called, it parses the f IDENTIFIER_NODE and because
parser->context->object_type is set, it looks it up in that type and
creates a BASELINK from that and only with that the rest of
cp_parser_template_id can DTRT and create the right TEMPLATE_ID_EXPR,
everything before finish_class_member_access_expr is called.

Now, for the splice-specialization-specifier case for member access,
we get an OVERLOAD for a function template, but without a BASELINK
cp_parser_template_id with the new expr argument added by Marek where
it doesn't parse the identifier before < but uses the splice expression
it doesn't DTRT.
So, what I'm now using is
https://forge.sourceware.org/marek/gcc/src/commit/ebd656a2ba860bf05e0ef3283acd4efb6621f4dc/gcc/cp/parser.cc#L6155
and add a BASELINK in that case.

The relevant recent commits are
https://forge.sourceware.org/marek/gcc/commit/43b63499a56e507d1e646e5ba732e5db88bcfaa0
https://forge.sourceware.org/marek/gcc/commit/47efb49b8d32cf1fecadf28990f74d2deff0039c
https://forge.sourceware.org/marek/gcc/commit/d9d8a99731e44ca57944b03a30b66ed7450bd622
https://forge.sourceware.org/marek/gcc/commit/99aaea31a7e583946f541f1c09ce7d3daff4062c
https://forge.sourceware.org/marek/gcc/commit/a6a2829e25ec1bd4d57779785248ab9dca6e88ef
https://forge.sourceware.org/marek/gcc/commit/d1dff2d009b72047c768a383b28f748982b5f51a
https://forge.sourceware.org/marek/gcc/commit/33ceee24fb16bc3d4772e298536d31f3a103aed4
https://forge.sourceware.org/marek/gcc/commit/ebd656a2ba860bf05e0ef3283acd4efb6621f4dc

> > --- a/gcc/cp/parser.cc
> > +++ b/gcc/cp/parser.cc
> > @@ -6102,6 +6102,7 @@ cp_parser_next_tokens_can_start_splice_scope_spec_p 
> > (cp_parser *parser)
> >  static cp_expr
> >  cp_parser_splice_specifier (cp_parser *parser, bool template_p = false,
> > +                       bool member_access_p = false,
> >                         bool *targs_p = nullptr)
> >  {
> >    /* Get the location of the '[:'.  */
> > @@ -6120,11 +6121,22 @@ cp_parser_splice_specifier (cp_parser *parser, bool 
> > template_p = false,
> >        return error_mark_node;
> >      }
> > +  /* For member_access_p, temporarily clear parser->context->object_type.  
> > */
> 
> Why conditional on member_access_p?

It could be done for non-member_access_p too, I just think it will
never be non-NULL otherwise.

        Jakub

Reply via email to