https://gcc.gnu.org/g:59cf3fa79caa945a99fdc3b5bd349987fd23dd92
commit r16-5516-g59cf3fa79caa945a99fdc3b5bd349987fd23dd92 Author: Nathaniel Shead <[email protected]> Date: Sat Nov 22 22:11:35 2025 +1100 c++: Correct behaviour of layout_compatible_type for aligned types The standard does not require two types to have the same alignment (and hence size) to be considered layout-compatible. The same applies to members of unions. gcc/cp/ChangeLog: * typeck.cc (layout_compatible_type_p): Do not check TYPE_SIZE. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/is-layout-compatible3.C: Adjust expected results. Signed-off-by: Nathaniel Shead <[email protected]> Reviewed-by: Jason Merrill <[email protected]> Diff: --- gcc/cp/typeck.cc | 8 +++----- gcc/testsuite/g++.dg/cpp2a/is-layout-compatible3.C | 8 ++++---- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/gcc/cp/typeck.cc b/gcc/cp/typeck.cc index 2ab45f3fff6e..0b8ef84bf50a 100644 --- a/gcc/cp/typeck.cc +++ b/gcc/cp/typeck.cc @@ -1883,14 +1883,12 @@ layout_compatible_type_p (tree type1, tree type2) type2 = cp_build_qualified_type (type2, TYPE_UNQUALIFIED); if (TREE_CODE (type1) == ENUMERAL_TYPE) - return (tree_int_cst_equal (TYPE_SIZE (type1), TYPE_SIZE (type2)) - && same_type_p (finish_underlying_type (type1), - finish_underlying_type (type2))); + return 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) - && tree_int_cst_equal (TYPE_SIZE (type1), TYPE_SIZE (type2))) + && std_layout_type_p (type2)) { tree field1 = TYPE_FIELDS (type1); tree field2 = TYPE_FIELDS (type2); diff --git a/gcc/testsuite/g++.dg/cpp2a/is-layout-compatible3.C b/gcc/testsuite/g++.dg/cpp2a/is-layout-compatible3.C index 499ba4977d41..e48679fef11f 100644 --- a/gcc/testsuite/g++.dg/cpp2a/is-layout-compatible3.C +++ b/gcc/testsuite/g++.dg/cpp2a/is-layout-compatible3.C @@ -51,15 +51,15 @@ struct B1 { signed int b; }; struct alignas (16) C1 : public A1 {}; struct alignas (16) D1 : public B1 {}; -static_assert (!std::is_layout_compatible_v<I, J>); +static_assert (std::is_layout_compatible_v<I, J>); 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<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<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<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<G, H>); static_assert (std::is_layout_compatible_v<C1, D1>);
