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" } }
> 
> 

Reply via email to