In the case where the overlaid object is nested in a record or is an array element as in:
for Foo'Address use Item.Nested_Item'Address; or for Foo'Address use Item (Bar)'Address; the compiler was not emitting a warning in case of differing Scalar_Storage_Order values. gcc/ada/ChangeLog: * sem_util.adb (Find_Overlaid_Entity): Add extra parameter to extract the type being overlaid. (Note_Possible_Modification): Adjust call to Find_Overlaid_Entity. (Ultimate_Overlaid_Entity): Likewise. * sem_ch13.adb (Analyze_Attribute_Definition_Clause): Likewise. * sem_util.ads (Find_Overlaid_Entity): Add extra parameter to extract the type being overlaid. * freeze.adb (Check_Address_Clause): Likewise. Tested on x86_64-pc-linux-gnu, committed on master. --- gcc/ada/freeze.adb | 3 ++- gcc/ada/sem_ch13.adb | 9 +++++---- gcc/ada/sem_util.adb | 42 ++++++++++++++++++++++++++++++++++-------- gcc/ada/sem_util.ads | 10 +++++++--- 4 files changed, 48 insertions(+), 16 deletions(-) diff --git a/gcc/ada/freeze.adb b/gcc/ada/freeze.adb index ec0fb16e741..ce9a9742274 100644 --- a/gcc/ada/freeze.adb +++ b/gcc/ada/freeze.adb @@ -715,10 +715,11 @@ package body Freeze is then declare O_Ent : Entity_Id; + O_Typ : Entity_Id; Off : Boolean; begin - Find_Overlaid_Entity (Addr, O_Ent, Off); + Find_Overlaid_Entity (Addr, O_Ent, O_Typ, Off); if Ekind (O_Ent) = E_Constant and then Etype (O_Ent) = Typ diff --git a/gcc/ada/sem_ch13.adb b/gcc/ada/sem_ch13.adb index 76a8c0ba733..22575f9cbf5 100644 --- a/gcc/ada/sem_ch13.adb +++ b/gcc/ada/sem_ch13.adb @@ -6208,6 +6208,7 @@ package body Sem_Ch13 is declare Expr : constant Node_Id := Expression (N); O_Ent : Entity_Id; + O_Typ : Entity_Id; Off : Boolean; begin @@ -6220,7 +6221,7 @@ package body Sem_Ch13 is return; end if; - Find_Overlaid_Entity (N, O_Ent, Off); + Find_Overlaid_Entity (N, O_Ent, O_Typ, Off); if Present (O_Ent) then @@ -6273,10 +6274,10 @@ package body Sem_Ch13 is if (Is_Record_Type (Etype (U_Ent)) or else Is_Array_Type (Etype (U_Ent))) - and then (Is_Record_Type (Etype (O_Ent)) - or else Is_Array_Type (Etype (O_Ent))) + and then (Is_Record_Type (O_Typ) + or else Is_Array_Type (O_Typ)) and then Reverse_Storage_Order (Etype (U_Ent)) /= - Reverse_Storage_Order (Etype (O_Ent)) + Reverse_Storage_Order (O_Typ) then Error_Msg_N ("??overlay changes scalar storage order", Expr); diff --git a/gcc/ada/sem_util.adb b/gcc/ada/sem_util.adb index 02ebb71b562..40e3da36c20 100644 --- a/gcc/ada/sem_util.adb +++ b/gcc/ada/sem_util.adb @@ -8923,9 +8923,10 @@ package body Sem_Util is -------------------------- procedure Find_Overlaid_Entity - (N : Node_Id; - Ent : out Entity_Id; - Off : out Boolean) + (N : Node_Id; + Ent : out Entity_Id; + Ovrl_Typ : out Entity_Id; + Off : out Boolean) is pragma Assert (Nkind (N) = N_Attribute_Definition_Clause @@ -8948,6 +8949,7 @@ package body Sem_Util is -- constant that eventually references Y'Address. Ent := Empty; + Ovrl_Typ := Empty; Off := False; Expr := Expression (N); @@ -8998,11 +9000,33 @@ package body Sem_Util is and then Is_Concurrent_Type (Scope (Ent))); Ent := Empty; end if; + + if No (Ovrl_Typ) then + Ovrl_Typ := Etype (Ent); + end if; + return; -- Check for components elsif Nkind (Expr) in N_Selected_Component | N_Indexed_Component then + if Nkind (Expr) = N_Selected_Component then + -- If Something.Other'Address, use + -- the Etype of the Other component. + + if No (Ovrl_Typ) then + Ovrl_Typ := Etype (Entity (Selector_Name (Expr))); + end if; + + else + -- If Something(Index)'Address, use + -- the Etype of the array component. + + if No (Ovrl_Typ) then + Ovrl_Typ := Etype (Expr); + end if; + end if; + Expr := Prefix (Expr); Off := True; @@ -25599,10 +25623,11 @@ package body Sem_Util is declare Addr : constant Node_Id := Address_Clause (Ent); O_Ent : Entity_Id; + O_Typ : Entity_Id; Off : Boolean; begin - Find_Overlaid_Entity (Addr, O_Ent, Off); + Find_Overlaid_Entity (Addr, O_Ent, O_Typ, Off); Error_Msg_Sloc := Sloc (Addr); Error_Msg_NE @@ -29050,9 +29075,10 @@ package body Sem_Util is ------------------------------ function Ultimate_Overlaid_Entity (E : Entity_Id) return Entity_Id is - Address : Node_Id; - Alias : Entity_Id := E; - Offset : Boolean; + Address : Node_Id; + Alias : Entity_Id := E; + Offset : Boolean; + Ovrl_Typ : Entity_Id; begin -- Currently this routine is only called for stand-alone objects that @@ -29064,7 +29090,7 @@ package body Sem_Util is loop Address := Address_Clause (Alias); if Present (Address) then - Find_Overlaid_Entity (Address, Alias, Offset); + Find_Overlaid_Entity (Address, Alias, Ovrl_Typ, Offset); if Present (Alias) then null; else diff --git a/gcc/ada/sem_util.ads b/gcc/ada/sem_util.ads index 29dbae8073e..0e97806f718 100644 --- a/gcc/ada/sem_util.ads +++ b/gcc/ada/sem_util.ads @@ -898,14 +898,18 @@ package Sem_Util is -- loop are nested within the block. procedure Find_Overlaid_Entity - (N : Node_Id; - Ent : out Entity_Id; - Off : out Boolean); + (N : Node_Id; + Ent : out Entity_Id; + Ovrl_Typ : out Entity_Id; + Off : out Boolean); -- The node N should be an address representation clause. Determines if the -- target expression is the address of an entity with an optional offset. -- If so, set Ent to the entity and, if there is an offset, set Off to -- True, otherwise to False. If it is not possible to determine that the -- address is of this form, then set Ent to Empty. + -- Ovrl_Typ is set to the type being overlaid and can be different than the + -- type of Ent, for example when the address clause is applied to a record + -- component or to an element of an array. function Find_Parameter_Type (Param : Node_Id) return Entity_Id; -- Return the type of formal parameter Param as determined by its -- 2.43.0