On Wed, Mar 12, 2025 at 09:01:17AM -0400, Jason Merrill wrote: > Why not use new_ctx for this instead of creating another copy? > > I would think once we see that we have an immediate function, we want to go > ahead and set ctx->manifestly_const_eval and new_call->manifestly_const_eval > to true. It looks like we currently cache immediate invocations separately > depending on whether they're in an enclosing immediate function context, > which seems redundant. > > Incidentally, I don't remember why we need a separate call_ctx either.
So like this then? Passes GXX_TESTSUITE_STDS=98,11,14,17,20,23,26 make check-g++ RUNTESTFLAGS="dg.exp=consteval*" ok if it passes full bootstrap/regtest? 2025-03-12 Jakub Jelinek <ja...@redhat.com> PR c++/119150 * constexpr.cc (cxx_eval_call_expression): For DECL_IMMEDIATE_FUNCTION_P (fun) set manifestly_const_eval in new_ctx and new_call to mce_true and set ctx to &new_ctx. * g++.dg/cpp2a/consteval41.C: New test. --- gcc/cp/constexpr.cc.jj 2025-03-01 09:13:17.694075636 +0100 +++ gcc/cp/constexpr.cc 2025-03-12 16:30:29.376492168 +0100 @@ -3077,6 +3077,15 @@ cxx_eval_call_expression (const constexp ctx->global->put_value (new_ctx.object, ctor); ctx = &new_ctx; } + /* An immediate invocation is manifestly constant evaluated including the + arguments of the call, so use mce_true even for the argument + evaluation. */ + if (DECL_IMMEDIATE_FUNCTION_P (fun)) + { + new_ctx.manifestly_const_eval = mce_true; + new_call.manifestly_const_eval = mce_true; + ctx = &new_ctx; + } /* We used to shortcut trivial constructor/op= here, but nowadays we can only get a trivial function here with -fno-elide-constructors. */ --- gcc/testsuite/g++.dg/cpp2a/consteval41.C.jj 2025-03-07 13:39:34.526101144 +0100 +++ gcc/testsuite/g++.dg/cpp2a/consteval41.C 2025-03-07 13:38:38.128871572 +0100 @@ -0,0 +1,37 @@ +// PR c++/119150 +// { dg-do run { target c++20 } } + +consteval bool +foo (bool x) +{ + return x; +} + +constexpr bool +bar () +{ +#if __cpp_if_consteval >= 202106L + if consteval + { + return true; + } + else + { + return false; + } +#else + return __builtin_is_constant_evaluated (); +#endif +} + +int +main () +{ + bool a = false; + a = foo (bar ()); + if (!a) + __builtin_abort (); + bool b = foo (bar ()); + if (!b) + __builtin_abort (); +} Jakub