https://gcc.gnu.org/g:a72d2abbfc10e4d9620b17ffc41bdbcb98bff100
commit r15-6207-ga72d2abbfc10e4d9620b17ffc41bdbcb98bff100 Author: Eric Botcazou <ebotca...@adacore.com> Date: Tue Nov 19 19:14:53 2024 +0100 ada: Fix internal error on packed record with 0-size component The problem is that the order of components listed in a constant CONSTRUCTOR does not match that of the associated record type. gcc/ada/ChangeLog: * gcc-interface/utils2.cc (compare_elmt_bitpos): Deal specially with 0-sized components when the bit position is the same. Diff: --- gcc/ada/gcc-interface/utils2.cc | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/gcc/ada/gcc-interface/utils2.cc b/gcc/ada/gcc-interface/utils2.cc index 8eebf5935960..e91f67d7e452 100644 --- a/gcc/ada/gcc-interface/utils2.cc +++ b/gcc/ada/gcc-interface/utils2.cc @@ -2113,7 +2113,23 @@ compare_elmt_bitpos (const void *rt1, const void *rt2) const int ret = tree_int_cst_compare (bit_position (field1), bit_position (field2)); - return ret ? ret : (int) (DECL_UID (field1) - DECL_UID (field2)); + if (ret) + return ret; + + /* The bit position can be the same if one of the fields has zero size. + In this case, if the other has nonzero size, put the former first to + match the layout done by components_to_record. Otherwise, preserve + the order of the source code. */ + + const bool field1_zero_size = integer_zerop (DECL_SIZE (field1)); + const bool field2_zero_size = integer_zerop (DECL_SIZE (field2)); + + if (field1_zero_size && !field2_zero_size) + return -1; + else if (!field1_zero_size && field2_zero_size) + return 1; + else + return (int) (DECL_UID (field1) - DECL_UID (field2)); } /* Return a CONSTRUCTOR of TYPE whose elements are V. */