On 4/2/25 3:07 PM, Patrick Palka wrote:
Bootstrapped and regtested on x86_64-pc-linux, does this look
OK for trunk/14?
OK.
-- >8 --
The testcase in this PR uses 2.5x more memory and 6x more compile
time ever since r14-5979 which implements P2280R4. This is because
our speculative constexpr folding now does a lot more work trying to
fold ultimately non-constant calls to constexpr functions, and in turn
produces a lot of garbage. Sometimes, we do successfully fold more
thanks to P2280R4, but it seems to be trivial stuff like calls to
std::array::size or std::addressof. The benefit of P2280 therefore
doesn't seem worth the cost during speculative constexpr folding, so
this patch restricts the paper to only manifestly-constant evaluation.
PR c++/119387
gcc/cp/ChangeLog:
* constexpr.cc (p2280_active_p): Define.
(cxx_eval_constant_expression) <case VAR_DECL>: Use it to
restrict P2280 relaxations.
<case PARM_DECL>: Likewise.
---
gcc/cp/constexpr.cc | 22 +++++++++++++++++++---
1 file changed, 19 insertions(+), 3 deletions(-)
diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc
index 4820bcc84aa..ee968bc4630 100644
--- a/gcc/cp/constexpr.cc
+++ b/gcc/cp/constexpr.cc
@@ -1294,6 +1294,22 @@ struct constexpr_ctx {
mce_value manifestly_const_eval;
};
+/* True if the constexpr relaxations afforded by P2280R4 for unknown
+ references and objects are in effect. */
+
+static bool
+p2280_active_p (const constexpr_ctx *ctx)
+{
+ if (ctx->manifestly_const_eval != mce_true)
+ /* Disable these relaxations during speculative constexpr folding,
+ as it can significantly increase compile time/memory use
+ (PR119387). */
+ return false;
+
+ /* P2280R4 is accepted as a DR back to C++11. */
+ return cxx_dialect >= cxx11;
+}
+
/* Remove T from the global values map, checking for attempts to destroy
a value that has already finished its lifetime. */
@@ -7792,7 +7808,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
r = TARGET_EXPR_INITIAL (r);
if (DECL_P (r)
/* P2280 allows references to unknown. */
- && !(VAR_P (t) && TYPE_REF_P (TREE_TYPE (t))))
+ && !(p2280_active_p (ctx) && VAR_P (t) && TYPE_REF_P (TREE_TYPE (t))))
{
if (!ctx->quiet)
non_const_var_error (loc, r, /*fundef_p*/false);
@@ -7844,9 +7860,9 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx,
tree t,
r = build_constructor (TREE_TYPE (t), NULL);
TREE_CONSTANT (r) = true;
}
- else if (TYPE_REF_P (TREE_TYPE (t)))
+ else if (p2280_active_p (ctx) && TYPE_REF_P (TREE_TYPE (t)))
/* P2280 allows references to unknown... */;
- else if (is_this_parameter (t))
+ else if (p2280_active_p (ctx) && is_this_parameter (t))
/* ...as well as the this pointer. */;
else
{