]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c++: Alignment changes to layout compatibility/common initial sequence - DR2583
authorJakub Jelinek <jakub@redhat.com>
Wed, 16 Nov 2022 13:49:47 +0000 (14:49 +0100)
committerJakub Jelinek <jakub@redhat.com>
Wed, 16 Nov 2022 13:49:47 +0000 (14:49 +0100)
When trying to figure out what to do about alignment,
layout_compatible_type_p returns false if TYPE_ALIGN on
ENUMERAL_TYPE/CLASS_TYPE_P (but not scalar types?) differ, or if members
don't have the same positions.

What is in DR2583 doesn't say anything like that though, on the other side
it says that if the corresponding entities don't have the same alignment
requirements, they aren't part of the common initial sequence.

So, my understanding of this is we shouldn't check TYPE_ALIGN in
layout_compatible_type_p, but instead DECL_ALIGN in
next_common_initial_seqence.

2022-11-16  Jakub Jelinek  <jakub@redhat.com>

* typeck.cc (next_common_initial_sequence): Return false members have
different DECL_ALIGN.
(layout_compatible_type_p): Don't test TYPE_ALIGN of ENUMERAL_TYPE
or CLASS_TYPE_P.

* g++.dg/cpp2a/is-layout-compatible3.C: Expect enums with different
alignas to be layout compatible, while classes with different
alignas on members layout incompatible.
* g++.dg/DRs/dr2583.C: New test.

gcc/cp/typeck.cc
gcc/testsuite/g++.dg/DRs/dr2583.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp2a/is-layout-compatible3.C

index 6c911827778c7e36e4b34b59126cce40f4594dbe..281d281629b372a73425015c4c784dfd427d2fea 100644 (file)
@@ -1833,6 +1833,8 @@ next_common_initial_sequence (tree &memb1, tree &memb2)
   if ((!lookup_attribute ("no_unique_address", DECL_ATTRIBUTES (memb1)))
       != !lookup_attribute ("no_unique_address", DECL_ATTRIBUTES (memb2)))
     return false;
+  if (DECL_ALIGN (memb1) != DECL_ALIGN (memb2))
+    return false;
   if (!tree_int_cst_equal (bit_position (memb1), bit_position (memb2)))
     return false;
   return true;
@@ -1854,15 +1856,13 @@ layout_compatible_type_p (tree type1, tree type2)
   type2 = cp_build_qualified_type (type2, TYPE_UNQUALIFIED);
 
   if (TREE_CODE (type1) == ENUMERAL_TYPE)
-    return (TYPE_ALIGN (type1) == TYPE_ALIGN (type2)
-           && tree_int_cst_equal (TYPE_SIZE (type1), TYPE_SIZE (type2))
+    return (tree_int_cst_equal (TYPE_SIZE (type1), TYPE_SIZE (type2))
            && same_type_p (finish_underlying_type (type1),
                            finish_underlying_type (type2)));
 
   if (CLASS_TYPE_P (type1)
       && std_layout_type_p (type1)
       && std_layout_type_p (type2)
-      && TYPE_ALIGN (type1) == TYPE_ALIGN (type2)
       && tree_int_cst_equal (TYPE_SIZE (type1), TYPE_SIZE (type2)))
     {
       tree field1 = TYPE_FIELDS (type1);
diff --git a/gcc/testsuite/g++.dg/DRs/dr2583.C b/gcc/testsuite/g++.dg/DRs/dr2583.C
new file mode 100644 (file)
index 0000000..e80834c
--- /dev/null
@@ -0,0 +1,45 @@
+// DR 2583 - Common initial sequence should consider over-alignment.
+// { dg-do compile { target c++11 } }
+
+#include <type_traits>
+
+struct A {
+  int i;
+  char c;
+};
+
+struct B {
+  int i;
+  alignas(8) char c;
+};
+
+struct C {
+  int i;
+  alignas(alignof(char)) char c;
+};
+
+struct D {
+  alignas(alignof(int)) int i;
+  char c;
+};
+
+struct S0 {
+  alignas(16) char x[128];
+  int i;
+};
+
+struct alignas(16) S1 {
+  char x[128];
+  int i;
+};
+
+#if __cpp_lib_is_layout_compatible >= 201907L
+static_assert (std::is_corresponding_member (&A::i, &B::i), "");
+static_assert (std::is_corresponding_member (&A::c, &B::c) == (alignof (char) == 8), "");
+static_assert (std::is_corresponding_member (&A::i, &C::i), "");
+static_assert (std::is_corresponding_member (&A::c, &C::c), "");
+static_assert (std::is_corresponding_member (&A::i, &D::i), "");
+static_assert (std::is_corresponding_member (&A::c, &D::c), "");
+static_assert (std::is_corresponding_member (&S0::x, &S1::x) == (alignof (char) == 16), "");
+static_assert (std::is_corresponding_member (&S0::i, &S1::i) == (alignof (char) == 16), "");
+#endif
index c54858746606cf61671d204779637d4a43e34f22..8f48ba8679a11d868a538909eaa84c07bb3090ec 100644 (file)
@@ -55,10 +55,10 @@ static_assert (!std::is_layout_compatible_v<K, L>);
 static_assert (!std::is_layout_compatible_v<M, N>);
 static_assert (!std::is_layout_compatible_v<O, P>);
 static_assert (!std::is_layout_compatible_v<P, D>);
-static_assert (!std::is_layout_compatible_v<Q, R>);
+static_assert (std::is_layout_compatible_v<Q, R>);
 static_assert (!std::is_layout_compatible_v<U, V>);
 static_assert (!std::is_layout_compatible_v<A, I>);
 static_assert (!std::is_layout_compatible_v<C, I>);
-static_assert (std::is_layout_compatible_v<E, F>);
+static_assert (!std::is_layout_compatible_v<E, F>);
 static_assert (std::is_layout_compatible_v<G, H>);
 static_assert (std::is_layout_compatible_v<C1, D1>);