OK.
On Thu, Jan 25, 2018 at 10:26 AM, Jakub Jelinek <ja...@redhat.com> wrote: > Hi! > > Unnamed bitfields are not data members, so we should ignore them when > counting the members or picking up members to initialize from, and > also should ignore them in find_decomp_class_base, they can appear > in various bases etc. and still there could be just one base containing > direct non-static data members. > > The patch also fixes an issue I ran into on the testcase, when recursing > from type in which we've found any direct non-static data members, we have > ret set to that type and if the recursion doesn't find anything nor an > error, it returns that ret rather than NULL. So, if t == ret, it just > means it didn't find anything preventing return of ret to the caller. > > Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? > > 2018-01-25 Jakub Jelinek <ja...@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. > > * g++.dg/cpp1z/decomp36.C: New test. > > --- gcc/cp/decl.c.jj 2018-01-24 17:18:42.376392255 +0100 > +++ gcc/cp/decl.c 2018-01-25 10:22:51.267122576 +0100 > @@ -7206,7 +7206,9 @@ find_decomp_class_base (location_t loc, > { > 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 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, > } > 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, > 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 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 > { > --- gcc/testsuite/g++.dg/cpp1z/decomp36.C.jj 2018-01-25 10:25:23.900154509 > +0100 > +++ gcc/testsuite/g++.dg/cpp1z/decomp36.C 2018-01-25 10:25:15.996152860 > +0100 > @@ -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, ""); > +} > > Jakub