aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2016-11-16 16:30:41 -0500
committerJason Merrill <jason@gcc.gnu.org>2016-11-16 16:30:41 -0500
commitfc72d1ed3c8b11437981487755a7d6edfaf06d22 (patch)
tree2550dbae7c32ca1011f1b45cf788c648f8f3c47d /gcc
parent8e2be5aefcc78b213c2f44e50cbec2c799f40f8b (diff)
downloadgcc-fc72d1ed3c8b11437981487755a7d6edfaf06d22.zip
gcc-fc72d1ed3c8b11437981487755a7d6edfaf06d22.tar.gz
gcc-fc72d1ed3c8b11437981487755a7d6edfaf06d22.tar.bz2
Fix tuple decomposition decltype.
* 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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog7
-rw-r--r--gcc/cp/cp-tree.h1
-rw-r--r--gcc/cp/decl.c18
-rw-r--r--gcc/cp/semantics.c2
-rw-r--r--gcc/testsuite/g++.dg/cpp1z/decomp17.C15
-rw-r--r--gcc/tree.h3
6 files changed, 43 insertions, 3 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 0bcb730..fdbd153 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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,
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 0dcb897..cb1b9fa 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -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);
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 23ba087..c54a2de 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -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);
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index dc5ad13..96c67a5 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -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
index 0000000..484094b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1z/decomp17.C
@@ -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&&>{};
+}
diff --git a/gcc/tree.h b/gcc/tree.h
index 6a98b6e..0a82a4a 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -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)