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.
Jason