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.

gcc/cp/ChangeLog:

        * cp-tree.h (finish_id_expression): Adjust declaration.
        * parser.cc (cp_parser_splice_expression): Don't defer access checking.
        Don't pass context to finish_id_expression.  Call finish_id_expression
        with splice_p = true.
        (cp_parser_primary_expression): Adjust the call to finish_id_expression.
        (cp_parser_lambda_introducer): Likewise.
        (cp_parser_decltype_expr): Likewise.
        (cp_finish_omp_declare_variant): Likewise.
        * pt.cc (tsubst_expr): Likewise.
        * semantics.cc (finish_id_expression_1): New splice_p parameter.
        For FIELD_DECLs and functions, call build_offset_ref when taking
        the address when the entity was designated by a splice-expression.
        Use nullptr.  Allow a VAR_DECL in an assert.
        (finish_id_expression): New splice_p parameter.  Use it.
        (omp_reduction_lookup): Adjust the call to finish_id_expression.
---
 gcc/cp/cp-tree.h    |  2 +-
 gcc/cp/parser.cc    | 21 +++++++--------------
 gcc/cp/pt.cc        |  1 +
 gcc/cp/semantics.cc | 41 +++++++++++++++++++++++++++++------------
 4 files changed, 38 insertions(+), 27 deletions(-)

diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index fcad67a662c..99f4c2fc2e4 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -8443,7 +8443,7 @@ extern tree process_outer_var_ref         (tree, 
tsubst_flags_t, bool force_use = false
 extern cp_expr finish_id_expression            (tree, tree, tree,
                                                 cp_id_kind *,
                                                 bool, bool, bool *,
-                                                bool, bool, bool, bool,
+                                                bool, bool, bool, bool, bool,
                                                 const char **,
                                                  location_t);
 extern tree finish_typeof                      (tree);
diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
index 8c46b260fff..a7ad4876ac3 100644
--- a/gcc/cp/parser.cc
+++ b/gcc/cp/parser.cc
@@ -6395,18 +6395,8 @@ cp_parser_splice_expression (cp_parser *parser, bool 
template_p,
         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.  */
-      push_deferring_access_checks (dk_no_check);
       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,
@@ -6414,11 +6404,11 @@ cp_parser_splice_expression (cp_parser *parser, bool 
template_p,
                                /*done=*/true,
                                address_p,
                                template_arg_p,
+                               /*splice_p=*/true,
                                &error_msg,
                                loc);
       if (error_msg)
        cp_parser_error (parser, error_msg);
-      pop_deferring_access_checks ();
     }
 
   return t;
@@ -7174,6 +7164,7 @@ cp_parser_primary_expression (cp_parser *parser,
                 &parser->non_integral_constant_expression_p,
                 template_p, done, address_p,
                 template_arg_p,
+                /*splice_p=*/false,
                 &error_msg,
                 id_expression.get_location ()));
        if (error_msg)
@@ -13177,6 +13168,7 @@ cp_parser_lambda_introducer (cp_parser* parser, tree 
lambda_expr)
                  /*done=*/true,
                  /*address_p=*/false,
                  /*template_arg_p=*/false,
+                /*splice_p=*/false,
                  &error_msg,
                  capture_token->location);
 
@@ -19299,6 +19291,7 @@ cp_parser_decltype_expr (cp_parser *parser,
                    /*done=*/true,
                    /*address_p=*/false,
                    /*template_arg_p=*/false,
+                  /*splice_p=*/false,
                    &error_msg,
                   id_expr_start_token->location));
 
@@ -53549,8 +53542,8 @@ cp_finish_omp_declare_variant (cp_parser *parser, 
cp_token *pragma_tok,
        = finish_id_expression (varid, variant, parser->scope,
                                &idk, false, true,
                                &parser->non_integral_constant_expression_p,
-                               template_p, true, false, false, &error_msg,
-                               varid.get_location ());
+                               template_p, true, false, false, false,
+                               &error_msg, varid.get_location ());
       if (error_msg)
        cp_parser_error (parser, error_msg);
     }
diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index 7c6577b48ef..c510733d41b 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -21185,6 +21185,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t 
complain, tree in_decl)
                                     /*done=*/true,
                                     /*address_p=*/false,
                                     /*template_arg_p=*/false,
+                                    /*splice_p=*/false,
                                     &error_msg,
                                     input_location);
        if (error_msg)
diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index 236bc625c25..76b0ddb1b12 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -4735,6 +4735,7 @@ process_outer_var_ref (tree decl, tsubst_flags_t 
complain, bool odr_use)
    TEMPLATE_P is true iff the qualified-id was of the form
    "A::template B".  TEMPLATE_ARG_P is true iff this qualified name
    appears as a template argument.
+   SPLICE_P is true if ID_EXPRESSION was designated by a splice-expression.
 
    If an error occurs, and it is the kind of error that might cause
    the parser to abort a tentative parse, *ERROR_MSG is filled in.  It
@@ -4760,6 +4761,7 @@ finish_id_expression_1 (tree id_expression,
                        bool done,
                        bool address_p,
                        bool template_arg_p,
+                       bool splice_p,
                        const char **error_msg,
                        location_t location)
 {
@@ -5022,16 +5024,23 @@ finish_id_expression_1 (tree id_expression,
              && contract_class_ptr == current_class_ptr)
            {
              error ("%qD 'this' required when accessing a member within a "
-                 "constructor precondition or destructor postcondition "
-                 "contract check", decl);
-                     return error_mark_node;
+                    "constructor precondition or destructor postcondition "
+                    "contract check", decl);
+             return error_mark_node;
            }
          /* Since SCOPE is NULL here, this is an unqualified name.
             Access checking has been performed during name lookup
             already.  Turn off checking to avoid duplicate errors.  */
          push_deferring_access_checks (dk_no_check);
-         decl = finish_non_static_data_member (decl, NULL_TREE,
-                                               /*qualifying_scope=*/NULL_TREE);
+
+         if (splice_p && address_p)
+           decl = build_offset_ref (DECL_CONTEXT (decl), decl,
+                                    /*address_p=*/true,
+                                    tf_warning_or_error);
+         else
+           decl
+             = finish_non_static_data_member (decl, NULL_TREE,
+                                              /*qualifying_scope=*/NULL_TREE);
          pop_deferring_access_checks ();
        }
       else if (is_overloaded_fn (decl))
@@ -5041,6 +5050,11 @@ finish_id_expression_1 (tree id_expression,
             concerned with (all member fns or all non-members).  */
          tree first_fn = get_first_fn (decl);
          first_fn = STRIP_TEMPLATE (first_fn);
+         tree ctx = DECL_CONTEXT (first_fn);
+
+         if (splice_p && address_p)
+           return build_offset_ref (ctx, first_fn, /*address_p=*/true,
+                                    tf_warning_or_error);
 
          if (!template_arg_p
              && (TREE_CODE (first_fn) == USING_DECL
@@ -5053,14 +5067,15 @@ finish_id_expression_1 (tree id_expression,
                  && contract_class_ptr == current_class_ptr)
                {
                  error ("%qD 'this' required when accessing a member within a "
-                     "constructor precondition or destructor postcondition "
-                     "contract check", decl);
+                        "constructor precondition or destructor postcondition "
+                        "contract check", decl);
                  return error_mark_node;
                }
-             decl = maybe_dummy_object (DECL_CONTEXT (first_fn), 0);
+             decl = maybe_dummy_object (ctx, nullptr);
              return finish_class_member_access_expr (decl, id_expression,
                                                      /*template_p=*/false,
-                                                     tf_warning_or_error);
+                                                     tf_warning_or_error,
+                                                     splice_p);
            }
 
          decl = baselink_for_fns (decl);
@@ -5080,7 +5095,8 @@ 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
+                               || (splice_p && VAR_P (decl)));
                  else
                    perform_or_defer_access_check (TYPE_BINFO (path),
                                                   decl, decl,
@@ -5114,6 +5130,7 @@ finish_id_expression (tree id_expression,
                      bool done,
                      bool address_p,
                      bool template_arg_p,
+                     bool splice_p,
                      const char **error_msg,
                      location_t location)
 {
@@ -5123,7 +5140,7 @@ finish_id_expression (tree id_expression,
                              allow_non_integral_constant_expression_p,
                              non_integral_constant_expression_p,
                              template_p, done, address_p, template_arg_p,
-                             error_msg, location);
+                             splice_p, error_msg, location);
   return result.maybe_add_location_wrapper ();
 }
 
@@ -6744,7 +6761,7 @@ omp_reduction_lookup (location_t loc, tree id, tree type, 
tree *baselinkp,
        decl = error_mark_node;
       id = finish_id_expression (id, decl, NULL_TREE, &idk, false, true,
                                 &nonint_cst_expression_p, false, true, false,
-                                false, &error_msg, loc);
+                                false, false, &error_msg, loc);
       if (idk == CP_ID_KIND_UNQUALIFIED
          && identifier_p (id))
        {

base-commit: 065a6ab3747fe9116643ac6754582bc195847bfc
-- 
2.53.0

Reply via email to