Fix tuple decomposition decltype.
authorJason Merrill <jason@redhat.com>
Wed, 16 Nov 2016 21:30:41 +0000 (16:30 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Wed, 16 Nov 2016 21:30:41 +0000 (16:30 -0500)
* decl.c (store_decomp_type, lookup_decomp_type): New.
(cp_finish_decomp): Call store_decomp_type.
* semantics.c (finish_decltype_type): Call lookup_decomp_type.
* cp-tree.h: Declare lookup_decomp_type.

From-SVN: r242513

gcc/cp/ChangeLog
gcc/cp/cp-tree.h
gcc/cp/decl.c
gcc/cp/semantics.c
gcc/testsuite/g++.dg/cpp1z/decomp17.C [new file with mode: 0644]
gcc/tree.h

index 0bcb730cb1ca9303f0161cc98f92c4aa36a2c482..fdbd1536002a9db68fb04a06692762f9370829ec 100644 (file)
@@ -1,3 +1,10 @@
+2016-11-16  Jason Merrill  <jason@redhat.com>
+
+       * decl.c (store_decomp_type, lookup_decomp_type): New.
+       (cp_finish_decomp): Call store_decomp_type.
+       * semantics.c (finish_decltype_type): Call lookup_decomp_type.
+       * cp-tree.h: Declare lookup_decomp_type.
+
 2016-11-15  Jakub Jelinek  <jakub@redhat.com>
 
        * decl.c (cp_finish_decomp): For DECL_NAMESPACE_SCOPE_P decl,
index 0dcb8971edd066dc8cbbbfe5aef465465b3032dc..cb1b9faef0ef8963d25981bdbadea3d5f40c74b4 100644 (file)
@@ -5808,6 +5808,7 @@ extern tree start_decl                            (const cp_declarator *, cp_decl_specifier_seq *, int,
 extern void start_decl_1                       (tree, bool);
 extern bool check_array_initializer            (tree, tree, tree);
 extern void cp_finish_decl                     (tree, tree, bool, tree, int);
+extern tree lookup_decomp_type                 (tree);
 extern void cp_finish_decomp                   (tree, tree, unsigned int);
 extern int cp_complete_array_type              (tree *, tree, bool);
 extern int cp_complete_array_type_or_error     (tree *, tree, bool, tsubst_flags_t);
index 23ba087a86f06a23f22562d93c71e656d6a1c0f4..c54a2de0af666f740c4864f49935a97ca885b0e9 100644 (file)
@@ -7293,6 +7293,22 @@ get_tuple_decomp_init (tree decl, unsigned i)
     }
 }
 
+/* It's impossible to recover the decltype of a tuple decomposition variable
+   based on the actual type of the variable, so store it in a hash table.  */
+static GTY(()) hash_map<tree,tree> *decomp_type_table;
+static void
+store_decomp_type (tree v, tree t)
+{
+  if (!decomp_type_table)
+    decomp_type_table = hash_map<tree,tree>::create_ggc (13);
+  decomp_type_table->put (v, t);
+}
+tree
+lookup_decomp_type (tree v)
+{
+  return *decomp_type_table->get (v);
+}
+
 /* Finish a decomposition declaration.  DECL is the underlying declaration
    "e", FIRST is the head of a chain of decls for the individual identifiers
    chained through DECL_CHAIN in reverse order and COUNT is the number of
@@ -7467,6 +7483,8 @@ cp_finish_decomp (tree decl, tree first, unsigned int count)
                      v[i]);
              goto error_out;
            }
+         /* Save the decltype away before reference collapse.  */
+         store_decomp_type (v[i], eltype);
          eltype = cp_build_reference_type (eltype, !lvalue_p (init));
          TREE_TYPE (v[i]) = eltype;
          layout_decl (v[i], 0);
index dc5ad13f681cd31b20d9de1f21d714149978b459..96c67a59a009279f22a626c2da5c88e5d5540772 100644 (file)
@@ -8902,7 +8902,7 @@ finish_decltype_type (tree expr, bool id_expression_or_member_access_p,
            return unlowered_expr_type (expr);
          else
            /* Expr is a reference variable for the tuple case.  */
-           return non_reference (TREE_TYPE (expr));
+           return lookup_decomp_type (expr);
        }
 
       switch (TREE_CODE (expr))
diff --git a/gcc/testsuite/g++.dg/cpp1z/decomp17.C b/gcc/testsuite/g++.dg/cpp1z/decomp17.C
new file mode 100644 (file)
index 0000000..484094b
--- /dev/null
@@ -0,0 +1,15 @@
+// { dg-options -std=c++1z }
+
+#include <tuple>
+
+template <typename, typename> struct same_type;
+template <typename T> struct same_type<T, T> {};
+
+int main() {
+  int i;
+  std::tuple<int,int&,int&&> tuple = { 1, i, 1 };
+  auto &[v, r, rr] = tuple;
+  same_type<decltype(v), int>{};
+  same_type<decltype(r), int&>{};
+  same_type<decltype(rr), int&&>{};
+}
index 6a98b6ee0b6820b389bcd929a1fbf0c6e38f5d62..0a82a4aceb8d513ac58d05a36b28f20240eb0fb4 100644 (file)
@@ -2457,8 +2457,7 @@ extern void decl_value_expr_insert (tree, tree);
 
 /* In a VAR_DECL or PARM_DECL, the location at which the value may be found,
    if transformations have made this more complicated than evaluating the
-   decl itself.  This should only be used for debugging; once this field has
-   been set, the decl itself may not legitimately appear in the function.  */
+   decl itself.  */
 #define DECL_HAS_VALUE_EXPR_P(NODE) \
   (TREE_CHECK3 (NODE, VAR_DECL, PARM_DECL, RESULT_DECL) \
    ->decl_common.decl_flag_2)