re PR c++/84031 (structured binding unpacks nameless padding bitfields)
authorJakub Jelinek <jakub@redhat.com>
Thu, 25 Jan 2018 16:38:40 +0000 (17:38 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Thu, 25 Jan 2018 16:38:40 +0000 (17:38 +0100)
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
gcc/cp/decl.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp1z/decomp36.C [new file with mode: 0644]

index 2c499dbc323f7460016be4676621017919d06c54..bea42736cfa9b4c394e972e04ca54bc7863f98b3 100644 (file)
@@ -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.
index 408a1b778305919def12c700a55a3c90ac26c706..244a3efe831f55c4d8a937a20a1988f3c3b9cc7c 100644 (file)
@@ -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
          {
index 8493bcdadd63403d19da1ecf58493588f0b62e09..222df9d3db9b381be17758403af861c0161227c6 100644 (file)
@@ -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 (file)
index 0000000..5a66d0c
--- /dev/null
@@ -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, "");
+}