aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaolo Carlini <paolo.carlini@oracle.com>2016-04-30 00:00:51 +0000
committerPaolo Carlini <paolo@gcc.gnu.org>2016-04-30 00:00:51 +0000
commit411e5c675d26d342493d8dba910c3887c8846257 (patch)
treeadedee90aeaee51ba2ab43c501ad598dac10d6ec
parent63ce14e03b93e351286c9c7b0d20abb5d85b0f20 (diff)
downloadgcc-411e5c675d26d342493d8dba910c3887c8846257.zip
gcc-411e5c675d26d342493d8dba910c3887c8846257.tar.gz
gcc-411e5c675d26d342493d8dba910c3887c8846257.tar.bz2
re PR c++/66644 (Rejects C++11 in-class anonymous union members initialization)
/cp 2016-04-29 Paolo Carlini <paolo.carlini@oracle.com> PR c++/66644 * class.c (check_field_decl): Remove final int* parameter, change the return type to bool; fix logic in order not to reject multiple initialized fields in anonymous struct. (check_field_decls): Adjust call. /testsuite 2016-04-29 Paolo Carlini <paolo.carlini@oracle.com> PR c++/66644 * g++.dg/cpp0x/nsdmi-anon-struct1.C: New. From-SVN: r235662
-rw-r--r--gcc/cp/ChangeLog8
-rw-r--r--gcc/cp/class.c49
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/nsdmi-anon-struct1.C48
4 files changed, 87 insertions, 23 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index bb2b7cf..25af3f2 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,11 @@
+2016-04-29 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/66644
+ * class.c (check_field_decl): Remove final int* parameter, change
+ the return type to bool; fix logic in order not to reject multiple
+ initialized fields in anonymous struct.
+ (check_field_decls): Adjust call.
+
2016-04-29 Cesar Philippidis <cesar@codesourcery.com>
PR middle-end/70626
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 2705e18..31fa4b0 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -139,7 +139,7 @@ static int count_fields (tree);
static int add_fields_to_record_type (tree, struct sorted_fields_type*, int);
static void insert_into_classtype_sorted_fields (tree, tree, int);
static bool check_bitfield_decl (tree);
-static void check_field_decl (tree, tree, int *, int *, int *);
+static bool check_field_decl (tree, tree, int *, int *);
static void check_field_decls (tree, tree *, int *, int *);
static tree *build_base_field (record_layout_info, tree, splay_tree, tree *);
static void build_base_fields (record_layout_info, splay_tree, tree *);
@@ -3541,14 +3541,14 @@ check_bitfield_decl (tree field)
enclosing type T. Issue any appropriate messages and set appropriate
flags. */
-static void
+static bool
check_field_decl (tree field,
tree t,
int* cant_have_const_ctor,
- int* no_const_asn_ref,
- int* any_default_members)
+ int* no_const_asn_ref)
{
tree type = strip_array_types (TREE_TYPE (field));
+ bool any_default_members = false;
/* In C++98 an anonymous union cannot contain any fields which would change
the settings of CANT_HAVE_CONST_CTOR and friends. */
@@ -3558,12 +3558,12 @@ check_field_decl (tree field,
structs. So, we recurse through their fields here. */
else if (ANON_AGGR_TYPE_P (type))
{
- tree fields;
-
- for (fields = TYPE_FIELDS (type); fields; fields = DECL_CHAIN (fields))
+ for (tree fields = TYPE_FIELDS (type); fields;
+ fields = DECL_CHAIN (fields))
if (TREE_CODE (fields) == FIELD_DECL && !DECL_C_BIT_FIELD (field))
- check_field_decl (fields, t, cant_have_const_ctor,
- no_const_asn_ref, any_default_members);
+ any_default_members |= check_field_decl (fields, t,
+ cant_have_const_ctor,
+ no_const_asn_ref);
}
/* Check members with class type for constructors, destructors,
etc. */
@@ -3620,13 +3620,11 @@ check_field_decl (tree field,
check_abi_tags (t, field);
if (DECL_INITIAL (field) != NULL_TREE)
- {
- /* `build_class_init_list' does not recognize
- non-FIELD_DECLs. */
- if (TREE_CODE (t) == UNION_TYPE && *any_default_members != 0)
- error ("multiple fields in union %qT initialized", t);
- *any_default_members = 1;
- }
+ /* `build_class_init_list' does not recognize
+ non-FIELD_DECLs. */
+ any_default_members = true;
+
+ return any_default_members;
}
/* Check the data members (both static and non-static), class-scoped
@@ -3662,7 +3660,7 @@ check_field_decls (tree t, tree *access_decls,
tree *field;
tree *next;
bool has_pointers;
- int any_default_members;
+ bool any_default_members;
int cant_pack = 0;
int field_access = -1;
@@ -3672,7 +3670,7 @@ check_field_decls (tree t, tree *access_decls,
has_pointers = false;
/* Assume none of the members of this class have default
initializations. */
- any_default_members = 0;
+ any_default_members = false;
for (field = &TYPE_FIELDS (t); *field; field = next)
{
@@ -3867,11 +3865,16 @@ check_field_decls (tree t, tree *access_decls,
/* We set DECL_C_BIT_FIELD in grokbitfield.
If the type and width are valid, we'll also set DECL_BIT_FIELD. */
- if (! DECL_C_BIT_FIELD (x) || ! check_bitfield_decl (x))
- check_field_decl (x, t,
- cant_have_const_ctor_p,
- no_const_asn_ref_p,
- &any_default_members);
+ if ((! DECL_C_BIT_FIELD (x) || ! check_bitfield_decl (x))
+ && check_field_decl (x, t,
+ cant_have_const_ctor_p,
+ no_const_asn_ref_p))
+ {
+ if (any_default_members
+ && TREE_CODE (t) == UNION_TYPE)
+ error ("multiple fields in union %qT initialized", t);
+ any_default_members = true;
+ }
/* Now that we've removed bit-field widths from DECL_INITIAL,
anything left in DECL_INITIAL is an NSDMI that makes the class
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index cf91897..b1d63d8 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2016-04-29 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/66644
+ * g++.dg/cpp0x/nsdmi-anon-struct1.C: New.
+
2016-04-29 Bill Schmidt <wschmidt@linux.vnet.ibm.com>
* gcc.target/powerpc/vsx-elemrev-1.c: New.
diff --git a/gcc/testsuite/g++.dg/cpp0x/nsdmi-anon-struct1.C b/gcc/testsuite/g++.dg/cpp0x/nsdmi-anon-struct1.C
new file mode 100644
index 0000000..35c342a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/nsdmi-anon-struct1.C
@@ -0,0 +1,48 @@
+// PR c++/66644
+// { dg-do compile { target c++11 } }
+// { dg-options "-Wno-pedantic" }
+
+struct test1
+{
+ union
+ {
+ struct { char a=0, b=0; };
+ char buffer[16];
+ };
+};
+
+struct test2
+{
+ union
+ {
+ struct { char a=0, b; };
+ char buffer[16];
+ };
+};
+
+struct test3
+{
+ union
+ {
+ struct { char a, b; } test2{0,0};
+ char buffer[16];
+ };
+};
+
+struct test4
+{
+ union
+ { // { dg-error "multiple fields" }
+ struct { char a=0, b=0; };
+ struct { char c=0, d; };
+ };
+};
+
+struct test5
+{
+ union
+ {
+ union { char a=0, b=0; }; // { dg-error "multiple fields" }
+ char buffer[16];
+ };
+};