On Thu, 6 Aug 2026, Patrick Palka wrote:

> Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look
> OK for trunk/backports?

Ping (along with the first patch in the series "c++: testsuite: Add some
opt/is_constant_evaluated3.C variant")

> 
> -- >8 --
> 
> Here when processing a's copy-initialization we overeagerly fold its
> initializer as if the lambda scope is not constexpr, and thus assume
> is_const_eval() is false.  Subsequent constant evaluation of the lambda
> gives the wrong answer due to this premature folding.
> 
> The culprit cp_fully_fold_init call is guarded by DECL_DECLARED_CONSTEXPR_P
> but that isn't set on maybe-constexpr lambdas until the lambda is fully
> parsed and its body is checked as a whole for constexpr suitability.
> The call needs to instead be guarded by maybe_constexpr_fn which considers
> such lambdas (although it considers all lambdas to be maybe-constexpr
> even fully parsed ones that have been deemed non-constexpr).
> 
> This however means we no longer fold a's copy-init even for the runtime
> version of the lambda body, hence the is_constant_evaluated3b xfail.
> Making maybe_constexpr_fn distinguish between fully parsed constexpr and
> non-constexpr lambdas doesn't help because we don't hit this code path
> again and cp_fold_function can't seem to fold the copy-init form:
> 
> struct A a1;
> <<cleanup_point <<< Unknown tree: expr_stmt
>   (void) (a1 = <<< Unknown tree: aggr_init_expr
>     5
>     __ct_comp
>     D.3052
>     (struct A *) <<< Unknown tree: void_cst >>>
>     42 >>>) >>>>>;
> 
> whereas (after r14-6506) it does fold direct-init etc which is expressed
> as:
> 
> struct A a3;
> <<cleanup_point <<< Unknown tree: expr_stmt
>   A::A (&a3, NON_LVALUE_EXPR <42>) >>>>>;
> 
> Marek's prvalue folding patch r15-6052 doesn't seem to help because
> naturally it looks for TARGET_EXPR and we don't have one here.  It
> should be possible to have cp_fold_function fold this but I haven't
> looked into it.  It would fix the xfail in is_constant_evaluated3{a,b}.
> 
>       PR c++/126483
> 
> gcc/cp/ChangeLog:
> 
>       * typeck2.cc (store_init_value): Check maybe_constexpr_fn
>       instead of DECL_DECLARED_CONSTEXPR_P.
> 
> gcc/testsuite/ChangeLog:
> 
>       * gcc/testsuite/g++.dg/opt/is_constant_evaluated3b.C: xfail
>       a1 initializer folding.
>       * g++.dg/cpp2a/is-constant-evaluated16.C: New test.
> ---
>  gcc/cp/typeck2.cc                             |  2 +-
>  .../g++.dg/cpp2a/is-constant-evaluated16.C    | 20 +++++++++++++++++++
>  .../g++.dg/opt/is_constant_evaluated3b.C      |  2 +-
>  3 files changed, 22 insertions(+), 2 deletions(-)
>  create mode 100644 gcc/testsuite/g++.dg/cpp2a/is-constant-evaluated16.C
> 
> diff --git a/gcc/cp/typeck2.cc b/gcc/cp/typeck2.cc
> index 6c4ed50cb94e..62f583dcf405 100644
> --- a/gcc/cp/typeck2.cc
> +++ b/gcc/cp/typeck2.cc
> @@ -1129,7 +1129,7 @@ store_init_value (tree decl, tree init, vec<tree, 
> va_gc>** cleanups, int flags)
>       that might fold away something that needs to be diagnosed at constexpr
>       evaluation time.  */
>    if (!current_function_decl
> -      || !DECL_DECLARED_CONSTEXPR_P (current_function_decl)
> +      || !maybe_constexpr_fn (current_function_decl)
>        || TREE_STATIC (decl))
>      value = cp_fully_fold_init (value);
>  
> diff --git a/gcc/testsuite/g++.dg/cpp2a/is-constant-evaluated16.C 
> b/gcc/testsuite/g++.dg/cpp2a/is-constant-evaluated16.C
> new file mode 100644
> index 000000000000..c727967673e3
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/cpp2a/is-constant-evaluated16.C
> @@ -0,0 +1,20 @@
> +// PR c++/126483
> +// { dg-do compile { target c++17 } }
> +
> +struct A {
> +  int m;
> +  constexpr A(int n) : m(__builtin_is_constant_evaluated() ? 42 : n) { }
> +};
> +
> +constexpr auto v = [] {
> +  A a = 0;
> +  return a.m;
> +};
> +static_assert(v() == 42);
> +
> +template<class>
> +constexpr auto vt = [] {
> +  A a = 0;
> +  return a.m;
> +};
> +static_assert(vt<void>() == 42);
> diff --git a/gcc/testsuite/g++.dg/opt/is_constant_evaluated3b.C 
> b/gcc/testsuite/g++.dg/opt/is_constant_evaluated3b.C
> index ff708e23832b..ac6d21d632e1 100644
> --- a/gcc/testsuite/g++.dg/opt/is_constant_evaluated3b.C
> +++ b/gcc/testsuite/g++.dg/opt/is_constant_evaluated3b.C
> @@ -17,7 +17,7 @@ auto f = [] {
>    A a5{};
>  };
>  
> -// { dg-final { scan-tree-dump "a1 = {\\.n=42, \\.m=0}" "original" } }
> +// { dg-final { scan-tree-dump "a1 = {\\.n=42, \\.m=0}" "original" { xfail 
> *-*-* } } }
>  // { dg-final { scan-tree-dump "a2 = {\\.n=42, \\.m=0}" "original" } }
>  // { dg-final { scan-tree-dump "a3 = {\\.n=42, \\.m=0}" "original" } }
>  // { dg-final { scan-tree-dump "a4 = {\\.n=42, \\.m=0}" "original" } }
> -- 
> 2.55.0.481.ga97fcc37c2
> 
> 

Reply via email to