From 41df0109de5fe4ddad66bfd742ee813688362ab8 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Thu, 25 Jan 2018 17:38:40 +0100 Subject: [PATCH] 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 --- gcc/cp/ChangeLog | 7 +++++++ gcc/cp/decl.c | 17 ++++++++++------- gcc/testsuite/ChangeLog | 3 +++ gcc/testsuite/g++.dg/cpp1z/decomp36.C | 19 +++++++++++++++++++ 4 files changed, 39 insertions(+), 7 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp1z/decomp36.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 2c499dbc323..bea42736cfa 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2018-01-25 Jakub Jelinek + + 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 PR c++/82249 - wrong mismatched pack length error. diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 408a1b77830..244a3efe831 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 8493bcdadd6..222df9d3db9 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,8 @@ 2018-01-25 Jakub Jelinek + 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 00000000000..5a66d0c7b56 --- /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, ""); +} -- 2.30.2