Ping. On Wed, Feb 11, 2026 at 10:29:24AM -0500, 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. > So I think the patch wouldn't be much simpler if I called b_o_r in _parser_. > > > > 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 > > > > Marek
Marek
