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?

dg.exp=reflect/* passed on x86_64-linux so far.

-- >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.  Handle
        class-scope VAR_DECLs.  Don't pass context to finish_id_expression.
---
 gcc/cp/parser.cc | 36 +++++++++++++++++++++---------------
 1 file changed, 21 insertions(+), 15 deletions(-)

diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
index 13b9b8f46b4..6f3c4fa092e 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,28 @@ 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 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:];  */
+    t = convert_from_reference (t);
+  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 +6413,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;

base-commit: 918cf3a50de02334af7bac2ad11ac89e8d816c11
-- 
2.53.0

Reply via email to