C++ PATCH for DR 1813, c++/83374 - __is_standard_layout wrong for a class with repeated bases.

Marek Polacek polacek@redhat.com
Wed Jul 3 22:27:00 GMT 2019


This resolves DR 1813 which says that for a class to be a standard-layout
class, it may not have two (possibly indirect) base class subobjects of the
same type.  I was going to play DFS games but then I noticed we'd already set
CLASSTYPE_REPEATED_BASE_P, making this significantly easier.

There are 3 related DRs which I opened PRs for:

91079 - [DR 1881] Standard-layout classes and unnamed bit-fields
91080 - [DR 1672] Layout compatibility with multiple empty bases
91081 - [DR 2120] Array as first non-static data member in standard-layout class

Bootstrapped/regtested on x86_64-linux, ok for trunk?

2019-07-03  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.

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

diff --git gcc/cp/class.c gcc/cp/class.c
index 73291b341fe..f77b7f4834b 100644
--- gcc/cp/class.c
+++ gcc/cp/class.c
@@ -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
diff --git gcc/testsuite/g++.dg/ext/is_std_layout3.C gcc/testsuite/g++.dg/ext/is_std_layout3.C
new file mode 100644
index 00000000000..b0555c8207b
--- /dev/null
+++ gcc/testsuite/g++.dg/ext/is_std_layout3.C
@@ -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 gcc/testsuite/g++.dg/ext/is_std_layout4.C gcc/testsuite/g++.dg/ext/is_std_layout4.C
new file mode 100644
index 00000000000..09c0098120d
--- /dev/null
+++ gcc/testsuite/g++.dg/ext/is_std_layout4.C
@@ -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), "");



More information about the Gcc-patches mailing list