diff mbox series

[Ada] Improve layout ABI compatibility with C++

Message ID 20171109102702.GA22678@adacore.com
State New
Headers show
Series [Ada] Improve layout ABI compatibility with C++ | expand

Commit Message

Pierre-Marie de Rodat Nov. 9, 2017, 10:27 a.m. UTC
This patch modifies the initialization of the offset_to_top field of
secondary dispatch tables to store negative offsets, thus improving
the layout compatibility of secondary dispatch tables with C++.

No functionality change.

Tested on x86_64-pc-linux-gnu, committed on trunk

2017-11-09  Javier Miranda  <miranda@adacore.com>

	* exp_disp.adb (Expand_Interface_Thunk): Replace substraction of
	offset-to-top field by addition.
	(Make_Secondary_DT): Initialize the offset-to-top field with a negative
	offset.
	* exp_ch3.adb (Build_Offset_To_Top_Function): Build functions that
	return a negative offset-to-top value.
	(Initialize_Tag): Invoke runtime services Set_Dynamic_Offset_To_Top and
	Set_Static_Offset_To_Top passing a negative offet-to-top value;
	initialize also the offset-to-top field with a negative offset.
	* libgnat/a-tags.adb (Base_Address): Displace the pointer by means of
	an addition since the offset-to-top field is now a negative value.
	(Displace): Displace the pointer to the object means of a substraction
	since it is now a negative value.
	(Set_Dynamic_Offset_to_top): Displace the pointer to the object by
	means of a substraction since it is now a negative value.
diff mbox series

Patch

Index: libgnat/a-tags.adb
===================================================================
--- libgnat/a-tags.adb	(revision 254563)
+++ libgnat/a-tags.adb	(working copy)
@@ -332,7 +332,7 @@ 
 
    function Base_Address (This : System.Address) return System.Address is
    begin
-      return This - Offset_To_Top (This);
+      return This + Offset_To_Top (This);
    end Base_Address;
 
    ---------------
@@ -412,14 +412,14 @@ 
                --  Case of Static value of Offset_To_Top
 
                if Iface_Table.Ifaces_Table (Id).Static_Offset_To_Top then
-                  Obj_Base := Obj_Base +
+                  Obj_Base := Obj_Base -
                     Iface_Table.Ifaces_Table (Id).Offset_To_Top_Value;
 
                --  Otherwise call the function generated by the expander to
                --  provide the value.
 
                else
-                  Obj_Base := Obj_Base +
+                  Obj_Base := Obj_Base -
                     Iface_Table.Ifaces_Table (Id).Offset_To_Top_Func.all
                       (Obj_Base);
                end if;
@@ -1046,7 +1046,7 @@ 
       --  Save the offset to top field in the secondary dispatch table
 
       if Offset_Value /= 0 then
-         Sec_Base := This + Offset_Value;
+         Sec_Base := This - Offset_Value;
          Sec_DT := DT (To_Tag_Ptr (Sec_Base).all);
          Sec_DT.Offset_To_Top := SSE.Storage_Offset'Last;
       end if;
Index: exp_disp.adb
===================================================================
--- exp_disp.adb	(revision 254563)
+++ exp_disp.adb	(working copy)
@@ -1884,7 +1884,7 @@ 
             --  Generate:
             --     type T is access all <<type of the target formal>>
             --     S : Storage_Offset := Storage_Offset!(Formal)
-            --                            - Offset_To_Top (address!(Formal))
+            --                            + Offset_To_Top (address!(Formal))
 
             Decl_2 :=
               Make_Full_Type_Declaration (Loc,
@@ -1918,7 +1918,7 @@ 
                 Object_Definition   =>
                   New_Occurrence_Of (RTE (RE_Storage_Offset), Loc),
                 Expression          =>
-                  Make_Op_Subtract (Loc,
+                  Make_Op_Add (Loc,
                     Left_Opnd  =>
                       Unchecked_Convert_To
                         (RTE (RE_Storage_Offset),
@@ -1942,7 +1942,7 @@ 
 
             --  Generate:
             --     S1 : Storage_Offset := Storage_Offset!(Formal'Address)
-            --                             - Offset_To_Top (Formal'Address)
+            --                             + Offset_To_Top (Formal'Address)
             --     S2 : Addr_Ptr := Addr_Ptr!(S1)
 
             New_Arg :=
@@ -1969,7 +1969,7 @@ 
                 Object_Definition   =>
                   New_Occurrence_Of (RTE (RE_Storage_Offset), Loc),
                 Expression          =>
-                  Make_Op_Subtract (Loc,
+                  Make_Op_Add (Loc,
                     Left_Opnd =>
                       Unchecked_Convert_To
                         (RTE (RE_Storage_Offset),
@@ -4234,14 +4234,15 @@ 
 
          else
             Append_To (DT_Aggr_List,
-              Make_Attribute_Reference (Loc,
-                Prefix         =>
-                  Make_Selected_Component (Loc,
-                    Prefix        =>
-                      New_Occurrence_Of (Dummy_Object, Loc),
-                    Selector_Name =>
-                      New_Occurrence_Of (Iface_Comp, Loc)),
-                Attribute_Name => Name_Position));
+              Make_Op_Minus (Loc,
+                Make_Attribute_Reference (Loc,
+                  Prefix         =>
+                    Make_Selected_Component (Loc,
+                      Prefix        =>
+                        New_Occurrence_Of (Dummy_Object, Loc),
+                      Selector_Name =>
+                        New_Occurrence_Of (Iface_Comp, Loc)),
+                  Attribute_Name => Name_Position)));
          end if;
 
          --  Generate the Object Specific Data table required to dispatch calls
Index: exp_ch3.adb
===================================================================
--- exp_ch3.adb	(revision 254563)
+++ exp_ch3.adb	(working copy)
@@ -2176,7 +2176,7 @@ 
             --  Generate
             --    function Fxx (O : in Rec_Typ) return Storage_Offset is
             --    begin
-            --       return O.Iface_Comp'Position;
+            --       return -O.Iface_Comp'Position;
             --    end Fxx;
 
             Body_Node := New_Node (N_Subprogram_Body, Loc);
@@ -2199,15 +2199,16 @@ 
                 Statements     => New_List (
                   Make_Simple_Return_Statement (Loc,
                     Expression =>
-                      Make_Attribute_Reference (Loc,
-                        Prefix         =>
-                          Make_Selected_Component (Loc,
-                            Prefix        =>
-                              Unchecked_Convert_To (Acc_Type,
-                                Make_Identifier (Loc, Name_uO)),
-                            Selector_Name =>
-                              New_Occurrence_Of (Iface_Comp, Loc)),
-                        Attribute_Name => Name_Position)))));
+                      Make_Op_Minus (Loc,
+                        Make_Attribute_Reference (Loc,
+                          Prefix         =>
+                            Make_Selected_Component (Loc,
+                              Prefix        =>
+                                Unchecked_Convert_To (Acc_Type,
+                                  Make_Identifier (Loc, Name_uO)),
+                              Selector_Name =>
+                                New_Occurrence_Of (Iface_Comp, Loc)),
+                          Attribute_Name => Name_Position))))));
 
             Set_Ekind       (Func_Id, E_Function);
             Set_Mechanism   (Func_Id, Default_Mechanism);
@@ -8516,13 +8517,14 @@ 
 
                   Unchecked_Convert_To
                     (RTE (RE_Storage_Offset),
-                     Make_Attribute_Reference (Loc,
-                       Prefix         =>
-                         Make_Selected_Component (Loc,
-                           Prefix        => New_Copy_Tree (Target),
-                           Selector_Name =>
-                             New_Occurrence_Of (Tag_Comp, Loc)),
-                       Attribute_Name => Name_Position)),
+                     Make_Op_Minus (Loc,
+                       Make_Attribute_Reference (Loc,
+                         Prefix         =>
+                           Make_Selected_Component (Loc,
+                             Prefix        => New_Copy_Tree (Target),
+                             Selector_Name =>
+                               New_Occurrence_Of (Tag_Comp, Loc)),
+                         Attribute_Name => Name_Position))),
 
                   Unchecked_Convert_To (RTE (RE_Offset_To_Top_Function_Ptr),
                     Make_Attribute_Reference (Loc,
@@ -8545,12 +8547,13 @@ 
                       New_Occurrence_Of (Offset_To_Top_Comp, Loc)),
 
                 Expression =>
-                  Make_Attribute_Reference (Loc,
-                    Prefix       =>
-                      Make_Selected_Component (Loc,
-                        Prefix        => New_Copy_Tree (Target),
-                        Selector_Name => New_Occurrence_Of (Tag_Comp, Loc)),
-                  Attribute_Name => Name_Position)));
+                  Make_Op_Minus (Loc,
+                    Make_Attribute_Reference (Loc,
+                      Prefix       =>
+                        Make_Selected_Component (Loc,
+                          Prefix        => New_Copy_Tree (Target),
+                          Selector_Name => New_Occurrence_Of (Tag_Comp, Loc)),
+                    Attribute_Name => Name_Position))));
 
          --  Normal case: No discriminants in the parent type
 
@@ -8567,13 +8570,14 @@ 
                    Iface_Tag    => New_Occurrence_Of (Iface_Tag, Loc),
                    Offset_Value =>
                      Unchecked_Convert_To (RTE (RE_Storage_Offset),
-                       Make_Attribute_Reference (Loc,
-                         Prefix         =>
-                           Make_Selected_Component (Loc,
-                             Prefix        => New_Copy_Tree (Target),
-                             Selector_Name =>
-                               New_Occurrence_Of (Tag_Comp, Loc)),
-                         Attribute_Name => Name_Position))));
+                       Make_Op_Minus (Loc,
+                         Make_Attribute_Reference (Loc,
+                           Prefix         =>
+                             Make_Selected_Component (Loc,
+                               Prefix        => New_Copy_Tree (Target),
+                               Selector_Name =>
+                                 New_Occurrence_Of (Tag_Comp, Loc)),
+                           Attribute_Name => Name_Position)))));
             end if;
 
             --  Generate:
@@ -8602,13 +8606,14 @@ 
                      New_Occurrence_Of (Standard_True, Loc),
 
                      Unchecked_Convert_To (RTE (RE_Storage_Offset),
-                       Make_Attribute_Reference (Loc,
-                         Prefix         =>
-                           Make_Selected_Component (Loc,
-                             Prefix         => New_Copy_Tree (Target),
-                             Selector_Name  =>
-                               New_Occurrence_Of (Tag_Comp, Loc)),
-                         Attribute_Name => Name_Position)),
+                       Make_Op_Minus (Loc,
+                         Make_Attribute_Reference (Loc,
+                           Prefix         =>
+                             Make_Selected_Component (Loc,
+                               Prefix         => New_Copy_Tree (Target),
+                               Selector_Name  =>
+                                 New_Occurrence_Of (Tag_Comp, Loc)),
+                           Attribute_Name => Name_Position))),
 
                      Make_Null (Loc))));
             end if;
@@ -8712,15 +8717,10 @@ 
             --  Initialize secondary tags
 
             else
-               Append_To (Init_Tags_List,
-                 Make_Assignment_Statement (Loc,
-                   Name =>
-                     Make_Selected_Component (Loc,
-                       Prefix => New_Copy_Tree (Target),
-                       Selector_Name =>
-                         New_Occurrence_Of (Node (Iface_Comp_Elmt), Loc)),
-                   Expression =>
-                     New_Occurrence_Of (Node (Iface_Tag_Elmt), Loc)));
+               Initialize_Tag (Full_Typ,
+                 Iface     => Node (Iface_Elmt),
+                 Tag_Comp  => Tag_Comp,
+                 Iface_Tag => Node (Iface_Tag_Elmt));
             end if;
 
          --  Otherwise generate code to initialize the tag