aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2016-10-14 17:54:39 -0400
committerJason Merrill <jason@gcc.gnu.org>2016-10-14 17:54:39 -0400
commitec2416b5fff0e603e94ee98c1042003812847b59 (patch)
tree20dc5c1492c844c3ef6699033ebb18974cd22f91 /gcc/cp
parentefc5aa6bc7c686b302c5d7fd7f65e3f6361961e1 (diff)
downloadgcc-ec2416b5fff0e603e94ee98c1042003812847b59.zip
gcc-ec2416b5fff0e603e94ee98c1042003812847b59.tar.gz
gcc-ec2416b5fff0e603e94ee98c1042003812847b59.tar.bz2
Implement P0017R1, C++17 aggregates with bases.
* class.c (build_base_field_1): Split out from... (build_base_field): ...here. In C++17 mode, build a field for empty bases. * decl.c (xref_basetypes): In C++17 aggregates can have bases. (next_initializable_field): Allow base fields in C++17. * typeck2.c (process_init_constructor_record): Likewise. From-SVN: r241187
Diffstat (limited to 'gcc/cp')
-rw-r--r--gcc/cp/ChangeLog10
-rw-r--r--gcc/cp/class.c75
-rw-r--r--gcc/cp/decl.c14
-rw-r--r--gcc/cp/typeck2.c5
4 files changed, 71 insertions, 33 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index cdc5aff..43c573b 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,13 @@
+2016-10-14 Jason Merrill <jason@redhat.com>
+
+ Implement P0017R1, C++17 aggregates with bases.
+ * class.c (build_base_field_1): Split out from...
+ (build_base_field): ...here. In C++17 mode, build a field for
+ empty bases.
+ * decl.c (xref_basetypes): In C++17 aggregates can have bases.
+ (next_initializable_field): Allow base fields in C++17.
+ * typeck2.c (process_init_constructor_record): Likewise.
+
2016-10-14 Jakub Jelinek <jakub@redhat.com>
DR 1511 - const volatile variables and ODR
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 46f1bac..d334b7c 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -4452,6 +4452,34 @@ layout_empty_base (record_layout_info rli, tree binfo,
return atend;
}
+/* Build the FIELD_DECL for BASETYPE as a base of T, add it to the chain of
+ fields at NEXT_FIELD, and return it. */
+
+static tree
+build_base_field_1 (tree t, tree basetype, tree *&next_field)
+{
+ /* Create the FIELD_DECL. */
+ gcc_assert (CLASSTYPE_AS_BASE (basetype));
+ tree decl = build_decl (input_location,
+ FIELD_DECL, NULL_TREE, CLASSTYPE_AS_BASE (basetype));
+ DECL_ARTIFICIAL (decl) = 1;
+ DECL_IGNORED_P (decl) = 1;
+ DECL_FIELD_CONTEXT (decl) = t;
+ DECL_SIZE (decl) = CLASSTYPE_SIZE (basetype);
+ DECL_SIZE_UNIT (decl) = CLASSTYPE_SIZE_UNIT (basetype);
+ SET_DECL_ALIGN (decl, CLASSTYPE_ALIGN (basetype));
+ DECL_USER_ALIGN (decl) = CLASSTYPE_USER_ALIGN (basetype);
+ DECL_MODE (decl) = TYPE_MODE (basetype);
+ DECL_FIELD_IS_BASE (decl) = 1;
+
+ /* Add the new FIELD_DECL to the list of fields for T. */
+ DECL_CHAIN (decl) = *next_field;
+ *next_field = decl;
+ next_field = &DECL_CHAIN (decl);
+
+ return decl;
+}
+
/* Layout the base given by BINFO in the class indicated by RLI.
*BASE_ALIGN is a running maximum of the alignments of
any base class. OFFSETS gives the location of empty base
@@ -4483,29 +4511,12 @@ build_base_field (record_layout_info rli, tree binfo,
CLASSTYPE_EMPTY_P (t) = 0;
/* Create the FIELD_DECL. */
- decl = build_decl (input_location,
- FIELD_DECL, NULL_TREE, CLASSTYPE_AS_BASE (basetype));
- DECL_ARTIFICIAL (decl) = 1;
- DECL_IGNORED_P (decl) = 1;
- DECL_FIELD_CONTEXT (decl) = t;
- if (CLASSTYPE_AS_BASE (basetype))
- {
- DECL_SIZE (decl) = CLASSTYPE_SIZE (basetype);
- DECL_SIZE_UNIT (decl) = CLASSTYPE_SIZE_UNIT (basetype);
- SET_DECL_ALIGN (decl, CLASSTYPE_ALIGN (basetype));
- DECL_USER_ALIGN (decl) = CLASSTYPE_USER_ALIGN (basetype);
- DECL_MODE (decl) = TYPE_MODE (basetype);
- DECL_FIELD_IS_BASE (decl) = 1;
-
- /* Try to place the field. It may take more than one try if we
- have a hard time placing the field without putting two
- objects of the same type at the same address. */
- layout_nonempty_base_or_field (rli, decl, binfo, offsets);
- /* Add the new FIELD_DECL to the list of fields for T. */
- DECL_CHAIN (decl) = *next_field;
- *next_field = decl;
- next_field = &DECL_CHAIN (decl);
- }
+ decl = build_base_field_1 (t, basetype, next_field);
+
+ /* Try to place the field. It may take more than one try if we
+ have a hard time placing the field without putting two
+ objects of the same type at the same address. */
+ layout_nonempty_base_or_field (rli, decl, binfo, offsets);
}
else
{
@@ -4536,11 +4547,17 @@ build_base_field (record_layout_info rli, tree binfo,
CLASSTYPE_NEARLY_EMPTY_P (t) = 0;
}
- /* We do not create a FIELD_DECL for empty base classes because
- it might overlap some other field. We want to be able to
- create CONSTRUCTORs for the class by iterating over the
- FIELD_DECLs, and the back end does not handle overlapping
- FIELD_DECLs. */
+ /* We used to not create a FIELD_DECL for empty base classes because of
+ back end issues with overlapping FIELD_DECLs, but that doesn't seem to
+ be a problem anymore. We need them to handle initialization of C++17
+ aggregate bases. */
+ if (cxx_dialect >= cxx1z && !BINFO_VIRTUAL_P (binfo))
+ {
+ tree decl = build_base_field_1 (t, basetype, next_field);
+ DECL_FIELD_OFFSET (decl) = BINFO_OFFSET (binfo);
+ DECL_FIELD_BIT_OFFSET (decl) = bitsize_zero_node;
+ SET_DECL_OFFSET_ALIGN (decl, BITS_PER_UNIT);
+ }
/* An empty virtual base causes a class to be non-empty
-- but in that case we do not need to clear CLASSTYPE_EMPTY_P
@@ -6586,7 +6603,7 @@ layout_class_type (tree t, tree *virtuals_p)
/* Make sure that empty classes are reflected in RLI at this
point. */
- include_empty_classes(rli);
+ include_empty_classes (rli);
/* Make sure not to create any structures with zero size. */
if (integer_zerop (rli_size_unit_so_far (rli)) && CLASSTYPE_EMPTY_P (t))
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index d70d583..ecf4d14 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -5569,7 +5569,8 @@ next_initializable_field (tree field)
while (field
&& (TREE_CODE (field) != FIELD_DECL
|| (DECL_C_BIT_FIELD (field) && !DECL_NAME (field))
- || DECL_ARTIFICIAL (field)))
+ || (DECL_ARTIFICIAL (field)
+ && !(cxx_dialect >= cxx1z && DECL_FIELD_IS_BASE (field)))))
field = DECL_CHAIN (field);
return field;
@@ -13153,8 +13154,8 @@ xref_basetypes (tree ref, tree base_list)
if (max_bases)
{
vec_alloc (BINFO_BASE_ACCESSES (binfo), max_bases);
- /* An aggregate cannot have baseclasses. */
- CLASSTYPE_NON_AGGREGATE (ref) = 1;
+ /* A C++98 POD cannot have base classes. */
+ CLASSTYPE_NON_LAYOUT_POD_P (ref) = true;
if (TREE_CODE (ref) == UNION_TYPE)
error ("derived union %qT invalid", ref);
@@ -13182,6 +13183,13 @@ xref_basetypes (tree ref, tree base_list)
if (access == access_default_node)
access = default_access;
+ /* Before C++17, an aggregate cannot have base classes. In C++17, an
+ aggregate can't have virtual, private, or protected base classes. */
+ if (cxx_dialect < cxx1z
+ || access != access_public_node
+ || via_virtual)
+ CLASSTYPE_NON_AGGREGATE (ref) = true;
+
if (PACK_EXPANSION_P (basetype))
basetype = PACK_EXPANSION_PATTERN (basetype);
if (TREE_CODE (basetype) == TYPE_DECL)
diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c
index 121da32..022a478 100644
--- a/gcc/cp/typeck2.c
+++ b/gcc/cp/typeck2.c
@@ -1352,6 +1352,7 @@ process_init_constructor_record (tree type, tree init,
gcc_assert (TREE_CODE (type) == RECORD_TYPE);
gcc_assert (!CLASSTYPE_VBASECLASSES (type));
gcc_assert (!TYPE_BINFO (type)
+ || cxx_dialect >= cxx1z
|| !BINFO_N_BASE_BINFOS (TYPE_BINFO (type)));
gcc_assert (!TYPE_POLYMORPHIC_P (type));
@@ -1369,7 +1370,9 @@ process_init_constructor_record (tree type, tree init,
if (!DECL_NAME (field) && DECL_C_BIT_FIELD (field))
continue;
- if (TREE_CODE (field) != FIELD_DECL || DECL_ARTIFICIAL (field))
+ if (TREE_CODE (field) != FIELD_DECL
+ || (DECL_ARTIFICIAL (field)
+ && !(cxx_dialect >= cxx1z && DECL_FIELD_IS_BASE (field))))
continue;
/* If this is a bitfield, first convert to the declared type. */