Commit fc72d1ed by Jason Merrill Committed by Jason Merrill

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
parent 8e2be5ae
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> 2016-11-15 Jakub Jelinek <jakub@redhat.com>
* decl.c (cp_finish_decomp): For DECL_NAMESPACE_SCOPE_P decl, * decl.c (cp_finish_decomp): For DECL_NAMESPACE_SCOPE_P decl,
......
...@@ -5808,6 +5808,7 @@ extern tree start_decl (const cp_declarator *, cp_decl_specifier_seq *, int, ...@@ -5808,6 +5808,7 @@ extern tree start_decl (const cp_declarator *, cp_decl_specifier_seq *, int,
extern void start_decl_1 (tree, bool); extern void start_decl_1 (tree, bool);
extern bool check_array_initializer (tree, tree, tree); extern bool check_array_initializer (tree, tree, tree);
extern void cp_finish_decl (tree, tree, bool, tree, int); 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 void cp_finish_decomp (tree, tree, unsigned int);
extern int cp_complete_array_type (tree *, tree, bool); extern int cp_complete_array_type (tree *, tree, bool);
extern int cp_complete_array_type_or_error (tree *, tree, bool, tsubst_flags_t); extern int cp_complete_array_type_or_error (tree *, tree, bool, tsubst_flags_t);
......
...@@ -7293,6 +7293,22 @@ get_tuple_decomp_init (tree decl, unsigned i) ...@@ -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 /* Finish a decomposition declaration. DECL is the underlying declaration
"e", FIRST is the head of a chain of decls for the individual identifiers "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 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) ...@@ -7467,6 +7483,8 @@ cp_finish_decomp (tree decl, tree first, unsigned int count)
v[i]); v[i]);
goto error_out; 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)); eltype = cp_build_reference_type (eltype, !lvalue_p (init));
TREE_TYPE (v[i]) = eltype; TREE_TYPE (v[i]) = eltype;
layout_decl (v[i], 0); layout_decl (v[i], 0);
......
...@@ -8902,7 +8902,7 @@ finish_decltype_type (tree expr, bool id_expression_or_member_access_p, ...@@ -8902,7 +8902,7 @@ finish_decltype_type (tree expr, bool id_expression_or_member_access_p,
return unlowered_expr_type (expr); return unlowered_expr_type (expr);
else else
/* Expr is a reference variable for the tuple case. */ /* Expr is a reference variable for the tuple case. */
return non_reference (TREE_TYPE (expr)); return lookup_decomp_type (expr);
} }
switch (TREE_CODE (expr)) switch (TREE_CODE (expr))
......
// { 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); ...@@ -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, /* 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 if transformations have made this more complicated than evaluating the
decl itself. This should only be used for debugging; once this field has decl itself. */
been set, the decl itself may not legitimately appear in the function. */
#define DECL_HAS_VALUE_EXPR_P(NODE) \ #define DECL_HAS_VALUE_EXPR_P(NODE) \
(TREE_CHECK3 (NODE, VAR_DECL, PARM_DECL, RESULT_DECL) \ (TREE_CHECK3 (NODE, VAR_DECL, PARM_DECL, RESULT_DECL) \
->decl_common.decl_flag_2) ->decl_common.decl_flag_2)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment