After the recent implementation work for the Default_Initial_Condition
aspect there were still some cases where DIC checks weren't performed
properly with respect to calls to Initialize in the case of array and
record components of controlled types. That is now corrected. There was
also an issue of Output_Verification_Call getting called on partial DIC
procedures, when it should only be applied to the main DIC procedure
of a type, which could result in extraneous warnings, and that is also
corrected.

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

gcc/ada/

        * exp_aggr.adb (Build_Array_Aggr_Code.Gen_Assign): Move
        generation of the call for DIC check past the optional
        generation of calls to controlled Initialize procedures.
        * exp_ch3.adb
        (Build_Array_Init_Proc.Init_One_Dimension.Possible_DIC_Call):
        Suppress generation of a DIC call when the array component type
        is controlled.  The call will now be generated later inside the
        array's DI (Deep_Initialize) procedure.
        * exp_ch7.adb
        (Make_Deep_Array_Body.Build_Initialize_Statements): Generate a
        DIC call (when needed by the array component type) after any
        call to the component type's controlled Initialize procedure, or
        generate the DIC call by itself if there's no Initialize to
        call.
        * sem_aggr.adb (Resolve_Record_Aggregate.Add_Association):
        Simplify condition to only test Is_Box_Init_By_Default (previous
        condition was overkill, as well as incorrect in some cases).
        * sem_elab.adb (Active_Scenarios.Output_Call): For
        Default_Initial_Condition, suppress call to
        Output_Verification_Call when the subprogram is a partial DIC
        procedure.
diff --git a/gcc/ada/exp_aggr.adb b/gcc/ada/exp_aggr.adb
--- a/gcc/ada/exp_aggr.adb
+++ b/gcc/ada/exp_aggr.adb
@@ -1865,21 +1865,6 @@ package body Exp_Aggr is
                    Typ               => Ctype,
                    With_Default_Init => True));
 
-               --  If Default_Initial_Condition applies to the component type,
-               --  add a DIC check after the component is default-initialized.
-               --  It will be analyzed and resolved before the code for
-               --  initialization of other components.
-
-               --  Theoretically this might also be needed for cases where
-               --  the component type doesn't have an init proc (such as for
-               --  Default_Value cases), but those should be uncommon, and for
-               --  now we only support the init proc case. ???
-
-               if Has_DIC (Ctype) and then Present (DIC_Procedure (Ctype)) then
-                  Append_To (Stmts,
-                    Build_DIC_Call (Loc, New_Copy_Tree (Indexed_Comp), Ctype));
-               end if;
-
                --  If the component type has invariants, add an invariant
                --  check after the component is default-initialized. It will
                --  be analyzed and resolved before the code for initialization
@@ -1910,6 +1895,22 @@ package body Exp_Aggr is
                   Append_To (Stmts, Init_Call);
                end if;
             end if;
+
+            --  If Default_Initial_Condition applies to the component type,
+            --  add a DIC check after the component is default-initialized,
+            --  as well as after an Initialize procedure is called, in the
+            --  case of components of a controlled type. It will be analyzed
+            --  and resolved before the code for initialization of other
+            --  components.
+
+            --  Theoretically this might also be needed for cases where Expr
+            --  is not empty, but a default init still applies, such as for
+            --  Default_Value cases, in which case we won't get here. ???
+
+            if Has_DIC (Ctype) and then Present (DIC_Procedure (Ctype)) then
+               Append_To (Stmts,
+                 Build_DIC_Call (Loc, New_Copy_Tree (Indexed_Comp), Ctype));
+            end if;
          end if;
 
          return Add_Loop_Actions (Stmts);


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
@@ -697,6 +697,11 @@ package body Exp_Ch3 is
 
               and then not GNATprove_Mode
 
+              --  DIC checks for components of controlled types are done later
+              --  (see Exp_Ch7.Make_Deep_Array_Body).
+
+              and then not Is_Controlled (Comp_Type)
+
               and then Present (DIC_Procedure (Comp_Type))
 
               and then not Has_Null_Body (DIC_Procedure (Comp_Type))


diff --git a/gcc/ada/exp_ch7.adb b/gcc/ada/exp_ch7.adb
--- a/gcc/ada/exp_ch7.adb
+++ b/gcc/ada/exp_ch7.adb
@@ -6848,22 +6848,49 @@ package body Exp_Ch7 is
 
          Init_Call := Build_Initialization_Call;
 
-         --  Only create finalization block if there is a non-trivial
-         --  call to initialization.
-
-         if Present (Init_Call)
-           and then Nkind (Init_Call) /= N_Null_Statement
+         --  Only create finalization block if there is a nontrivial call
+         --  to initialization or a Default_Initial_Condition check to be
+         --  performed.
+
+         if (Present (Init_Call)
+              and then Nkind (Init_Call) /= N_Null_Statement)
+           or else
+             (Has_DIC (Comp_Typ)
+               and then not GNATprove_Mode
+               and then Present (DIC_Procedure (Comp_Typ))
+               and then not Has_Null_Body (DIC_Procedure (Comp_Typ)))
          then
-            Init_Loop :=
-              Make_Block_Statement (Loc,
-                Handled_Statement_Sequence =>
-                  Make_Handled_Sequence_Of_Statements (Loc,
-                    Statements         => New_List (Init_Call),
-                    Exception_Handlers => New_List (
-                      Make_Exception_Handler (Loc,
-                        Exception_Choices => New_List (
-                          Make_Others_Choice (Loc)),
-                        Statements        => New_List (Final_Block)))));
+            declare
+               Init_Stmts : constant List_Id := New_List;
+
+            begin
+               if Present (Init_Call) then
+                  Append_To (Init_Stmts, Init_Call);
+               end if;
+
+               if Has_DIC (Comp_Typ)
+                 and then Present (DIC_Procedure (Comp_Typ))
+               then
+                  Append_To
+                    (Init_Stmts,
+                     Build_DIC_Call (Loc,
+                         Make_Indexed_Component (Loc,
+                           Prefix      => Make_Identifier (Loc, Name_V),
+                           Expressions => New_References_To (Index_List, Loc)),
+                         Comp_Typ));
+               end if;
+
+               Init_Loop :=
+                 Make_Block_Statement (Loc,
+                   Handled_Statement_Sequence =>
+                     Make_Handled_Sequence_Of_Statements (Loc,
+                       Statements         => Init_Stmts,
+                       Exception_Handlers => New_List (
+                         Make_Exception_Handler (Loc,
+                           Exception_Choices => New_List (
+                             Make_Others_Choice (Loc)),
+                           Statements        => New_List (Final_Block)))));
+            end;
 
             Append_To (Statements (Handled_Statement_Sequence (Init_Loop)),
               Make_Assignment_Statement (Loc,


diff --git a/gcc/ada/sem_aggr.adb b/gcc/ada/sem_aggr.adb
--- a/gcc/ada/sem_aggr.adb
+++ b/gcc/ada/sem_aggr.adb
@@ -3848,10 +3848,7 @@ package body Sem_Aggr is
          --  by default, then set flag on the new association to indicate that
          --  the original association was for such a box-initialized component.
 
-         if Resolve_Record_Aggregate.Is_Box_Present
-           and then not Is_Box_Present
-           and then Is_Box_Init_By_Default  -- ???
-         then
+         if Is_Box_Init_By_Default then
             Set_Was_Default_Init_Box_Association (Last (Assoc_List));
          end if;
       end Add_Association;


diff --git a/gcc/ada/sem_elab.adb b/gcc/ada/sem_elab.adb
--- a/gcc/ada/sem_elab.adb
+++ b/gcc/ada/sem_elab.adb
@@ -2414,10 +2414,16 @@ package body Sem_Elab is
          --  Default_Initial_Condition
 
          elsif Is_Default_Initial_Condition_Proc (Subp_Id) then
-            Output_Verification_Call
-              (Pred    => "Default_Initial_Condition",
-               Id      => First_Formal_Type (Subp_Id),
-               Id_Kind => "type");
+
+            --  Only do output for a normal DIC procedure, since partial DIC
+            --  procedures are subsidiary to those.
+
+            if not Is_Partial_DIC_Procedure (Subp_Id) then
+               Output_Verification_Call
+                 (Pred    => "Default_Initial_Condition",
+                  Id      => First_Formal_Type (Subp_Id),
+                  Id_Kind => "type");
+            end if;
 
          --  Entries
 


Reply via email to