c++: consteval propagation and templates [PR115986]

Here the call to e() makes us decide to check d() for escalation at EOF, but
while checking it we try to fold_immediate 0_c, and get confused by the
template trees.  Let's not mess with escalation for function templates.

	PR c++/115986

gcc/cp/ChangeLog:

	* cp-gimplify.cc (remember_escalating_expr): Skip function
	templates.

gcc/testsuite/ChangeLog:

	* g++.dg/cpp2a/consteval-prop21.C: New test.
This commit is contained in:
Jason Merrill 2024-07-26 17:20:18 -04:00
parent 3129a2ed6a
commit a9e9f772c7
2 changed files with 21 additions and 0 deletions

View File

@ -53,6 +53,10 @@ static GTY(()) hash_set<tree> *deferred_escalating_exprs;
static void
remember_escalating_expr (tree t)
{
if (uses_template_parms (t))
/* Templates don't escalate, and cp_fold_immediate can get confused by
other template trees in the function body (c++/115986). */
return;
if (!deferred_escalating_exprs)
deferred_escalating_exprs = hash_set<tree>::create_ggc (37);
deferred_escalating_exprs->add (t);

View File

@ -0,0 +1,17 @@
// PR c++/115986
// { dg-do compile { target c++20 } }
template <typename T>
constexpr int b(T) {
return 0;
}
consteval __uint128_t operator"" _c(const char*) { return 0; }
constexpr char e() {
long f = true ? 0 : b(long(1));
return b(f);
}
template <typename>
void d() {
0_c;
static_assert(e());
}