On Sat, 12 Apr 2025, Jason Merrill wrote: > On 4/11/25 4:36 PM, Patrick Palka wrote: > > Boostrapped and regtested on x86_64-pc-linux- gnu, does this look OK > > for GCC 15 perhaps? > > > > -- >8 -- > > > > This patch improves upon r15-6052-g12de1942a0a673 by performing prvalue > > folding with mce_false rather than mce_unknown when it's safe to do so > > (i.e. the caller passed ff_mce_false), so that we can also fold temporary > > initializers that call is_constant_evaluated etc. > > > > In passing I noticed constexpr-prvalue1.C could more precisely verify > > the optimization happened by inspecting what the front end spits out > > instead of the final assembly. > > I'm not sure that specificity is necessary, but OK.
Since we're compiling with -O the middle-end inlines the constructor call, so the scan-assembler test succeeds even without r15-6052. > > > PR c++/116416 > > > > gcc/cp/ChangeLog: > > > > * constexpr.cc (maybe_constant_init_1): Generalize type of > > of manifestly_const_eval parameter from bool to mce_value. > > (maybe_constant_init): Define 3-parameter version taking a > > manifestly_const_eval instead of bool parameter. > > (cxx_constant_init): Adjust maybe_constant_init_1. > > * cp-gimplify.cc (cp_fold_r) <case TARGET_EXPR>: Pass mce_false > > to maybe_constant_init during prvalue folding if ff_mce_false is > > set. > > * cp-tree.h (maybe_constant_init): Declare new overload. > > > > gcc/testsuite/ChangeLog: > > > > * g++.dg/cpp1y/constexpr-prvalue1.C: Adjust to instead inspect > > the 'original' dump. > > * g++.dg/cpp1y/constexpr-prvalue1a.C: New test. > > --- > > gcc/cp/constexpr.cc | 16 +++++++--- > > gcc/cp/cp-gimplify.cc | 4 ++- > > gcc/cp/cp-tree.h | 1 + > > .../g++.dg/cpp1y/constexpr-prvalue1.C | 11 ++++--- > > .../g++.dg/cpp1y/constexpr-prvalue1a.C | 32 +++++++++++++++++++ > > 5 files changed, 53 insertions(+), 11 deletions(-) > > create mode 100644 gcc/testsuite/g++.dg/cpp1y/constexpr-prvalue1a.C > > > > diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc > > index 497f64f3ceaa..0242425370f4 100644 > > --- a/gcc/cp/constexpr.cc > > +++ b/gcc/cp/constexpr.cc > > @@ -9679,7 +9679,7 @@ fold_non_dependent_init (tree t, > > static tree > > maybe_constant_init_1 (tree t, tree decl, bool allow_non_constant, > > - bool manifestly_const_eval) > > + mce_value manifestly_const_eval) > > { > > if (!t) > > return t; > > @@ -9709,13 +9709,13 @@ maybe_constant_init_1 (tree t, tree decl, bool > > allow_non_constant, > > bool is_static = (decl && DECL_P (decl) > > && (TREE_STATIC (decl) || DECL_EXTERNAL (decl))); > > if (is_static) > > - manifestly_const_eval = true; > > + manifestly_const_eval = mce_true; > > - if (cp_unevaluated_operand && !manifestly_const_eval) > > + if (cp_unevaluated_operand && manifestly_const_eval != mce_true) > > return fold_to_constant (t); > > t = cxx_eval_outermost_constant_expr (t, allow_non_constant, > > !is_static, > > - mce_value (manifestly_const_eval), > > + manifestly_const_eval, > > false, decl); > > } > > if (TREE_CODE (t) == TARGET_EXPR) > > @@ -9731,6 +9731,12 @@ maybe_constant_init_1 (tree t, tree decl, bool > > allow_non_constant, > > tree > > maybe_constant_init (tree t, tree decl, bool manifestly_const_eval) > > +{ > > + return maybe_constant_init_1 (t, decl, true, mce_value > > (manifestly_const_eval)); > > +} > > + > > +tree > > +maybe_constant_init (tree t, tree decl, mce_value manifestly_const_eval) > > { > > return maybe_constant_init_1 (t, decl, true, manifestly_const_eval); > > } > > @@ -9740,7 +9746,7 @@ maybe_constant_init (tree t, tree decl, bool > > manifestly_const_eval) > > tree > > cxx_constant_init (tree t, tree decl) > > { > > - return maybe_constant_init_1 (t, decl, false, true); > > + return maybe_constant_init_1 (t, decl, false, mce_true); > > } > > #if 0 > > diff --git a/gcc/cp/cp-gimplify.cc b/gcc/cp/cp-gimplify.cc > > index 550cea29dd29..8dfa5ac2b88d 100644 > > --- a/gcc/cp/cp-gimplify.cc > > +++ b/gcc/cp/cp-gimplify.cc > > @@ -1480,7 +1480,9 @@ cp_fold_r (tree *stmt_p, int *walk_subtrees, void > > *data_) > > *walk_subtrees = 0; > > if (!flag_no_inline) > > { > > - tree folded = maybe_constant_init (init, TARGET_EXPR_SLOT > > (stmt)); > > + tree folded = maybe_constant_init (init, TARGET_EXPR_SLOT > > (stmt), > > + (data->flags & ff_mce_false > > + ? mce_false : mce_unknown)); > > if (folded != init && TREE_CONSTANT (folded)) > > init = folded; > > } > > diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h > > index 927f51b116b3..55f986e25c14 100644 > > --- a/gcc/cp/cp-tree.h > > +++ b/gcc/cp/cp-tree.h > > @@ -8837,6 +8837,7 @@ extern void cxx_constant_dtor (tree, > > tree); > > extern tree cxx_constant_init (tree, tree = > > NULL_TREE); > > extern tree maybe_constant_value (tree, tree = NULL_TREE, > > mce_value = mce_unknown); > > extern tree maybe_constant_init (tree, tree = > > NULL_TREE, bool = false); > > +extern tree maybe_constant_init (tree, tree, > > mce_value); > > extern tree fold_non_dependent_expr (tree, > > tsubst_flags_t = > > tf_warning_or_error, > > bool = false, tree = > > NULL_TREE); > > diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-prvalue1.C > > b/gcc/testsuite/g++.dg/cpp1y/constexpr-prvalue1.C > > index ad31e3001167..a17fed786fe8 100644 > > --- a/gcc/testsuite/g++.dg/cpp1y/constexpr-prvalue1.C > > +++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-prvalue1.C > > @@ -1,6 +1,6 @@ > > // PR c++/116416 > > // { dg-do compile { target c++14 } } > > -// { dg-options "-O" } > > +// { dg-options "-O -fdump-tree-original" } > > struct Str { > > constexpr Str() {} > > @@ -17,14 +17,15 @@ extern void callback(Str str); > > void > > func1() > > { > > - callback(Str{"Test"}); > > + callback(Str{"Test1"}); > > } > > void > > func2() > > { > > - Str str{"Test"}; > > + Str str{"Test2"}; > > callback(str); > > } > > -// Check that we don't call Str::Str(char const*) > > -// { dg-final { scan-assembler-not "_ZN3StrC1EPKc" } } > > +// Check that the front end folds both constructor calls. > > +// { dg-final { scan-tree-dump "{.str=\\(const char \\*\\) \"Test1\", > > .length=5}" "original" } } > > +// { dg-final { scan-tree-dump "{.str=\\(const char \\*\\) \"Test2\", > > .length=5}" "original" } } > > diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-prvalue1a.C > > b/gcc/testsuite/g++.dg/cpp1y/constexpr-prvalue1a.C > > new file mode 100644 > > index 000000000000..3f6ef97f9bf4 > > --- /dev/null > > +++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-prvalue1a.C > > @@ -0,0 +1,32 @@ > > +// PR c++/116416 > > +// A version of constexpr-prvalue1.C that calls > > __builtin_is_constant_evaluated. > > +// { dg-do compile { target c++14 } } > > +// { dg-options "-O -fdump-tree-original" } > > + > > +struct Str { > > + constexpr Str() {} > > + constexpr Str(const char *instr) { > > + str = instr; length = 0; > > + for (auto index = 0; instr[index]; ++index) { > > + length += __builtin_is_constant_evaluated() ? 1 : 1; > > + } > > + } > > + const char *str = nullptr; > > + int length = 0; > > +}; > > +extern void callback(Str str); > > +void > > +func1() > > +{ > > + callback(Str{"Test1"}); > > +} > > +void > > +func2() > > +{ > > + Str str{"Test2"}; > > + callback(str); > > +} > > + > > +// Check that the front end folds both constructor calls. > > +// { dg-final { scan-tree-dump "{.str=\\(const char \\*\\) \"Test1\", > > .length=5}" "original" } } > > +// { dg-final { scan-tree-dump "{.str=\\(const char \\*\\) \"Test2\", > > .length=5}" "original" } } > >