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.
Reviewed-by: Jason Merrill <jason@redhat.com>
{
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);
RETURN (r);
}
else if (type_dependent_expression_p (object))
--- /dev/null
+// 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&;
+}