This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug c++/81176] decltype(auto) yields reference type for structured binding


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?

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]