PR c++/78358 - tuple decomposition decltype
* semantics.c (finish_decltype_type): Strip references for a tuple decomposition. * cp-tree.h (DECL_DECOMPOSITION_P): False for non-variables. From-SVN: r242432
This commit is contained in:
parent
435fd40738
commit
944608029f
4 changed files with 42 additions and 10 deletions
|
@ -1,5 +1,10 @@
|
|||
2016-11-15 Jason Merrill <jason@redhat.com>
|
||||
|
||||
PR c++/78358
|
||||
* semantics.c (finish_decltype_type): Strip references for a tuple
|
||||
decomposition.
|
||||
* cp-tree.h (DECL_DECOMPOSITION_P): False for non-variables.
|
||||
|
||||
* decl2.c (decl_maybe_constant_var_p): References qualify.
|
||||
* constexpr.c (non_const_var_error): Handle references.
|
||||
* init.c (constant_value_1): Always check decl_constant_var_p.
|
||||
|
|
|
@ -3627,10 +3627,10 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter)
|
|||
(DECL_LANG_SPECIFIC (VAR_DECL_CHECK (NODE))->u.base.var_declared_inline_p \
|
||||
= true)
|
||||
|
||||
/* Nonzero if NODE is the artificial VAR_DECL for decomposition
|
||||
/* Nonzero if NODE is an artificial VAR_DECL for a C++17 decomposition
|
||||
declaration. */
|
||||
#define DECL_DECOMPOSITION_P(NODE) \
|
||||
(DECL_LANG_SPECIFIC (VAR_DECL_CHECK (NODE)) \
|
||||
(VAR_P (NODE) && DECL_LANG_SPECIFIC (NODE) \
|
||||
? DECL_LANG_SPECIFIC (NODE)->u.base.decomposition_p \
|
||||
: false)
|
||||
#define SET_DECL_DECOMPOSITION_P(NODE) \
|
||||
|
|
|
@ -8873,14 +8873,6 @@ finish_decltype_type (tree expr, bool id_expression_or_member_access_p,
|
|||
if (identifier_p (expr))
|
||||
expr = lookup_name (expr);
|
||||
|
||||
/* The decltype rules for decomposition are different from the rules for
|
||||
member access; in particular, the decomposition decl gets
|
||||
cv-qualifiers from the aggregate object, whereas decltype of a member
|
||||
access expr ignores the object. */
|
||||
if (VAR_P (expr) && DECL_DECOMPOSITION_P (expr)
|
||||
&& DECL_HAS_VALUE_EXPR_P (expr))
|
||||
return unlowered_expr_type (DECL_VALUE_EXPR (expr));
|
||||
|
||||
if (INDIRECT_REF_P (expr))
|
||||
/* This can happen when the expression is, e.g., "a.b". Just
|
||||
look at the underlying operand. */
|
||||
|
@ -8898,6 +8890,21 @@ finish_decltype_type (tree expr, bool id_expression_or_member_access_p,
|
|||
/* See through BASELINK nodes to the underlying function. */
|
||||
expr = BASELINK_FUNCTIONS (expr);
|
||||
|
||||
/* 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 non_reference (TREE_TYPE (expr));
|
||||
}
|
||||
|
||||
switch (TREE_CODE (expr))
|
||||
{
|
||||
case FIELD_DECL:
|
||||
|
|
20
gcc/testsuite/g++.dg/cpp1z/decomp12.C
Normal file
20
gcc/testsuite/g++.dg/cpp1z/decomp12.C
Normal file
|
@ -0,0 +1,20 @@
|
|||
// PR c++/78358
|
||||
// { dg-do run }
|
||||
// { dg-options -std=c++1z }
|
||||
|
||||
#include <tuple>
|
||||
|
||||
template <typename, typename> struct same_type;
|
||||
template <typename T> struct same_type<T, T> {};
|
||||
|
||||
int main() {
|
||||
std::tuple tuple = { 1, 'a', 2.3, true };
|
||||
auto[i, c, d, b] = tuple;
|
||||
same_type<std::tuple_element<0, decltype(tuple)>::type, decltype(i)>{};
|
||||
same_type<decltype(i), int>{};
|
||||
same_type<decltype(c), char>{};
|
||||
same_type<decltype(d), double>{};
|
||||
same_type<decltype(b), bool>{};
|
||||
if (i != 1 || c != 'a' || d != 2.3 || b != true)
|
||||
__builtin_abort ();
|
||||
}
|
Loading…
Add table
Reference in a new issue