aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/constexpr.cc
diff options
context:
space:
mode:
authorMarek Polacek <polacek@redhat.com>2023-08-31 20:11:50 -0400
committerMarek Polacek <polacek@redhat.com>2023-09-19 09:24:44 -0400
commit6851e3423c2b5ec6516efa0677745d25c905e079 (patch)
tree72c6c8bc7a321e6f9f6090b9db82fea35931e707 /gcc/cp/constexpr.cc
parentf25960b03834712f312d46fed9a021df36f89f22 (diff)
downloadgcc-6851e3423c2b5ec6516efa0677745d25c905e079.zip
gcc-6851e3423c2b5ec6516efa0677745d25c905e079.tar.gz
gcc-6851e3423c2b5ec6516efa0677745d25c905e079.tar.bz2
c++: Move consteval folding to cp_fold_r
In the review of P2564: <https://gcc.gnu.org/pipermail/gcc-patches/2023-August/628747.html> it turned out that in order to correctly handle an example in the paper, we should stop doing immediate evaluation in build_over_call and bot_replace, and instead do it in cp_fold_r. This patch does that. Another benefit is that this is a pretty significant simplification, at least in my opinion. Also, this fixes the c++/110997 ICE (but the test doesn't compile yet). The main drawback seems to be that cp_fold_r doesn't process uninstantiated templates. We still have to handle things like "false ? foo () : 1". To that end, I've added cp_fold_immediate, called on dead branches in cxx_eval_conditional_expression. You'll see that I've reintroduced ADDR_EXPR_DENOTES_CALL_P here. This is to detect *(&foo)) () (s.*&S::foo) () which were deemed ill-formed. gcc/cp/ChangeLog: * call.cc (build_over_call): Set ADDR_EXPR_DENOTES_CALL_P. Don't handle immediate_invocation_p here. * constexpr.cc (cxx_eval_call_expression): Use mce_true for DECL_IMMEDIATE_FUNCTION_P. (cxx_eval_conditional_expression): Call cp_fold_immediate. * cp-gimplify.cc (enum fold_flags): Add ff_fold_immediate. (maybe_replace_decl): Make static. (cp_fold_r): Expand immediate invocations. (cp_fold_immediate_r): New. (cp_fold_immediate): New. * cp-tree.h (ADDR_EXPR_DENOTES_CALL_P): Define. (cp_fold_immediate): Declare. * tree.cc (bot_replace): Don't handle immediate invocations here. libstdc++-v3/ChangeLog: * testsuite/20_util/allocator/105975.cc: Add dg-error. gcc/testsuite/ChangeLog: * g++.dg/cpp23/consteval-if2.C: Add xfail. * g++.dg/cpp2a/consteval-memfn1.C: Adjust. * g++.dg/cpp2a/consteval11.C: Remove dg-message. * g++.dg/cpp2a/consteval3.C: Remove dg-message and dg-error. * g++.dg/cpp2a/consteval9.C: Remove dg-message. * g++.dg/cpp2a/consteval32.C: New test. * g++.dg/cpp2a/consteval33.C: New test. * g++.dg/cpp2a/consteval34.C: New test. * g++.dg/cpp2a/consteval35.C: New test.
Diffstat (limited to 'gcc/cp/constexpr.cc')
-rw-r--r--gcc/cp/constexpr.cc23
1 files changed, 20 insertions, 3 deletions
diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc
index 0ca4370..a673a60 100644
--- a/gcc/cp/constexpr.cc
+++ b/gcc/cp/constexpr.cc
@@ -3135,6 +3135,11 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t,
unsigned save_heap_alloc_count = ctx->global->heap_vars.length ();
unsigned save_heap_dealloc_count = ctx->global->heap_dealloc_count;
+ /* 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;
+
/* If this is a constexpr destructor, the object's const and volatile
semantics are no longer in effect; see [class.dtor]p5. */
if (new_obj && DECL_DESTRUCTOR_P (fun))
@@ -3807,8 +3812,7 @@ cxx_eval_binary_expression (const constexpr_ctx *ctx, tree t,
}
/* Subroutine of cxx_eval_constant_expression.
- Attempt to evaluate condition expressions. Dead branches are not
- looked into. */
+ Attempt to evaluate condition expressions. */
static tree
cxx_eval_conditional_expression (const constexpr_ctx *ctx, tree t,
@@ -3837,12 +3841,25 @@ cxx_eval_conditional_expression (const constexpr_ctx *ctx, tree t,
boolean_type_node);
}
/* Don't VERIFY_CONSTANT the other operands. */
- if (integer_zerop (val))
+ const bool zero_p = integer_zerop (val);
+ if (zero_p)
val = TREE_OPERAND (t, 2);
else
val = TREE_OPERAND (t, 1);
if (TREE_CODE (t) == IF_STMT && !val)
val = void_node;
+
+ /* P2564: a subexpression of a manifestly constant-evaluated expression
+ or conversion is an immediate function context. */
+ if (ctx->manifestly_const_eval != mce_true
+ && !in_immediate_context ()
+ && cp_fold_immediate (&TREE_OPERAND (t, zero_p ? 1 : 2),
+ ctx->manifestly_const_eval))
+ {
+ *non_constant_p = true;
+ return t;
+ }
+
/* A TARGET_EXPR may be nested inside another TARGET_EXPR, but still
serve as the initializer for the same object as the outer TARGET_EXPR,
as in