Pragma Component_Alignment was not implemented properly and caused a crash when used in a configuration file due to how it was applied via the scope table. This patch correctly identifies this case and uses a global variable Configuration_Component_Alignment to capture the value set during configuration analysis and applies it in place of the default value.
------------ -- Source -- ------------ -- stor_unit.adc pragma Component_Alignment (Form => Storage_Unit); -- pack_storage_unit.ads package Pack_Storage_Unit is pragma Component_Alignment (Form => Storage_Unit); type Small_Int is new Integer range 0 .. 1; for Small_Int'Size use 1; type Rec is record Comp_1 : Small_Int; Comp_2 : Small_Int; Comp_3 : Boolean; Comp_4 : Integer; Comp_5 : Long_Integer; end record; end Pack_Storage_Unit; -- pack.ads package Pack is type Small_Int is new Integer range 0 .. 1; for Small_Int'Size use 1; type Rec is record Comp_1 : Small_Int; Comp_2 : Small_Int; Comp_3 : Boolean; Comp_4 : Integer; Comp_5 : Long_Integer; end record; end Pack; ---------------------------- -- Compilation and output -- ---------------------------- $ gcc -c -gnatR pack_storage_unit.ads > output1.txt $ gcc -c -gnatR pack.ads -gnatec=stor_unit.adc > output2.txt $ grep -v -F -x -f output1.txt output2.txt Representation information for unit Pack (spec) for Rec'Size use 128; for Rec'Alignment use 8; Comp_4 at 4 range 0 .. 31; Comp_5 at 8 range 0 .. 63; Tested on x86_64-pc-linux-gnu, committed on trunk 2016-06-22 Justin Squirek <squi...@adacore.com> * sem_ch8.adb (Push_Scope): Add a check for when the scope table is empty to assign the global variable Configuration_Component_Alignment. * sem.adb (Do_Analyze): Add Configuration_Component_Alignment to be assigned when the environment is cleaned instead of the default. * sem.ads Add a global variable Configuration_Component_Alignment to store the value given by pragma Component_Alignment in the context of a configuration file. * sem_prag.adb (Analyze_Pragma): Correct the case for Component_Alignment so that the pragma is verified and add comments to explain how it is applied to the scope stack.
Index: sem.adb =================================================================== --- sem.adb (revision 237680) +++ sem.adb (working copy) @@ -1355,7 +1355,8 @@ Outer_Generic_Scope := Empty; Scope_Suppress := Suppress_Options; Scope_Stack.Table - (Scope_Stack.Last).Component_Alignment_Default := Calign_Default; + (Scope_Stack.Last).Component_Alignment_Default := + Configuration_Component_Alignment; Scope_Stack.Table (Scope_Stack.Last).Is_Active_Stack_Base := True; Index: sem.ads =================================================================== --- sem.ads (revision 237680) +++ sem.ads (working copy) @@ -461,6 +461,11 @@ -- Transient blocks have three associated actions list, to be inserted -- before and after the block's statements, and as cleanup actions. + Configuration_Component_Alignment : Component_Alignment_Kind := + Calign_Default; + -- Used for handling the pragma Component_Alignment in the context of a + -- configuration file. + type Scope_Stack_Entry is record Entity : Entity_Id; -- Entity representing the scope Index: sem_ch8.adb =================================================================== --- sem_ch8.adb (revision 237693) +++ sem_ch8.adb (working copy) @@ -8192,10 +8192,22 @@ SST.Save_Default_SSO := Default_SSO; SST.Save_Uneval_Old := Uneval_Old; + -- Each new scope pushed onto the scope stack inherits the component + -- alignment of the previous scope. This emulates the "visibility" + -- semantics of pragma Component_Alignment. + if Scope_Stack.Last > Scope_Stack.First then SST.Component_Alignment_Default := Scope_Stack.Table (Scope_Stack.Last - 1). Component_Alignment_Default; + + -- Otherwise, this is the first scope being pushed on the scope + -- stack. Inherit the component alignment from the configuration + -- form of pragma Component_Alignment (if any). + + else + SST.Component_Alignment_Default := + Configuration_Component_Alignment; end if; SST.Last_Subprogram_Name := null; Index: sem_prag.adb =================================================================== --- sem_prag.adb (revision 237693) +++ sem_prag.adb (working copy) @@ -12787,9 +12787,21 @@ ("invalid Form parameter for pragma%", Form); end if; + -- The pragma appears in a configuration file + + if No (Parent (N)) then + Check_Valid_Configuration_Pragma; + + -- Capture the component alignment in a global variable when + -- the pragma appears in a configuration file. Note that the + -- scope stack is empty at this point and cannot be used to + -- store the alignment value. + + Configuration_Component_Alignment := Atype; + -- Case with no name, supplied, affects scope table entry - if No (Name) then + elsif No (Name) then Scope_Stack.Table (Scope_Stack.Last).Component_Alignment_Default := Atype; @@ -20901,7 +20913,7 @@ Mode_Id := Get_SPARK_Mode_Type (Mode); Context := Parent (N); - -- The pragma appears in a configuration pragmas file + -- The pragma appears in a configuration file if No (Context) then Check_Valid_Configuration_Pragma;