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?