aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2018-01-25 17:38:40 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2018-01-25 17:38:40 +0100
commit41df0109de5fe4ddad66bfd742ee813688362ab8 (patch)
tree206c7a387ea1a86678e5575437968763e25d30a1 /gcc
parenta794e494c6e3b1c0d63158e414beaa52ded2eac1 (diff)
downloadgcc-41df0109de5fe4ddad66bfd742ee813688362ab8.zip
gcc-41df0109de5fe4ddad66bfd742ee813688362ab8.tar.gz
gcc-41df0109de5fe4ddad66bfd742ee813688362ab8.tar.bz2
re PR c++/84031 (structured binding unpacks nameless padding bitfields)
PR c++/84031 * decl.c (find_decomp_class_base): Ignore unnamed bitfields. Ignore recursive calls that return ret. (cp_finish_decomp): Ignore unnamed bitfields. * g++.dg/cpp1z/decomp36.C: New test. From-SVN: r257057
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog7
-rw-r--r--gcc/cp/decl.c17
-rw-r--r--gcc/testsuite/ChangeLog3
-rw-r--r--gcc/testsuite/g++.dg/cpp1z/decomp36.C19
4 files changed, 39 insertions, 7 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 2c499db..bea4273 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,10 @@
+2018-01-25 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/84031
+ * decl.c (find_decomp_class_base): Ignore unnamed bitfields. Ignore
+ recursive calls that return ret.
+ (cp_finish_decomp): Ignore unnamed bitfields.
+
2018-01-23 Jason Merrill <jason@redhat.com>
PR c++/82249 - wrong mismatched pack length error.
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 408a1b7..244a3ef 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -7206,7 +7206,9 @@ find_decomp_class_base (location_t loc, tree type, tree ret)
{
bool member_seen = false;
for (tree field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
- if (TREE_CODE (field) != FIELD_DECL || DECL_ARTIFICIAL (field))
+ if (TREE_CODE (field) != FIELD_DECL
+ || DECL_ARTIFICIAL (field)
+ || (DECL_C_BIT_FIELD (field) && !DECL_NAME (field)))
continue;
else if (ret)
return type;
@@ -7245,7 +7247,7 @@ find_decomp_class_base (location_t loc, tree type, tree ret)
tree t = find_decomp_class_base (loc, TREE_TYPE (base_binfo), ret);
if (t == error_mark_node)
return error_mark_node;
- if (t != NULL_TREE)
+ if (t != NULL_TREE && t != ret)
{
if (ret == type)
{
@@ -7256,9 +7258,6 @@ find_decomp_class_base (location_t loc, tree type, tree ret)
}
else if (orig_ret != NULL_TREE)
return t;
- else if (ret == t)
- /* OK, found the same base along another path. We'll complain
- in convert_to_base if it's ambiguous. */;
else if (ret != NULL_TREE)
{
error_at (loc, "cannot decompose class type %qT: its base "
@@ -7645,7 +7644,9 @@ cp_finish_decomp (tree decl, tree first, unsigned int count)
goto error_out;
}
for (tree field = TYPE_FIELDS (btype); field; field = TREE_CHAIN (field))
- if (TREE_CODE (field) != FIELD_DECL || DECL_ARTIFICIAL (field))
+ if (TREE_CODE (field) != FIELD_DECL
+ || DECL_ARTIFICIAL (field)
+ || (DECL_C_BIT_FIELD (field) && !DECL_NAME (field)))
continue;
else
eltscnt++;
@@ -7660,7 +7661,9 @@ cp_finish_decomp (tree decl, tree first, unsigned int count)
}
unsigned int i = 0;
for (tree field = TYPE_FIELDS (btype); field; field = TREE_CHAIN (field))
- if (TREE_CODE (field) != FIELD_DECL || DECL_ARTIFICIAL (field))
+ if (TREE_CODE (field) != FIELD_DECL
+ || DECL_ARTIFICIAL (field)
+ || (DECL_C_BIT_FIELD (field) && !DECL_NAME (field)))
continue;
else
{
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 8493bcd..222df9d 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,8 @@
2018-01-25 Jakub Jelinek <jakub@redhat.com>
+ PR c++/84031
+ * g++.dg/cpp1z/decomp36.C: New test.
+
PR middle-end/83977
* c-c++-common/gomp/pr83977-1.c: Add -w to dg-options.
diff --git a/gcc/testsuite/g++.dg/cpp1z/decomp36.C b/gcc/testsuite/g++.dg/cpp1z/decomp36.C
new file mode 100644
index 0000000..5a66d0c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1z/decomp36.C
@@ -0,0 +1,19 @@
+// PR c++/84031
+// { dg-do compile { target c++11 } }
+// { dg-options "" }
+
+struct A { unsigned char : 1, a1 : 1, a2 : 2, : 1, a3 : 3; };
+struct B { unsigned char : 1, : 7; };
+struct C : B { constexpr C () : c1 (1), c2 (2), c3 (3) {} unsigned char : 1, c1 : 1, c2 : 2, : 1, c3 : 3; };
+struct D : C { constexpr D () {} unsigned char : 1, : 7; };
+
+int
+main ()
+{
+ static constexpr A a { 1, 2, 3 };
+ const auto &[a1, a2, a3] = a; // { dg-warning "only available with" "" { target c++14_down } }
+ static_assert (a1 == 1 && a2 == 2 && a3 == 3, "");
+ static constexpr D d;
+ const auto &[d1, d2, d3] = d; // { dg-warning "only available with" "" { target c++14_down } }
+ static_assert (d1 == 1 && d2 == 2 && d3 == 3, "");
+}