diff options
author | Jason Merrill <jason@redhat.com> | 2016-11-16 16:30:41 -0500 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2016-11-16 16:30:41 -0500 |
commit | fc72d1ed3c8b11437981487755a7d6edfaf06d22 (patch) | |
tree | 2550dbae7c32ca1011f1b45cf788c648f8f3c47d /gcc | |
parent | 8e2be5aefcc78b213c2f44e50cbec2c799f40f8b (diff) | |
download | gcc-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/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 1 | ||||
-rw-r--r-- | gcc/cp/decl.c | 18 | ||||
-rw-r--r-- | gcc/cp/semantics.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp1z/decomp17.C | 15 | ||||
-rw-r--r-- | gcc/tree.h | 3 |
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&&>{}; +} @@ -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) |