On Fri, Feb 14, 2025 at 11:04:09PM +0100, Jason Merrill wrote:
> On 2/14/25 4:29 PM, Marek Polacek wrote:
> > On Fri, Feb 14, 2025 at 09:30:34AM -0500, Patrick Palka wrote:
> > > On Thu, 13 Feb 2025, Marek Polacek wrote:
> > > 
> > > > Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?
> > > > 
> > > > -- >8 --
> > > > Here we have:
> > > > 
> > > >    template<typename T>
> > > >    struct X{
> > > >        T val;
> > > >        decltype(auto) value(){
> > > >           return (val);
> > > >        }
> > > >    };
> > > > 
> > > > where the return type of value should be 'int &' since '(val)' is an
> > > > expression, not a name, and decltype(auto) performs the type deduction
> > > > using the decltype rules.
> > > > 
> > > > The problem is that we weren't propagating REF_PARENTHESIZED_P
> > > > correctly: the return value of finish_non_static_data_member in this
> > > > test was a REFERENCE_REF_P, so we didn't set the flag.  We should
> > > > use force_paren_expr like below.
> > > > 
> > > >         PR c++/116379
> > > > 
> > > > gcc/cp/ChangeLog:
> > > > 
> > > >         * pt.cc (tsubst_expr) <COMPONENT_REF>: Use force_paren_expr to 
> > > > set
> > > >         REF_PARENTHESIZED_P.
> > > > 
> > > > gcc/testsuite/ChangeLog:
> > > > 
> > > >         * g++.dg/cpp1y/decltype-auto9.C: New test.
> > > > ---
> > > >   gcc/cp/pt.cc                                |  4 ++--
> > > >   gcc/testsuite/g++.dg/cpp1y/decltype-auto9.C | 15 +++++++++++++++
> > > >   2 files changed, 17 insertions(+), 2 deletions(-)
> > > >   create mode 100644 gcc/testsuite/g++.dg/cpp1y/decltype-auto9.C
> > > > 
> > > > diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
> > > > index a2fc8813e9d..5706a3987c3 100644
> > > > --- a/gcc/cp/pt.cc
> > > > +++ b/gcc/cp/pt.cc
> > > > @@ -21712,8 +21712,8 @@ tsubst_expr (tree t, tree args, tsubst_flags_t 
> > > > complain, tree in_decl)
> > > >           {
> > > >             r = finish_non_static_data_member (member, object, 
> > > > NULL_TREE,
> > > >                                                complain);
> > > > -           if (TREE_CODE (r) == COMPONENT_REF)
> > > > -             REF_PARENTHESIZED_P (r) = REF_PARENTHESIZED_P (t);
> > > > +           if (REF_PARENTHESIZED_P (t))
> > > > +             force_paren_expr (r);
> > > 
> > > Looks like this is the first use of force_paren_expr whose result we
> > > ignore.  If r is a decl then force_paren_expr returns a new tree
> > > wrapping it, which we'd lose by ignoring the result -- or is that not
> > > possible at this call site?
> > 
> > I don't see how finish_non_static_data_member would return a DECL.
> > But I can add "r = " if preferred ;-).
> 
> Please.

Done:

Tested x86_64-pc-linux-gnu, applying to trunk.

gcc/cp/ChangeLog:

        * pt.cc (tsubst_expr) <COMPONENT_REF>: Assign the result of
        force_paren_expr.
---
 gcc/cp/pt.cc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index 5706a3987c3..62d91a2dd15 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -21713,7 +21713,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t 
complain, tree in_decl)
            r = finish_non_static_data_member (member, object, NULL_TREE,
                                               complain);
            if (REF_PARENTHESIZED_P (t))
-             force_paren_expr (r);
+             r = force_paren_expr (r);
            RETURN (r);
          }
        else if (type_dependent_expression_p (object))

base-commit: 1dc4e220ca2272d668ddb3041ccd9e69b968e532
-- 
2.48.1

Reply via email to