On Wed, Feb 25, 2026 at 11:00:50AM +0900, Jason Merrill wrote:
> On 2/25/26 1:38 AM, Marek Polacek wrote:
> > On Tue, Feb 24, 2026 at 10:54:55PM +0900, Jason Merrill wrote:
> > > On 2/24/26 5:44 AM, Marek Polacek wrote:
> > > > Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?
> > > >
> > > > -- >8 --
> > > > This patch fixes a very annoying problem where we emit a bogus
> > > > check_out_of_consteval_use error. The error is provoked while
> > > > processing
> > > >
> > > > [: std::meta::reflect_constant_array (data) :]
> > > >
> > > > The argument of a [: :] is a constant-expression = a manifestly
> > > > constant-evaluated context, so any consteval-only exprs in it
> > > > are OK. But in eval_reflect_constant_array we do
> > > > get_template_parm_object
> > > > which does push_to_top_level -- so we have no scope_chain, therefore
> > > > any in_consteval_if_p and current_function_decl are cleared, so we're
> > > > not in an immediate context.
> > >
> > > Since we're initializing a constexpr variable (the template parameter
> > > object), we should be in MCE for that regardless of the splice expression.
> > > Maybe check_initializer should set that up?
> >
> > Yeah, that sounds right, thanks.
> >
> > I think that my change is also right, but not necessary anymore.
> >
> > Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?
> >
> > -- >8 --
> > This patch fixes a very annoying problem where we emit a bogus
> > check_out_of_consteval_use error. The error is provoked while
> > processing
> >
> > [: std::meta::reflect_constant_array (data) :]
> >
> > The argument of a [: :] is a constant-expression = a manifestly
> > constant-evaluated context, so any consteval-only exprs in it
> > are OK. But in eval_reflect_constant_array we do get_template_parm_object
> > which does push_to_top_level -- so we have no scope_chain, therefore
> > any in_consteval_if_p and current_function_decl are cleared, so we're
> > not in an immediate context. As part of this get_template_parm_object,
> > we call cp_finish_decl -> check_initializer -> build_aggr_init ->
> > -> build_vec_init.
> >
> > Here in build_vec_init try_const is true, but we still generate code
> > for the initializer like
> >
> > <<< Unknown tree: expr_stmt
> > (void) ++D.67757 >>>;
> > <<< Unknown tree: expr_stmt
> > (void) --D.67758 >>>;
> >
> > etc. We add ++D.67757 with finish_expr_stmt which calls
> > convert_to_void -> check_out_of_consteval_use which causes the error
> > because ++D.67757's type is consteval-only. Note that what we end up using
> > is the simple
> >
> > _ZTAX... = {{.name=<<< Unknown tree: reflect_expr _ZTAXtlA2_KcLS_95EEE
> > >>>, .none=1}}
> >
> > because we didn't see anything non-const in the initializer.
> >
> > When initializing a constexpr variable, we are in a manifestly
> > constant-evaluated context, so fix check_initializer to that effect.
> >
> > PR c++/123662
> > PR c++/123611
> >
> > gcc/cp/ChangeLog:
> >
> > * decl.cc (check_initializer): Set in_consteval_if_p when initializing
> > a constexpr variable.
>
> Hmm, this doesn't address more ambiguously MCE variables that aren't
> declared constexpr (or constinit) but have constant initialization.
>
> So I think I was wrong and your first patch was better, it improves the
> issue of checking out-of-consteval-use when we're still mce_unknown. But it
> doesn't completely fix it:
>
> int i = (^^i, 42); // OK, MCE
Argh, true. I've opened <https://gcc.gnu.org/PR124249> for this.
What do you think about merging v1 and v2? Or should I push v1 only?
> Fundamentally the problem is that convert_to_void is too soon to diagnose
> this in general.
I did it there because convert_to_void is where we may discard expressions
and so it's our last chance to diagnose out-of-consteval-uses. But as you
point out, it shouldn't check initializers. For those, we should probably
wait till cp_finish_decl, after store_init_value's fold_non_dependent_init,
I would guess.
Marek