mirror of
https://gcc.gnu.org/git/gcc.git
synced 2026-02-22 03:46:53 -05:00
c++: Evaluate immediate invocation call arguments with mce_true [PR119150]
Since Marek's r14-4140 which moved immediate invocation evaluation
from build_over_call to cp_fold_r, the following testcase is miscompiled.
The a = foo (bar ()); case is actually handled right, that is handled
in cp_fold_r and the whole CALL_EXPR is at that point evaluated by
cp_fold_immediate_r with cxx_constant_value (stmt, tf_none);
and that uses mce_true for evaluation of the argument as well as the actual
call.
But in the bool b = foo (bar ()); case we actually try to evaluate this
as non-manifestly constant-evaluated. And while
/* Make sure we fold std::is_constant_evaluated to true in an
immediate function. */
if (DECL_IMMEDIATE_FUNCTION_P (fun))
call_ctx.manifestly_const_eval = mce_true;
ensures that if consteval and __builtin_is_constant_evaluated () is true
inside of that call, this happens after arguments to the function
have been already constant evaluated in cxx_bind_parameters_in_call.
The call_ctx in that case also includes new call_ctx.call, something that
shouldn't be used for the arguments, so the following patch just arranges
to call cxx_bind_parameters_in_call with manifestly_constant_evaluated =
mce_true.
2025-03-13 Jakub Jelinek <jakub@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.
This commit is contained in:
committed by
Jakub Jelinek
parent
2eb3d7454e
commit
ebf6e6241f
@@ -3077,6 +3077,15 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t,
|
||||
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. */
|
||||
|
||||
37
gcc/testsuite/g++.dg/cpp2a/consteval41.C
Normal file
37
gcc/testsuite/g++.dg/cpp2a/consteval41.C
Normal file
@@ -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 ();
|
||||
}
|
||||
Reference in New Issue
Block a user