[Ada] Small housekeeping work in Expand_N_Object_Declaration

Message ID 20220704075026.GA99349@adacore.com
State Committed
Headers
Series [Ada] Small housekeeping work in Expand_N_Object_Declaration |

Commit Message

Pierre-Marie de Rodat July 4, 2022, 7:50 a.m. UTC
  The local function Rewrite_As_Renaming can be called twice in certain
circumstances, which is both not quite safe and unnecessary, so this
replaces it with a local variable whose value is computed only once.

No functional changes.

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

gcc/ada/

	* exp_ch3.adb (Expand_N_Object_Declaration) <OK_To_Rename_Ref>: New
	local function.
	<Rewrite_As_Renaming>: Change to a local variable whose value is
	computed once and generate a call to Finalize after this is done.
	Simplify the code creating the renaming at the end.
  

Patch

diff --git a/gcc/ada/exp_ch3.adb b/gcc/ada/exp_ch3.adb
--- a/gcc/ada/exp_ch3.adb
+++ b/gcc/ada/exp_ch3.adb
@@ -6173,7 +6173,7 @@  package body Exp_Ch3 is
       Obj_Def  : constant Node_Id    := Object_Definition (N);
       Typ      : constant Entity_Id  := Etype (Def_Id);
       Base_Typ : constant Entity_Id  := Base_Type (Typ);
-      Expr_Q   : Node_Id;
+      Next_N   : constant Node_Id    := Next (N);
 
       function Build_Equivalent_Aggregate return Boolean;
       --  If the object has a constrained discriminated type and no initial
@@ -6193,9 +6193,8 @@  package body Exp_Ch3 is
       --  Generate all default initialization actions for object Def_Id. Any
       --  new code is inserted after node After.
 
-      function Rewrite_As_Renaming return Boolean;
-      --  Indicate whether to rewrite a declaration with initialization into an
-      --  object renaming declaration (see below).
+      function OK_To_Rename_Ref (N : Node_Id) return Boolean;
+      --  Return True if N denotes an entity with OK_To_Rename set
 
       --------------------------------
       -- Build_Equivalent_Aggregate --
@@ -6801,91 +6800,21 @@  package body Exp_Ch3 is
          end if;
       end Default_Initialize_Object;
 
-      -------------------------
-      -- Rewrite_As_Renaming --
-      -------------------------
-
-      function Rewrite_As_Renaming return Boolean is
-
-         function OK_To_Rename_Entity_Name (N : Node_Id) return Boolean;
-         --  Return True if N denotes an entity with OK_To_Rename set
-
-         ------------------------------
-         -- OK_To_Rename_Entity_Name --
-         ------------------------------
-
-         function OK_To_Rename_Entity_Name (N : Node_Id) return Boolean is
-         begin
-            return Is_Entity_Name (N)
-              and then Ekind (Entity (N)) = E_Variable
-              and then OK_To_Rename (Entity (N));
-         end OK_To_Rename_Entity_Name;
-
-         Result : constant Boolean :=
-
-         --  If the object declaration appears in the form
-
-         --    Obj : Typ := Func (...);
-
-         --  where Typ both needs finalization and is returned on the secondary
-         --  stack, the object declaration can be rewritten into a dereference
-         --  of the reference to the result built on the secondary stack (see
-         --  Expand_Ctrl_Function_Call for this expansion of the call):
-
-         --    type Axx is access all Typ;
-         --    Rxx : constant Axx := Func (...)'reference;
-         --    Obj : Typ renames Rxx.all;
-
-         --  This avoids an extra copy and the pair of Adjust/Finalize calls.
-
-         (not Is_Library_Level_Entity (Def_Id)
-            and then Nkind (Expr_Q) = N_Explicit_Dereference
-            and then not Comes_From_Source (Expr_Q)
-            and then Nkind (Original_Node (Expr_Q)) = N_Function_Call
-            and then Needs_Finalization (Typ)
-            and then not Is_Class_Wide_Type (Typ))
-
-           --  If the initializing expression is for a variable with attribute
-           --  OK_To_Rename set, then transform:
-
-           --     Obj : Typ := Expr;
-
-           --  into
-
-           --     Obj : Typ renames Expr;
-
-           --  provided that Obj is not aliased. The aliased case has to be
-           --  excluded in general because Expr will not be aliased in general.
+      ----------------------
+      -- OK_To_Rename_Ref --
+      ----------------------
 
-           or else
-             (not Aliased_Present (N)
-               and then (OK_To_Rename_Entity_Name (Expr_Q)
-                          or else
-                         (Nkind (Expr_Q) = N_Slice
-                           and then
-                          OK_To_Rename_Entity_Name (Prefix (Expr_Q)))));
+      function OK_To_Rename_Ref (N : Node_Id) return Boolean is
       begin
-         return Result
-
-           --  The declaration cannot be rewritten if it has got constraints,
-           --  in other words the nominal subtype must be unconstrained.
-
-           and then Is_Entity_Name (Original_Node (Obj_Def))
-
-           --  ??? Return False if there are any aspect specifications, because
-           --  otherwise we duplicate that corresponding implicit attribute
-           --  definition, and call Insert_Action, which has no place to insert
-           --  the attribute definition. The attribute definition is stored in
-           --  Aspect_Rep_Item, which is not a list.
-
-           and then No (Aspect_Specifications (N));
-      end Rewrite_As_Renaming;
+         return Is_Entity_Name (N)
+           and then Ekind (Entity (N)) = E_Variable
+           and then OK_To_Rename (Entity (N));
+      end OK_To_Rename_Ref;
 
       --  Local variables
 
-      Next_N : constant Node_Id := Next (N);
-
       Adj_Call   : Node_Id;
+      Expr_Q     : Node_Id;
       Id_Ref     : Node_Id;
       Tag_Assign : Node_Id;
 
@@ -6895,6 +6824,9 @@  package body Exp_Ch3 is
       --  which case the init proc call must be inserted only after the bodies
       --  of the shared variable procedures have been seen.
 
+      Rewrite_As_Renaming : Boolean := False;
+      --  Whether to turn the declaration into a renaming at the end
+
    --  Start of processing for Expand_N_Object_Declaration
 
    begin
@@ -7442,33 +7374,6 @@  package body Exp_Ch3 is
                end if;
             end if;
 
-            --  If the type needs finalization and is not inherently limited,
-            --  then the target is adjusted after the copy and attached to the
-            --  finalization list. However, no adjustment is needed in the case
-            --  where the object has been initialized by a call to a function
-            --  returning on the primary stack (see Expand_Ctrl_Function_Call)
-            --  since no copy occurred, given that the type is by-reference.
-            --  Similarly, no adjustment is needed if we are going to rewrite
-            --  the object declaration into a renaming declaration.
-
-            if Needs_Finalization (Typ)
-              and then not Is_Limited_View (Typ)
-              and then Nkind (Expr_Q) /= N_Function_Call
-              and then not Rewrite_As_Renaming
-            then
-               Adj_Call :=
-                 Make_Adjust_Call (
-                   Obj_Ref => New_Occurrence_Of (Def_Id, Loc),
-                   Typ     => Base_Typ);
-
-               --  Guard against a missing [Deep_]Adjust when the base type
-               --  was not properly frozen.
-
-               if Present (Adj_Call) then
-                  Insert_Action_After (Init_After, Adj_Call);
-               end if;
-            end if;
-
             --  For tagged types, when an init value is given, the tag has to
             --  be re-initialized separately in order to avoid the propagation
             --  of a wrong tag coming from a view conversion unless the type
@@ -7587,6 +7492,91 @@  package body Exp_Ch3 is
                   Set_Is_Known_Valid (Def_Id);
                end if;
             end if;
+
+            --  Now determine whether we will use a renaming
+
+            Rewrite_As_Renaming :=
+
+              --  If the object declaration appears in the form
+
+              --    Obj : Typ := Func (...);
+
+              --  where Typ needs finalization and is returned on the secondary
+              --  stack, the declaration can be rewritten into a dereference of
+              --  the reference to the result built on the secondary stack (see
+              --  Expand_Ctrl_Function_Call for this expansion of the call):
+
+              --    type Axx is access all Typ;
+              --    Rxx : constant Axx := Func (...)'reference;
+              --    Obj : Typ renames Rxx.all;
+
+              --  This avoids an extra copy and a pair of Adjust/Finalize calls
+
+              ((not Is_Library_Level_Entity (Def_Id)
+                 and then Nkind (Expr_Q) = N_Explicit_Dereference
+                 and then not Comes_From_Source (Expr_Q)
+                 and then Nkind (Original_Node (Expr_Q)) = N_Function_Call
+                 and then Needs_Finalization (Typ)
+                 and then not Is_Class_Wide_Type (Typ))
+
+                --  If the initializing expression is for a variable with flag
+                --  OK_To_Rename set, then transform:
+
+                --     Obj : Typ := Expr;
+
+                --  into
+
+                --     Obj : Typ renames Expr;
+
+                --  provided that Obj is not aliased. The aliased case has to
+                --  be excluded because Expr will not be aliased in general.
+
+               or else (not Aliased_Present (N)
+                         and then (OK_To_Rename_Ref (Expr_Q)
+                                    or else
+                                   (Nkind (Expr_Q) = N_Slice
+                                     and then
+                                    OK_To_Rename_Ref (Prefix (Expr_Q))))))
+
+              --  The declaration cannot be rewritten if it has got constraints
+              --  in other words the nominal subtype must be unconstrained.
+
+              and then Is_Entity_Name (Original_Node (Obj_Def))
+
+              --  ??? Likewise if there are any aspect specifications, because
+              --  otherwise we duplicate that corresponding implicit attribute
+              --  definition and call Insert_Action, which has no place for the
+              --  attribute definition. The attribute definition is stored in
+              --  Aspect_Rep_Item, which is not a list.
+
+              and then No (Aspect_Specifications (N));
+
+            --  If the type needs finalization and is not inherently limited,
+            --  then the target is adjusted after the copy and attached to the
+            --  finalization list. However, no adjustment is needed in the case
+            --  where the object has been initialized by a call to a function
+            --  returning on the primary stack (see Expand_Ctrl_Function_Call)
+            --  since no copy occurred, given that the type is by-reference.
+            --  Similarly, no adjustment is needed if we are going to rewrite
+            --  the object declaration into a renaming declaration.
+
+            if Needs_Finalization (Typ)
+              and then not Is_Limited_View (Typ)
+              and then Nkind (Expr_Q) /= N_Function_Call
+              and then not Rewrite_As_Renaming
+            then
+               Adj_Call :=
+                 Make_Adjust_Call (
+                   Obj_Ref => New_Occurrence_Of (Def_Id, Loc),
+                   Typ     => Base_Typ);
+
+               --  Guard against a missing [Deep_]Adjust when the base type
+               --  was not properly frozen.
+
+               if Present (Adj_Call) then
+                  Insert_Action_After (Init_After, Adj_Call);
+               end if;
+            end if;
          end if;
 
          --  Cases where the back end cannot handle the initialization
@@ -7714,40 +7704,32 @@  package body Exp_Ch3 is
       --  declaration, then this transformation generates what would be
       --  illegal code if written by hand, but that's OK.
 
-      if Present (Expr) then
-         if Rewrite_As_Renaming then
-            Rewrite (N,
-              Make_Object_Renaming_Declaration (Loc,
-                Defining_Identifier => Defining_Identifier (N),
-                Subtype_Mark        => Obj_Def,
-                Name                => Expr_Q));
+      if Rewrite_As_Renaming then
+         Rewrite (N,
+           Make_Object_Renaming_Declaration (Loc,
+             Defining_Identifier => Defining_Identifier (N),
+             Subtype_Mark        => Obj_Def,
+             Name                => Expr_Q));
 
-            --  We do not analyze this renaming declaration, because all its
-            --  components have already been analyzed, and if we were to go
-            --  ahead and analyze it, we would in effect be trying to generate
-            --  another declaration of X, which won't do.
+         --  We do not analyze this renaming declaration, because all its
+         --  components have already been analyzed, and if we were to go
+         --  ahead and analyze it, we would in effect be trying to generate
+         --  another declaration of X, which won't do.
 
-            Set_Renamed_Object (Defining_Identifier (N), Expr_Q);
-            Set_Analyzed (N);
+         Set_Renamed_Object (Defining_Identifier (N), Expr_Q);
+         Set_Analyzed (N);
 
-            --  We do need to deal with debug issues for this renaming
+         --  We do need to deal with debug issues for this renaming
 
-            --  First, if entity comes from source, then mark it as needing
-            --  debug information, even though it is defined by a generated
-            --  renaming that does not come from source.
+         --  First, if entity comes from source, then mark it as needing
+         --  debug information, even though it is defined by a generated
+         --  renaming that does not come from source.
 
-            Set_Debug_Info_Defining_Id (N);
+         Set_Debug_Info_Defining_Id (N);
 
-            --  Now call the routine to generate debug info for the renaming
+         --  Now call the routine to generate debug info for the renaming
 
-            declare
-               Decl : constant Node_Id := Debug_Renaming_Declaration (N);
-            begin
-               if Present (Decl) then
-                  Insert_Action (N, Decl);
-               end if;
-            end;
-         end if;
+         Insert_Action (N, Debug_Renaming_Declaration (N));
       end if;
 
    --  Exception on library entity not available