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.  */

Reply via email to