DR 1813 PR c++/83374 - __is_standard_layout wrong for a class with repeated bases.
authorMarek Polacek <polacek@redhat.com>
Fri, 5 Jul 2019 14:45:30 +0000 (14:45 +0000)
committerMarek Polacek <mpolacek@gcc.gnu.org>
Fri, 5 Jul 2019 14:45:30 +0000 (14:45 +0000)
DR 1813
PR c++/83374 - __is_standard_layout wrong for a class with repeated bases.
* class.c (check_bases): Set CLASSTYPE_NON_STD_LAYOUT for a class if
CLASSTYPE_REPEATED_BASE_P is true.

* g++.dg/ext/is_std_layout3.C: New test.
* g++.dg/ext/is_std_layout4.C: New test.

From-SVN: r273139

gcc/cp/ChangeLog
gcc/cp/class.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/ext/is_std_layout3.C [new file with mode: 0644]
gcc/testsuite/g++.dg/ext/is_std_layout4.C [new file with mode: 0644]

index c1dfb7cee390a96e577f382ed518b5870e525d5d..f24a096b9e84b9976b4b9072210b50e420e95fbf 100644 (file)
@@ -1,3 +1,10 @@
+2019-07-04  Marek Polacek  <polacek@redhat.com>
+
+       DR 1813
+       PR c++/83374 - __is_standard_layout wrong for a class with repeated bases.
+       * class.c (check_bases): Set CLASSTYPE_NON_STD_LAYOUT for a class if
+       CLASSTYPE_REPEATED_BASE_P is true.
+
 2019-07-04  Andrew Stubbs  <ams@codesourcery.com>
 
        * cp-tree.h (cp_omp_emit_unmappable_type_notes): New prototype.
index 73291b341fe8815d433f46f959bf2640675e4b04..f77b7f4834b200d4308f21017e407bb1ca32cd68 100644 (file)
@@ -1715,11 +1715,15 @@ check_bases (tree t,
              && (same_type_ignoring_top_level_qualifiers_p
                  (TREE_TYPE (field), basetype)))
            CLASSTYPE_NON_STD_LAYOUT (t) = 1;
+         /* DR 1813:
+            ...has at most one base class subobject of any given type...  */
+         else if (CLASSTYPE_REPEATED_BASE_P (t))
+           CLASSTYPE_NON_STD_LAYOUT (t) = 1;
          else
            /* ...either has no non-static data members in the most-derived
               class and at most one base class with non-static data
               members, or has no base classes with non-static data
-              members */
+              members.  FIXME This was reworded in DR 1813.  */
            for (basefield = TYPE_FIELDS (basetype); basefield;
                 basefield = DECL_CHAIN (basefield))
              if (TREE_CODE (basefield) == FIELD_DECL
index a57c230d57d8b99ca48dea177cc939edb0fe36e6..98ad88063c711b3c5dc407e0964837bb2ce8121a 100644 (file)
@@ -1,3 +1,10 @@
+2019-07-04  Marek Polacek  <polacek@redhat.com>
+
+       DR 1813
+       PR c++/83374 - __is_standard_layout wrong for a class with repeated bases.
+       * g++.dg/ext/is_std_layout3.C: New test.
+       * g++.dg/ext/is_std_layout4.C: New test.
+
 2019-07-05  Richard Biener  <rguenther@suse.de>
 
        * gcc.dg/tree-ssa/ssa-fre-77.c: New testcase.
diff --git a/gcc/testsuite/g++.dg/ext/is_std_layout3.C b/gcc/testsuite/g++.dg/ext/is_std_layout3.C
new file mode 100644 (file)
index 0000000..b0555c8
--- /dev/null
@@ -0,0 +1,18 @@
+// DR 1813
+// PR c++/83374 - __is_standard_layout wrong for a class with repeated bases.
+// { dg-do compile { target c++11 } }
+
+struct B { int i; };        // standard-layout class
+struct C : B { };           // standard-layout class
+struct D : C { };           // standard-layout class
+struct E : D { char : 4; }; // not a standard-layout class
+static_assert( __is_standard_layout(B), "" );
+static_assert( __is_standard_layout(C), "" );
+static_assert( __is_standard_layout(D), "" );
+static_assert( ! __is_standard_layout(E), "" );
+
+struct Q {};
+struct S : Q { };
+struct T : Q { };
+struct U : S, T { };         // not a standard-layout class
+static_assert( ! __is_standard_layout(U), "" );
diff --git a/gcc/testsuite/g++.dg/ext/is_std_layout4.C b/gcc/testsuite/g++.dg/ext/is_std_layout4.C
new file mode 100644 (file)
index 0000000..09c0098
--- /dev/null
@@ -0,0 +1,11 @@
+// DR 1813
+// PR c++/83374 - __is_standard_layout wrong for a class with repeated bases.
+// { dg-do compile { target c++11 } }
+
+struct R { };
+struct Q { };
+struct S : R { };
+struct T : Q { };
+struct U : S, T { };
+// No repeated base class subobjects.
+static_assert(__is_standard_layout(U), "");