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?

>           RETURN (r);
>         }
>       else if (type_dependent_expression_p (object))
> diff --git a/gcc/testsuite/g++.dg/cpp1y/decltype-auto9.C 
> b/gcc/testsuite/g++.dg/cpp1y/decltype-auto9.C
> new file mode 100644
> index 00000000000..1ccf95a0170
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/cpp1y/decltype-auto9.C
> @@ -0,0 +1,15 @@
> +// PR c++/116379
> +// { dg-do compile { target c++14 } }
> +
> +template<typename T>
> +struct X {
> +  T val;
> +  decltype(auto) value() { return (val); }
> +};
> +
> +int main() {
> +  int i = 0;
> +  X<int&&> x{ static_cast<int&&>(i) };
> +  using type = decltype(x.value());
> +  using type = int&;
> +}
> 
> base-commit: a134dcd8a010744a0097d190f73a4efc2e381531
> -- 
> 2.48.1
> 
> 

Reply via email to