The patch for P0595R1 - is_constant_evaluated had this hunk: @@ -5279,7 +5315,9 @@ maybe_constant_init_1 (tree t, tree decl, bool allow_non_constant) else if (CONSTANT_CLASS_P (t) && allow_non_constant) /* No evaluation needed. */; else - t = cxx_eval_outermost_constant_expr (t, allow_non_constant, false, decl); + t = cxx_eval_outermost_constant_expr (t, allow_non_constant, + !allow_non_constant, + pretend_const_required, decl); if (TREE_CODE (t) == TARGET_EXPR) { tree init = TARGET_EXPR_INITIAL (t);
the false -> !allow_non_constant change means that when calling cxx_constant_init strict will be true because cxx_constant_init does not allow non constants. That means that for VAR_DECLs such as __func__ we'll call decl_really_constant_value instead of decl_constant_value. But only the latter can evaluate __func__ to "foo()". Jakub, was there a specific reason for this change? Changing it back still regtests cleanly and the attached test compiles again. Bootstrapped/regtested on x86_64-linux, ok for trunk? 2018-09-20 Marek Polacek <pola...@redhat.com> PR c++/87372 - __func__ constexpr evaluation. * constexpr.c (maybe_constant_init_1): Pass false for strict down to cxx_eval_outermost_constant_expr. * g++.dg/cpp1y/func_constexpr2.C: New test. diff --git gcc/cp/constexpr.c gcc/cp/constexpr.c index fdea769faa9..6436b2f832d 100644 --- gcc/cp/constexpr.c +++ gcc/cp/constexpr.c @@ -5361,7 +5361,7 @@ maybe_constant_init_1 (tree t, tree decl, bool allow_non_constant, /* No evaluation needed. */; else t = cxx_eval_outermost_constant_expr (t, allow_non_constant, - !allow_non_constant, + /*strict*/false, pretend_const_required, decl); if (TREE_CODE (t) == TARGET_EXPR) { diff --git gcc/testsuite/g++.dg/cpp1y/func_constexpr2.C gcc/testsuite/g++.dg/cpp1y/func_constexpr2.C index e69de29bb2d..b1576e64960 100644 --- gcc/testsuite/g++.dg/cpp1y/func_constexpr2.C +++ gcc/testsuite/g++.dg/cpp1y/func_constexpr2.C @@ -0,0 +1,21 @@ +// PR c++/87372 +// { dg-do compile { target c++14 } } + +constexpr int +foo (char const *s) +{ + int i = 0; + while (s[i]) + ++i; + return i; +} + +constexpr int +bar () +{ + constexpr int l = foo (__PRETTY_FUNCTION__); + constexpr int l2 = foo (__FUNCTION__); + constexpr int l3 = foo (__func__); + return l + l2 + l3; +} +static_assert (bar () == 25, "");