From: Jason Merrill Date: Sat, 27 Jul 2024 20:40:02 +0000 (-0400) Subject: c++: if consteval and consteval propagation [PR115583] X-Git-Tag: basepoints/gcc-16~7184 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d5f1948640815a554d106542c2e91e4e117aa3bc;p=thirdparty%2Fgcc.git c++: if consteval and consteval propagation [PR115583] During speculative constant folding of an if consteval, we take the false branch, but the true branch is an immediate function context, so we don't want to to cp_fold_immediate it. So we could check IF_STMT_CONSTEVAL_P here. But beyond that, we don't want to do this inside a call, only when first parsing a function. PR c++/115583 gcc/cp/ChangeLog: * constexpr.cc (cxx_eval_conditional_expression): Don't cp_fold_immediate for if consteval. gcc/testsuite/ChangeLog: * g++.dg/cpp23/consteval-if13.C: New test. --- diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc index abd3b04ea7f..8277b3b79ba 100644 --- a/gcc/cp/constexpr.cc +++ b/gcc/cp/constexpr.cc @@ -3974,10 +3974,13 @@ cxx_eval_conditional_expression (const constexpr_ctx *ctx, tree t, 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. */ + /* P2564: If we aren't in immediate function context (including a manifestly + constant-evaluated expression), check any uses of immediate functions in + the arm we're discarding. But don't do this inside a call; we already + checked when parsing the function. */ if (ctx->manifestly_const_eval != mce_true && !in_immediate_context () + && !ctx->call && cp_fold_immediate (&TREE_OPERAND (t, zero_p ? 1 : 2), ctx->manifestly_const_eval)) { diff --git a/gcc/testsuite/g++.dg/cpp23/consteval-if13.C b/gcc/testsuite/g++.dg/cpp23/consteval-if13.C new file mode 100644 index 00000000000..b98bbc33d13 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp23/consteval-if13.C @@ -0,0 +1,17 @@ +// PR c++/115583 +// { dg-do compile { target c++23 } } + +consteval int f(int i) { + return i; +} +const bool b = 0; +constexpr int g(int i) { + if consteval { + return f(i); + } else { + return i; + } +} +int main() { + return g(1); +}