On Fri, Feb 20, 2026 at 03:40:49PM +0900, Jason Merrill wrote: > On 2/20/26 1:14 AM, Marek Polacek wrote: > > On Thu, Feb 19, 2026 at 11:07:56PM +0900, Jason Merrill wrote: > > > On 2/19/26 10:35 PM, Marek Polacek wrote: > > > > On Thu, Feb 19, 2026 at 05:28:24PM +0900, Jason Merrill wrote: > > > > > On 2/12/26 12:29 AM, Marek Polacek wrote: > > > > > > On Wed, Feb 11, 2026 at 05:02:40PM +0900, Jason Merrill wrote: > > > > > > > On 2/11/26 1:05 AM, Marek Polacek wrote: > > > > > > > > Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk? > > > > > > > > > > > > > > > > -- >8 -- > > > > > > > > In > > > > > > > > <https://gcc.gnu.org/pipermail/gcc-patches/2026-January/705175.html> > > > > > > > > (bottom of the message) we discussed not passing ctx to > > > > > > > > finish_id_expression > > > > > > > > so that we can get rid of the _deferring_access_checks calls. > > > > > > > > So the > > > > > > > > cp_parser_splice_expression changes are what we want. In order > > > > > > > > to be > > > > > > > > able to do that, I had to adjust finish_id_expression_1 so that > > > > > > > > things > > > > > > > > like &[: ^^S::fn :] and &[: ^^S::mem :] keep working. > > > > > > > > > > > > > > Would it make sense to call build_offset_ref in > > > > > > > cp_parser_splice_expression? > > > > > > > > > > > > I could do that, but then I'd also have to duplicate the calls to > > > > > > push/pop_deferring_access_checks, and add checks around > > > > > > build_offset_ref > > > > > > just like in the r16-7445 patch. But then I think I wouldn't have > > > > > > to add the new splice_p parameter. Thought maybe we want to signal > > > > > > to > > > > > > finish_class_member_access_expr that we're coming from a splice > > > > > > anyway. > > > > > > > > > > But why? I would think that accessing a pre-determined member ought > > > > > to work > > > > > the same whether or not it comes from a splice. > > > > > > > > I don't think passing splice_p to finish_class_member_access_expr > > > > currently does anything. But the note about various checks that > > > > would have to be added around build_offset_ref still stands. > > > > > > That still sounds more localized, and therefore better, than cluttering > > > the > > > API with more splice_p parameters. > > > > Ok, fair enough. How about this, then? > > > > + else if (VAR_P (t) && DECL_CLASS_SCOPE_P (t)) > > + /* finish_id_expression doesn't handle these well: > > + constexpr auto r = ^^S::i; > > + auto a = [:r:]; */ > This seems to be referring to this assert in finish_id_expression_1:
Yes, it was. > > /* PATH can be null for using an enum of an unrelated > > class; we checked its access in lookup_using_decl. > > ??? Should this case make a clone instead, like > > handle_using_decl? */ > > gcc_assert (TREE_CODE (decl) == CONST_DECL); > > How about, instead of a special case in cp_parser_splice_expression, adding > || flag_reflection to the assert? I can do that too: dg.exp passed so far, ok for trunk? -- >8 -- In <https://gcc.gnu.org/pipermail/gcc-patches/2026-January/705175.html> (bottom of the message) we discussed not passing ctx to finish_id_expression so that we can get rid of the _deferring_access_checks calls. We can avoid passing context to finish_id_expression but we can't completely avoid the _deferring_access_checks calls, because for address_p we need to call build_offset_ref which needs it. gcc/cp/ChangeLog: * parser.cc (cp_parser_splice_expression): For dependent splices return earlier. Refactor. For address_p, build an OFFSET_REF. Don't pass context to finish_id_expression. * semantics.cc (finish_id_expression_1): Adjust an assert to also check flag_reflection. --- gcc/cp/parser.cc | 31 ++++++++++++++++--------------- gcc/cp/semantics.cc | 6 +++++- 2 files changed, 21 insertions(+), 16 deletions(-) diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc index 13b9b8f46b4..8fd3ed08673 100644 --- a/gcc/cp/parser.cc +++ b/gcc/cp/parser.cc @@ -6313,6 +6313,7 @@ cp_parser_splice_expression (cp_parser *parser, bool template_p, SET_SPLICE_EXPR_EXPRESSION_P (t); SET_SPLICE_EXPR_MEMBER_ACCESS_P (t, member_access_p); SET_SPLICE_EXPR_ADDRESS_P (t, address_p); + return t; } if (error_operand_p (t)) @@ -6358,6 +6359,8 @@ cp_parser_splice_expression (cp_parser *parser, bool template_p, /* Were 'template' present, this would be valid code, so keep going. */ missing_template_diag (loc, diagnostics::kind::pedwarn); + cp_unevaluated u; + /* When doing foo.[: bar :], cp_parser_postfix_dot_deref_expression wants to see an identifier or a TEMPLATE_ID_EXPR, if we have something like s.template [: ^^S::var :]<int> where S::var is a variable template. */ @@ -6377,24 +6380,23 @@ cp_parser_splice_expression (cp_parser *parser, bool template_p, || TREE_CODE (t) == TREE_BINFO); /* ??? We're not setting *idk here. */ } - else + else if (address_p + && (BASELINK_P (t) || DECL_NONSTATIC_MEMBER_P (t))) { - /* We may have to instantiate; for instance, if we're dealing with - a variable template. For &[: ^^S::x :], we have to create an - OFFSET_REF. For a VAR_DECL, we need the convert_from_reference. */ - cp_unevaluated u; /* CWG 3109 adjusted [class.protected] to say that checking access to - protected non-static members is disabled for members designated by a - splice-expression. */ + protected non-static members is disabled for members designated by + a splice-expression. */ push_deferring_access_checks (dk_no_check); + tree type = (BASELINK_P (t) + ? BINFO_TYPE (BASELINK_ACCESS_BINFO (t)) + : DECL_CONTEXT (t)); + t = build_offset_ref (type, t, /*address_p=*/true, tf_warning_or_error); + pop_deferring_access_checks (); + } + else + { const char *error_msg; - /* We don't have the parser scope here, so figure out the context. In - struct S { static constexpr int i = 42; }; - constexpr auto r = ^^S::i; - int i = [: r :]; - we need to pass down 'S'. */ - tree ctx = DECL_P (t) ? DECL_CONTEXT (t) : NULL_TREE; - t = finish_id_expression (t, t, ctx, idk, + t = finish_id_expression (t, t, NULL_TREE, idk, /*integral_constant_expression_p=*/false, /*allow_non_integral_constant_expr_p=*/true, &parser->non_integral_constant_expression_p, @@ -6406,7 +6408,6 @@ cp_parser_splice_expression (cp_parser *parser, bool template_p, loc); if (error_msg) cp_parser_error (parser, error_msg); - pop_deferring_access_checks (); } return t; diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc index fbf7c6d7596..4aa2f14b468 100644 --- a/gcc/cp/semantics.cc +++ b/gcc/cp/semantics.cc @@ -5086,7 +5086,11 @@ finish_id_expression_1 (tree id_expression, ??? Should this case make a clone instead, like handle_using_decl? */ - gcc_assert (TREE_CODE (decl) == CONST_DECL); + gcc_assert (TREE_CODE (decl) == CONST_DECL + /* This is for: + constexpr auto r = ^^S::i; + auto a = [:r:]; */ + || flag_reflection); else perform_or_defer_access_check (TYPE_BINFO (path), decl, decl, base-commit: 8d8725bedd2f7cd5a894b47b43022f6ec0fef2c0 -- 2.53.0
