This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug c++/81176] decltype(auto) yields reference type for structured binding
- From: "jakub at gcc dot gnu.org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Thu, 22 Jun 2017 16:03:25 +0000
- Subject: [Bug c++/81176] decltype(auto) yields reference type for structured binding
- Auto-submitted: auto-generated
- References: <bug-81176-4@http.gcc.gnu.org/bugzilla/>
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81176
Jakub Jelinek <jakub at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |jakub at gcc dot gnu.org,
| |jason at gcc dot gnu.org,
| |nathan at gcc dot gnu.org
--- Comment #1 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
Testcase without any headers:
namespace std {
template<typename T> struct tuple_size;
template<int, typename> struct tuple_element;
}
struct A {
int i;
template <int I> int& get() { return i; }
};
template<> struct std::tuple_size<A> { static const int value = 2; };
template<int I> struct std::tuple_element<I,A> { using type = int; };
template <class,class> struct same_type;
template <class T> struct same_type<T,T> {};
void
foo (A x)
{
auto [ a, b ] = x;
decltype(auto) c = a;
same_type<decltype(a), int>{};
same_type<decltype(c), int>{};
}
In finish_decltype_type we have code to handle this:
/* decltype of a decomposition name drops references in the tuple case
(unlike decltype of a normal variable) and keeps cv-qualifiers from
the containing object in the other cases (unlike decltype of a member
access expression). */
if (DECL_DECOMPOSITION_P (expr))
{
if (DECL_HAS_VALUE_EXPR_P (expr))
/* Expr is an array or struct subobject proxy, handle
bit-fields properly. */
return unlowered_expr_type (expr);
else
/* Expr is a reference variable for the tuple case. */
return lookup_decomp_type (expr);
}
But for decltype(auto) c = a; we have do_auto_deduction called with init which
is *a:
else if (AUTO_IS_DECLTYPE (auto_node))
{
bool id = (DECL_P (init)
|| ((TREE_CODE (init) == COMPONENT_REF
|| TREE_CODE (init) == SCOPE_REF)
&& !REF_PARENTHESIZED_P (init)));
thus id is false because init is not DECL_P and do_auto_deduction doesn't have
special handling of DECL_DECOMPOSITION_P if id_expression_or_member_access_p
argument is false.
So, shall we for the above DECL_P (init) test test it with
tree rinit = INDIRECT_REF_P (init) ? TREE_OPERAND (init, 0) : init;
or something similar (what about the COMPONENT_REF/SCOPE_REF case? Shall we
pass the INDIRECT_REF to finish_decltype_type if INDIRECT_REF_P (init) or not?