This change fixes an oversight in the predicate that determines whether two composite types have the same representation (difference of scalar storage order was ignored, causing the compiler to incorrectly omit a per-component assignment in this case).
The following test case must compile and execute as shown: $ gnatmake conv_endianness $ ./conv_endianness X_L = (S => 12345, C => 'a') X_H = (S => 23456, C => 'b') X_H = (S => 12345, C => 'a') with System; use System; with Ada.Text_IO; use Ada.Text_IO; procedure Conv_Endianness is type Short is mod 2**16; type R_L is record S : Short; C : Character; end record; for R_L'Bit_Order use Low_Order_First; for R_L'Scalar_Storage_Order use Low_Order_First; for R_L use record S at 0 range 0 .. 15; C at 2 range 0 .. 7; end record; type R_H is new R_L; for R_H'Bit_Order use High_Order_First; for R_H'Scalar_Storage_Order use High_Order_First; for R_H use record S at 0 range 0 .. 15; C at 2 range 0 .. 7; end record; procedure Dump (Name : String; S : Short; C : Character) is begin Put_Line (Name & " = (S =>" & S'Img & ", C => '" & C & "')"); end Dump; X_L : R_L; X_H : R_H; begin X_L.S := 12345; X_L.C := 'a'; Dump ("X_L", X_L.S, X_L.C); X_H.S := 23456; X_H.C := 'b'; Dump ("X_H", X_H.S, X_H.C); X_H := R_H (X_L); Dump ("X_H", X_H.S, X_H.C); end Conv_Endianness; Tested on x86_64-pc-linux-gnu, committed on trunk 2013-04-11 Thomas Quinot <qui...@adacore.com> * sem_ch13.adb (Same_Representation): Two types with different scalar storage order never have the same representation.
Index: sem_ch13.adb =================================================================== --- sem_ch13.adb (revision 197781) +++ sem_ch13.adb (working copy) @@ -9448,12 +9448,16 @@ return False; end if; - -- Representations are different if component alignments differ + -- Representations are different if component alignments or scalar + -- storage orders differ. if (Is_Record_Type (T1) or else Is_Array_Type (T1)) and then (Is_Record_Type (T2) or else Is_Array_Type (T2)) - and then Component_Alignment (T1) /= Component_Alignment (T2) + and then + (Component_Alignment (T1) /= Component_Alignment (T2) + or else + Reverse_Storage_Order (T1) /= Reverse_Storage_Order (T2)) then return False; end if; @@ -9530,7 +9534,7 @@ function Same_Rep return Boolean; -- CD1 and CD2 are either components or discriminants. This - -- function tests whether the two have the same representation + -- function tests whether they have the same representation. -------------- -- Same_Rep -- @@ -9540,8 +9544,11 @@ begin if No (Component_Clause (CD1)) then return No (Component_Clause (CD2)); + else + -- Note: at this point, component clauses have been + -- normalized to the default bit order, so that the + -- comparison of Component_Bit_Offsets is meaningful. - else return Present (Component_Clause (CD2)) and then