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

Reply via email to