diff options
author | Jason Merrill <jason@redhat.com> | 2016-11-15 00:22:28 -0500 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2016-11-15 00:22:28 -0500 |
commit | 47e5d7ccf12c5d11abdd18e8e9089735e4fd3d05 (patch) | |
tree | 376f8789de74bf75a940c9583acaea031e9de6d6 /gcc/cp | |
parent | a274cc11ac675686a71aef82e2e734795d18f339 (diff) | |
download | gcc-47e5d7ccf12c5d11abdd18e8e9089735e4fd3d05.zip gcc-47e5d7ccf12c5d11abdd18e8e9089735e4fd3d05.tar.gz gcc-47e5d7ccf12c5d11abdd18e8e9089735e4fd3d05.tar.bz2 |
Various C++17 decomposition fixes.
* tree.c (bitfield_p): New.
* cp-tree.h: Declare it.
* typeck.c (cxx_sizeof_expr, cxx_alignof_expr)
(cp_build_addr_expr_1): Use it instead of DECL_C_BIT_FIELD.
* decl.c (cp_finish_decomp): Look through reference. Always
SET_DECL_DECOMPOSITION_P.
* semantics.c (finish_decltype_type): Adjust decomposition handling.
From-SVN: r242408
Diffstat (limited to 'gcc/cp')
-rw-r--r-- | gcc/cp/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 1 | ||||
-rw-r--r-- | gcc/cp/decl.c | 27 | ||||
-rw-r--r-- | gcc/cp/semantics.c | 9 | ||||
-rw-r--r-- | gcc/cp/tree.c | 8 | ||||
-rw-r--r-- | gcc/cp/typeck.c | 22 |
6 files changed, 51 insertions, 26 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 1a92ffa..e9dd17c 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,13 @@ +2016-11-14 Jason Merrill <jason@redhat.com> + + * tree.c (bitfield_p): New. + * cp-tree.h: Declare it. + * typeck.c (cxx_sizeof_expr, cxx_alignof_expr) + (cp_build_addr_expr_1): Use it instead of DECL_C_BIT_FIELD. + * decl.c (cp_finish_decomp): Look through reference. Always + SET_DECL_DECOMPOSITION_P. + * semantics.c (finish_decltype_type): Adjust decomposition handling. + 2016-11-13 Jakub Jelinek <jakub@redhat.com> Jason Merrill <jason@redhat.com> diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 8c2dbe1..edcd3b4 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -6572,6 +6572,7 @@ extern cp_lvalue_kind lvalue_kind (const_tree); extern bool glvalue_p (const_tree); extern bool obvalue_p (const_tree); extern bool xvalue_p (const_tree); +extern bool bitfield_p (const_tree); extern tree cp_stabilize_reference (tree); extern bool builtin_valid_in_constant_expr_p (const_tree); extern tree build_min (enum tree_code, tree, ...); diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index f142c1f..2af95a7 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -7350,18 +7350,23 @@ cp_finish_decomp (tree decl, tree first, unsigned int count) for (unsigned int i = 0; i < count; i++, d = DECL_CHAIN (d)) { v[count - i - 1] = d; - if (processing_template_decl) - { - retrofit_lang_decl (d); - SET_DECL_DECOMPOSITION_P (d); - } + retrofit_lang_decl (d); + SET_DECL_DECOMPOSITION_P (d); } tree type = TREE_TYPE (decl); - tree eltype = NULL_TREE; + tree dexp = decl; + if (TREE_CODE (type) == REFERENCE_TYPE) - type = TREE_TYPE (type); + { + /* If e is a constant reference, use the referent directly. */ + if (DECL_INITIAL (decl)) + dexp = DECL_INITIAL (decl); + dexp = convert_from_reference (dexp); + type = TREE_TYPE (type); + } + tree eltype = NULL_TREE; unsigned HOST_WIDE_INT eltscnt = 0; if (TREE_CODE (type) == ARRAY_TYPE) { @@ -7391,7 +7396,7 @@ cp_finish_decomp (tree decl, tree first, unsigned int count) { TREE_TYPE (v[i]) = eltype; layout_decl (v[i], 0); - tree t = convert_from_reference (decl); + tree t = dexp; t = build4_loc (DECL_SOURCE_LOCATION (v[i]), ARRAY_REF, eltype, t, size_int (i), NULL_TREE, NULL_TREE); @@ -7410,7 +7415,7 @@ cp_finish_decomp (tree decl, tree first, unsigned int count) { TREE_TYPE (v[i]) = eltype; layout_decl (v[i], 0); - tree t = convert_from_reference (decl); + tree t = dexp; t = build1_loc (DECL_SOURCE_LOCATION (v[i]), i ? IMAGPART_EXPR : REALPART_EXPR, eltype, t); @@ -7428,7 +7433,7 @@ cp_finish_decomp (tree decl, tree first, unsigned int count) { TREE_TYPE (v[i]) = eltype; layout_decl (v[i], 0); - tree t = convert_from_reference (decl); + tree t = dexp; convert_vector_to_array_for_subscript (DECL_SOURCE_LOCATION (v[i]), &t, size_int (i)); t = build4_loc (DECL_SOURCE_LOCATION (v[i]), ARRAY_REF, @@ -7501,7 +7506,7 @@ cp_finish_decomp (tree decl, tree first, unsigned int count) eltscnt++; if (count != eltscnt) goto cnt_mismatch; - tree t = convert_from_reference (decl); + tree t = dexp; if (type != btype) { t = convert_to_base (t, btype, /*check_access*/true, diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 0164f2e..29f5233 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -8873,8 +8873,13 @@ finish_decltype_type (tree expr, bool id_expression_or_member_access_p, if (identifier_p (expr)) expr = lookup_name (expr); - if (VAR_P (expr) && DECL_HAS_VALUE_EXPR_P (expr)) - expr = DECL_VALUE_EXPR (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 diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index c595437..d1dd7c4 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -305,6 +305,14 @@ xvalue_p (const_tree ref) return (lvalue_kind (ref) == clk_rvalueref); } +/* True if REF is a bit-field. */ + +bool +bitfield_p (const_tree ref) +{ + return (lvalue_kind (ref) & clk_bitfield); +} + /* C++-specific version of stabilize_reference. */ tree diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 2d8b7b1..6f9ad0e 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -1650,9 +1650,7 @@ cxx_sizeof_expr (tree e, tsubst_flags_t complain) e = mark_type_use (e); - if (TREE_CODE (e) == COMPONENT_REF - && TREE_CODE (TREE_OPERAND (e, 1)) == FIELD_DECL - && DECL_C_BIT_FIELD (TREE_OPERAND (e, 1))) + if (bitfield_p (e)) { if (complain & tf_error) error ("invalid application of %<sizeof%> to a bit-field"); @@ -1709,9 +1707,7 @@ cxx_alignof_expr (tree e, tsubst_flags_t complain) if (VAR_P (e)) t = size_int (DECL_ALIGN_UNIT (e)); - else if (TREE_CODE (e) == COMPONENT_REF - && TREE_CODE (TREE_OPERAND (e, 1)) == FIELD_DECL - && DECL_C_BIT_FIELD (TREE_OPERAND (e, 1))) + else if (bitfield_p (e)) { if (complain & tf_error) error ("invalid application of %<__alignof%> to a bit-field"); @@ -5751,6 +5747,13 @@ cp_build_addr_expr_1 (tree arg, bool strict_lvalue, tsubst_flags_t complain) if (argtype != error_mark_node) argtype = build_pointer_type (argtype); + if (bitfield_p (arg)) + { + if (complain & tf_error) + error ("attempt to take address of bit-field"); + return error_mark_node; + } + /* In a template, we are processing a non-dependent expression so we can just form an ADDR_EXPR with the correct type. */ if (processing_template_decl || TREE_CODE (arg) != COMPONENT_REF) @@ -5775,13 +5778,6 @@ cp_build_addr_expr_1 (tree arg, bool strict_lvalue, tsubst_flags_t complain) val = build2 (COMPOUND_EXPR, TREE_TYPE (val), TREE_OPERAND (arg, 0), val); } - else if (DECL_C_BIT_FIELD (TREE_OPERAND (arg, 1))) - { - if (complain & tf_error) - error ("attempt to take address of bit-field structure member %qD", - TREE_OPERAND (arg, 1)); - return error_mark_node; - } else { tree object = TREE_OPERAND (arg, 0); |