aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2016-11-15 00:22:28 -0500
committerJason Merrill <jason@gcc.gnu.org>2016-11-15 00:22:28 -0500
commit47e5d7ccf12c5d11abdd18e8e9089735e4fd3d05 (patch)
tree376f8789de74bf75a940c9583acaea031e9de6d6 /gcc/cp
parenta274cc11ac675686a71aef82e2e734795d18f339 (diff)
downloadgcc-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/ChangeLog10
-rw-r--r--gcc/cp/cp-tree.h1
-rw-r--r--gcc/cp/decl.c27
-rw-r--r--gcc/cp/semantics.c9
-rw-r--r--gcc/cp/tree.c8
-rw-r--r--gcc/cp/typeck.c22
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);