On 2/26/26 6:23 AM, Marek Polacek wrote:
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?
I guess just v1, with a comment pointing to that PR.
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.
Seems like we need to stop discarding expressions when we support
consteval-only. We might just stop discarding them there entirely, that
seems like a remnant of early folding that we've mostly gotten away from.
Jason