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

Reply via email to