On 3/12/25 11:38 AM, Jakub Jelinek wrote:
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?
OK.
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